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

#include <limits.h>

#include "core/include/fpdfapi/fpdf_module.h"
#include "core/include/fpdfapi/fpdf_page.h"
#include "core/include/fxcodec/fx_codec.h"
#include "core/include/fxcrt/fx_ext.h"

namespace {

const char kPathOperatorSubpath = 'm';
const char kPathOperatorLine = 'l';
const char kPathOperatorCubicBezier1 = 'c';
const char kPathOperatorCubicBezier2 = 'v';
const char kPathOperatorCubicBezier3 = 'y';
const char kPathOperatorClosePath = 'h';
const char kPathOperatorRectangle[] = "re";

}  // namespace

class CPDF_StreamParserAutoClearer {
 public:
  CPDF_StreamParserAutoClearer(CPDF_StreamParser** scoped_variable,
                               CPDF_StreamParser* new_parser)
      : scoped_variable_(scoped_variable) {
    *scoped_variable_ = new_parser;
  }
  ~CPDF_StreamParserAutoClearer() { *scoped_variable_ = NULL; }

 private:
  CPDF_StreamParser** scoped_variable_;
};
FX_DWORD CPDF_StreamContentParser::Parse(const uint8_t* pData,
                                         FX_DWORD dwSize,
                                         FX_DWORD max_cost) {
  if (m_Level > _FPDF_MAX_FORM_LEVEL_) {
    return dwSize;
  }
  FX_DWORD InitObjCount = m_pObjectList->CountObjects();
  CPDF_StreamParser syntax(pData, dwSize);
  CPDF_StreamParserAutoClearer auto_clearer(&m_pSyntax, &syntax);
  m_CompatCount = 0;
  while (1) {
    FX_DWORD cost = m_pObjectList->CountObjects() - InitObjCount;
    if (max_cost && cost >= max_cost) {
      break;
    }
    switch (syntax.ParseNextElement()) {
      case CPDF_StreamParser::EndOfData:
        return m_pSyntax->GetPos();
      case CPDF_StreamParser::Keyword:
        OnOperator((char*)syntax.GetWordBuf());
        ClearAllParams();
        break;
      case CPDF_StreamParser::Number:
        AddNumberParam((char*)syntax.GetWordBuf(), syntax.GetWordSize());
        break;
      case CPDF_StreamParser::Name:
        AddNameParam((const FX_CHAR*)syntax.GetWordBuf() + 1,
                     syntax.GetWordSize() - 1);
        break;
      default:
        AddObjectParam(syntax.GetObject());
    }
  }
  return m_pSyntax->GetPos();
}
void _PDF_ReplaceAbbr(CPDF_Object* pObj);
void CPDF_StreamContentParser::Handle_BeginImage() {
  FX_FILESIZE savePos = m_pSyntax->GetPos();
  CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
  while (1) {
    CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement();
    if (type == CPDF_StreamParser::Keyword) {
      CFX_ByteString bsKeyword(m_pSyntax->GetWordBuf(),
                               m_pSyntax->GetWordSize());
      if (bsKeyword != FX_BSTRC("ID")) {
        m_pSyntax->SetPos(savePos);
        pDict->Release();
        return;
      }
    }
    if (type != CPDF_StreamParser::Name) {
      break;
    }
    CFX_ByteString key((const FX_CHAR*)m_pSyntax->GetWordBuf() + 1,
                       m_pSyntax->GetWordSize() - 1);
    nonstd::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>> pObj(
        m_pSyntax->ReadNextObject());
    if (!key.IsEmpty()) {
      FX_DWORD dwObjNum = pObj ? pObj->GetObjNum() : 0;
      if (dwObjNum)
        pDict->SetAtReference(key, m_pDocument, dwObjNum);
      else
        pDict->SetAt(key, pObj.release());
    }
  }
  _PDF_ReplaceAbbr(pDict);
  CPDF_Object* pCSObj = NULL;
  if (pDict->KeyExist(FX_BSTRC("ColorSpace"))) {
    pCSObj = pDict->GetElementValue(FX_BSTRC("ColorSpace"));
    if (pCSObj->IsName()) {
      CFX_ByteString name = pCSObj->GetString();
      if (name != FX_BSTRC("DeviceRGB") && name != FX_BSTRC("DeviceGray") &&
          name != FX_BSTRC("DeviceCMYK")) {
        pCSObj = FindResourceObj(FX_BSTRC("ColorSpace"), name);
        if (pCSObj && !pCSObj->GetObjNum()) {
          pCSObj = pCSObj->Clone();
          pDict->SetAt(FX_BSTRC("ColorSpace"), pCSObj);
        }
      }
    }
  }
  CPDF_Stream* pStream = m_pSyntax->ReadInlineStream(
      m_pDocument, pDict, pCSObj, m_Options.m_bDecodeInlineImage);
  while (1) {
    CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement();
    if (type == CPDF_StreamParser::EndOfData) {
      break;
    }
    if (type != CPDF_StreamParser::Keyword) {
      continue;
    }
    if (m_pSyntax->GetWordSize() == 2 && m_pSyntax->GetWordBuf()[0] == 'E' &&
        m_pSyntax->GetWordBuf()[1] == 'I') {
      break;
    }
  }
  if (m_Options.m_bTextOnly) {
    if (pStream) {
      pStream->Release();
    } else {
      pDict->Release();
    }
    return;
  }
  pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Image"));
  CPDF_ImageObject* pImgObj = AddImage(pStream, NULL, TRUE);
  if (!pImgObj) {
    if (pStream) {
      pStream->Release();
    } else {
      pDict->Release();
    }
  }
}
void CPDF_StreamContentParser::ParsePathObject() {
  FX_FLOAT params[6] = {};
  int nParams = 0;
  int last_pos = m_pSyntax->GetPos();
  while (1) {
    CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement();
    FX_BOOL bProcessed = TRUE;
    switch (type) {
      case CPDF_StreamParser::EndOfData:
        return;
      case CPDF_StreamParser::Keyword: {
        int len = m_pSyntax->GetWordSize();
        if (len == 1) {
          switch (m_pSyntax->GetWordBuf()[0]) {
            case kPathOperatorSubpath:
              AddPathPoint(params[0], params[1], FXPT_MOVETO);
              nParams = 0;
              break;
            case kPathOperatorLine:
              AddPathPoint(params[0], params[1], FXPT_LINETO);
              nParams = 0;
              break;
            case kPathOperatorCubicBezier1:
              AddPathPoint(params[0], params[1], FXPT_BEZIERTO);
              AddPathPoint(params[2], params[3], FXPT_BEZIERTO);
              AddPathPoint(params[4], params[5], FXPT_BEZIERTO);
              nParams = 0;
              break;
            case kPathOperatorCubicBezier2:
              AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXPT_BEZIERTO);
              AddPathPoint(params[0], params[1], FXPT_BEZIERTO);
              AddPathPoint(params[2], params[3], FXPT_BEZIERTO);
              nParams = 0;
              break;
            case kPathOperatorCubicBezier3:
              AddPathPoint(params[0], params[1], FXPT_BEZIERTO);
              AddPathPoint(params[2], params[3], FXPT_BEZIERTO);
              AddPathPoint(params[2], params[3], FXPT_BEZIERTO);
              nParams = 0;
              break;
            case kPathOperatorClosePath:
              Handle_ClosePath();
              nParams = 0;
              break;
            default:
              bProcessed = FALSE;
              break;
          }
        } else if (len == 2) {
          if (m_pSyntax->GetWordBuf()[0] == kPathOperatorRectangle[0] &&
              m_pSyntax->GetWordBuf()[1] == kPathOperatorRectangle[1]) {
            AddPathRect(params[0], params[1], params[2], params[3]);
            nParams = 0;
          } else {
            bProcessed = FALSE;
          }
        } else {
          bProcessed = FALSE;
        }
        if (bProcessed) {
          last_pos = m_pSyntax->GetPos();
        }
        break;
      }
      case CPDF_StreamParser::Number: {
        if (nParams == 6) {
          break;
        }
        FX_BOOL bInteger;
        int value;
        FX_atonum(
            CFX_ByteStringC(m_pSyntax->GetWordBuf(), m_pSyntax->GetWordSize()),
            bInteger, &value);
        params[nParams++] = bInteger ? (FX_FLOAT)value : *(FX_FLOAT*)&value;
        break;
      }
      default:
        bProcessed = FALSE;
    }
    if (!bProcessed) {
      m_pSyntax->SetPos(last_pos);
      return;
    }
  }
}
CPDF_StreamParser::CPDF_StreamParser(const uint8_t* pData, FX_DWORD dwSize) {
  m_pBuf = pData;
  m_Size = dwSize;
  m_Pos = 0;
  m_pLastObj = NULL;
}
CPDF_StreamParser::~CPDF_StreamParser() {
  if (m_pLastObj) {
    m_pLastObj->Release();
  }
}
FX_DWORD _DecodeAllScanlines(ICodec_ScanlineDecoder* pDecoder,
                             uint8_t*& dest_buf,
                             FX_DWORD& dest_size) {
  if (pDecoder == NULL) {
    return (FX_DWORD)-1;
  }
  int ncomps = pDecoder->CountComps();
  int bpc = pDecoder->GetBPC();
  int width = pDecoder->GetWidth();
  int height = pDecoder->GetHeight();
  int pitch = (width * ncomps * bpc + 7) / 8;
  if (height == 0 || pitch > (1 << 30) / height) {
    delete pDecoder;
    return -1;
  }
  dest_buf = FX_Alloc2D(uint8_t, pitch, height);
  dest_size = pitch * height;  // Safe since checked alloc returned.
  for (int row = 0; row < height; row++) {
    const uint8_t* pLine = pDecoder->GetScanline(row);
    if (!pLine)
      break;

    FXSYS_memcpy(dest_buf + row * pitch, pLine, pitch);
  }
  FX_DWORD srcoff = pDecoder->GetSrcOffset();
  delete pDecoder;
  return srcoff;
}
ICodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder(
    const uint8_t* src_buf,
    FX_DWORD src_size,
    int width,
    int height,
    const CPDF_Dictionary* pParams);

