// 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() {
  if (m_pCache) {
    FX_Free(m_pCache);
  }
  if (m_pRanges) {
    FX_Free(m_pRanges);
  }
  if (m_pAlterCS && m_bOwn) {
    m_pAlterCS->ReleaseCS();
  }
  if (m_pProfile && m_pDocument) {
    m_pDocument->GetPageData()->ReleaseIccProfile(m_pProfile);
  }
}

FX_BOOL CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
  CPDF_Stream* pStream = pArray->GetStream(1);
  if (pStream == NULL) {
    return FALSE;
  }
  m_pProfile = pDoc->LoadIccProfile(pStream);
  if (!m_pProfile) {
    return FALSE;
  }
  m_nComponents =
      m_pProfile
          ->GetComponents();  // Try using the nComponents from ICC profile
  CPDF_Dictionary* pDict = pStream->GetDict();
  if (m_pProfile->m_pTransform == NULL) {  // No valid ICC profile or using sRGB
    CPDF_Object* pAlterCSObj =
        pDict ? pDict->GetElementValue(FX_BSTRC("Alternate")) : NULL;
    if (pAlterCSObj) {
      CPDF_ColorSpace* pAlterCS = CPDF_ColorSpace::Load(pDoc, pAlterCSObj);
      if (pAlterCS) {
        if (m_nComponents == 0) {                 // NO valid ICC profile
          if (pAlterCS->CountComponents() > 0) {  // Use Alternative colorspace
            m_nComponents = pAlterCS->CountComponents();
            m_pAlterCS = pAlterCS;
            m_bOwn = TRUE;
          } else {  // No valid alternative colorspace
            pAlterCS->ReleaseCS();
            int32_t nDictComponents =
                pDict ? pDict->GetInteger(FX_BSTRC("N")) : 0;
            if (nDictComponents != 1 && nDictComponents != 3 &&
                nDictComponents != 4) {
              return FALSE;
            }
            m_nComponents = nDictComponents;
          }

        } else {  // Using sRGB
          if (pAlterCS->CountComponents() != m_nComponents) {
            pAlterCS->ReleaseCS();
          } else {
            m_pAlterCS = pAlterCS;
            m_bOwn = TRUE;
          }
        }
      }
    }
    if (!m_pAlterCS) {
      if (m_nComponents == 1) {
        m_pAlterCS = GetStockCS(PDFCS_DEVICEGRAY);
      } else if (m_nComponents == 3) {
        m_pAlterCS = GetStockCS(PDFCS_DEVICERGB);
      } else if (m_nComponents == 4) {
        m_pAlterCS = GetStockCS(PDFCS_DEVICECMYK);
      }
    }
  }
  CPDF_Array* pRanges = pDict->GetArray(FX_BSTRC("Range"));
  m_pRanges = FX_Alloc2D(FX_FLOAT, m_nComponents, 2);
  for (int i = 0; i < m_nComponents * 2; i++) {
    if (pRanges) {
      m_pRanges[i] = pRanges->GetNumber(i);
    } else if (i % 2) {
      m_pRanges[i] = 1.0f;
    } else {
      m_pRanges[i] = 0;
    }
  }
  return TRUE;
}
FX_BOOL CPDF_ICCBasedCS::GetRGB(FX_FLOAT* pBuf,
                                FX_FLOAT& R,
                                FX_FLOAT& G,
                                FX_FLOAT& B) const {
  if (m_pProfile && m_pProfile->m_bsRGB) {
    R = pBuf[0];
    G = pBuf[1];
    B = pBuf[2];
    return TRUE;
  }
  ICodec_IccModule* pIccModule = CPDF_ModuleMgr::Get()->GetIccModule();
  if (m_pProfile->m_pTransform == NULL || pIccModule == NULL) {
    if (m_pAlterCS) {
      m_pAlterCS->GetRGB(pBuf, R, G, B);
    } else {
      R = G = B = 0.0f;
    }
    return TRUE;
  }
  FX_FLOAT rgb[3];
  pIccModule->SetComponents(m_nComponents);
  pIccModule->Translate(m_pProfile->m_pTransform, pBuf, rgb);
  R = rgb[0];
  G = rgb[1];
  B = rgb[2];
  return TRUE;
}
FX_BOOL CPDF_ICCBasedCS::v_GetCMYK(FX_FLOAT* pBuf,
                                   FX_FLOAT& c,
                                   FX_FLOAT& m,
                                   FX_FLOAT& y,
                                   FX_FLOAT& k) const {
  if (m_nComponents != 4) {
    return FALSE;
  }
  c = pBuf[0];
  m = pBuf[1];
  y = pBuf[2];
  k = pBuf[3];
  return TRUE;
}
FX_BOOL CPDF_ICCBasedCS::SetRGB(FX_FLOAT* pBuf,
                                FX_FLOAT R,
                                FX_FLOAT G,
                                FX_FLOAT B) const {
  return FALSE;
}
void CPDF_ICCBasedCS::EnableStdConversion(FX_BOOL bEnabled) {
  CPDF_ColorSpace::EnableStdConversion(bEnabled);
  if (m_pAlterCS) {
    m_pAlterCS->EnableStdConversion(bEnabled);
  }
}
void CPDF_ICCBasedCS::TranslateImageLine(uint8_t* pDestBuf,
                                         const uint8_t* pSrcBuf,
                                         int pixels,
                                         int image_width,
                                         int image_height,
                                         FX_BOOL bTransMask) const {
  if (m_pProfile->m_bsRGB) {
    ReverseRGB(pDestBuf, pSrcBuf, pixels);
  } else if (m_pProfile->m_pTransform) {
    int nMaxColors = 1;
    for (int i = 0; i < m_nComponents; i++) {
      nMaxColors *= 52;
    }
    if (m_nComponents > 3 || image_width * image_height < nMaxColors * 3 / 2) {
      CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(
          m_pProfile->m_pTransform, pDestBuf, pSrcBuf, pixels);
    } else {
      if (m_pCache == NULL) {
        ((CPDF_ICCBasedCS*)this)->m_pCache = FX_Alloc2D(uint8_t, nMaxColors, 3);
        uint8_t* temp_src = FX_Alloc2D(uint8_t, nMaxColors, m_nComponents);
        uint8_t* pSrc = temp_src;
        for (int i = 0; i < nMaxColors; i++) {
          FX_DWORD color = i;
          FX_DWORD order = nMaxColors / 52;
          for (int c = 0; c < m_nComponents; c++) {
            *pSrc++ = (uint8_t)(color / order * 5);
            color %= order;
            order /= 52;
          }
        }
        CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(
            m_pProfile->m_pTransform, m_pCache, temp_src, nMaxColors);
        FX_Free(temp_src);
      }
      for (int i = 0; i < pixels; i++) {
        int index = 0;
        for (int c = 0; c < m_nComponents; c++) {
          index = index * 52 + (*pSrcBuf) / 5;
          pSrcBuf++;
        }
        index *= 3;
        *pDestBuf++ = m_pCache[index];
        *pDestBuf++ = m_pCache[index + 1];
        *pDestBuf++ = m_pCache[index + 2];
      }
    }
  } else if (m_pAlterCS) {
    m_pAlterCS->TranslateImageLine(pDestBuf, pSrcBuf, pixels, image_width,
                                   image_height);
  }
}
class CPDF_IndexedCS : public CPDF_ColorSpace {
 public:
  explicit CPDF_IndexedCS(CPDF_Document* pDoc)
      : CPDF_ColorSpace(pDoc, PDFCS_INDEXED, 1),
        m_pBaseCS(nullptr),
        m_pCountedBaseCS(nullptr),
        m_pCompMinMax(nullptr) {}
  ~CPDF_IndexedCS() override;

  FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
  FX_BOOL GetRGB(FX_FLOAT* pBuf,
                 FX_FLOAT& R,
                 FX_FLOAT& G,
                 FX_FLOAT& B) const override;
  CPDF_ColorSpace* GetBaseCS() const override;
  void EnableStdConversion(FX_BOOL bEnabled) override;

  CPDF_ColorSpace* m_pBaseCS;
  CPDF_CountedColorSpace* m_pCountedBaseCS;
  int m_nBaseComponents;
  int m_MaxIndex;
  CFX_ByteString m_Table;
  FX_FLOAT* m_pCompMinMax;
};
CPDF_IndexedCS::~CPDF_IndexedCS() {
  if (m_pCompMinMax) {
    FX_Free(m_pCompMinMax);
  }
  CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : NULL;
  if (pCS && m_pDocument) {
    m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
  }
}
FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
  if (pArray->GetCount() < 4) {
    return FALSE;
  }
  CPDF_Object* pBaseObj = pArray->GetElementValue(1);
  if (pBaseObj == m_pArray) {
    return FALSE;
  }
  CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
  m_pBaseCS = pDocPageData->GetColorSpace(pBaseObj, NULL);
  if (m_pBaseCS == NULL) {
    return FALSE;
  }
  m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray());
  m_nBaseComponents = m_pBaseCS->CountComponents();
  m_pCompMinMax = FX_Alloc2D(FX_FLOAT, m_nBaseComponents, 2);
  FX_FLOAT defvalue;
  for (int i = 0; i < m_nBaseComponents; i++) {
    m_pBaseCS->GetDefaultValue(i, defvalue, m_pCompMinMax[i * 2],
                               m_pCompMinMax[i * 2 + 1]);
    m_pCompMinMax[i * 2 + 1] -= m_pCompMinMax[i * 2];
  }
  m_MaxIndex = pArray->GetInteger(2);
  CPDF_Object* pTableObj = pArray->GetElementValue(3);
  if (pTableObj == NULL) {
    return FALSE;
  }
  if (pTableObj->GetType() == PDFOBJ_STRING) {
    m_Table = ((CPDF_String*)pTableObj)->GetString();
  } else if (pTableObj->GetType() == PDFOBJ_STREAM) {
    CPDF_StreamAcc acc;
    acc.LoadAllData((CPDF_Stream*)pTableObj, FALSE);
    m_Table = CFX_ByteStringC(acc.GetData(), acc.GetSize());
  }
  return TRUE;
}

