// 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 "core/fpdfapi/page/pageint.h"

#include <limits.h>

#include <algorithm>
#include <memory>
#include <utility>
#include <vector>

#include "core/fpdfapi/page/cpdf_psengine.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_simple_parser.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fxcrt/fx_safe_types.h"

namespace {

struct PDF_PSOpName {
  const FX_CHAR* name;
  PDF_PSOP op;
};

const PDF_PSOpName kPsOpNames[] = {
    {"add", PSOP_ADD},         {"sub", PSOP_SUB},
    {"mul", PSOP_MUL},         {"div", PSOP_DIV},
    {"idiv", PSOP_IDIV},       {"mod", PSOP_MOD},
    {"neg", PSOP_NEG},         {"abs", PSOP_ABS},
    {"ceiling", PSOP_CEILING}, {"floor", PSOP_FLOOR},
    {"round", PSOP_ROUND},     {"truncate", PSOP_TRUNCATE},
    {"sqrt", PSOP_SQRT},       {"sin", PSOP_SIN},
    {"cos", PSOP_COS},         {"atan", PSOP_ATAN},
    {"exp", PSOP_EXP},         {"ln", PSOP_LN},
    {"log", PSOP_LOG},         {"cvi", PSOP_CVI},
    {"cvr", PSOP_CVR},         {"eq", PSOP_EQ},
    {"ne", PSOP_NE},           {"gt", PSOP_GT},
    {"ge", PSOP_GE},           {"lt", PSOP_LT},
    {"le", PSOP_LE},           {"and", PSOP_AND},
    {"or", PSOP_OR},           {"xor", PSOP_XOR},
    {"not", PSOP_NOT},         {"bitshift", PSOP_BITSHIFT},
    {"true", PSOP_TRUE},       {"false", PSOP_FALSE},
    {"if", PSOP_IF},           {"ifelse", PSOP_IFELSE},
    {"pop", PSOP_POP},         {"exch", PSOP_EXCH},
    {"dup", PSOP_DUP},         {"copy", PSOP_COPY},
    {"index", PSOP_INDEX},     {"roll", PSOP_ROLL}};

// See PDF Reference 1.7, page 170, table 3.36.
bool IsValidBitsPerSample(uint32_t x) {
  switch (x) {
    case 1:
    case 2:
    case 4:
    case 8:
    case 12:
    case 16:
    case 24:
    case 32:
      return true;
    default:
      return false;
  }
}

// See PDF Reference 1.7, page 170.
FX_FLOAT PDF_Interpolate(FX_FLOAT x,
                         FX_FLOAT xmin,
                         FX_FLOAT xmax,
                         FX_FLOAT ymin,
                         FX_FLOAT ymax) {
  FX_FLOAT divisor = xmax - xmin;
  return ymin + (divisor ? (x - xmin) * (ymax - ymin) / divisor : 0);
}

class CPDF_PSFunc : public CPDF_Function {
 public:
  CPDF_PSFunc() : CPDF_Function(Type::kType4PostScript) {}
  ~CPDF_PSFunc() override {}

  // CPDF_Function
  FX_BOOL v_Init(CPDF_Object* pObj) override;
  FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override;

 private:
  CPDF_PSEngine m_PS;
};

FX_BOOL CPDF_PSFunc::v_Init(CPDF_Object* pObj) {
  CPDF_StreamAcc acc;
  acc.LoadAllData(pObj->AsStream(), FALSE);
  return m_PS.Parse(reinterpret_cast<const FX_CHAR*>(acc.GetData()),
                    acc.GetSize());
}

FX_BOOL CPDF_PSFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
  CPDF_PSEngine& PS = const_cast<CPDF_PSEngine&>(m_PS);
  PS.Reset();
  for (uint32_t i = 0; i < m_nInputs; i++)
    PS.Push(inputs[i]);
  PS.Execute();
  if (PS.GetStackSize() < m_nOutputs)
    return FALSE;
  for (uint32_t i = 0; i < m_nOutputs; i++)
    results[m_nOutputs - i - 1] = PS.Pop();
  return TRUE;
}

}  // namespace