FX_DWORD PDF_DecodeInlineStream(const uint8_t* src_buf,
                                FX_DWORD limit,
                                int width,
                                int height,
                                CFX_ByteString& decoder,
                                CPDF_Dictionary* pParam,
                                uint8_t*& dest_buf,
                                FX_DWORD& dest_size) {
  if (decoder == FX_BSTRC("CCITTFaxDecode") || decoder == FX_BSTRC("CCF")) {
    ICodec_ScanlineDecoder* pDecoder =
        FPDFAPI_CreateFaxDecoder(src_buf, limit, width, height, pParam);
    return _DecodeAllScanlines(pDecoder, dest_buf, dest_size);
  }
  if (decoder == FX_BSTRC("ASCII85Decode") || decoder == FX_BSTRC("A85")) {
    return A85Decode(src_buf, limit, dest_buf, dest_size);
  }
  if (decoder == FX_BSTRC("ASCIIHexDecode") || decoder == FX_BSTRC("AHx")) {
    return HexDecode(src_buf, limit, dest_buf, dest_size);
  }
  if (decoder == FX_BSTRC("FlateDecode") || decoder == FX_BSTRC("Fl")) {
    return FPDFAPI_FlateOrLZWDecode(FALSE, src_buf, limit, pParam, dest_size,
                                    dest_buf, dest_size);
  }
  if (decoder == FX_BSTRC("LZWDecode") || decoder == FX_BSTRC("LZW")) {
    return FPDFAPI_FlateOrLZWDecode(TRUE, src_buf, limit, pParam, 0, dest_buf,
                                    dest_size);
  }
  if (decoder == FX_BSTRC("DCTDecode") || decoder == FX_BSTRC("DCT")) {
    ICodec_ScanlineDecoder* pDecoder =
        CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder(
            src_buf, limit, width, height, 0,
            pParam ? pParam->GetInteger(FX_BSTRC("ColorTransform"), 1) : 1);
    return _DecodeAllScanlines(pDecoder, dest_buf, dest_size);
  }
  if (decoder == FX_BSTRC("RunLengthDecode") || decoder == FX_BSTRC("RL")) {
    return RunLengthDecode(src_buf, limit, dest_buf, dest_size);
  }
  dest_size = 0;
  dest_buf = 0;
  return (FX_DWORD)-1;
}
CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc,
                                                 CPDF_Dictionary* pDict,
                                                 CPDF_Object* pCSObj,
                                                 FX_BOOL bDecode) {
  if (m_Pos == m_Size)
    return nullptr;

  if (PDFCharIsWhitespace(m_pBuf[m_Pos]))
    m_Pos++;

  CFX_ByteString Decoder;
  CPDF_Dictionary* pParam = nullptr;
  CPDF_Object* pFilter = pDict->GetElementValue(FX_BSTRC("Filter"));
  if (pFilter) {
    if (CPDF_Array* pArray = pFilter->AsArray()) {
      Decoder = pArray->GetString(0);
      CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms"));
      if (pParams)
        pParam = pParams->GetDict(0);
    } else {
      Decoder = pFilter->GetString();
      pParam = pDict->GetDict(FX_BSTRC("DecodeParms"));
    }
  }
  FX_DWORD width = pDict->GetInteger(FX_BSTRC("Width"));
  FX_DWORD height = pDict->GetInteger(FX_BSTRC("Height"));
  FX_DWORD OrigSize = 0;
  if (pCSObj != NULL) {
    FX_DWORD bpc = pDict->GetInteger(FX_BSTRC("BitsPerComponent"));
    FX_DWORD nComponents = 1;
    CPDF_ColorSpace* pCS = pDoc->LoadColorSpace(pCSObj);
    if (pCS == NULL) {
      nComponents = 3;
    } else {
      nComponents = pCS->CountComponents();
      pDoc->GetPageData()->ReleaseColorSpace(pCSObj);
    }
    FX_DWORD pitch = width;
    if (bpc && pitch > INT_MAX / bpc) {
      return NULL;
    }
    pitch *= bpc;
    if (nComponents && pitch > INT_MAX / nComponents) {
      return NULL;
    }
    pitch *= nComponents;
    if (pitch > INT_MAX - 7) {
      return NULL;
    }
    pitch += 7;
    pitch /= 8;
    OrigSize = pitch;
  } else {
    if (width > INT_MAX - 7) {
      return NULL;
    }
    OrigSize = ((width + 7) / 8);
  }
  if (height && OrigSize > INT_MAX / height) {
    return NULL;
  }
  OrigSize *= height;
  uint8_t* pData = NULL;
  FX_DWORD dwStreamSize;
  if (Decoder.IsEmpty()) {
    if (OrigSize > m_Size - m_Pos) {
      OrigSize = m_Size - m_Pos;
    }
    pData = FX_Alloc(uint8_t, OrigSize);
    FXSYS_memcpy(pData, m_pBuf + m_Pos, OrigSize);
    dwStreamSize = OrigSize;
    m_Pos += OrigSize;
  } else {
    FX_DWORD dwDestSize = OrigSize;
    dwStreamSize =
        PDF_DecodeInlineStream(m_pBuf + m_Pos, m_Size - m_Pos, width, height,
                               Decoder, pParam, pData, dwDestSize);
    if ((int)dwStreamSize < 0) {
      FX_Free(pData);
      return NULL;
    }
    if (bDecode) {
      m_Pos += dwStreamSize;
      dwStreamSize = dwDestSize;
      if (CPDF_Array* pArray = pFilter->AsArray()) {
        pArray->RemoveAt(0);
        CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms"));
        if (pParams)
          pParams->RemoveAt(0);
      } else {
        pDict->RemoveAt(FX_BSTRC("Filter"));
        pDict->RemoveAt(FX_BSTRC("DecodeParms"));
      }
    } else {
      FX_Free(pData);
      FX_DWORD dwSavePos = m_Pos;
      m_Pos += dwStreamSize;
      while (1) {
        FX_DWORD dwPrevPos = m_Pos;
        CPDF_StreamParser::SyntaxType type = ParseNextElement();
        if (type == CPDF_StreamParser::EndOfData) {
          break;
        }
        if (type != CPDF_StreamParser::Keyword) {
          dwStreamSize += m_Pos - dwPrevPos;
          continue;
        }
        if (GetWordSize() == 2 && GetWordBuf()[0] == 'E' &&
            GetWordBuf()[1] == 'I') {
          m_Pos = dwPrevPos;
          break;
        }
        dwStreamSize += m_Pos - dwPrevPos;
      }
      m_Pos = dwSavePos;
      pData = FX_Alloc(uint8_t, dwStreamSize);
      FXSYS_memcpy(pData, m_pBuf + m_Pos, dwStreamSize);
      m_Pos += dwStreamSize;
    }
  }
  pDict->SetAtInteger(FX_BSTRC("Length"), (int)dwStreamSize);
  return new CPDF_Stream(pData, dwStreamSize, pDict);
}