FX_BOOL CPDF_IndexedCS::GetRGB(FX_FLOAT* pBuf,
                               FX_FLOAT& R,
                               FX_FLOAT& G,
                               FX_FLOAT& B) const {
  int index = (int32_t)(*pBuf);
  if (index < 0 || index > m_MaxIndex) {
    return FALSE;
  }
  if (m_nBaseComponents) {
    if (index == INT_MAX || (index + 1) > INT_MAX / m_nBaseComponents ||
        (index + 1) * m_nBaseComponents > (int)m_Table.GetLength()) {
      R = G = B = 0;
      return FALSE;
    }
  }
  CFX_FixedBufGrow<FX_FLOAT, 16> Comps(m_nBaseComponents);
  FX_FLOAT* comps = Comps;
  const uint8_t* pTable = m_Table;
  for (int i = 0; i < m_nBaseComponents; i++) {
    comps[i] =
        m_pCompMinMax[i * 2] +
        m_pCompMinMax[i * 2 + 1] * pTable[index * m_nBaseComponents + i] / 255;
  }
  m_pBaseCS->GetRGB(comps, R, G, B);
  return TRUE;
}
CPDF_ColorSpace* CPDF_IndexedCS::GetBaseCS() const {
  return m_pBaseCS;
}
void CPDF_IndexedCS::EnableStdConversion(FX_BOOL bEnabled) {
  CPDF_ColorSpace::EnableStdConversion(bEnabled);
  if (m_pBaseCS) {
    m_pBaseCS->EnableStdConversion(bEnabled);
  }
}
#define MAX_PATTERN_COLORCOMPS 16
typedef struct _PatternValue {
  CPDF_Pattern* m_pPattern;
  CPDF_CountedPattern* m_pCountedPattern;
  int m_nComps;
  FX_FLOAT m_Comps[MAX_PATTERN_COLORCOMPS];
} PatternValue;
CPDF_PatternCS::~CPDF_PatternCS() {
  CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : NULL;
  if (pCS && m_pDocument) {
    m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
  }
}
FX_BOOL CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
  CPDF_Object* pBaseCS = pArray->GetElementValue(1);
  if (pBaseCS == m_pArray) {
    return FALSE;
  }
  CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
  m_pBaseCS = pDocPageData->GetColorSpace(pBaseCS, NULL);
  if (m_pBaseCS) {
    if (m_pBaseCS->GetFamily() == PDFCS_PATTERN) {
      return FALSE;
    }
    m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray());
    m_nComponents = m_pBaseCS->CountComponents() + 1;
    if (m_pBaseCS->CountComponents() > MAX_PATTERN_COLORCOMPS) {
      return FALSE;
    }
  } else {
    m_nComponents = 1;
  }
  return TRUE;
}
FX_BOOL CPDF_PatternCS::GetRGB(FX_FLOAT* pBuf,
                               FX_FLOAT& R,
                               FX_FLOAT& G,
                               FX_FLOAT& B) const {
  if (m_pBaseCS) {
    ASSERT(m_pBaseCS->GetFamily() != PDFCS_PATTERN);
    PatternValue* pvalue = (PatternValue*)pBuf;
    if (m_pBaseCS->GetRGB(pvalue->m_Comps, R, G, B)) {
      return TRUE;
    }
  }
  R = G = B = 0.75f;
  return FALSE;
}
CPDF_ColorSpace* CPDF_PatternCS::GetBaseCS() const {
  return m_pBaseCS;
}
class CPDF_SeparationCS : public CPDF_ColorSpace {
 public:
  CPDF_SeparationCS(CPDF_Document* pDoc)
      : CPDF_ColorSpace(pDoc, PDFCS_SEPARATION, 1),
        m_pAltCS(nullptr),
        m_pFunc(nullptr) {}
  ~CPDF_SeparationCS() override;
  void GetDefaultValue(int iComponent,
                       FX_FLOAT& value,
                       FX_FLOAT& min,
                       FX_FLOAT& max) const override;
  FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
  FX_BOOL GetRGB(FX_FLOAT* pBuf,
                 FX_FLOAT& R,
                 FX_FLOAT& G,
                 FX_FLOAT& B) const override;
  void EnableStdConversion(FX_BOOL bEnabled) override;

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