class CPDF_PSOP {
 public:
  explicit CPDF_PSOP(PDF_PSOP op) : m_op(op), m_value(0) {
    ASSERT(m_op != PSOP_CONST);
    ASSERT(m_op != PSOP_PROC);
  }
  explicit CPDF_PSOP(FX_FLOAT value) : m_op(PSOP_CONST), m_value(value) {}
  explicit CPDF_PSOP(std::unique_ptr<CPDF_PSProc> proc)
      : m_op(PSOP_PROC), m_value(0), m_proc(std::move(proc)) {}

  FX_FLOAT GetFloatValue() const {
    if (m_op == PSOP_CONST)
      return m_value;

    ASSERT(false);
    return 0;
  }
  CPDF_PSProc* GetProc() const {
    if (m_op == PSOP_PROC)
      return m_proc.get();
    ASSERT(false);
    return nullptr;
  }

  PDF_PSOP GetOp() const { return m_op; }

 private:
  const PDF_PSOP m_op;
  const FX_FLOAT m_value;
  std::unique_ptr<CPDF_PSProc> m_proc;
};

FX_BOOL CPDF_PSEngine::Execute() {
  return m_MainProc.Execute(this);
}

CPDF_PSProc::CPDF_PSProc() {}
CPDF_PSProc::~CPDF_PSProc() {}

FX_BOOL CPDF_PSProc::Execute(CPDF_PSEngine* pEngine) {
  for (size_t i = 0; i < m_Operators.size(); ++i) {
    const PDF_PSOP op = m_Operators[i]->GetOp();
    if (op == PSOP_PROC)
      continue;

    if (op == PSOP_CONST) {
      pEngine->Push(m_Operators[i]->GetFloatValue());
      continue;
    }

    if (op == PSOP_IF) {
      if (i == 0 || m_Operators[i - 1]->GetOp() != PSOP_PROC)
        return FALSE;

      if (static_cast<int>(pEngine->Pop()))
        m_Operators[i - 1]->GetProc()->Execute(pEngine);
    } else if (op == PSOP_IFELSE) {
      if (i < 2 || m_Operators[i - 1]->GetOp() != PSOP_PROC ||
          m_Operators[i - 2]->GetOp() != PSOP_PROC) {
        return FALSE;
      }
      size_t offset = static_cast<int>(pEngine->Pop()) ? 2 : 1;
      m_Operators[i - offset]->GetProc()->Execute(pEngine);
    } else {
      pEngine->DoOperator(op);
    }
  }
  return TRUE;
}

CPDF_PSEngine::CPDF_PSEngine() {
  m_StackCount = 0;
}
CPDF_PSEngine::~CPDF_PSEngine() {}
void CPDF_PSEngine::Push(FX_FLOAT v) {
  if (m_StackCount == PSENGINE_STACKSIZE) {
    return;
  }
  m_Stack[m_StackCount++] = v;
}
FX_FLOAT CPDF_PSEngine::Pop() {
  if (m_StackCount == 0) {
    return 0;
  }
  return m_Stack[--m_StackCount];
}
FX_BOOL CPDF_PSEngine::Parse(const FX_CHAR* str, int size) {
  CPDF_SimpleParser parser((uint8_t*)str, size);
  CFX_ByteStringC word = parser.GetWord();
  if (word != "{") {
    return FALSE;
  }
  return m_MainProc.Parse(&parser, 0);
}

FX_BOOL CPDF_PSProc::Parse(CPDF_SimpleParser* parser, int depth) {
  if (depth > kMaxDepth)
    return FALSE;

  while (1) {
    CFX_ByteStringC word = parser->GetWord();
    if (word.IsEmpty()) {
      return FALSE;
    }
    if (word == "}") {
      return TRUE;
    }
    if (word == "{") {
      std::unique_ptr<CPDF_PSProc> proc(new CPDF_PSProc);
      std::unique_ptr<CPDF_PSOP> op(new CPDF_PSOP(std::move(proc)));
      m_Operators.push_back(std::move(op));
      if (!m_Operators.back()->GetProc()->Parse(parser, depth + 1)) {
        return FALSE;
      }
    } else {
      bool found = false;
      for (const PDF_PSOpName& op_name : kPsOpNames) {
        if (word == CFX_ByteStringC(op_name.name)) {
          std::unique_ptr<CPDF_PSOP> op(new CPDF_PSOP(op_name.op));
          m_Operators.push_back(std::move(op));
          found = true;
          break;
        }
      }
      if (!found) {
        std::unique_ptr<CPDF_PSOP> op(new CPDF_PSOP(FX_atof(word)));
        m_Operators.push_back(std::move(op));
      }
    }
  }
}