#define MAX_WORD_BUFFER 256
#define MAX_STRING_LENGTH 32767
#define FXDWORD_TRUE FXDWORD_FROM_LSBFIRST(0x65757274)
#define FXDWORD_NULL FXDWORD_FROM_LSBFIRST(0x6c6c756e)
#define FXDWORD_FALS FXDWORD_FROM_LSBFIRST(0x736c6166)
CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() {
  if (m_pLastObj) {
    m_pLastObj->Release();
    m_pLastObj = nullptr;
  }

  m_WordSize = 0;
  FX_BOOL bIsNumber = TRUE;
  if (!PositionIsInBounds())
    return EndOfData;

  int ch = m_pBuf[m_Pos++];
  while (1) {
    while (PDFCharIsWhitespace(ch)) {
      if (!PositionIsInBounds())
        return EndOfData;

      ch = m_pBuf[m_Pos++];
    }

    if (ch != '%')
      break;

    while (1) {
      if (!PositionIsInBounds())
        return EndOfData;

      ch = m_pBuf[m_Pos++];
      if (PDFCharIsLineEnding(ch))
        break;
    }
  }

  if (PDFCharIsDelimiter(ch) && ch != '/') {
    m_Pos--;
    m_pLastObj = ReadNextObject();
    return Others;
  }

  while (1) {
    if (m_WordSize < MAX_WORD_BUFFER)
      m_WordBuffer[m_WordSize++] = ch;

    if (!PDFCharIsNumeric(ch))
      bIsNumber = FALSE;

    if (!PositionIsInBounds())
      break;

    ch = m_pBuf[m_Pos++];

    if (PDFCharIsDelimiter(ch) || PDFCharIsWhitespace(ch)) {
      m_Pos--;
      break;
    }
  }

  m_WordBuffer[m_WordSize] = 0;
  if (bIsNumber)
    return Number;
  if (m_WordBuffer[0] == '/')
    return Name;

  if (m_WordSize == 4) {
    if (*(FX_DWORD*)m_WordBuffer == FXDWORD_TRUE) {
      m_pLastObj = CPDF_Boolean::Create(TRUE);
      return Others;
    }
    if (*(FX_DWORD*)m_WordBuffer == FXDWORD_NULL) {
      m_pLastObj = CPDF_Null::Create();
      return Others;
    }
  } else if (m_WordSize == 5) {
    if (*(FX_DWORD*)m_WordBuffer == FXDWORD_FALS && m_WordBuffer[4] == 'e') {
      m_pLastObj = CPDF_Boolean::Create(FALSE);
      return Others;
    }
  }
  return Keyword;
}

