// 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"
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"

namespace {

struct PDF_PSOpName {
  const 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.
float PDF_Interpolate(float x, float xmin, float xmax, float ymin, float ymax) {
  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
  bool v_Init(CPDF_Object* pObj) override;
  bool v_Call(float* inputs, float* results) const override;

 private:
  CPDF_PSEngine m_PS;
};

bool CPDF_PSFunc::v_Init(CPDF_Object* pObj) {
  auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pObj->AsStream());
  pAcc->LoadAllData(false);
  return m_PS.Parse(reinterpret_cast<const char*>(pAcc->GetData()),
                    pAcc->GetSize());
}

bool CPDF_PSFunc::v_Call(float* inputs, 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(float value) : m_op(PSOP_CONST), m_value(value) {}
  CPDF_PSOP()
      : m_op(PSOP_PROC),
        m_value(0),
        m_proc(pdfium::MakeUnique<CPDF_PSProc>()) {}

  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 float m_value;
  std::unique_ptr<CPDF_PSProc> m_proc;
};

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

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

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(float v) {
  if (m_StackCount < PSENGINE_STACKSIZE)
    m_Stack[m_StackCount++] = v;
}

float CPDF_PSEngine::Pop() {
  return m_StackCount > 0 ? m_Stack[--m_StackCount] : 0;
}

bool CPDF_PSEngine::Parse(const char* str, int size) {
  CPDF_SimpleParser parser(reinterpret_cast<const uint8_t*>(str), size);
  CFX_ByteStringC word = parser.GetWord();
  return word == "{" ? m_MainProc.Parse(&parser, 0) : false;
}

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 == "{") {
      m_Operators.push_back(pdfium::MakeUnique<CPDF_PSOP>());
      if (!m_Operators.back()->GetProc()->Parse(parser, depth + 1))
        return false;
      continue;
    }

    std::unique_ptr<CPDF_PSOP> op;
    for (const PDF_PSOpName& op_name : kPsOpNames) {
      if (word == CFX_ByteStringC(op_name.name)) {
        op = pdfium::MakeUnique<CPDF_PSOP>(op_name.op);
        break;
      }
    }
    if (!op)
      op = pdfium::MakeUnique<CPDF_PSOP>(FX_atof(word));
    m_Operators.push_back(std::move(op));
  }
}

bool CPDF_PSEngine::DoOperator(PDF_PSOP op) {
  int i1;
  int i2;
  float d1;
  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((float)fabs(d1));
      break;
    case PSOP_CEILING:
      d1 = Pop();
      Push((float)ceil(d1));
      break;
    case PSOP_FLOOR:
      d1 = Pop();
      Push((float)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((float)sqrt(d1));
      break;
    case PSOP_SIN:
      d1 = Pop();
      Push((float)sin(d1 * FX_PI / 180.0f));
      break;
    case PSOP_COS:
      d1 = Pop();
      Push((float)cos(d1 * FX_PI / 180.0f));
      break;
    case PSOP_ATAN:
      d2 = Pop();
      d1 = Pop();
      d1 = (float)(atan2(d1, d2) * 180.0 / FX_PI);
      if (d1 < 0) {
        d1 += 360;
      }
      Push(d1);
      break;
    case PSOP_EXP:
      d2 = Pop();
      d1 = Pop();
      Push((float)FXSYS_pow(d1, d2));
      break;
    case PSOP_LN:
      d1 = Pop();
      Push((float)log(d1));
      break;
    case PSOP_LOG:
      d1 = Pop();
      Push((float)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();
      result = (int)Pop();
      if (shift > 0) {
        result <<= shift;
      } else {
        // Avoids unsafe negation of INT_MIN.
        FX_SAFE_INT32 safe_shift = shift;
        result >>= (-safe_shift).ValueOrDefault(0);
      }
      Push(result.ValueOrDefault(0));
      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() {}

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 = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
  m_pSampleStream->LoadAllData(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 : (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;
}

bool CPDF_SampledFunc::v_Call(float* inputs, float* results) const {
  int pos = 0;
  CFX_FixedBufGrow<float, 16> encoded_input_buf(m_nInputs);
  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] = pdfium::clamp(static_cast<uint32_t>(encoded_input[i]), 0U,
                             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++, bitpos += m_nBitsPerSample) {
    uint32_t sample =
        GetBits32(pSampleData, bitpos.ValueOrDie(), m_nBitsPerSample);
    float encoded = (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] * (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]) * ((float)sample1 - (float)sample);
      }
    }
    results[j] =
        PDF_Interpolate(encoded, 0, (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);
}

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(float, m_nOutputs, 2);
  m_pEndValues = FX_Alloc2D(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;
}

bool CPDF_ExpIntFunc::v_Call(float* inputs, 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] +
          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);
}

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

bool CPDF_StitchFunc::v_Call(float* inputs, float* outputs) const {
  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 = pdfium::MakeUnique<CPDF_SampledFunc>();
  else if (type == Type::kType2ExpotentialInterpolation)
    pFunc = pdfium::MakeUnique<CPDF_ExpIntFunc>();
  else if (type == Type::kType3Stitching)
    pFunc = pdfium::MakeUnique<CPDF_StitchFunc>();
  else if (type == Type::kType4PostScript)
    pFunc = pdfium::MakeUnique<CPDF_PSFunc>();

  if (!pFunc || !pFunc->Init(pFuncObj))
    return nullptr;

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

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(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(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(float, m_pRanges, m_nOutputs * 2);
    if (m_pRanges) {
      memset(m_pRanges + (old_outputs * 2), 0,
             sizeof(float) * (m_nOutputs - old_outputs) * 2);
    }
  }
  return true;
}

bool CPDF_Function::Call(float* inputs,
                         uint32_t ninputs,
                         float* results,
                         int* nresults) const {
  if (m_nInputs != ninputs)
    return false;

  *nresults = m_nOutputs;
  for (uint32_t i = 0; i < m_nInputs; i++) {
    inputs[i] =
        pdfium::clamp(inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1]);
  }
  v_Call(inputs, results);
  if (!m_pRanges)
    return true;

  for (uint32_t i = 0; i < m_nOutputs; i++) {
    results[i] =
        pdfium::clamp(results[i], m_pRanges[i * 2], 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;
}