FX_BOOL CPDF_PSEngine::DoOperator(PDF_PSOP op) {
  int i1;
  int i2;
  FX_FLOAT d1;
  FX_FLOAT d2;
  FX_SAFE_INT32 result;
  switch (op) {
    case PSOP_ADD:
      d1 = Pop();
      d2 = Pop();
      Push(d1 + d2);
      break;
    case PSOP_SUB:
      d2 = Pop();
      d1 = Pop();
      Push(d1 - d2);
      break;
    case PSOP_MUL:
      d1 = Pop();
      d2 = Pop();
      Push(d1 * d2);
      break;
    case PSOP_DIV:
      d2 = Pop();
      d1 = Pop();
      Push(d1 / d2);
      break;
    case PSOP_IDIV:
      i2 = static_cast<int>(Pop());
      i1 = static_cast<int>(Pop());
      if (i2) {
        result = i1;
        result /= i2;
        Push(result.ValueOrDefault(0));
      } else {
        Push(0);
      }
      break;
    case PSOP_MOD:
      i2 = static_cast<int>(Pop());
      i1 = static_cast<int>(Pop());
      if (i2) {
        result = i1;
        result %= i2;
        Push(result.ValueOrDefault(0));
      } else {
        Push(0);
      }
      break;
    case PSOP_NEG:
      d1 = Pop();
      Push(-d1);
      break;
    case PSOP_ABS:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_fabs(d1));
      break;
    case PSOP_CEILING:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_ceil(d1));
      break;
    case PSOP_FLOOR:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_floor(d1));
      break;
    case PSOP_ROUND:
      d1 = Pop();
      Push(FXSYS_round(d1));
      break;
    case PSOP_TRUNCATE:
      i1 = (int)Pop();
      Push(i1);
      break;
    case PSOP_SQRT:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_sqrt(d1));
      break;
    case PSOP_SIN:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_sin(d1 * FX_PI / 180.0f));
      break;
    case PSOP_COS:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_cos(d1 * FX_PI / 180.0f));
      break;
    case PSOP_ATAN:
      d2 = Pop();
      d1 = Pop();
      d1 = (FX_FLOAT)(FXSYS_atan2(d1, d2) * 180.0 / FX_PI);
      if (d1 < 0) {
        d1 += 360;
      }
      Push(d1);
      break;
    case PSOP_EXP:
      d2 = Pop();
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_pow(d1, d2));
      break;
    case PSOP_LN:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_log(d1));
      break;
    case PSOP_LOG:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_log10(d1));
      break;
    case PSOP_CVI:
      i1 = (int)Pop();
      Push(i1);
      break;
    case PSOP_CVR:
      break;
    case PSOP_EQ:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 == d2));
      break;
    case PSOP_NE:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 != d2));
      break;
    case PSOP_GT:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 > d2));
      break;
    case PSOP_GE:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 >= d2));
      break;
    case PSOP_LT:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 < d2));
      break;
    case PSOP_LE:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 <= d2));
      break;
    case PSOP_AND:
      i1 = (int)Pop();
      i2 = (int)Pop();
      Push(i1 & i2);
      break;
    case PSOP_OR:
      i1 = (int)Pop();
      i2 = (int)Pop();
      Push(i1 | i2);
      break;
    case PSOP_XOR:
      i1 = (int)Pop();
      i2 = (int)Pop();
      Push(i1 ^ i2);
      break;
    case PSOP_NOT:
      i1 = (int)Pop();
      Push((int)!i1);
      break;
    case PSOP_BITSHIFT: {
      int shift = (int)Pop();
      int i = (int)Pop();
      if (shift > 0) {
        Push(i << shift);
      } else {
        Push(i >> -shift);
      }
      break;
    }
    case PSOP_TRUE:
      Push(1);
      break;
    case PSOP_FALSE:
      Push(0);
      break;
    case PSOP_POP:
      Pop();
      break;
    case PSOP_EXCH:
      d2 = Pop();
      d1 = Pop();
      Push(d2);
      Push(d1);
      break;
    case PSOP_DUP:
      d1 = Pop();
      Push(d1);
      Push(d1);
      break;
    case PSOP_COPY: {
      int n = static_cast<int>(Pop());
      if (n < 0 || m_StackCount + n > PSENGINE_STACKSIZE ||
          n > static_cast<int>(m_StackCount))
        break;
      for (int i = 0; i < n; i++)
        m_Stack[m_StackCount + i] = m_Stack[m_StackCount + i - n];
      m_StackCount += n;
      break;
    }
    case PSOP_INDEX: {
      int n = static_cast<int>(Pop());
      if (n < 0 || n >= static_cast<int>(m_StackCount))
        break;
      Push(m_Stack[m_StackCount - n - 1]);
      break;
    }
    case PSOP_ROLL: {
      int j = static_cast<int>(Pop());
      int n = static_cast<int>(Pop());
      if (j == 0 || n == 0 || m_StackCount == 0)
        break;
      if (n < 0 || n > static_cast<int>(m_StackCount))
        break;

      j %= n;
      if (j > 0)
        j -= n;
      auto begin_it = std::begin(m_Stack) + m_StackCount - n;
      auto middle_it = begin_it - j;
      auto end_it = std::begin(m_Stack) + m_StackCount;
      std::rotate(begin_it, middle_it, end_it);
      break;
    }
    default:
      break;
  }
  return TRUE;
}