void CPDF_StreamParser::SkipPathObject() {
  FX_DWORD command_startpos = m_Pos;
  if (!PositionIsInBounds())
    return;

  int ch = m_pBuf[m_Pos++];
  while (1) {
    while (PDFCharIsWhitespace(ch)) {
      if (!PositionIsInBounds())
        return;
      ch = m_pBuf[m_Pos++];
    }

    if (!PDFCharIsNumeric(ch)) {
      m_Pos = command_startpos;
      return;
    }

    while (1) {
      while (!PDFCharIsWhitespace(ch)) {
        if (!PositionIsInBounds())
          return;
        ch = m_pBuf[m_Pos++];
      }

      while (PDFCharIsWhitespace(ch)) {
        if (!PositionIsInBounds())
          return;
        ch = m_pBuf[m_Pos++];
      }

      if (PDFCharIsNumeric(ch))
        continue;

      FX_DWORD op_startpos = m_Pos - 1;
      while (!PDFCharIsWhitespace(ch) && !PDFCharIsDelimiter(ch)) {
        if (!PositionIsInBounds())
          return;
        ch = m_pBuf[m_Pos++];
      }

      if (m_Pos - op_startpos == 2) {
        int op = m_pBuf[op_startpos];
        if (op == kPathOperatorSubpath || op == kPathOperatorLine ||
            op == kPathOperatorCubicBezier1 ||
            op == kPathOperatorCubicBezier2 ||
            op == kPathOperatorCubicBezier3) {
          command_startpos = m_Pos;
          break;
        }
      } else if (m_Pos - op_startpos == 3) {
        if (m_pBuf[op_startpos] == kPathOperatorRectangle[0] &&
            m_pBuf[op_startpos + 1] == kPathOperatorRectangle[1]) {
          command_startpos = m_Pos;
          break;
        }
      }
      m_Pos = command_startpos;
      return;
    }
  }
}
CPDF_Object* CPDF_StreamParser::ReadNextObject(FX_BOOL bAllowNestedArray,
                                               FX_BOOL bInArray) {
  FX_BOOL bIsNumber;
  GetNextWord(bIsNumber);
  if (m_WordSize == 0) {
    return NULL;
  }
  if (bIsNumber) {
    m_WordBuffer[m_WordSize] = 0;
    return CPDF_Number::Create(CFX_ByteStringC(m_WordBuffer, m_WordSize));
  }
  int first_char = m_WordBuffer[0];
  if (first_char == '/') {
    return CPDF_Name::Create(
        PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)));
  }
  if (first_char == '(') {
    return CPDF_String::Create(ReadString());
  }
  if (first_char == '<') {
    if (m_WordSize == 1) {
      return CPDF_String::Create(ReadHexString(), TRUE);
    }
    CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
    while (1) {
      GetNextWord(bIsNumber);
      if (m_WordSize == 0) {
        pDict->Release();
        return NULL;
      }
      if (m_WordSize == 2 && m_WordBuffer[0] == '>') {
        break;
      }
      if (m_WordBuffer[0] != '/') {
        pDict->Release();
        return NULL;
      }
      CFX_ByteString key =
          PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1));
      CPDF_Object* pObj = ReadNextObject(TRUE);
      if (pObj == NULL) {
        if (pDict) {
          pDict->Release();
        }
        return NULL;
      }
      if (!key.IsEmpty()) {
        pDict->SetAt(key, pObj);
      } else {
        pObj->Release();
      }
    }
    return pDict;
  }
  if (first_char == '[') {
    if (!bAllowNestedArray && bInArray) {
      return NULL;
    }
    CPDF_Array* pArray = CPDF_Array::Create();
    while (1) {
      CPDF_Object* pObj = ReadNextObject(bAllowNestedArray, TRUE);
      if (pObj == NULL) {
        if (m_WordSize == 0 || m_WordBuffer[0] == ']') {
          return pArray;
        }
        if (m_WordBuffer[0] == '[') {
          continue;
        }
      } else {
        pArray->Add(pObj);
      }
    }
  }
  if (m_WordSize == 4) {
    if (*(FX_DWORD*)m_WordBuffer == FXDWORD_TRUE) {
      return CPDF_Boolean::Create(TRUE);
    }
    if (*(FX_DWORD*)m_WordBuffer == FXDWORD_NULL) {
      return CPDF_Null::Create();
    }
  } else if (m_WordSize == 5) {
    if (*(FX_DWORD*)m_WordBuffer == FXDWORD_FALS && m_WordBuffer[4] == 'e') {
      return CPDF_Boolean::Create(FALSE);
    }
  }
  return NULL;
}
void CPDF_StreamParser::GetNextWord(FX_BOOL& bIsNumber) {
  m_WordSize = 0;
  bIsNumber = TRUE;
  if (!PositionIsInBounds())
    return;

  int ch = m_pBuf[m_Pos++];
  while (1) {
    while (PDFCharIsWhitespace(ch)) {
      if (!PositionIsInBounds()) {
        return;
      }
      ch = m_pBuf[m_Pos++];
    }

    if (ch != '%')
      break;

    while (1) {
      if (!PositionIsInBounds())
        return;
      ch = m_pBuf[m_Pos++];
      if (PDFCharIsLineEnding(ch))
        break;
    }
  }

  if (PDFCharIsDelimiter(ch)) {
    bIsNumber = FALSE;
    m_WordBuffer[m_WordSize++] = ch;
    if (ch == '/') {
      while (1) {
        if (!PositionIsInBounds())
          return;
        ch = m_pBuf[m_Pos++];
        if (!PDFCharIsOther(ch) && !PDFCharIsNumeric(ch)) {
          m_Pos--;
          return;
        }

        if (m_WordSize < MAX_WORD_BUFFER)
          m_WordBuffer[m_WordSize++] = ch;
      }
    } else if (ch == '<') {
      if (!PositionIsInBounds())
        return;
      ch = m_pBuf[m_Pos++];
      if (ch == '<')
        m_WordBuffer[m_WordSize++] = ch;
      else
        m_Pos--;
    } else if (ch == '>') {
      if (!PositionIsInBounds())
        return;
      ch = m_pBuf[m_Pos++];
      if (ch == '>')
        m_WordBuffer[m_WordSize++] = ch;
      else
        m_Pos--;
    }
    return;
  }

  while (1) {
    if (m_WordSize < MAX_WORD_BUFFER)
      m_WordBuffer[m_WordSize++] = ch;
    if (!PDFCharIsNumeric(ch))
      bIsNumber = FALSE;

    if (!PositionIsInBounds())
      return;
    ch = m_pBuf[m_Pos++];
    if (PDFCharIsDelimiter(ch) || PDFCharIsWhitespace(ch)) {
      m_Pos--;
      break;
    }
  }
}