  CPDF_ColorSpace* m_pAltCS;
  CPDF_Function* m_pFunc;
};
CPDF_DeviceNCS::~CPDF_DeviceNCS() {
  delete m_pFunc;
  if (m_pAltCS) {
    m_pAltCS->ReleaseCS();
  }
}
void CPDF_DeviceNCS::GetDefaultValue(int iComponent,
                                     FX_FLOAT& value,
                                     FX_FLOAT& min,
                                     FX_FLOAT& max) const {
  value = 1.0f;
  min = 0;
  max = 1.0f;
}
FX_BOOL CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
  CPDF_Object* pObj = pArray->GetElementValue(1);
  if (!pObj) {
    return FALSE;
  }
  if (pObj->GetType() != PDFOBJ_ARRAY) {
    return FALSE;
  }
  m_nComponents = ((CPDF_Array*)pObj)->GetCount();
  CPDF_Object* pAltCS = pArray->GetElementValue(2);
  if (!pAltCS || pAltCS == m_pArray) {
    return FALSE;
  }
  m_pAltCS = Load(pDoc, pAltCS);
  m_pFunc = CPDF_Function::Load(pArray->GetElementValue(3));
  if (m_pAltCS == NULL || m_pFunc == NULL) {
    return FALSE;
  }
  if (m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) {
    return FALSE;
  }
  return TRUE;
}
FX_BOOL CPDF_DeviceNCS::GetRGB(FX_FLOAT* pBuf,
                               FX_FLOAT& R,
                               FX_FLOAT& G,
                               FX_FLOAT& B) const {
  if (m_pFunc == NULL) {
    return FALSE;
  }
  CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs());
  int nresults = 0;
  m_pFunc->Call(pBuf, m_nComponents, results, nresults);
  if (nresults == 0) {
    return FALSE;
  }
  m_pAltCS->GetRGB(results, R, G, B);
  return TRUE;
}
void CPDF_DeviceNCS::EnableStdConversion(FX_BOOL bEnabled) {
  CPDF_ColorSpace::EnableStdConversion(bEnabled);
  if (m_pAltCS) {
    m_pAltCS->EnableStdConversion(bEnabled);
  }
}
CPDF_ColorSpace* CPDF_ColorSpace::GetStockCS(int family) {
  return CPDF_ModuleMgr::Get()->GetPageModule()->GetStockCS(family);
  ;
}
CPDF_ColorSpace* _CSFromName(const CFX_ByteString& name) {
  if (name == FX_BSTRC("DeviceRGB") || name == FX_BSTRC("RGB")) {
    return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
  }
  if (name == FX_BSTRC("DeviceGray") || name == FX_BSTRC("G")) {
    return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
  }
  if (name == FX_BSTRC("DeviceCMYK") || name == FX_BSTRC("CMYK")) {
    return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
  }
  if (name == FX_BSTRC("Pattern")) {
    return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
  }
  return NULL;
}
CPDF_ColorSpace* CPDF_ColorSpace::Load(CPDF_Document* pDoc, CPDF_Object* pObj) {
  if (pObj == NULL) {
    return NULL;
  }
  if (pObj->GetType() == PDFOBJ_NAME) {
    return _CSFromName(pObj->GetString());
  }
  if (pObj->GetType() == PDFOBJ_STREAM) {
    CPDF_Dictionary* pDict = ((CPDF_Stream*)pObj)->GetDict();
    if (!pDict) {
      return NULL;
    }
    CPDF_ColorSpace* pRet = NULL;
    FX_POSITION pos = pDict->GetStartPos();
    while (pos) {
      CFX_ByteString bsKey;
      CPDF_Object* pValue = pDict->GetNextElement(pos, bsKey);
      if (pValue && pValue->GetType() == PDFOBJ_NAME) {
        pRet = _CSFromName(pValue->GetString());
      }
      if (pRet) {
        return pRet;
      }
    }
    return NULL;
  }
  if (pObj->GetType() != PDFOBJ_ARRAY) {
    return NULL;
  }
  CPDF_Array* pArray = (CPDF_Array*)pObj;
  if (pArray->GetCount() == 0) {
    return NULL;
  }
  CPDF_Object* pFamilyObj = pArray->GetElementValue(0);
  if (!pFamilyObj) {
    return NULL;
  }
  CFX_ByteString familyname = pFamilyObj->GetString();
  if (pArray->GetCount() == 1) {
    return _CSFromName(familyname);
  }
  CPDF_ColorSpace* pCS = NULL;
  FX_DWORD id = familyname.GetID();
  if (id == FXBSTR_ID('C', 'a', 'l', 'G')) {
    pCS = new CPDF_CalGray(pDoc);
  } else if (id == FXBSTR_ID('C', 'a', 'l', 'R')) {
    pCS = new CPDF_CalRGB(pDoc);
  } else if (id == FXBSTR_ID('L', 'a', 'b', 0)) {
    pCS = new CPDF_LabCS(pDoc);
  } else if (id == FXBSTR_ID('I', 'C', 'C', 'B')) {
    pCS = new CPDF_ICCBasedCS(pDoc);
  } else if (id == FXBSTR_ID('I', 'n', 'd', 'e') ||
             id == FXBSTR_ID('I', 0, 0, 0)) {
    pCS = new CPDF_IndexedCS(pDoc);
  } else if (id == FXBSTR_ID('S', 'e', 'p', 'a')) {
    pCS = new CPDF_SeparationCS(pDoc);
  } else if (id == FXBSTR_ID('D', 'e', 'v', 'i')) {
    pCS = new CPDF_DeviceNCS(pDoc);
  } else if (id == FXBSTR_ID('P', 'a', 't', 't')) {
    pCS = new CPDF_PatternCS(pDoc);
  } else {
    return NULL;
  }
  pCS->m_pArray = pArray;
  if (!pCS->v_Load(pDoc, pArray)) {
    pCS->ReleaseCS();
    return NULL;
  }
  return pCS;
}
void CPDF_ColorSpace::ReleaseCS() {
  if (this == GetStockCS(PDFCS_DEVICERGB)) {
    return;
  }
  if (this == GetStockCS(PDFCS_DEVICEGRAY)) {
    return;
  }
  if (this == GetStockCS(PDFCS_DEVICECMYK)) {
    return;
  }
  if (this == GetStockCS(PDFCS_PATTERN)) {
    return;
  }
  delete this;
}
int CPDF_ColorSpace::GetBufSize() const {
  if (m_Family == PDFCS_PATTERN) {
    return sizeof(PatternValue);
  }
  return m_nComponents * sizeof(FX_FLOAT);
}
FX_FLOAT* CPDF_ColorSpace::CreateBuf() {
  int size = GetBufSize();
  uint8_t* pBuf = FX_Alloc(uint8_t, size);
  return (FX_FLOAT*)pBuf;
}
FX_BOOL CPDF_ColorSpace::sRGB() const {
  if (m_Family == PDFCS_DEVICERGB) {
    return TRUE;
  }
  if (m_Family != PDFCS_ICCBASED) {
    return FALSE;
  }
  CPDF_ICCBasedCS* pCS = (CPDF_ICCBasedCS*)this;
  return pCS->m_pProfile->m_bsRGB;
}
FX_BOOL CPDF_ColorSpace::GetCMYK(FX_FLOAT* pBuf,
                                 FX_FLOAT& c,
                                 FX_FLOAT& m,
                                 FX_FLOAT& y,
                                 FX_FLOAT& k) const {
  if (v_GetCMYK(pBuf, c, m, y, k)) {
    return TRUE;
  }
  FX_FLOAT R, G, B;
  if (!GetRGB(pBuf, R, G, B)) {
    return FALSE;
  }
  sRGB_to_AdobeCMYK(R, G, B, c, m, y, k);
  return TRUE;
}
FX_BOOL CPDF_ColorSpace::SetCMYK(FX_FLOAT* pBuf,
                                 FX_FLOAT c,
                                 FX_FLOAT m,
                                 FX_FLOAT y,
                                 FX_FLOAT k) const {
  if (v_SetCMYK(pBuf, c, m, y, k)) {
    return TRUE;
  }
  FX_FLOAT R, G, B;
  AdobeCMYK_to_sRGB(c, m, y, k, R, G, B);
  return SetRGB(pBuf, R, G, B);
}
void CPDF_ColorSpace::GetDefaultColor(FX_FLOAT* buf) const {
  if (buf == NULL || m_Family == PDFCS_PATTERN) {
    return;
  }
  FX_FLOAT min, max;
  for (int i = 0; i < m_nComponents; i++) {
    GetDefaultValue(i, buf[i], min, max);
  }
}
int CPDF_ColorSpace::GetMaxIndex() const {
  if (m_Family != PDFCS_INDEXED) {
    return 0;
  }
  CPDF_IndexedCS* pCS = (CPDF_IndexedCS*)this;
  return pCS->m_MaxIndex;
}
void CPDF_ColorSpace::TranslateImageLine(uint8_t* dest_buf,
                                         const uint8_t* src_buf,
                                         int pixels,
                                         int image_width,
                                         int image_height,
                                         FX_BOOL bTransMask) const {
  CFX_FixedBufGrow<FX_FLOAT, 16> srcbuf(m_nComponents);
  FX_FLOAT* src = srcbuf;
  FX_FLOAT R, G, B;
  for (int i = 0; i < pixels; i++) {
    for (int j = 0; j < m_nComponents; j++)
      if (m_Family == PDFCS_INDEXED) {
        src[j] = (FX_FLOAT)(*src_buf++);
      } else {
        src[j] = (FX_FLOAT)(*src_buf++) / 255;
      }
    GetRGB(src, R, G, B);
    *dest_buf++ = (int32_t)(B * 255);
    *dest_buf++ = (int32_t)(G * 255);
    *dest_buf++ = (int32_t)(R * 255);
  }
}
void CPDF_ColorSpace::EnableStdConversion(FX_BOOL bEnabled) {
  if (bEnabled) {
    m_dwStdConversion++;
  } else if (m_dwStdConversion) {
    m_dwStdConversion--;
  }
}
CPDF_Color::CPDF_Color(int family) {
  m_pCS = CPDF_ColorSpace::GetStockCS(family);
  int nComps = 3;
  if (family == PDFCS_DEVICEGRAY) {
    nComps = 1;
  } else if (family == PDFCS_DEVICECMYK) {
    nComps = 4;
  }
  m_pBuffer = FX_Alloc(FX_FLOAT, nComps);
  for (int i = 0; i < nComps; i++) {
    m_pBuffer[i] = 0;
  }
}
CPDF_Color::~CPDF_Color() {
  ReleaseBuffer();
  ReleaseColorSpace();
}
void CPDF_Color::ReleaseBuffer() {
  if (!m_pBuffer) {
    return;
  }
  if (m_pCS->GetFamily() == PDFCS_PATTERN) {
    PatternValue* pvalue = (PatternValue*)m_pBuffer;
    CPDF_Pattern* pPattern =
        pvalue->m_pCountedPattern ? pvalue->m_pCountedPattern->get() : NULL;
    if (pPattern && pPattern->m_pDocument) {
      CPDF_DocPageData* pPageData = pPattern->m_pDocument->GetPageData();
      if (pPageData) {
        pPageData->ReleasePattern(pPattern->m_pPatternObj);
      }
    }
  }
  FX_Free(m_pBuffer);
  m_pBuffer = NULL;
}
void CPDF_Color::ReleaseColorSpace() {
  if (m_pCS && m_pCS->m_pDocument && m_pCS->GetArray()) {
    m_pCS->m_pDocument->GetPageData()->ReleaseColorSpace(m_pCS->GetArray());
    m_pCS = NULL;
  }
}
void CPDF_Color::SetColorSpace(CPDF_ColorSpace* pCS) {
  if (m_pCS == pCS) {
    if (m_pBuffer == NULL) {
      m_pBuffer = pCS->CreateBuf();
    }
    ReleaseColorSpace();
    m_pCS = pCS;
    return;
  }
  ReleaseBuffer();
  ReleaseColorSpace();
  m_pCS = pCS;
  if (m_pCS) {
    m_pBuffer = pCS->CreateBuf();
    pCS->GetDefaultColor(m_pBuffer);
  }
}
void CPDF_Color::SetValue(FX_FLOAT* comps) {
  if (m_pBuffer == NULL) {
    return;
  }
  if (m_pCS->GetFamily() != PDFCS_PATTERN) {
    FXSYS_memcpy(m_pBuffer, comps, m_pCS->CountComponents() * sizeof(FX_FLOAT));
  }
}
void CPDF_Color::SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comps, int ncomps) {
  if (ncomps > MAX_PATTERN_COLORCOMPS) {
    return;
  }
  if (m_pCS == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
    if (m_pBuffer) {
      FX_Free(m_pBuffer);
    }
    m_pCS = CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
    m_pBuffer = m_pCS->CreateBuf();
  }
  CPDF_DocPageData* pDocPageData = NULL;
  PatternValue* pvalue = (PatternValue*)m_pBuffer;
  if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) {
    pDocPageData = pvalue->m_pPattern->m_pDocument->GetPageData();
    if (pDocPageData) {
      pDocPageData->ReleasePattern(pvalue->m_pPattern->m_pPatternObj);
    }
  }
  pvalue->m_nComps = ncomps;
  pvalue->m_pPattern = pPattern;
  if (ncomps) {
    FXSYS_memcpy(pvalue->m_Comps, comps, ncomps * sizeof(FX_FLOAT));
  }
  pvalue->m_pCountedPattern = NULL;
  if (pPattern && pPattern->m_pDocument) {
    if (!pDocPageData) {
      pDocPageData = pPattern->m_pDocument->GetPageData();
    }
    pvalue->m_pCountedPattern =
        pDocPageData->FindPatternPtr(pPattern->m_pPatternObj);
  }
}
void CPDF_Color::Copy(const CPDF_Color* pSrc) {
  ReleaseBuffer();
  ReleaseColorSpace();
  m_pCS = pSrc->m_pCS;
  if (m_pCS && m_pCS->m_pDocument) {
    CPDF_Array* pArray = m_pCS->GetArray();
    if (pArray) {
      m_pCS = m_pCS->m_pDocument->GetPageData()->GetCopiedColorSpace(pArray);
    }
  }
  if (m_pCS == NULL) {
    return;
  }
  m_pBuffer = m_pCS->CreateBuf();
  FXSYS_memcpy(m_pBuffer, pSrc->m_pBuffer, m_pCS->GetBufSize());
  if (m_pCS->GetFamily() == PDFCS_PATTERN) {
    PatternValue* pvalue = (PatternValue*)m_pBuffer;
    if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) {
      pvalue->m_pPattern =
          pvalue->m_pPattern->m_pDocument->GetPageData()->GetPattern(
              pvalue->m_pPattern->m_pPatternObj, FALSE,
              &pvalue->m_pPattern->m_ParentMatrix);
    }
  }
}
FX_BOOL CPDF_Color::GetRGB(int& R, int& G, int& B) const {
  if (m_pCS == NULL || m_pBuffer == NULL) {
    return FALSE;
  }
  FX_FLOAT r = 0.0f, g = 0.0f, b = 0.0f;
  if (!m_pCS->GetRGB(m_pBuffer, r, g, b)) {
    return FALSE;
  }
  R = (int32_t)(r * 255 + 0.5f);
  G = (int32_t)(g * 255 + 0.5f);
  B = (int32_t)(b * 255 + 0.5f);
  return TRUE;
}
CPDF_Pattern* CPDF_Color::GetPattern() const {
  if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
    return NULL;
  }
  PatternValue* pvalue = (PatternValue*)m_pBuffer;
  return pvalue->m_pPattern;
}
CPDF_ColorSpace* CPDF_Color::GetPatternCS() const {
  if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
    return NULL;
  }
  return m_pCS->GetBaseCS();
}
FX_FLOAT* CPDF_Color::GetPatternColor() const {
  if (m_pBuffer == NULL || m_pCS->GetFamily() != PDFCS_PATTERN) {
    return NULL;
  }
  PatternValue* pvalue = (PatternValue*)m_pBuffer;
  return pvalue->m_nComps ? pvalue->m_Comps : NULL;
}
FX_BOOL CPDF_Color::IsEqual(const CPDF_Color& other) const {
  if (m_pCS != other.m_pCS || m_pCS == NULL) {
    return FALSE;
  }
  return FXSYS_memcmp(m_pBuffer, other.m_pBuffer, m_pCS->GetBufSize()) == 0;
}