CPDF_SampledFunc::CPDF_SampledFunc() : CPDF_Function(Type::kType0Sampled) {}

CPDF_SampledFunc::~CPDF_SampledFunc() {}

FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) {
  CPDF_Stream* pStream = pObj->AsStream();
  if (!pStream)
    return false;

  CPDF_Dictionary* pDict = pStream->GetDict();
  CPDF_Array* pSize = pDict->GetArrayFor("Size");
  CPDF_Array* pEncode = pDict->GetArrayFor("Encode");
  CPDF_Array* pDecode = pDict->GetArrayFor("Decode");
  m_nBitsPerSample = pDict->GetIntegerFor("BitsPerSample");
  if (!IsValidBitsPerSample(m_nBitsPerSample))
    return FALSE;

  m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample);
  m_pSampleStream.reset(new CPDF_StreamAcc);
  m_pSampleStream->LoadAllData(pStream, FALSE);
  FX_SAFE_UINT32 nTotalSampleBits = 1;
  m_EncodeInfo.resize(m_nInputs);
  for (uint32_t i = 0; i < m_nInputs; i++) {
    m_EncodeInfo[i].sizes = pSize ? pSize->GetIntegerAt(i) : 0;
    if (!pSize && i == 0)
      m_EncodeInfo[i].sizes = pDict->GetIntegerFor("Size");
    nTotalSampleBits *= m_EncodeInfo[i].sizes;
    if (pEncode) {
      m_EncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2);
      m_EncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1);
    } else {
      m_EncodeInfo[i].encode_min = 0;
      m_EncodeInfo[i].encode_max =
          m_EncodeInfo[i].sizes == 1 ? 1 : (FX_FLOAT)m_EncodeInfo[i].sizes - 1;
    }
  }
  nTotalSampleBits *= m_nBitsPerSample;
  nTotalSampleBits *= m_nOutputs;
  FX_SAFE_UINT32 nTotalSampleBytes = nTotalSampleBits;
  nTotalSampleBytes += 7;
  nTotalSampleBytes /= 8;
  if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 ||
      nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) {
    return FALSE;
  }
  m_DecodeInfo.resize(m_nOutputs);
  for (uint32_t i = 0; i < m_nOutputs; i++) {
    if (pDecode) {
      m_DecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i);
      m_DecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1);
    } else {
      m_DecodeInfo[i].decode_min = m_pRanges[i * 2];
      m_DecodeInfo[i].decode_max = m_pRanges[i * 2 + 1];
    }
  }
  return TRUE;
}

FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
  int pos = 0;
  CFX_FixedBufGrow<FX_FLOAT, 16> encoded_input_buf(m_nInputs);
  FX_FLOAT* encoded_input = encoded_input_buf;
  CFX_FixedBufGrow<uint32_t, 32> int_buf(m_nInputs * 2);
  uint32_t* index = int_buf;
  uint32_t* blocksize = index + m_nInputs;
  for (uint32_t i = 0; i < m_nInputs; i++) {
    if (i == 0)
      blocksize[i] = 1;
    else
      blocksize[i] = blocksize[i - 1] * m_EncodeInfo[i - 1].sizes;
    encoded_input[i] =
        PDF_Interpolate(inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1],
                        m_EncodeInfo[i].encode_min, m_EncodeInfo[i].encode_max);
    index[i] = std::min((uint32_t)std::max(0.f, encoded_input[i]),
                        m_EncodeInfo[i].sizes - 1);
    pos += index[i] * blocksize[i];
  }
  FX_SAFE_INT32 bits_to_output = m_nOutputs;
  bits_to_output *= m_nBitsPerSample;
  if (!bits_to_output.IsValid())
    return FALSE;

  FX_SAFE_INT32 bitpos = pos;
  bitpos *= bits_to_output.ValueOrDie();
  if (!bitpos.IsValid())
    return FALSE;

  FX_SAFE_INT32 range_check = bitpos;
  range_check += bits_to_output.ValueOrDie();
  if (!range_check.IsValid())
    return FALSE;

  const uint8_t* pSampleData = m_pSampleStream->GetData();
  if (!pSampleData)
    return FALSE;

  for (uint32_t j = 0; j < m_nOutputs; j++) {
    uint32_t sample =
        GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nBitsPerSample,
                  m_nBitsPerSample);
    FX_FLOAT encoded = (FX_FLOAT)sample;
    for (uint32_t i = 0; i < m_nInputs; i++) {
      if (index[i] == m_EncodeInfo[i].sizes - 1) {
        if (index[i] == 0)
          encoded = encoded_input[i] * (FX_FLOAT)sample;
      } else {
        FX_SAFE_INT32 bitpos2 = blocksize[i];
        bitpos2 += pos;
        bitpos2 *= m_nOutputs;
        bitpos2 += j;
        bitpos2 *= m_nBitsPerSample;
        if (!bitpos2.IsValid())
          return FALSE;
        uint32_t sample1 =
            GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample);
        encoded += (encoded_input[i] - index[i]) *
                   ((FX_FLOAT)sample1 - (FX_FLOAT)sample);
      }
    }
    results[j] =
        PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax,
                        m_DecodeInfo[j].decode_min, m_DecodeInfo[j].decode_max);
  }
  return TRUE;
}

CPDF_ExpIntFunc::CPDF_ExpIntFunc()
    : CPDF_Function(Type::kType2ExpotentialInterpolation),
      m_pBeginValues(nullptr),
      m_pEndValues(nullptr) {}

CPDF_ExpIntFunc::~CPDF_ExpIntFunc() {
  FX_Free(m_pBeginValues);
  FX_Free(m_pEndValues);
}
FX_BOOL CPDF_ExpIntFunc::v_Init(CPDF_Object* pObj) {
  CPDF_Dictionary* pDict = pObj->GetDict();
  if (!pDict) {
    return FALSE;
  }
  CPDF_Array* pArray0 = pDict->GetArrayFor("C0");
  if (m_nOutputs == 0) {
    m_nOutputs = 1;
    if (pArray0) {
      m_nOutputs = pArray0->GetCount();
    }
  }
  CPDF_Array* pArray1 = pDict->GetArrayFor("C1");
  m_pBeginValues = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2);
  m_pEndValues = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2);
  for (uint32_t i = 0; i < m_nOutputs; i++) {
    m_pBeginValues[i] = pArray0 ? pArray0->GetFloatAt(i) : 0.0f;
    m_pEndValues[i] = pArray1 ? pArray1->GetFloatAt(i) : 1.0f;
  }
  m_Exponent = pDict->GetFloatFor("N");
  m_nOrigOutputs = m_nOutputs;
  if (m_nOutputs && m_nInputs > INT_MAX / m_nOutputs) {
    return FALSE;
  }
  m_nOutputs *= m_nInputs;
  return TRUE;
}
FX_BOOL CPDF_ExpIntFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
  for (uint32_t i = 0; i < m_nInputs; i++)
    for (uint32_t j = 0; j < m_nOrigOutputs; j++) {
      results[i * m_nOrigOutputs + j] =
          m_pBeginValues[j] +
          (FX_FLOAT)FXSYS_pow(inputs[i], m_Exponent) *
              (m_pEndValues[j] - m_pBeginValues[j]);
    }
  return TRUE;
}