CFX_ByteString CPDF_StreamParser::ReadString() {
  if (!PositionIsInBounds())
    return CFX_ByteString();

  int ch = m_pBuf[m_Pos++];
  CFX_ByteTextBuf buf;
  int parlevel = 0;
  int status = 0, iEscCode = 0;
  while (1) {
    switch (status) {
      case 0:
        if (ch == ')') {
          if (parlevel == 0) {
            if (buf.GetLength() > MAX_STRING_LENGTH) {
              return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH);
            }
            return buf.GetByteString();
          }
          parlevel--;
          buf.AppendChar(')');
        } else if (ch == '(') {
          parlevel++;
          buf.AppendChar('(');
        } else if (ch == '\\') {
          status = 1;
        } else {
          buf.AppendChar((char)ch);
        }
        break;
      case 1:
        if (ch >= '0' && ch <= '7') {
          iEscCode = FXSYS_toDecimalDigit(ch);
          status = 2;
          break;
        }
        if (ch == 'n') {
          buf.AppendChar('\n');
        } else if (ch == 'r') {
          buf.AppendChar('\r');
        } else if (ch == 't') {
          buf.AppendChar('\t');
        } else if (ch == 'b') {
          buf.AppendChar('\b');
        } else if (ch == 'f') {
          buf.AppendChar('\f');
        } else if (ch == '\r') {
          status = 4;
          break;
        } else if (ch == '\n') {
        } else {
          buf.AppendChar(ch);
        }
        status = 0;
        break;
      case 2:
        if (ch >= '0' && ch <= '7') {
          iEscCode = iEscCode * 8 + FXSYS_toDecimalDigit(ch);
          status = 3;
        } else {
          buf.AppendChar(iEscCode);
          status = 0;
          continue;
        }
        break;
      case 3:
        if (ch >= '0' && ch <= '7') {
          iEscCode = iEscCode * 8 + FXSYS_toDecimalDigit(ch);
          buf.AppendChar(iEscCode);
          status = 0;
        } else {
          buf.AppendChar(iEscCode);
          status = 0;
          continue;
        }
        break;
      case 4:
        status = 0;
        if (ch != '\n') {
          continue;
        }
        break;
    }
    if (!PositionIsInBounds())
      break;

    ch = m_pBuf[m_Pos++];
  }
  if (PositionIsInBounds())
    ch = m_pBuf[m_Pos++];

  if (buf.GetLength() > MAX_STRING_LENGTH) {
    return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH);
  }
  return buf.GetByteString();
}
CFX_ByteString CPDF_StreamParser::ReadHexString() {
  if (!PositionIsInBounds())
    return CFX_ByteString();

  CFX_ByteTextBuf buf;
  bool bFirst = true;
  int code = 0;
  while (PositionIsInBounds()) {
    int ch = m_pBuf[m_Pos++];

    if (ch == '>')
      break;

    if (!std::isxdigit(ch))
      continue;

    int val = FXSYS_toHexDigit(ch);
    if (bFirst) {
      code = val * 16;
    } else {
      code += val;
      buf.AppendByte((uint8_t)code);
    }
    bFirst = !bFirst;
  }
  if (!bFirst)
    buf.AppendChar((char)code);

  if (buf.GetLength() > MAX_STRING_LENGTH)
    return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH);

  return buf.GetByteString();
}

bool CPDF_StreamParser::PositionIsInBounds() const {
  return m_Pos < m_Size;
}

#define PAGEPARSE_STAGE_GETCONTENT 1
#define PAGEPARSE_STAGE_PARSE 2
#define PAGEPARSE_STAGE_CHECKCLIP 3
CPDF_ContentParser::CPDF_ContentParser() {
  m_pParser = NULL;
  m_pStreamArray = NULL;
  m_pSingleStream = NULL;
  m_pData = NULL;
  m_Status = Ready;
  m_pType3Char = NULL;
}
CPDF_ContentParser::~CPDF_ContentParser() {
  Clear();
}
void CPDF_ContentParser::Clear() {
  delete m_pParser;
  delete m_pSingleStream;
  if (m_pStreamArray) {
    for (FX_DWORD i = 0; i < m_nStreams; i++)
      delete m_pStreamArray[i];
    FX_Free(m_pStreamArray);
  }
  if (!m_pSingleStream)
    FX_Free(m_pData);
  m_pParser = NULL;
  m_pStreamArray = NULL;
  m_pSingleStream = NULL;
  m_pData = NULL;
  m_Status = Ready;
}
void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions) {
  if (m_Status != Ready || pPage == NULL || pPage->m_pDocument == NULL ||
      pPage->m_pFormDict == NULL) {
    m_Status = Done;
    return;
  }
  m_pObjects = pPage;
  m_bForm = FALSE;
  if (pOptions) {
    m_Options = *pOptions;
  }
  m_Status = ToBeContinued;
  m_InternalStage = PAGEPARSE_STAGE_GETCONTENT;
  m_CurrentOffset = 0;
  CPDF_Object* pContent =
      pPage->m_pFormDict->GetElementValue(FX_BSTRC("Contents"));
  if (pContent == NULL) {
    m_Status = Done;
    return;
  }
  if (CPDF_Stream* pStream = pContent->AsStream()) {
    m_nStreams = 0;
    m_pSingleStream = new CPDF_StreamAcc;
    m_pSingleStream->LoadAllData(pStream, FALSE);
  } else if (CPDF_Array* pArray = pContent->AsArray()) {
    m_nStreams = pArray->GetCount();
    if (m_nStreams == 0) {
      m_Status = Done;
      return;
    }
    m_pStreamArray = FX_Alloc(CPDF_StreamAcc*, m_nStreams);
  } else {
    m_Status = Done;
    return;
  }
}
void CPDF_ContentParser::Start(CPDF_Form* pForm,
                               CPDF_AllStates* pGraphicStates,
                               CFX_AffineMatrix* pParentMatrix,
                               CPDF_Type3Char* pType3Char,
                               CPDF_ParseOptions* pOptions,
                               int level) {
  m_pType3Char = pType3Char;
  m_pObjects = pForm;
  m_bForm = TRUE;
  CFX_AffineMatrix form_matrix =
      pForm->m_pFormDict->GetMatrix(FX_BSTRC("Matrix"));
  if (pGraphicStates) {
    form_matrix.Concat(pGraphicStates->m_CTM);
  }
  CPDF_Array* pBBox = pForm->m_pFormDict->GetArray(FX_BSTRC("BBox"));
  CFX_FloatRect form_bbox;
  CPDF_Path ClipPath;
  if (pBBox) {
    form_bbox = pBBox->GetRect();
    ClipPath.New();
    ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right,
                        form_bbox.top);
    ClipPath.Transform(&form_matrix);
    if (pParentMatrix) {
      ClipPath.Transform(pParentMatrix);
    }
    form_bbox.Transform(&form_matrix);
    if (pParentMatrix) {
      form_bbox.Transform(pParentMatrix);
    }
  }
  CPDF_Dictionary* pResources =
      pForm->m_pFormDict->GetDict(FX_BSTRC("Resources"));
  m_pParser = new CPDF_StreamContentParser(
      pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources,
      pParentMatrix, pForm, pResources, &form_bbox, pOptions, pGraphicStates,
      level);

  m_pParser->GetCurStates()->m_CTM = form_matrix;
  m_pParser->GetCurStates()->m_ParentMatrix = form_matrix;
  if (ClipPath.NotNull()) {
    m_pParser->GetCurStates()->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING,
                                                     TRUE);
  }
  if (pForm->m_Transparency & PDFTRANS_GROUP) {
    CPDF_GeneralStateData* pData =
        m_pParser->GetCurStates()->m_GeneralState.GetModify();
    pData->m_BlendType = FXDIB_BLEND_NORMAL;
    pData->m_StrokeAlpha = 1.0f;
    pData->m_FillAlpha = 1.0f;
    pData->m_pSoftMask = NULL;
  }
  m_nStreams = 0;
  m_pSingleStream = new CPDF_StreamAcc;
  if (pForm->m_pDocument) {
    m_pSingleStream->LoadAllData(pForm->m_pFormStream, FALSE);
  } else {
    m_pSingleStream->LoadAllData(pForm->m_pFormStream, FALSE);
  }
  m_pData = (uint8_t*)m_pSingleStream->GetData();
  m_Size = m_pSingleStream->GetSize();
  m_Status = ToBeContinued;
  m_InternalStage = PAGEPARSE_STAGE_PARSE;
  m_CurrentOffset = 0;
}
void CPDF_ContentParser::Continue(IFX_Pause* pPause) {
  int steps = 0;
  while (m_Status == ToBeContinued) {
    if (m_InternalStage == PAGEPARSE_STAGE_GETCONTENT) {
      if (m_CurrentOffset == m_nStreams) {
        if (m_pStreamArray) {
          m_Size = 0;
          FX_DWORD i;
          for (i = 0; i < m_nStreams; i++) {
            FX_DWORD size = m_pStreamArray[i]->GetSize();
            if (m_Size + size + 1 <= m_Size) {
              m_Status = Done;
              return;
            }
            m_Size += size + 1;
          }
          m_pData = FX_Alloc(uint8_t, m_Size);
          FX_DWORD pos = 0;
          for (i = 0; i < m_nStreams; i++) {
            FXSYS_memcpy(m_pData + pos, m_pStreamArray[i]->GetData(),
                         m_pStreamArray[i]->GetSize());
            pos += m_pStreamArray[i]->GetSize() + 1;
            m_pData[pos - 1] = ' ';
            delete m_pStreamArray[i];
          }
          FX_Free(m_pStreamArray);
          m_pStreamArray = NULL;
        } else {
          m_pData = (uint8_t*)m_pSingleStream->GetData();
          m_Size = m_pSingleStream->GetSize();
        }
        m_InternalStage = PAGEPARSE_STAGE_PARSE;
        m_CurrentOffset = 0;
      } else {
        CPDF_Array* pContent =
            m_pObjects->m_pFormDict->GetArray(FX_BSTRC("Contents"));
        m_pStreamArray[m_CurrentOffset] = new CPDF_StreamAcc;
        CPDF_Stream* pStreamObj = ToStream(
            pContent ? pContent->GetElementValue(m_CurrentOffset) : nullptr);
        m_pStreamArray[m_CurrentOffset]->LoadAllData(pStreamObj, FALSE);
        m_CurrentOffset++;
      }
    }
    if (m_InternalStage == PAGEPARSE_STAGE_PARSE) {
      if (!m_pParser) {
        m_pParser = new CPDF_StreamContentParser(
            m_pObjects->m_pDocument, m_pObjects->m_pPageResources, nullptr,
            nullptr, m_pObjects, m_pObjects->m_pResources, &m_pObjects->m_BBox,
            &m_Options, nullptr, 0);
        m_pParser->GetCurStates()->m_ColorState.GetModify()->Default();
      }
      if (m_CurrentOffset >= m_Size) {
        m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP;
      } else {
        m_CurrentOffset +=
            m_pParser->Parse(m_pData + m_CurrentOffset,
                             m_Size - m_CurrentOffset, PARSE_STEP_LIMIT);
      }
    }
    if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) {
      if (m_pType3Char) {
        m_pType3Char->m_bColored = m_pParser->IsColored();
        m_pType3Char->m_Width =
            FXSYS_round(m_pParser->GetType3Data()[0] * 1000);
        m_pType3Char->m_BBox.left =
            FXSYS_round(m_pParser->GetType3Data()[2] * 1000);
        m_pType3Char->m_BBox.bottom =
            FXSYS_round(m_pParser->GetType3Data()[3] * 1000);
        m_pType3Char->m_BBox.right =
            FXSYS_round(m_pParser->GetType3Data()[4] * 1000);
        m_pType3Char->m_BBox.top =
            FXSYS_round(m_pParser->GetType3Data()[5] * 1000);
      }
      FX_POSITION pos = m_pObjects->m_ObjectList.GetHeadPosition();
      while (pos) {
        CPDF_PageObject* pObj =
            (CPDF_PageObject*)m_pObjects->m_ObjectList.GetNext(pos);
        if (pObj->m_ClipPath.IsNull()) {
          continue;
        }
        if (pObj->m_ClipPath.GetPathCount() != 1) {
          continue;
        }
        if (pObj->m_ClipPath.GetTextCount()) {
          continue;
        }
        CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0);
        if (!ClipPath.IsRect() || pObj->m_Type == PDFPAGE_SHADING) {
          continue;
        }
        CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY(0),
                               ClipPath.GetPointX(2), ClipPath.GetPointY(2));
        CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right,
                               pObj->m_Top);
        if (old_rect.Contains(obj_rect)) {
          pObj->m_ClipPath.SetNull();
        }
      }
      m_Status = Done;
      return;
    }
    steps++;
    if (pPause && pPause->NeedToPauseNow()) {
      break;
    }
  }
}