CPDF_StitchFunc::CPDF_StitchFunc()
    : CPDF_Function(Type::kType3Stitching),
      m_pBounds(nullptr),
      m_pEncode(nullptr) {}

CPDF_StitchFunc::~CPDF_StitchFunc() {
  FX_Free(m_pBounds);
  FX_Free(m_pEncode);
}

FX_BOOL CPDF_StitchFunc::v_Init(CPDF_Object* pObj) {
  CPDF_Dictionary* pDict = pObj->GetDict();
  if (!pDict) {
    return FALSE;
  }
  if (m_nInputs != kRequiredNumInputs) {
    return FALSE;
  }
  CPDF_Array* pArray = pDict->GetArrayFor("Functions");
  if (!pArray) {
    return FALSE;
  }
  uint32_t nSubs = pArray->GetCount();
  if (nSubs == 0)
    return FALSE;
  m_nOutputs = 0;
  for (uint32_t i = 0; i < nSubs; i++) {
    CPDF_Object* pSub = pArray->GetDirectObjectAt(i);
    if (pSub == pObj)
      return FALSE;
    std::unique_ptr<CPDF_Function> pFunc(CPDF_Function::Load(pSub));
    if (!pFunc)
      return FALSE;
    // Check that the input dimensionality is 1, and that all output
    // dimensionalities are the same.
    if (pFunc->CountInputs() != kRequiredNumInputs)
      return FALSE;
    if (pFunc->CountOutputs() != m_nOutputs) {
      if (m_nOutputs)
        return FALSE;

      m_nOutputs = pFunc->CountOutputs();
    }

    m_pSubFunctions.push_back(std::move(pFunc));
  }
  m_pBounds = FX_Alloc(FX_FLOAT, nSubs + 1);
  m_pBounds[0] = m_pDomains[0];
  pArray = pDict->GetArrayFor("Bounds");
  if (!pArray)
    return FALSE;
  for (uint32_t i = 0; i < nSubs - 1; i++)
    m_pBounds[i + 1] = pArray->GetFloatAt(i);
  m_pBounds[nSubs] = m_pDomains[1];
  m_pEncode = FX_Alloc2D(FX_FLOAT, nSubs, 2);
  pArray = pDict->GetArrayFor("Encode");
  if (!pArray)
    return FALSE;

  for (uint32_t i = 0; i < nSubs * 2; i++)
    m_pEncode[i] = pArray->GetFloatAt(i);
  return TRUE;
}

FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const {
  FX_FLOAT input = inputs[0];
  size_t i;
  for (i = 0; i < m_pSubFunctions.size() - 1; i++) {
    if (input < m_pBounds[i + 1])
      break;
  }
  input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1],
                          m_pEncode[i * 2], m_pEncode[i * 2 + 1]);
  int nresults;
  m_pSubFunctions[i]->Call(&input, kRequiredNumInputs, outputs, nresults);
  return TRUE;
}

// static
std::unique_ptr<CPDF_Function> CPDF_Function::Load(CPDF_Object* pFuncObj) {
  std::unique_ptr<CPDF_Function> pFunc;
  if (!pFuncObj)
    return pFunc;

  int iType = -1;
  if (CPDF_Stream* pStream = pFuncObj->AsStream())
    iType = pStream->GetDict()->GetIntegerFor("FunctionType");
  else if (CPDF_Dictionary* pDict = pFuncObj->AsDictionary())
    iType = pDict->GetIntegerFor("FunctionType");

  Type type = IntegerToFunctionType(iType);
  if (type == Type::kType0Sampled)
    pFunc.reset(new CPDF_SampledFunc());
  else if (type == Type::kType2ExpotentialInterpolation)
    pFunc.reset(new CPDF_ExpIntFunc());
  else if (type == Type::kType3Stitching)
    pFunc.reset(new CPDF_StitchFunc());
  else if (type == Type::kType4PostScript)
    pFunc.reset(new CPDF_PSFunc());

  if (!pFunc || !pFunc->Init(pFuncObj))
    return std::unique_ptr<CPDF_Function>();
  return pFunc;
}

// static
CPDF_Function::Type CPDF_Function::IntegerToFunctionType(int iType) {
  switch (iType) {
    case 0:
    case 2:
    case 3:
    case 4:
      return static_cast<Type>(iType);
    default:
      return Type::kTypeInvalid;
  }
}

CPDF_Function::CPDF_Function(Type type)
    : m_pDomains(nullptr), m_pRanges(nullptr), m_Type(type) {}

CPDF_Function::~CPDF_Function() {
  FX_Free(m_pDomains);
  FX_Free(m_pRanges);
}

FX_BOOL CPDF_Function::Init(CPDF_Object* pObj) {
  CPDF_Stream* pStream = pObj->AsStream();
  CPDF_Dictionary* pDict = pStream ? pStream->GetDict() : pObj->AsDictionary();

  CPDF_Array* pDomains = pDict->GetArrayFor("Domain");
  if (!pDomains)
    return FALSE;

  m_nInputs = pDomains->GetCount() / 2;
  if (m_nInputs == 0)
    return FALSE;

  m_pDomains = FX_Alloc2D(FX_FLOAT, m_nInputs, 2);
  for (uint32_t i = 0; i < m_nInputs * 2; i++) {
    m_pDomains[i] = pDomains->GetFloatAt(i);
  }
  CPDF_Array* pRanges = pDict->GetArrayFor("Range");
  m_nOutputs = 0;
  if (pRanges) {
    m_nOutputs = pRanges->GetCount() / 2;
    m_pRanges = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2);
    for (uint32_t i = 0; i < m_nOutputs * 2; i++)
      m_pRanges[i] = pRanges->GetFloatAt(i);
  }
  uint32_t old_outputs = m_nOutputs;
  if (!v_Init(pObj))
    return FALSE;
  if (m_pRanges && m_nOutputs > old_outputs) {
    m_pRanges = FX_Realloc(FX_FLOAT, m_pRanges, m_nOutputs * 2);
    if (m_pRanges) {
      FXSYS_memset(m_pRanges + (old_outputs * 2), 0,
                   sizeof(FX_FLOAT) * (m_nOutputs - old_outputs) * 2);
    }
  }
  return TRUE;
}

FX_BOOL CPDF_Function::Call(FX_FLOAT* inputs,
                            uint32_t ninputs,
                            FX_FLOAT* results,
                            int& nresults) const {
  if (m_nInputs != ninputs) {
    return FALSE;
  }
  nresults = m_nOutputs;
  for (uint32_t i = 0; i < m_nInputs; i++) {
    if (inputs[i] < m_pDomains[i * 2])
      inputs[i] = m_pDomains[i * 2];
    else if (inputs[i] > m_pDomains[i * 2 + 1])
      inputs[i] = m_pDomains[i * 2] + 1;
  }
  v_Call(inputs, results);
  if (m_pRanges) {
    for (uint32_t i = 0; i < m_nOutputs; i++) {
      if (results[i] < m_pRanges[i * 2])
        results[i] = m_pRanges[i * 2];
      else if (results[i] > m_pRanges[i * 2 + 1])
        results[i] = m_pRanges[i * 2 + 1];
    }
  }
  return TRUE;
}

const CPDF_SampledFunc* CPDF_Function::ToSampledFunc() const {
  return m_Type == Type::kType0Sampled
             ? static_cast<const CPDF_SampledFunc*>(this)
             : nullptr;
}

const CPDF_ExpIntFunc* CPDF_Function::ToExpIntFunc() const {
  return m_Type == Type::kType2ExpotentialInterpolation
             ? static_cast<const CPDF_ExpIntFunc*>(this)
             : nullptr;
}

const CPDF_StitchFunc* CPDF_Function::ToStitchFunc() const {
  return m_Type == Type::kType3Stitching
             ? static_cast<const CPDF_StitchFunc*>(this)
             : nullptr;
}
