Fix uninitialized offset
[pdfium.git] / core / src / fpdfapi / fpdf_parser / fpdf_parser_parser.cpp
index b3e587a..b9e5359 100644 (file)
-// Copyright 2014 PDFium Authors. All rights reserved.\r
-// Use of this source code is governed by a BSD-style license that can be\r
-// found in the LICENSE file.\r
\r
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
-\r
-#include "../../../include/fpdfapi/fpdf_parser.h"\r
-#include "../../../include/fpdfapi/fpdf_module.h"\r
-#include "../../../include/fpdfapi/fpdf_page.h"\r
-#include "../fpdf_page/pageint.h"\r
-#include <limits.h>\r
-#define _PARSER_OBJECT_LEVLE_          64\r
-extern const FX_LPCSTR _PDF_CharType;\r
-FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict)\r
-{\r
-    CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type"));\r
-    if (!pType) {\r
-        pType = pDict->GetElementValue(FX_BSTRC("FT"));\r
-        if (!pType) {\r
-            return FALSE;\r
-        }\r
-    }\r
-    if (pType->GetString() == FX_BSTRC("Sig")) {\r
-        return TRUE;\r
-    }\r
-    return FALSE;\r
-}\r
-static FX_INT32 _CompareDWord(const void* p1, const void* p2)\r
-{\r
-    return (*(FX_DWORD*)p1) - (*(FX_DWORD*)p2);\r
-}\r
-static int _CompareFileSize(const void* p1, const void* p2)\r
-{\r
-    FX_FILESIZE ret = (*(FX_FILESIZE*)p1) - (*(FX_FILESIZE*)p2);\r
-    if (ret > 0) {\r
-        return 1;\r
-    }\r
-    if (ret < 0) {\r
-        return -1;\r
-    }\r
-    return 0;\r
-}\r
-CPDF_Parser::CPDF_Parser()\r
-{\r
-    m_pDocument = NULL;\r
-    m_pTrailer = NULL;\r
-    m_pEncryptDict = NULL;\r
-    m_pSecurityHandler = NULL;\r
-    m_pLinearized = NULL;\r
-    m_dwFirstPageNo = 0;\r
-    m_dwXrefStartObjNum = 0;\r
-    m_bOwnFileRead = TRUE;\r
-    m_bForceUseSecurityHandler = FALSE;\r
-}\r
-CPDF_Parser::~CPDF_Parser()\r
-{\r
-    CloseParser(FALSE);\r
-}\r
-FX_DWORD CPDF_Parser::GetLastObjNum()\r
-{\r
-    FX_DWORD dwSize = m_CrossRef.GetSize();\r
-    return dwSize ? dwSize - 1 : 0;\r
-}\r
-void CPDF_Parser::SetEncryptDictionary(CPDF_Dictionary* pDict)\r
-{\r
-    m_pEncryptDict = pDict;\r
-}\r
-void CPDF_Parser::CloseParser(FX_BOOL bReParse)\r
-{\r
-    m_bVersionUpdated = FALSE;\r
-    if (m_pDocument && !bReParse) {\r
-        delete m_pDocument;\r
-        m_pDocument = NULL;\r
-    }\r
-    if (m_pTrailer) {\r
-        m_pTrailer->Release();\r
-        m_pTrailer = NULL;\r
-    }\r
-    ReleaseEncryptHandler();\r
-    SetEncryptDictionary(NULL);\r
-    if (m_bOwnFileRead && m_Syntax.m_pFileAccess != NULL) {\r
-        m_Syntax.m_pFileAccess->Release();\r
-        m_Syntax.m_pFileAccess = NULL;\r
-    }\r
-    FX_POSITION pos = m_ObjectStreamMap.GetStartPosition();\r
-    while (pos) {\r
-        FX_LPVOID objnum;\r
-        CPDF_StreamAcc* pStream;\r
-        m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream);\r
-        delete pStream;\r
-    }\r
-    m_ObjectStreamMap.RemoveAll();\r
-    m_SortedOffset.RemoveAll();\r
-    m_CrossRef.RemoveAll();\r
-    m_V5Type.RemoveAll();\r
-    m_ObjVersion.RemoveAll();\r
-    FX_INT32 iLen = m_Trailers.GetSize();\r
-    for (FX_INT32 i = 0; i < iLen; ++i) {\r
-        m_Trailers.GetAt(i)->Release();\r
-    }\r
-    m_Trailers.RemoveAll();\r
-    if (m_pLinearized) {\r
-        m_pLinearized->Release();\r
-        m_pLinearized = NULL;\r
-    }\r
-}\r
-static FX_INT32 GetHeaderOffset(IFX_FileRead* pFile)\r
-{\r
-    FX_DWORD tag = FXDWORD_FROM_LSBFIRST(0x46445025);\r
-    FX_BYTE buf[4];\r
-    FX_INT32 offset = 0;\r
-    while (1) {\r
-        if (!pFile->ReadBlock(buf, offset, 4)) {\r
-            return -1;\r
-        }\r
-        if (*(FX_DWORD*)buf == tag) {\r
-            return offset;\r
-        }\r
-        offset ++;\r
-        if (offset > 1024) {\r
-            return -1;\r
-        }\r
-    }\r
-    return -1;\r
-}\r
-FX_DWORD CPDF_Parser::StartParse(FX_LPCSTR filename, FX_BOOL bReParse)\r
-{\r
-    IFX_FileRead* pFileAccess = FX_CreateFileRead(filename);\r
-    if (!pFileAccess) {\r
-        return PDFPARSE_ERROR_FILE;\r
-    }\r
-    return StartParse(pFileAccess, bReParse);\r
-}\r
-FX_DWORD CPDF_Parser::StartParse(FX_LPCWSTR filename, FX_BOOL bReParse)\r
-{\r
-    IFX_FileRead* pFileAccess = FX_CreateFileRead(filename);\r
-    if (!pFileAccess) {\r
-        return PDFPARSE_ERROR_FILE;\r
-    }\r
-    return StartParse(pFileAccess, bReParse);\r
-}\r
-CPDF_SecurityHandler* FPDF_CreateStandardSecurityHandler();\r
-CPDF_SecurityHandler* FPDF_CreatePubKeyHandler(void*);\r
-FX_DWORD CPDF_Parser::StartParse(IFX_FileRead* pFileAccess, FX_BOOL bReParse, FX_BOOL bOwnFileRead)\r
-{\r
-    CloseParser(bReParse);\r
-    m_bXRefStream = FALSE;\r
-    m_LastXRefOffset = 0;\r
-    m_bOwnFileRead = bOwnFileRead;\r
-    FX_INT32 offset = GetHeaderOffset(pFileAccess);\r
-    if (offset == -1) {\r
-        if (bOwnFileRead && pFileAccess) {\r
-            pFileAccess->Release();\r
-        }\r
-        return PDFPARSE_ERROR_FORMAT;\r
-    }\r
-    m_Syntax.InitParser(pFileAccess, offset);\r
-    FX_BYTE ch;\r
-    m_Syntax.GetCharAt(5, ch);\r
-    m_FileVersion = (ch - '0') * 10;\r
-    m_Syntax.GetCharAt(7, ch);\r
-    m_FileVersion += ch - '0';\r
-    m_Syntax.RestorePos(m_Syntax.m_FileLen - m_Syntax.m_HeaderOffset - 9);\r
-    if (!bReParse) {\r
-        m_pDocument = FX_NEW CPDF_Document(this);\r
-    }\r
-    FX_BOOL bXRefRebuilt = FALSE;\r
-    if (m_Syntax.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, 4096)) {\r
-        FX_FILESIZE startxref_offset = m_Syntax.SavePos();\r
-        FX_LPVOID pResult = FXSYS_bsearch(&startxref_offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);\r
-        if (pResult == NULL) {\r
-            m_SortedOffset.Add(startxref_offset);\r
-        }\r
-        m_Syntax.GetKeyword();\r
-        FX_BOOL bNumber;\r
-        CFX_ByteString xrefpos_str = m_Syntax.GetNextWord(bNumber);\r
-        if (!bNumber) {\r
-            return PDFPARSE_ERROR_FORMAT;\r
-        }\r
-        m_LastXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str);\r
-        if (!LoadAllCrossRefV4(m_LastXRefOffset) && !LoadAllCrossRefV5(m_LastXRefOffset)) {\r
-            if (!RebuildCrossRef()) {\r
-                return PDFPARSE_ERROR_FORMAT;\r
-            }\r
-            bXRefRebuilt = TRUE;\r
-            m_LastXRefOffset = 0;\r
-        }\r
-    } else {\r
-        if (!RebuildCrossRef()) {\r
-            return PDFPARSE_ERROR_FORMAT;\r
-        }\r
-        bXRefRebuilt = TRUE;\r
-    }\r
-    FX_DWORD dwRet = SetEncryptHandler();\r
-    if (dwRet != PDFPARSE_ERROR_SUCCESS) {\r
-        return dwRet;\r
-    }\r
-    m_pDocument->LoadDoc();\r
-    if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) {\r
-        if (bXRefRebuilt) {\r
-            return PDFPARSE_ERROR_FORMAT;\r
-        }\r
-        ReleaseEncryptHandler();\r
-        if (!RebuildCrossRef()) {\r
-            return PDFPARSE_ERROR_FORMAT;\r
-        }\r
-        dwRet = SetEncryptHandler();\r
-        if (dwRet != PDFPARSE_ERROR_SUCCESS) {\r
-            return dwRet;\r
-        }\r
-        m_pDocument->LoadDoc();\r
-        if (m_pDocument->GetRoot() == NULL) {\r
-            return PDFPARSE_ERROR_FORMAT;\r
-        }\r
-    }\r
-    FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);\r
-    FX_DWORD RootObjNum = GetRootObjNum();\r
-    if (RootObjNum == 0) {\r
-        ReleaseEncryptHandler();\r
-        RebuildCrossRef();\r
-        RootObjNum = GetRootObjNum();\r
-        if (RootObjNum == 0) {\r
-            return PDFPARSE_ERROR_FORMAT;\r
-        }\r
-        dwRet = SetEncryptHandler();\r
-        if (dwRet != PDFPARSE_ERROR_SUCCESS) {\r
-            return dwRet;\r
-        }\r
-    }\r
-    if (m_pSecurityHandler && !m_pSecurityHandler->IsMetadataEncrypted()) {\r
-        CPDF_Reference* pMetadata = (CPDF_Reference*)m_pDocument->GetRoot()->GetElement(FX_BSTRC("Metadata"));\r
-        if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) {\r
-            m_Syntax.m_MetadataObjnum = pMetadata->GetRefObjNum();\r
-        }\r
-    }\r
-    return PDFPARSE_ERROR_SUCCESS;\r
-}\r
-FX_DWORD CPDF_Parser::SetEncryptHandler()\r
-{\r
-    ReleaseEncryptHandler();\r
-    SetEncryptDictionary(NULL);\r
-    if (m_pTrailer == NULL) {\r
-        return PDFPARSE_ERROR_FORMAT;\r
-    }\r
-    CPDF_Object* pEncryptObj = m_pTrailer->GetElement(FX_BSTRC("Encrypt"));\r
-    if (pEncryptObj) {\r
-        if (pEncryptObj->GetType() == PDFOBJ_DICTIONARY) {\r
-            SetEncryptDictionary((CPDF_Dictionary*)pEncryptObj);\r
-        } else if (pEncryptObj->GetType() == PDFOBJ_REFERENCE) {\r
-            pEncryptObj = m_pDocument->GetIndirectObject(((CPDF_Reference*)pEncryptObj)->GetRefObjNum());\r
-            if (pEncryptObj) {\r
-                SetEncryptDictionary(pEncryptObj->GetDict());\r
-            }\r
-        }\r
-    }\r
-    if (m_bForceUseSecurityHandler) {\r
-        FX_DWORD err = PDFPARSE_ERROR_HANDLER;\r
-        if (m_pSecurityHandler == NULL) {\r
-            return PDFPARSE_ERROR_HANDLER;\r
-        }\r
-        if (!m_pSecurityHandler->OnInit(this, m_pEncryptDict)) {\r
-            return err;\r
-        }\r
-        CPDF_CryptoHandler* pCryptoHandler = m_pSecurityHandler->CreateCryptoHandler();\r
-        if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) {\r
-            delete pCryptoHandler;\r
-            pCryptoHandler = NULL;\r
-            return PDFPARSE_ERROR_HANDLER;\r
-        }\r
-        m_Syntax.SetEncrypt(pCryptoHandler);\r
-    } else if (m_pEncryptDict) {\r
-        CFX_ByteString filter = m_pEncryptDict->GetString(FX_BSTRC("Filter"));\r
-        CPDF_SecurityHandler* pSecurityHandler = NULL;\r
-        FX_DWORD err = PDFPARSE_ERROR_HANDLER;\r
-        if (filter == FX_BSTRC("Standard")) {\r
-            pSecurityHandler = FPDF_CreateStandardSecurityHandler();\r
-            err = PDFPARSE_ERROR_PASSWORD;\r
-        }\r
-        if (pSecurityHandler == NULL) {\r
-            return PDFPARSE_ERROR_HANDLER;\r
-        }\r
-        if (!pSecurityHandler->OnInit(this, m_pEncryptDict)) {\r
-            delete pSecurityHandler;\r
-            pSecurityHandler = NULL;\r
-            return err;\r
-        }\r
-        m_pSecurityHandler = pSecurityHandler;\r
-        CPDF_CryptoHandler* pCryptoHandler = pSecurityHandler->CreateCryptoHandler();\r
-        if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) {\r
-            delete pCryptoHandler;\r
-            pCryptoHandler = NULL;\r
-            return PDFPARSE_ERROR_HANDLER;\r
-        }\r
-        m_Syntax.SetEncrypt(pCryptoHandler);\r
-    }\r
-    return PDFPARSE_ERROR_SUCCESS;\r
-}\r
-void CPDF_Parser::ReleaseEncryptHandler()\r
-{\r
-    if (m_Syntax.m_pCryptoHandler) {\r
-        delete m_Syntax.m_pCryptoHandler;\r
-        m_Syntax.m_pCryptoHandler = NULL;\r
-    }\r
-    if (m_pSecurityHandler && !m_bForceUseSecurityHandler) {\r
-        delete m_pSecurityHandler;\r
-        m_pSecurityHandler = NULL;\r
-    }\r
-}\r
-FX_FILESIZE CPDF_Parser::GetObjectOffset(FX_DWORD objnum)\r
-{\r
-    if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {\r
-        return 0;\r
-    }\r
-    if (m_V5Type[objnum] == 1) {\r
-        return m_CrossRef[objnum];\r
-    }\r
-    if (m_V5Type[objnum] == 2) {\r
-        return m_CrossRef[(FX_INT32)m_CrossRef[objnum]];\r
-    }\r
-    return 0;\r
-}\r
-static FX_INT32 GetDirectInteger(CPDF_Dictionary* pDict, FX_BSTR key)\r
-{\r
-    CPDF_Object* pObj = pDict->GetElement(key);\r
-    if (pObj == NULL) {\r
-        return 0;\r
-    }\r
-    if (pObj->GetType() == PDFOBJ_NUMBER) {\r
-        return ((CPDF_Number*)pObj)->GetInteger();\r
-    }\r
-    return 0;\r
-}\r
-static FX_BOOL CheckDirectType(CPDF_Dictionary* pDict, FX_BSTR key, FX_INT32 iType)\r
-{\r
-    CPDF_Object* pObj = pDict->GetElement(key);\r
-    if (!pObj) {\r
-        return TRUE;\r
-    }\r
-    return pObj->GetType() == iType;\r
-}\r
-FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos)\r
-{\r
-    if (!LoadCrossRefV4(xrefpos, 0, TRUE, FALSE)) {\r
-        return FALSE;\r
-    }\r
-    m_pTrailer = LoadTrailerV4();\r
-    if (m_pTrailer == NULL) {\r
-        return FALSE;\r
-    }\r
-    FX_INT32 xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size"));\r
-    if (xrefsize <= 0 || xrefsize > (1 << 20)) {\r
-        return FALSE;\r
-    }\r
-    m_CrossRef.SetSize(xrefsize);\r
-    m_V5Type.SetSize(xrefsize);\r
-    CFX_FileSizeArray CrossRefList, XRefStreamList;\r
-    CrossRefList.Add(xrefpos);\r
-    XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm")));\r
-    if (!CheckDirectType(m_pTrailer, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) {\r
-        return FALSE;\r
-    }\r
-    FX_FILESIZE newxrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev"));\r
-    if (newxrefpos == xrefpos) {\r
-        return FALSE;\r
-    }\r
-    xrefpos = newxrefpos;\r
-    while (xrefpos) {\r
-        CrossRefList.InsertAt(0, xrefpos);\r
-        LoadCrossRefV4(xrefpos, 0, TRUE, FALSE);\r
-        CPDF_Dictionary* pDict = LoadTrailerV4();\r
-        if (pDict == NULL) {\r
-            return FALSE;\r
-        }\r
-        if (!CheckDirectType(pDict, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) {\r
-            pDict->Release();\r
-            return FALSE;\r
-        }\r
-        newxrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev"));\r
-        if (newxrefpos == xrefpos) {\r
-            pDict->Release();\r
-            return FALSE;\r
-        }\r
-        xrefpos = newxrefpos;\r
-        XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm")));\r
-        m_Trailers.Add(pDict);\r
-    }\r
-    for (FX_INT32 i = 0; i < CrossRefList.GetSize(); i ++)\r
-        if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) {\r
-            return FALSE;\r
-        }\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, FX_DWORD dwObjCount)\r
-{\r
-    if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) {\r
-        return FALSE;\r
-    }\r
-    m_pTrailer = LoadTrailerV4();\r
-    if (m_pTrailer == NULL) {\r
-        return FALSE;\r
-    }\r
-    FX_INT32 xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size"));\r
-    if (xrefsize == 0) {\r
-        return FALSE;\r
-    }\r
-    CFX_FileSizeArray CrossRefList, XRefStreamList;\r
-    CrossRefList.Add(xrefpos);\r
-    XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm")));\r
-    xrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev"));\r
-    while (xrefpos) {\r
-        CrossRefList.InsertAt(0, xrefpos);\r
-        LoadCrossRefV4(xrefpos, 0, TRUE, FALSE);\r
-        CPDF_Dictionary* pDict = LoadTrailerV4();\r
-        if (pDict == NULL) {\r
-            return FALSE;\r
-        }\r
-        xrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev"));\r
-        XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm")));\r
-        m_Trailers.Add(pDict);\r
-    }\r
-    for (FX_INT32 i = 1; i < CrossRefList.GetSize(); i ++)\r
-        if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) {\r
-            return FALSE;\r
-        }\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos, FX_DWORD dwObjCount)\r
-{\r
-    FX_FILESIZE dwStartPos = pos - m_Syntax.m_HeaderOffset;\r
-    m_Syntax.RestorePos(dwStartPos);\r
-    FX_LPVOID pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);\r
-    if (pResult == NULL) {\r
-        m_SortedOffset.Add(pos);\r
-    }\r
-    FX_DWORD start_objnum = 0;\r
-    FX_DWORD count = dwObjCount;\r
-    FX_FILESIZE SavedPos = m_Syntax.SavePos();\r
-    FX_INT32 recordsize = 20;\r
-    char* pBuf = FX_Alloc(char, 1024 * recordsize + 1);\r
-    pBuf[1024 * recordsize] = '\0';\r
-    FX_INT32 nBlocks = count / 1024 + 1;\r
-    for (FX_INT32 block = 0; block < nBlocks; block ++) {\r
-        FX_INT32 block_size = block == nBlocks - 1 ? count % 1024 : 1024;\r
-        FX_DWORD dwReadSize = block_size * recordsize;\r
-        if ((FX_FILESIZE)(dwStartPos + dwReadSize) > m_Syntax.m_FileLen) {\r
-            FX_Free(pBuf);\r
-            return FALSE;\r
-        }\r
-        if (!m_Syntax.ReadBlock((FX_LPBYTE)pBuf, dwReadSize)) {\r
-            FX_Free(pBuf);\r
-            return FALSE;\r
-        }\r
-        for (FX_INT32 i = 0; i < block_size; i ++) {\r
-            FX_DWORD objnum = start_objnum + block * 1024 + i;\r
-            char* pEntry = pBuf + i * recordsize;\r
-            if (pEntry[17] == 'f') {\r
-                m_CrossRef.SetAtGrow(objnum, 0);\r
-                m_V5Type.SetAtGrow(objnum, 0);\r
-            } else {\r
-                FX_INT32 offset = FXSYS_atoi(pEntry);\r
-                if (offset == 0) {\r
-                    for (FX_INT32 c = 0; c < 10; c ++) {\r
-                        if (pEntry[c] < '0' || pEntry[c] > '9') {\r
-                            FX_Free(pBuf);\r
-                            return FALSE;\r
-                        }\r
-                    }\r
-                }\r
-                m_CrossRef.SetAtGrow(objnum, offset);\r
-                FX_INT32 version = FXSYS_atoi(pEntry + 11);\r
-                if (version >= 1) {\r
-                    m_bVersionUpdated = TRUE;\r
-                }\r
-                m_ObjVersion.SetAtGrow(objnum, version);\r
-                if (m_CrossRef[objnum] < m_Syntax.m_FileLen) {\r
-                    FX_LPVOID pResult = FXSYS_bsearch(&m_CrossRef[objnum], m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);\r
-                    if (pResult == NULL) {\r
-                        m_SortedOffset.Add(m_CrossRef[objnum]);\r
-                    }\r
-                }\r
-                m_V5Type.SetAtGrow(objnum, 1);\r
-            }\r
-        }\r
-    }\r
-    FX_Free(pBuf);\r
-    m_Syntax.RestorePos(SavedPos + count * recordsize);\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos, FX_FILESIZE streampos, FX_BOOL bSkip, FX_BOOL bFirst)\r
-{\r
-    m_Syntax.RestorePos(pos);\r
-    if (m_Syntax.GetKeyword() != FX_BSTRC("xref")) {\r
-        return FALSE;\r
-    }\r
-    FX_LPVOID pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);\r
-    if (pResult == NULL) {\r
-        m_SortedOffset.Add(pos);\r
-    }\r
-    if (streampos) {\r
-        FX_LPVOID pResult = FXSYS_bsearch(&streampos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);\r
-        if (pResult == NULL) {\r
-            m_SortedOffset.Add(streampos);\r
-        }\r
-    }\r
-    while (1) {\r
-        FX_FILESIZE SavedPos = m_Syntax.SavePos();\r
-        FX_BOOL bIsNumber;\r
-        CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);\r
-        if (word.IsEmpty()) {\r
-            return FALSE;\r
-        }\r
-        if (!bIsNumber) {\r
-            m_Syntax.RestorePos(SavedPos);\r
-            break;\r
-        }\r
-        FX_DWORD start_objnum = FXSYS_atoi(word);\r
-        if (start_objnum >= (1 << 20)) {\r
-            return FALSE;\r
-        }\r
-        FX_DWORD count = m_Syntax.GetDirectNum();\r
-        m_Syntax.ToNextWord();\r
-        SavedPos = m_Syntax.SavePos();\r
-        FX_BOOL bFirstItem = FALSE;\r
-        FX_INT32 recordsize = 20;\r
-        if (bFirst) {\r
-            bFirstItem = TRUE;\r
-        }\r
-        m_dwXrefStartObjNum = start_objnum;\r
-        if (!bSkip) {\r
-            char* pBuf = FX_Alloc(char, 1024 * recordsize + 1);\r
-            pBuf[1024 * recordsize] = '\0';\r
-            FX_INT32 nBlocks = count / 1024 + 1;\r
-            FX_BOOL bFirstBlock = TRUE;\r
-            for (FX_INT32 block = 0; block < nBlocks; block ++) {\r
-                FX_INT32 block_size = block == nBlocks - 1 ? count % 1024 : 1024;\r
-                m_Syntax.ReadBlock((FX_LPBYTE)pBuf, block_size * recordsize);\r
-                for (FX_INT32 i = 0; i < block_size; i ++) {\r
-                    FX_DWORD objnum = start_objnum + block * 1024 + i;\r
-                    char* pEntry = pBuf + i * recordsize;\r
-                    if (pEntry[17] == 'f') {\r
-                        if (bFirstItem) {\r
-                            objnum = 0;\r
-                            bFirstItem = FALSE;\r
-                        }\r
-                        if (bFirstBlock) {\r
-                            FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry);\r
-                            FX_INT32 version = FXSYS_atoi(pEntry + 11);\r
-                            if (offset == 0 && version == 65535 && start_objnum != 0) {\r
-                                start_objnum--;\r
-                                objnum = 0;\r
-                            }\r
-                        }\r
-                        m_CrossRef.SetAtGrow(objnum, 0);\r
-                        m_V5Type.SetAtGrow(objnum, 0);\r
-                    } else {\r
-                        FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry);\r
-                        if (offset == 0) {\r
-                            for (FX_INT32 c = 0; c < 10; c ++) {\r
-                                if (pEntry[c] < '0' || pEntry[c] > '9') {\r
-                                    FX_Free(pBuf);\r
-                                    return FALSE;\r
-                                }\r
-                            }\r
-                        }\r
-                        m_CrossRef.SetAtGrow(objnum, offset);\r
-                        FX_INT32 version = FXSYS_atoi(pEntry + 11);\r
-                        if (version >= 1) {\r
-                            m_bVersionUpdated = TRUE;\r
-                        }\r
-                        m_ObjVersion.SetAtGrow(objnum, version);\r
-                        if (m_CrossRef[objnum] < m_Syntax.m_FileLen) {\r
-                            FX_LPVOID pResult = FXSYS_bsearch(&m_CrossRef[objnum], m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);\r
-                            if (pResult == NULL) {\r
-                                m_SortedOffset.Add(m_CrossRef[objnum]);\r
-                            }\r
-                        }\r
-                        m_V5Type.SetAtGrow(objnum, 1);\r
-                    }\r
-                    if (bFirstBlock) {\r
-                        bFirstBlock = FALSE;\r
-                    }\r
-                }\r
-            }\r
-            FX_Free(pBuf);\r
-        }\r
-        m_Syntax.RestorePos(SavedPos + count * recordsize);\r
-    }\r
-    if (streampos)\r
-        if (!LoadCrossRefV5(streampos, streampos, FALSE)) {\r
-            return FALSE;\r
-        }\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos)\r
-{\r
-    if (!LoadCrossRefV5(xrefpos, xrefpos, TRUE)) {\r
-        return FALSE;\r
-    }\r
-    while (xrefpos)\r
-        if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) {\r
-            return FALSE;\r
-        }\r
-    m_ObjectStreamMap.InitHashTable(101, FALSE);\r
-    m_bXRefStream = TRUE;\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_Parser::RebuildCrossRef()\r
-{\r
-    m_CrossRef.RemoveAll();\r
-    m_V5Type.RemoveAll();\r
-    m_SortedOffset.RemoveAll();\r
-    m_ObjVersion.RemoveAll();\r
-    if (m_pTrailer) {\r
-        m_pTrailer->Release();\r
-        m_pTrailer = NULL;\r
-    }\r
-    FX_INT32 status = 0;\r
-    FX_INT32 inside_index = 0;\r
-    FX_DWORD objnum, gennum;\r
-    FX_INT32 depth = 0;\r
-    FX_LPBYTE buffer = FX_Alloc(FX_BYTE, 4096);\r
-    FX_FILESIZE pos = m_Syntax.m_HeaderOffset;\r
-    FX_FILESIZE start_pos, start_pos1;\r
-    FX_FILESIZE last_obj = -1, last_xref = -1, last_trailer = -1;\r
-    FX_BOOL bInUpdate = FALSE;\r
-    while (pos < m_Syntax.m_FileLen) {\r
-        FX_BOOL bOverFlow = FALSE;\r
-        FX_DWORD size = (FX_DWORD)(m_Syntax.m_FileLen - pos);\r
-        if (size > 4096) {\r
-            size = 4096;\r
-        }\r
-        if (!m_Syntax.m_pFileAccess->ReadBlock(buffer, pos, size)) {\r
-            break;\r
-        }\r
-        for (FX_DWORD i = 0; i < size; i ++) {\r
-            FX_BYTE byte = buffer[i];\r
-            FX_LPBYTE pData = buffer + i;\r
-            switch (status) {\r
-                case 0:\r
-                    if (_PDF_CharType[byte] == 'W') {\r
-                        status = 1;\r
-                    }\r
-                    if (byte <= '9' && byte >= '0') {\r
-                        --i;\r
-                        status = 1;\r
-                    }\r
-                    if (byte == '%') {\r
-                        inside_index = 0;\r
-                        status = 9;\r
-                    }\r
-                    if (byte == '(') {\r
-                        status = 10;\r
-                        depth = 1;\r
-                    }\r
-                    if (byte == '<') {\r
-                        inside_index = 1;\r
-                        status = 11;\r
-                    }\r
-                    if (byte == '\\') {\r
-                        status = 13;\r
-                    }\r
-                    if (byte == 't') {\r
-                        status = 7;\r
-                        inside_index = 1;\r
-                    }\r
-                    break;\r
-                case 1:\r
-                    if (_PDF_CharType[byte] == 'W') {\r
-                        break;\r
-                    } else if (byte <= '9' && byte >= '0') {\r
-                        start_pos = pos + i;\r
-                        status = 2;\r
-                        objnum = byte - '0';\r
-                    } else if (byte == 't') {\r
-                        status = 7;\r
-                        inside_index = 1;\r
-                    } else if (byte == 'x') {\r
-                        status = 8;\r
-                        inside_index = 1;\r
-                    } else {\r
-                        --i;\r
-                        status = 0;\r
-                    }\r
-                    break;\r
-                case 2:\r
-                    if (byte <= '9' && byte >= '0') {\r
-                        objnum = objnum * 10 + byte - '0';\r
-                        break;\r
-                    } else if (_PDF_CharType[byte] == 'W') {\r
-                        status = 3;\r
-                    } else {\r
-                        --i;\r
-                        status = 14;\r
-                        inside_index = 0;\r
-                    }\r
-                    break;\r
-                case 3:\r
-                    if (byte <= '9' && byte >= '0') {\r
-                        start_pos1 = pos + i;\r
-                        status = 4;\r
-                        gennum = byte - '0';\r
-                    } else if (_PDF_CharType[byte] == 'W') {\r
-                        break;\r
-                    } else if (byte == 't') {\r
-                        status = 7;\r
-                        inside_index = 1;\r
-                    } else {\r
-                        --i;\r
-                        status = 0;\r
-                    }\r
-                    break;\r
-                case 4:\r
-                    if (byte <= '9' && byte >= '0') {\r
-                        gennum = gennum * 10 + byte - '0';\r
-                        break;\r
-                    } else if (_PDF_CharType[byte] == 'W') {\r
-                        status = 5;\r
-                    } else {\r
-                        --i;\r
-                        status = 0;\r
-                    }\r
-                    break;\r
-                case 5:\r
-                    if (byte == 'o') {\r
-                        status = 6;\r
-                        inside_index = 1;\r
-                    } else if (_PDF_CharType[byte] == 'W') {\r
-                        break;\r
-                    } else if (byte <= '9' && byte >= '0') {\r
-                        objnum = gennum;\r
-                        gennum = byte - '0';\r
-                        start_pos = start_pos1;\r
-                        start_pos1 = pos + i;\r
-                        status = 4;\r
-                    } else if (byte == 't') {\r
-                        status = 7;\r
-                        inside_index = 1;\r
-                    } else {\r
-                        --i;\r
-                        status = 0;\r
-                    }\r
-                    break;\r
-                case 6:\r
-                    switch (inside_index) {\r
-                        case 1:\r
-                            if (byte != 'b') {\r
-                                --i;\r
-                                status = 0;\r
-                            } else {\r
-                                inside_index ++;\r
-                            }\r
-                            break;\r
-                        case 2:\r
-                            if (byte != 'j') {\r
-                                --i;\r
-                                status = 0;\r
-                            } else {\r
-                                inside_index ++;\r
-                            }\r
-                            break;\r
-                        case 3:\r
-                            if (_PDF_CharType[byte] == 'W' || _PDF_CharType[byte] == 'D') {\r
-                                if (objnum > 0x1000000) {\r
-                                    status = 0;\r
-                                    break;\r
-                                }\r
-                                FX_FILESIZE obj_pos = start_pos - m_Syntax.m_HeaderOffset;\r
-                                last_obj = start_pos;\r
-                                FX_LPVOID pResult = FXSYS_bsearch(&obj_pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);\r
-                                if (pResult == NULL) {\r
-                                    m_SortedOffset.Add(obj_pos);\r
-                                }\r
-                                FX_FILESIZE obj_end = 0;\r
-                                CPDF_Object *pObject = ParseIndirectObjectAtByStrict(m_pDocument, obj_pos, objnum, NULL, &obj_end);\r
-                                if (pObject) {\r
-                                    int iType =        pObject->GetType();\r
-                                    if (iType == PDFOBJ_STREAM) {\r
-                                        CPDF_Stream* pStream = (CPDF_Stream*)pObject;\r
-                                        CPDF_Dictionary* pDict = pStream->GetDict();\r
-                                        if (pDict) {\r
-                                            if (pDict->KeyExist(FX_BSTRC("Type"))) {\r
-                                                CFX_ByteString bsValue = pDict->GetString(FX_BSTRC("Type"));\r
-                                                if (bsValue == FX_BSTRC("XRef") && pDict->KeyExist(FX_BSTRC("Size"))) {\r
-                                                    CPDF_Object* pRoot = pDict->GetElement(FX_BSTRC("Root"));\r
-                                                    if (pRoot && pRoot->GetDict() && pRoot->GetDict()->GetElement(FX_BSTRC("Pages"))) {\r
-                                                        if (m_pTrailer) {\r
-                                                            m_pTrailer->Release();\r
-                                                        }\r
-                                                        m_pTrailer = (CPDF_Dictionary*)pDict->Clone();\r
-                                                    }\r
-                                                }\r
-                                            }\r
-                                        }\r
-                                    }\r
-                                }\r
-                                FX_FILESIZE offset = 0;\r
-                                m_Syntax.RestorePos(obj_pos);\r
-                                offset = m_Syntax.FindTag(FX_BSTRC("obj"), 0);\r
-                                if (offset == -1) {\r
-                                    offset = 0;\r
-                                } else {\r
-                                    offset += 3;\r
-                                }\r
-                                FX_FILESIZE nLen = obj_end - obj_pos - offset;\r
-                                if ((FX_DWORD)nLen > size - i) {\r
-                                    pos = obj_end + m_Syntax.m_HeaderOffset;\r
-                                    bOverFlow = TRUE;\r
-                                } else {\r
-                                    i += (FX_DWORD)nLen;\r
-                                }\r
-                                if (m_CrossRef.GetSize() > (FX_INT32)objnum && m_CrossRef[objnum]) {\r
-                                    if (pObject) {\r
-                                        FX_DWORD oldgen = m_ObjVersion.GetAt(objnum);\r
-                                        m_CrossRef[objnum] = obj_pos;\r
-                                        m_ObjVersion.SetAt(objnum, (FX_SHORT)gennum);\r
-                                        if (oldgen != gennum) {\r
-                                            m_bVersionUpdated = TRUE;\r
-                                        }\r
-                                    }\r
-                                } else {\r
-                                    m_CrossRef.SetAtGrow(objnum, obj_pos);\r
-                                    m_V5Type.SetAtGrow(objnum, 1);\r
-                                    m_ObjVersion.SetAtGrow(objnum, (FX_SHORT)gennum);\r
-                                }\r
-                                if (pObject) {\r
-                                    pObject->Release();\r
-                                }\r
-                            }\r
-                            --i;\r
-                            status = 0;\r
-                            break;\r
-                    }\r
-                    break;\r
-                case 7:\r
-                    if (inside_index == 7) {\r
-                        if (_PDF_CharType[byte] == 'W' || _PDF_CharType[byte] == 'D') {\r
-                            last_trailer = pos + i - 7;\r
-                            m_Syntax.RestorePos(pos + i - m_Syntax.m_HeaderOffset);\r
-                            CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0);\r
-                            if (pObj) {\r
-                                if (pObj->GetType() != PDFOBJ_DICTIONARY && pObj->GetType() != PDFOBJ_STREAM) {\r
-                                    pObj->Release();\r
-                                } else {\r
-                                    CPDF_Dictionary* pTrailer = NULL;\r
-                                    if (pObj->GetType() == PDFOBJ_STREAM) {\r
-                                        pTrailer = ((CPDF_Stream*)pObj)->GetDict();\r
-                                    } else {\r
-                                        pTrailer = (CPDF_Dictionary*)pObj;\r
-                                    }\r
-                                    if (pTrailer) {\r
-                                        if (m_pTrailer) {\r
-                                            CPDF_Object* pRoot = pTrailer->GetElement(FX_BSTRC("Root"));\r
-                                            if (pRoot == NULL || (pRoot->GetType() == PDFOBJ_REFERENCE &&\r
-                                                                  (FX_DWORD)m_CrossRef.GetSize() > ((CPDF_Reference*)pRoot)->GetRefObjNum() &&\r
-                                                                  m_CrossRef.GetAt(((CPDF_Reference*)pRoot)->GetRefObjNum()) != 0)) {\r
-                                                FX_POSITION pos = pTrailer->GetStartPos();\r
-                                                while (pos) {\r
-                                                    CFX_ByteString key;\r
-                                                    CPDF_Object* pObj = pTrailer->GetNextElement(pos, key);\r
-                                                    m_pTrailer->SetAt(key, pObj->Clone(), m_pDocument);\r
-                                                }\r
-                                                pObj->Release();\r
-                                            } else {\r
-                                                pObj->Release();\r
-                                            }\r
-                                        } else {\r
-                                            if (pObj->GetType() == PDFOBJ_STREAM) {\r
-                                                m_pTrailer = (CPDF_Dictionary*)pTrailer->Clone();\r
-                                                pObj->Release();\r
-                                            } else {\r
-                                                m_pTrailer = pTrailer;\r
-                                            }\r
-                                            FX_FILESIZE dwSavePos = m_Syntax.SavePos();\r
-                                            CFX_ByteString strWord = m_Syntax.GetKeyword();\r
-                                            if (!strWord.Compare(FX_BSTRC("startxref"))) {\r
-                                                FX_BOOL bNumber = FALSE;\r
-                                                CFX_ByteString bsOffset = m_Syntax.GetNextWord(bNumber);\r
-                                                if (bNumber) {\r
-                                                    m_LastXRefOffset = FXSYS_atoi(bsOffset);\r
-                                                }\r
-                                            }\r
-                                            m_Syntax.RestorePos(dwSavePos);\r
-                                        }\r
-                                    } else {\r
-                                        pObj->Release();\r
-                                    }\r
-                                    bInUpdate = TRUE;\r
-                                }\r
-                            }\r
-                        }\r
-                        --i;\r
-                        status = 0;\r
-                    } else if (byte == "trailer"[inside_index]) {\r
-                        inside_index ++;\r
-                    } else {\r
-                        --i;\r
-                        status = 0;\r
-                    }\r
-                    break;\r
-                case 8:\r
-                    if (inside_index == 4) {\r
-                        last_xref = pos + i - 4;\r
-                        status = 1;\r
-                    } else if (byte == "xref"[inside_index]) {\r
-                        inside_index ++;\r
-                    } else {\r
-                        --i;\r
-                        status = 0;\r
-                    }\r
-                    break;\r
-                case 9:\r
-                    if (byte == '\r' || byte == '\n') {\r
-                        status = 0;\r
-                    }\r
-                    break;\r
-                case 10:\r
-                    if (byte == ')') {\r
-                        if (depth > 0) {\r
-                            depth--;\r
-                        }\r
-                    } else if (byte == '(') {\r
-                        depth++;\r
-                    }\r
-                    if (!depth) {\r
-                        status = 0;\r
-                    }\r
-                    break;\r
-                case 11:\r
-                    if (byte == '<' && inside_index == 1) {\r
-                        status = 12;\r
-                    } else if (byte == '>') {\r
-                        status = 0;\r
-                    }\r
-                    inside_index = 0;\r
-                    break;\r
-                case 12:\r
-                    --i;\r
-                    status = 0;\r
-                    break;\r
-                case 13:\r
-                    if (_PDF_CharType[byte] == 'D' || _PDF_CharType[byte] == 'W') {\r
-                        --i;\r
-                        status = 0;\r
-                    }\r
-                    break;\r
-                case 14:\r
-                    if (_PDF_CharType[byte] == 'W') {\r
-                        status = 0;\r
-                    } else if (byte == '%' || byte == '(' || byte == '<' || byte == '\\') {\r
-                        status = 0;\r
-                        --i;\r
-                    } else if (inside_index == 6) {\r
-                        status = 0;\r
-                        --i;\r
-                    } else if (byte == "endobj"[inside_index]) {\r
-                        inside_index++;\r
-                    }\r
-                    break;\r
-            }\r
-            if (bOverFlow) {\r
-                size = 0;\r
-                break;\r
-            }\r
-        }\r
-        pos += size;\r
-    }\r
-    if (last_xref != -1 && last_xref > last_obj) {\r
-        last_trailer = last_xref;\r
-    } else if (last_trailer == -1 || last_xref < last_obj) {\r
-        last_trailer = m_Syntax.m_FileLen;\r
-    }\r
-    FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset;\r
-    FX_LPVOID pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);\r
-    if (pResult == NULL) {\r
-        m_SortedOffset.Add(offset);\r
-    }\r
-    FX_Free(buffer);\r
-    return TRUE;\r
-}\r
-static FX_DWORD _GetVarInt(FX_LPCBYTE p, FX_INT32 n)\r
-{\r
-    FX_DWORD result = 0;\r
-    for (FX_INT32 i = 0; i < n; i ++) {\r
-        result = result * 256 + p[i];\r
-    }\r
-    return result;\r
-}\r
-FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE pos, FX_FILESIZE& prev, FX_BOOL bMainXRef)\r
-{\r
-    CPDF_Stream* pStream = (CPDF_Stream*)ParseIndirectObjectAt(m_pDocument, pos, 0, NULL);\r
-    if (!pStream) {\r
-        return FALSE;\r
-    }\r
-    if (m_pDocument) {\r
-        m_pDocument->InsertIndirectObject(pStream->m_ObjNum, pStream);\r
-    }\r
-    if (pStream->GetType() != PDFOBJ_STREAM) {\r
-        return FALSE;\r
-    }\r
-    prev = pStream->GetDict()->GetInteger(FX_BSTRC("Prev"));\r
-    FX_INT32 size = pStream->GetDict()->GetInteger(FX_BSTRC("Size"));\r
-    if (size < 0) {\r
-        pStream->Release();\r
-        return FALSE;\r
-    }\r
-    if (bMainXRef) {\r
-        m_pTrailer = (CPDF_Dictionary*)pStream->GetDict()->Clone();\r
-        m_CrossRef.SetSize(size);\r
-        if (m_V5Type.SetSize(size)) {\r
-            FXSYS_memset32(m_V5Type.GetData(), 0, size);\r
-        }\r
-    } else {\r
-        m_Trailers.Add((CPDF_Dictionary*)pStream->GetDict()->Clone());\r
-    }\r
-    CFX_DWordArray IndexArray, WidthArray;\r
-    FX_DWORD nSegs = 0;\r
-    CPDF_Array* pArray = pStream->GetDict()->GetArray(FX_BSTRC("Index"));\r
-    if (pArray == NULL) {\r
-        IndexArray.Add(0);\r
-        IndexArray.Add(size);\r
-        nSegs = 1;\r
-    } else {\r
-        for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) {\r
-            IndexArray.Add(pArray->GetInteger(i));\r
-        }\r
-        nSegs = pArray->GetCount() / 2;\r
-    }\r
-    pArray = pStream->GetDict()->GetArray(FX_BSTRC("W"));\r
-    if (pArray == NULL) {\r
-        pStream->Release();\r
-        return FALSE;\r
-    }\r
-    FX_DWORD totalwidth = 0;\r
-    FX_DWORD i;\r
-    for (i = 0; i < pArray->GetCount(); i ++) {\r
-        WidthArray.Add(pArray->GetInteger(i));\r
-        if (totalwidth + WidthArray[i] < totalwidth) {\r
-            pStream->Release();\r
-            return FALSE;\r
-        }\r
-        totalwidth += WidthArray[i];\r
-    }\r
-    if (totalwidth == 0 || WidthArray.GetSize() < 3) {\r
-        pStream->Release();\r
-        return FALSE;\r
-    }\r
-    CPDF_StreamAcc acc;\r
-    acc.LoadAllData(pStream);\r
-    FX_LPCBYTE pData = acc.GetData();\r
-    FX_DWORD dwTotalSize = acc.GetSize();\r
-    FX_DWORD segindex = 0;\r
-    for (i = 0; i < nSegs; i ++) {\r
-        FX_INT32 startnum = IndexArray[i * 2];\r
-        if (startnum < 0) {\r
-            continue;\r
-        }\r
-        m_dwXrefStartObjNum = startnum;\r
-        FX_DWORD count = IndexArray[i * 2 + 1];\r
-        if (segindex + count < segindex || segindex + count == 0 ||\r
-                (FX_DWORD)totalwidth >= UINT_MAX / (segindex + count) || (segindex + count) * (FX_DWORD)totalwidth > dwTotalSize) {\r
-            continue;\r
-        }\r
-        FX_LPCBYTE segstart = pData + segindex * (FX_DWORD)totalwidth;\r
-        if ((FX_DWORD)startnum + count < (FX_DWORD)startnum ||\r
-                (FX_DWORD)startnum + count > (FX_DWORD)m_V5Type.GetSize()) {\r
-            continue;\r
-        }\r
-        for (FX_DWORD j = 0; j < count; j ++) {\r
-            FX_INT32 type = 1;\r
-            FX_LPCBYTE entrystart = segstart + j * totalwidth;\r
-            if (WidthArray[0]) {\r
-                type = _GetVarInt(entrystart, WidthArray[0]);\r
-            }\r
-            if (m_V5Type[startnum + j] == 255) {\r
-                FX_FILESIZE offset = _GetVarInt(entrystart + WidthArray[0], WidthArray[1]);\r
-                m_CrossRef[startnum + j] = offset;\r
-                FX_LPVOID pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);\r
-                if (pResult == NULL) {\r
-                    m_SortedOffset.Add(offset);\r
-                }\r
-                continue;\r
-            }\r
-            if (m_V5Type[startnum + j]) {\r
-                continue;\r
-            }\r
-            m_V5Type[startnum + j] = type;\r
-            if (type == 0) {\r
-                m_CrossRef[startnum + j] = 0;\r
-            } else {\r
-                FX_FILESIZE offset = _GetVarInt(entrystart + WidthArray[0], WidthArray[1]);\r
-                m_CrossRef[startnum + j] = offset;\r
-                if (type == 1) {\r
-                    FX_LPVOID pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);\r
-                    if (pResult == NULL) {\r
-                        m_SortedOffset.Add(offset);\r
-                    }\r
-                } else {\r
-                    if (offset < 0 || offset >= m_V5Type.GetSize()) {\r
-                        pStream->Release();\r
-                        return FALSE;\r
-                    }\r
-                    m_V5Type[offset] = 255;\r
-                }\r
-            }\r
-        }\r
-        segindex += count;\r
-    }\r
-    pStream->Release();\r
-    return TRUE;\r
-}\r
-CPDF_Array* CPDF_Parser::GetIDArray()\r
-{\r
-    CPDF_Object* pID = m_pTrailer->GetElement(FX_BSTRC("ID"));\r
-    if (pID == NULL) {\r
-        return NULL;\r
-    }\r
-    if (pID->GetType() == PDFOBJ_REFERENCE) {\r
-        pID = ParseIndirectObject(NULL, ((CPDF_Reference*)pID)->GetRefObjNum());\r
-        m_pTrailer->SetAt(FX_BSTRC("ID"), pID);\r
-    }\r
-    if (pID == NULL || pID->GetType() != PDFOBJ_ARRAY) {\r
-        return NULL;\r
-    }\r
-    return (CPDF_Array*)pID;\r
-}\r
-FX_DWORD CPDF_Parser::GetRootObjNum()\r
-{\r
-    CPDF_Reference* pRef = (CPDF_Reference*)m_pTrailer->GetElement(FX_BSTRC("Root"));\r
-    if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {\r
-        return 0;\r
-    }\r
-    return pRef->GetRefObjNum();\r
-}\r
-FX_DWORD CPDF_Parser::GetInfoObjNum()\r
-{\r
-    CPDF_Reference* pRef = (CPDF_Reference*)m_pTrailer->GetElement(FX_BSTRC("Info"));\r
-    if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {\r
-        return 0;\r
-    }\r
-    return pRef->GetRefObjNum();\r
-}\r
-FX_BOOL CPDF_Parser::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm)\r
-{\r
-    bForm = FALSE;\r
-    if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {\r
-        return TRUE;\r
-    }\r
-    if (m_V5Type[objnum] == 0) {\r
-        return TRUE;\r
-    }\r
-    if (m_V5Type[objnum] == 2) {\r
-        return TRUE;\r
-    }\r
-    FX_FILESIZE pos = m_CrossRef[objnum];\r
-    FX_LPVOID pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);\r
-    if (pResult == NULL) {\r
-        return TRUE;\r
-    }\r
-    if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == m_SortedOffset.GetSize() - 1) {\r
-        return FALSE;\r
-    }\r
-    FX_FILESIZE size = ((FX_FILESIZE*)pResult)[1] - pos;\r
-    FX_FILESIZE SavedPos = m_Syntax.SavePos();\r
-    m_Syntax.RestorePos(pos);\r
-    bForm = m_Syntax.SearchMultiWord(FX_BSTRC("/Form\0stream"), TRUE, size) == 0;\r
-    m_Syntax.RestorePos(SavedPos);\r
-    return TRUE;\r
-}\r
-CPDF_Object* CPDF_Parser::ParseIndirectObject(CPDF_IndirectObjects* pObjList, FX_DWORD objnum, PARSE_CONTEXT* pContext)\r
-{\r
-    if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {\r
-        return NULL;\r
-    }\r
-    if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) {\r
-        FX_FILESIZE pos = m_CrossRef[objnum];\r
-        if (pos <= 0) {\r
-            return NULL;\r
-        }\r
-        return ParseIndirectObjectAt(pObjList, pos, objnum, pContext);\r
-    }\r
-    if (m_V5Type[objnum] == 2) {\r
-        CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]);\r
-        if (pObjStream == NULL) {\r
-            return NULL;\r
-        }\r
-        FX_INT32 n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N"));\r
-        FX_INT32 offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First"));\r
-        CPDF_SyntaxParser syntax;\r
-        CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream((FX_LPBYTE)pObjStream->GetData(), (size_t)pObjStream->GetSize(), FALSE));\r
-        syntax.InitParser((IFX_FileStream*)file, 0);\r
-        CPDF_Object* pRet = NULL;\r
-        while (n) {\r
-            FX_DWORD thisnum = syntax.GetDirectNum();\r
-            FX_DWORD thisoff = syntax.GetDirectNum();\r
-            if (thisnum == objnum) {\r
-                syntax.RestorePos(offset + thisoff);\r
-                pRet = syntax.GetObject(pObjList, 0, 0, 0, pContext);\r
-                break;\r
-            }\r
-            n --;\r
-        }\r
-        return pRet;\r
-    }\r
-    return NULL;\r
-}\r
-CPDF_StreamAcc* CPDF_Parser::GetObjectStream(FX_DWORD objnum)\r
-{\r
-    CPDF_StreamAcc* pStreamAcc = NULL;\r
-    if (m_ObjectStreamMap.Lookup((void*)(FX_UINTPTR)objnum, (void*&)pStreamAcc)) {\r
-        return pStreamAcc;\r
-    }\r
-    const CPDF_Stream* pStream = (CPDF_Stream*)m_pDocument->GetIndirectObject(objnum);\r
-    if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) {\r
-        return NULL;\r
-    }\r
-    pStreamAcc = FX_NEW CPDF_StreamAcc;\r
-    pStreamAcc->LoadAllData(pStream);\r
-    m_ObjectStreamMap.SetAt((void*)(FX_UINTPTR)objnum, pStreamAcc);\r
-    return pStreamAcc;\r
-}\r
-FX_FILESIZE CPDF_Parser::GetObjectSize(FX_DWORD objnum)\r
-{\r
-    if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {\r
-        return 0;\r
-    }\r
-    if (m_V5Type[objnum] == 2) {\r
-        objnum = (FX_DWORD)m_CrossRef[objnum];\r
-    }\r
-    if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) {\r
-        FX_FILESIZE offset = m_CrossRef[objnum];\r
-        if (offset == 0) {\r
-            return 0;\r
-        }\r
-        FX_LPVOID pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);\r
-        if (pResult == NULL) {\r
-            return 0;\r
-        }\r
-        if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == m_SortedOffset.GetSize() - 1) {\r
-            return 0;\r
-        }\r
-        return ((FX_FILESIZE*)pResult)[1] - offset;\r
-    }\r
-    return 0;\r
-}\r
-void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum, FX_LPBYTE& pBuffer, FX_DWORD& size)\r
-{\r
-    pBuffer = NULL;\r
-    size = 0;\r
-    if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {\r
-        return;\r
-    }\r
-    if (m_V5Type[objnum] == 2) {\r
-        CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]);\r
-        if (pObjStream == NULL) {\r
-            return;\r
-        }\r
-        FX_INT32 n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N"));\r
-        FX_INT32 offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First"));\r
-        CPDF_SyntaxParser syntax;\r
-        FX_LPCBYTE pData = pObjStream->GetData();\r
-        FX_DWORD totalsize = pObjStream->GetSize();\r
-        CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream((FX_LPBYTE)pData, (size_t)totalsize, FALSE));\r
-        syntax.InitParser((IFX_FileStream*)file, 0);\r
-        while (n) {\r
-            FX_DWORD thisnum = syntax.GetDirectNum();\r
-            FX_DWORD thisoff = syntax.GetDirectNum();\r
-            if (thisnum == objnum) {\r
-                if (n == 1) {\r
-                    size = totalsize - (thisoff + offset);\r
-                } else {\r
-                    FX_DWORD nextnum = syntax.GetDirectNum();\r
-                    FX_DWORD nextoff = syntax.GetDirectNum();\r
-                    size = nextoff - thisoff;\r
-                }\r
-                pBuffer = FX_Alloc(FX_BYTE, size);\r
-                FXSYS_memcpy32(pBuffer, pData + thisoff + offset, size);\r
-                return;\r
-            }\r
-            n --;\r
-        }\r
-        return;\r
-    }\r
-    if (m_V5Type[objnum] == 1) {\r
-        FX_FILESIZE pos = m_CrossRef[objnum];\r
-        if (pos == 0) {\r
-            return;\r
-        }\r
-        FX_FILESIZE SavedPos = m_Syntax.SavePos();\r
-        m_Syntax.RestorePos(pos);\r
-        FX_BOOL bIsNumber;\r
-        CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);\r
-        if (!bIsNumber) {\r
-            m_Syntax.RestorePos(SavedPos);\r
-            return;\r
-        }\r
-        FX_DWORD real_objnum = FXSYS_atoi(word);\r
-        if (real_objnum && real_objnum != objnum) {\r
-            m_Syntax.RestorePos(SavedPos);\r
-            return;\r
-        }\r
-        word = m_Syntax.GetNextWord(bIsNumber);\r
-        if (!bIsNumber) {\r
-            m_Syntax.RestorePos(SavedPos);\r
-            return;\r
-        }\r
-        if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {\r
-            m_Syntax.RestorePos(SavedPos);\r
-            return;\r
-        }\r
-        FX_LPVOID pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);\r
-        if (pResult == NULL) {\r
-            m_Syntax.RestorePos(SavedPos);\r
-            return;\r
-        }\r
-        FX_FILESIZE nextoff = ((FX_FILESIZE*)pResult)[1];\r
-        FX_BOOL bNextOffValid = FALSE;\r
-        if (nextoff != pos) {\r
-            m_Syntax.RestorePos(nextoff);\r
-            word = m_Syntax.GetNextWord(bIsNumber);\r
-            if (word == FX_BSTRC("xref")) {\r
-                bNextOffValid = TRUE;\r
-            } else if (bIsNumber) {\r
-                word = m_Syntax.GetNextWord(bIsNumber);\r
-                if (bIsNumber && m_Syntax.GetKeyword() == FX_BSTRC("obj")) {\r
-                    bNextOffValid = TRUE;\r
-                }\r
-            }\r
-        }\r
-        if (!bNextOffValid) {\r
-            m_Syntax.RestorePos(pos);\r
-            while (1) {\r
-                if (m_Syntax.GetKeyword() == FX_BSTRC("endobj")) {\r
-                    break;\r
-                }\r
-                if (m_Syntax.SavePos() == m_Syntax.m_FileLen) {\r
-                    break;\r
-                }\r
-            }\r
-            nextoff = m_Syntax.SavePos();\r
-        }\r
-        size = (FX_DWORD)(nextoff - pos);\r
-        pBuffer = FX_Alloc(FX_BYTE, size);\r
-        m_Syntax.RestorePos(pos);\r
-        m_Syntax.ReadBlock(pBuffer, size);\r
-        m_Syntax.RestorePos(SavedPos);\r
-    }\r
-}\r
-CPDF_Object* CPDF_Parser::ParseIndirectObjectAt(CPDF_IndirectObjects* pObjList, FX_FILESIZE pos, FX_DWORD objnum,\r
-        PARSE_CONTEXT* pContext)\r
-{\r
-    FX_FILESIZE SavedPos = m_Syntax.SavePos();\r
-    m_Syntax.RestorePos(pos);\r
-    FX_BOOL bIsNumber;\r
-    CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);\r
-    if (!bIsNumber) {\r
-        m_Syntax.RestorePos(SavedPos);\r
-        return NULL;\r
-    }\r
-    FX_FILESIZE objOffset = m_Syntax.SavePos();\r
-    objOffset -= word.GetLength();\r
-    FX_DWORD real_objnum = FXSYS_atoi(word);\r
-    if (objnum && real_objnum != objnum) {\r
-        m_Syntax.RestorePos(SavedPos);\r
-        return NULL;\r
-    }\r
-    word = m_Syntax.GetNextWord(bIsNumber);\r
-    if (!bIsNumber) {\r
-        m_Syntax.RestorePos(SavedPos);\r
-        return NULL;\r
-    }\r
-    FX_DWORD gennum = FXSYS_atoi(word);\r
-    if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {\r
-        m_Syntax.RestorePos(SavedPos);\r
-        return NULL;\r
-    }\r
-    CPDF_Object* pObj = m_Syntax.GetObject(pObjList, objnum, gennum, 0, pContext);\r
-    FX_FILESIZE endOffset = m_Syntax.SavePos();\r
-    CFX_ByteString bsWord = m_Syntax.GetKeyword();\r
-    if (bsWord == FX_BSTRC("endobj")) {\r
-        endOffset = m_Syntax.SavePos();\r
-    }\r
-    FX_DWORD objSize = endOffset - objOffset;\r
-    m_Syntax.RestorePos(SavedPos);\r
-    if (pObj && !objnum) {\r
-        pObj->m_ObjNum = real_objnum;\r
-    }\r
-    return pObj;\r
-}\r
-CPDF_Object* CPDF_Parser::ParseIndirectObjectAtByStrict(CPDF_IndirectObjects* pObjList, FX_FILESIZE pos, FX_DWORD objnum,\r
-        struct PARSE_CONTEXT* pContext, FX_FILESIZE *pResultPos)\r
-{\r
-    FX_FILESIZE SavedPos = m_Syntax.SavePos();\r
-    m_Syntax.RestorePos(pos);\r
-    FX_BOOL bIsNumber;\r
-    CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);\r
-    if (!bIsNumber) {\r
-        m_Syntax.RestorePos(SavedPos);\r
-        return NULL;\r
-    }\r
-    FX_DWORD real_objnum = FXSYS_atoi(word);\r
-    if (objnum && real_objnum != objnum) {\r
-        m_Syntax.RestorePos(SavedPos);\r
-        return NULL;\r
-    }\r
-    word = m_Syntax.GetNextWord(bIsNumber);\r
-    if (!bIsNumber) {\r
-        m_Syntax.RestorePos(SavedPos);\r
-        return NULL;\r
-    }\r
-    FX_DWORD gennum = FXSYS_atoi(word);\r
-    if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {\r
-        m_Syntax.RestorePos(SavedPos);\r
-        return NULL;\r
-    }\r
-    CPDF_Object* pObj = m_Syntax.GetObjectByStrict(pObjList, objnum, gennum, 0, pContext);\r
-    if (pResultPos) {\r
-        *pResultPos = m_Syntax.m_Pos;\r
-    }\r
-    m_Syntax.RestorePos(SavedPos);\r
-    return pObj;\r
-}\r
-CPDF_Dictionary* CPDF_Parser::LoadTrailerV4()\r
-{\r
-    if (m_Syntax.GetKeyword() != FX_BSTRC("trailer")) {\r
-        return NULL;\r
-    }\r
-    CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0);\r
-    if (pObj == NULL || pObj->GetType() != PDFOBJ_DICTIONARY) {\r
-        if (pObj) {\r
-            pObj->Release();\r
-        }\r
-        return NULL;\r
-    }\r
-    return (CPDF_Dictionary*)pObj;\r
-}\r
-FX_DWORD CPDF_Parser::GetPermissions(FX_BOOL bCheckRevision)\r
-{\r
-    if (m_pSecurityHandler == NULL) {\r
-        return (FX_DWORD) - 1;\r
-    }\r
-    FX_DWORD dwPermission = m_pSecurityHandler->GetPermissions();\r
-    if (m_pEncryptDict && m_pEncryptDict->GetString(FX_BSTRC("Filter")) == FX_BSTRC("Standard")) {\r
-        dwPermission &= 0xFFFFFFFC;\r
-        dwPermission |= 0xFFFFF0C0;\r
-        if(bCheckRevision && m_pEncryptDict->GetInteger(FX_BSTRC("R")) == 2) {\r
-            dwPermission &= 0xFFFFF0FF;\r
-        }\r
-    }\r
-    return dwPermission;\r
-}\r
-FX_BOOL CPDF_Parser::IsOwner()\r
-{\r
-    return m_pSecurityHandler == NULL ? TRUE : m_pSecurityHandler->IsOwner();\r
-}\r
-void CPDF_Parser::SetSecurityHandler(CPDF_SecurityHandler* pSecurityHandler, FX_BOOL bForced)\r
-{\r
-    ASSERT(m_pSecurityHandler == NULL);\r
-    if (m_pSecurityHandler && !m_bForceUseSecurityHandler) {\r
-        delete m_pSecurityHandler;\r
-        m_pSecurityHandler = NULL;\r
-    }\r
-    m_bForceUseSecurityHandler = bForced;\r
-    m_pSecurityHandler = pSecurityHandler;\r
-    if (m_bForceUseSecurityHandler) {\r
-        return;\r
-    }\r
-    m_Syntax.m_pCryptoHandler = pSecurityHandler->CreateCryptoHandler();\r
-    m_Syntax.m_pCryptoHandler->Init(NULL, pSecurityHandler);\r
-}\r
-FX_BOOL CPDF_Parser::IsLinearizedFile(IFX_FileRead* pFileAccess, FX_DWORD offset)\r
-{\r
-    m_Syntax.InitParser(pFileAccess, offset);\r
-    m_Syntax.RestorePos(m_Syntax.m_HeaderOffset + 9);\r
-    FX_FILESIZE SavedPos = m_Syntax.SavePos();\r
-    FX_BOOL bIsNumber;\r
-    CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);\r
-    if (!bIsNumber) {\r
-        return FALSE;\r
-    }\r
-    FX_DWORD objnum = FXSYS_atoi(word);\r
-    word = m_Syntax.GetNextWord(bIsNumber);\r
-    if (!bIsNumber) {\r
-        return FALSE;\r
-    }\r
-    FX_DWORD gennum = FXSYS_atoi(word);\r
-    if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {\r
-        m_Syntax.RestorePos(SavedPos);\r
-        return FALSE;\r
-    }\r
-    m_pLinearized = m_Syntax.GetObject(NULL, objnum, gennum, 0);\r
-    if (!m_pLinearized) {\r
-        return FALSE;\r
-    }\r
-    if (m_pLinearized->GetDict()->GetElement(FX_BSTRC("Linearized"))) {\r
-        m_Syntax.GetNextWord(bIsNumber);\r
-        CPDF_Object *pLen = m_pLinearized->GetDict()->GetElement(FX_BSTRC("L"));\r
-        if (!pLen) {\r
-            m_pLinearized->Release();\r
-            return FALSE;\r
-        }\r
-        if (pLen->GetInteger() != (int)pFileAccess->GetSize()) {\r
-            return FALSE;\r
-        }\r
-        CPDF_Object *pNo = m_pLinearized->GetDict()->GetElement(FX_BSTRC("P"));\r
-        if (pNo && pNo->GetType() == PDFOBJ_NUMBER) {\r
-            m_dwFirstPageNo = pNo->GetInteger();\r
-        }\r
-        CPDF_Object *pTable = m_pLinearized->GetDict()->GetElement(FX_BSTRC("T"));\r
-        if (pTable && pTable->GetType() == PDFOBJ_NUMBER) {\r
-            m_LastXRefOffset = pTable->GetInteger();\r
-        }\r
-        return TRUE;\r
-    }\r
-    m_pLinearized->Release();\r
-    m_pLinearized = NULL;\r
-    return FALSE;\r
-}\r
-FX_DWORD CPDF_Parser::StartAsynParse(IFX_FileRead* pFileAccess, FX_BOOL bReParse, FX_BOOL bOwnFileRead)\r
-{\r
-    CloseParser(bReParse);\r
-    m_bXRefStream = FALSE;\r
-    m_LastXRefOffset = 0;\r
-    m_bOwnFileRead = bOwnFileRead;\r
-    FX_INT32 offset = GetHeaderOffset(pFileAccess);\r
-    if (offset == -1) {\r
-        return PDFPARSE_ERROR_FORMAT;\r
-    }\r
-    if (!IsLinearizedFile(pFileAccess, offset)) {\r
-        m_Syntax.m_pFileAccess = NULL;\r
-        return StartParse(pFileAccess, bReParse, bOwnFileRead);\r
-    }\r
-    if (!bReParse) {\r
-        m_pDocument = FX_NEW CPDF_Document(this);\r
-    }\r
-    FX_FILESIZE dwFirstXRefOffset = m_Syntax.SavePos();\r
-    FX_BOOL bXRefRebuilt = FALSE;\r
-    FX_BOOL bLoadV4 = FALSE;\r
-    if (!(bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE, FALSE)) && !LoadCrossRefV5(dwFirstXRefOffset, dwFirstXRefOffset, TRUE)) {\r
-        if (!RebuildCrossRef()) {\r
-            return PDFPARSE_ERROR_FORMAT;\r
-        }\r
-        bXRefRebuilt = TRUE;\r
-        m_LastXRefOffset = 0;\r
-    }\r
-    if (bLoadV4) {\r
-        m_pTrailer = LoadTrailerV4();\r
-        if (m_pTrailer == NULL) {\r
-            return FALSE;\r
-        }\r
-        FX_INT32 xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size"));\r
-        if (xrefsize == 0) {\r
-            return FALSE;\r
-        }\r
-        m_CrossRef.SetSize(xrefsize);\r
-        m_V5Type.SetSize(xrefsize);\r
-    }\r
-    FX_DWORD dwRet = SetEncryptHandler();\r
-    if (dwRet != PDFPARSE_ERROR_SUCCESS) {\r
-        return dwRet;\r
-    }\r
-    m_pDocument->LoadAsynDoc(m_pLinearized->GetDict());\r
-    if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) {\r
-        if (bXRefRebuilt) {\r
-            return PDFPARSE_ERROR_FORMAT;\r
-        }\r
-        ReleaseEncryptHandler();\r
-        if (!RebuildCrossRef()) {\r
-            return PDFPARSE_ERROR_FORMAT;\r
-        }\r
-        dwRet = SetEncryptHandler();\r
-        if (dwRet != PDFPARSE_ERROR_SUCCESS) {\r
-            return dwRet;\r
-        }\r
-        m_pDocument->LoadAsynDoc(m_pLinearized->GetDict());\r
-        if (m_pDocument->GetRoot() == NULL) {\r
-            return PDFPARSE_ERROR_FORMAT;\r
-        }\r
-    }\r
-    FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);\r
-    FX_DWORD RootObjNum = GetRootObjNum();\r
-    if (RootObjNum == 0) {\r
-        ReleaseEncryptHandler();\r
-        RebuildCrossRef();\r
-        RootObjNum = GetRootObjNum();\r
-        if (RootObjNum == 0) {\r
-            return PDFPARSE_ERROR_FORMAT;\r
-        }\r
-        dwRet = SetEncryptHandler();\r
-        if (dwRet != PDFPARSE_ERROR_SUCCESS) {\r
-            return dwRet;\r
-        }\r
-    }\r
-    if (m_pSecurityHandler && m_pSecurityHandler->IsMetadataEncrypted()) {\r
-        CPDF_Reference* pMetadata = (CPDF_Reference*)m_pDocument->GetRoot()->GetElement(FX_BSTRC("Metadata"));\r
-        if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) {\r
-            m_Syntax.m_MetadataObjnum = pMetadata->GetRefObjNum();\r
-        }\r
-    }\r
-    return PDFPARSE_ERROR_SUCCESS;\r
-}\r
-FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV5(FX_FILESIZE xrefpos)\r
-{\r
-    if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) {\r
-        return FALSE;\r
-    }\r
-    while (xrefpos)\r
-        if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) {\r
-            return FALSE;\r
-        }\r
-    m_ObjectStreamMap.InitHashTable(101, FALSE);\r
-    m_bXRefStream = TRUE;\r
-    return TRUE;\r
-}\r
-FX_DWORD CPDF_Parser::LoadLinearizedMainXRefTable()\r
-{\r
-    FX_DWORD dwSaveMetadataObjnum = m_Syntax.m_MetadataObjnum;\r
-    m_Syntax.m_MetadataObjnum = 0;\r
-    if (m_pTrailer) {\r
-        m_pTrailer->Release();\r
-        m_pTrailer = NULL;\r
-    }\r
-    m_Syntax.RestorePos(m_LastXRefOffset - m_Syntax.m_HeaderOffset);\r
-    FX_FILESIZE dwSavedPos = m_Syntax.SavePos();\r
-    FX_BYTE ch = 0;\r
-    FX_DWORD dwCount = 0;\r
-    m_Syntax.GetNextChar(ch);\r
-    FX_INT32 type = _PDF_CharType[ch];\r
-    while (type == 'W') {\r
-        ++dwCount;\r
-        if (m_Syntax.m_FileLen >= (FX_FILESIZE)(m_Syntax.SavePos() + m_Syntax.m_HeaderOffset)) {\r
-            break;\r
-        }\r
-        m_Syntax.GetNextChar(ch);\r
-        type = _PDF_CharType[ch];\r
-    }\r
-    m_LastXRefOffset += dwCount;\r
-    FX_POSITION pos = m_ObjectStreamMap.GetStartPosition();\r
-    while (pos) {\r
-        FX_LPVOID objnum;\r
-        CPDF_StreamAcc* pStream;\r
-        m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream);\r
-        delete pStream;\r
-    }\r
-    m_ObjectStreamMap.RemoveAll();\r
-    if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) {\r
-        m_LastXRefOffset = 0;\r
-        m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum;\r
-        return PDFPARSE_ERROR_FORMAT;\r
-    }\r
-    FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_DWORD), _CompareDWord);\r
-    m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum;\r
-    return PDFPARSE_ERROR_SUCCESS;\r
-}\r
-CPDF_SyntaxParser::CPDF_SyntaxParser()\r
-{\r
-    m_pFileAccess = NULL;\r
-    m_pCryptoHandler = NULL;\r
-    m_pFileBuf = NULL;\r
-    m_BufSize = CPDF_ModuleMgr::Get()->m_FileBufSize;\r
-    m_pFileBuf = NULL;\r
-    m_MetadataObjnum = 0;\r
-    m_dwWordPos = 0;\r
-#if defined(_FPDFAPI_MINI_)\r
-    m_bFileStream = TRUE;\r
-#else\r
-    m_bFileStream = FALSE;\r
-#endif\r
-}\r
-CPDF_SyntaxParser::~CPDF_SyntaxParser()\r
-{\r
-    if (m_pFileBuf) {\r
-        FX_Free(m_pFileBuf);\r
-    }\r
-}\r
-FX_BOOL CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, FX_BYTE& ch)\r
-{\r
-    FX_FILESIZE save_pos = m_Pos;\r
-    m_Pos = pos;\r
-    FX_BOOL ret = GetNextChar(ch);\r
-    m_Pos = save_pos;\r
-    return ret;\r
-}\r
-FX_BOOL CPDF_SyntaxParser::GetNextChar(FX_BYTE& ch)\r
-{\r
-    FX_FILESIZE pos = m_Pos + m_HeaderOffset;\r
-    if (pos >= m_FileLen) {\r
-        return FALSE;\r
-    }\r
-    if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) {\r
-        FX_FILESIZE read_pos = pos;\r
-        FX_DWORD read_size = m_BufSize;\r
-        if ((FX_FILESIZE)read_size > m_FileLen) {\r
-            read_size = (FX_DWORD)m_FileLen;\r
-        }\r
-        if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) {\r
-            if (m_FileLen < (FX_FILESIZE)read_size) {\r
-                read_pos = 0;\r
-                read_size = (FX_DWORD)m_FileLen;\r
-            } else {\r
-                read_pos = m_FileLen - read_size;\r
-            }\r
-        }\r
-        if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) {\r
-            return FALSE;\r
-        }\r
-        m_BufOffset = read_pos;\r
-    }\r
-    ch = m_pFileBuf[pos - m_BufOffset];\r
-    m_Pos ++;\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_SyntaxParser::GetCharAtBackward(FX_FILESIZE pos, FX_BYTE& ch)\r
-{\r
-    pos += m_HeaderOffset;\r
-    if (pos >= m_FileLen) {\r
-        return FALSE;\r
-    }\r
-    if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) {\r
-        FX_FILESIZE read_pos;\r
-        if (pos < (FX_FILESIZE)m_BufSize) {\r
-            read_pos = 0;\r
-        } else {\r
-            read_pos = pos - m_BufSize + 1;\r
-        }\r
-        FX_DWORD read_size = m_BufSize;\r
-        if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) {\r
-            if (m_FileLen < (FX_FILESIZE)read_size) {\r
-                read_pos = 0;\r
-                read_size = (FX_DWORD)m_FileLen;\r
-            } else {\r
-                read_pos = m_FileLen - read_size;\r
-            }\r
-        }\r
-        if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) {\r
-            return FALSE;\r
-        }\r
-        m_BufOffset = read_pos;\r
-    }\r
-    ch = m_pFileBuf[pos - m_BufOffset];\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_SyntaxParser::ReadBlock(FX_LPBYTE pBuf, FX_DWORD size)\r
-{\r
-    if (!m_pFileAccess->ReadBlock(pBuf, m_Pos + m_HeaderOffset, size)) {\r
-        return FALSE;\r
-    }\r
-    m_Pos += size;\r
-    return TRUE;\r
-}\r
-#define MAX_WORD_BUFFER 256\r
-void CPDF_SyntaxParser::GetNextWord()\r
-{\r
-    m_WordSize = 0;\r
-    m_bIsNumber = TRUE;\r
-    FX_BYTE ch;\r
-    if (!GetNextChar(ch)) {\r
-        return;\r
-    }\r
-    FX_BYTE type = _PDF_CharType[ch];\r
-    while (1) {\r
-        while (type == 'W') {\r
-            if (!GetNextChar(ch)) {\r
-                return;\r
-            }\r
-            type = _PDF_CharType[ch];\r
-        }\r
-        if (ch != '%') {\r
-            break;\r
-        }\r
-        while (1) {\r
-            if (!GetNextChar(ch)) {\r
-                return;\r
-            }\r
-            if (ch == '\r' || ch == '\n') {\r
-                break;\r
-            }\r
-        }\r
-        type = _PDF_CharType[ch];\r
-    }\r
-    if (type == 'D') {\r
-        m_bIsNumber = FALSE;\r
-        m_WordBuffer[m_WordSize++] = ch;\r
-        if (ch == '/') {\r
-            while (1) {\r
-                if (!GetNextChar(ch)) {\r
-                    return;\r
-                }\r
-                type = _PDF_CharType[ch];\r
-                if (type != 'R' && type != 'N') {\r
-                    m_Pos --;\r
-                    return;\r
-                }\r
-                if (m_WordSize < MAX_WORD_BUFFER) {\r
-                    m_WordBuffer[m_WordSize++] = ch;\r
-                }\r
-            }\r
-        } else if (ch == '<') {\r
-            if (!GetNextChar(ch)) {\r
-                return;\r
-            }\r
-            if (ch == '<') {\r
-                m_WordBuffer[m_WordSize++] = ch;\r
-            } else {\r
-                m_Pos --;\r
-            }\r
-        } else if (ch == '>') {\r
-            if (!GetNextChar(ch)) {\r
-                return;\r
-            }\r
-            if (ch == '>') {\r
-                m_WordBuffer[m_WordSize++] = ch;\r
-            } else {\r
-                m_Pos --;\r
-            }\r
-        }\r
-        return;\r
-    }\r
-    while (1) {\r
-        if (m_WordSize < MAX_WORD_BUFFER) {\r
-            m_WordBuffer[m_WordSize++] = ch;\r
-        }\r
-        if (type != 'N') {\r
-            m_bIsNumber = FALSE;\r
-        }\r
-        if (!GetNextChar(ch)) {\r
-            return;\r
-        }\r
-        type = _PDF_CharType[ch];\r
-        if (type == 'D' || type == 'W') {\r
-            m_Pos --;\r
-            break;\r
-        }\r
-    }\r
-}\r
-CFX_ByteString CPDF_SyntaxParser::ReadString()\r
-{\r
-    FX_BYTE ch;\r
-    if (!GetNextChar(ch)) {\r
-        return CFX_ByteString();\r
-    }\r
-    CFX_ByteTextBuf buf;\r
-    FX_INT32 parlevel = 0;\r
-    FX_INT32 status = 0, iEscCode = 0;\r
-    while (1) {\r
-        switch (status) {\r
-            case 0:\r
-                if (ch == ')') {\r
-                    if (parlevel == 0) {\r
-                        return buf.GetByteString();\r
-                    }\r
-                    parlevel --;\r
-                    buf.AppendChar(')');\r
-                } else if (ch == '(') {\r
-                    parlevel ++;\r
-                    buf.AppendChar('(');\r
-                } else if (ch == '\\') {\r
-                    status = 1;\r
-                } else {\r
-                    buf.AppendChar(ch);\r
-                }\r
-                break;\r
-            case 1:\r
-                if (ch >= '0' && ch <= '7') {\r
-                    iEscCode = ch - '0';\r
-                    status = 2;\r
-                    break;\r
-                }\r
-                if (ch == 'n') {\r
-                    buf.AppendChar('\n');\r
-                } else if (ch == 'r') {\r
-                    buf.AppendChar('\r');\r
-                } else if (ch == 't') {\r
-                    buf.AppendChar('\t');\r
-                } else if (ch == 'b') {\r
-                    buf.AppendChar('\b');\r
-                } else if (ch == 'f') {\r
-                    buf.AppendChar('\f');\r
-                } else if (ch == '\r') {\r
-                    status = 4;\r
-                    break;\r
-                } else if (ch == '\n') {\r
-                } else {\r
-                    buf.AppendChar(ch);\r
-                }\r
-                status = 0;\r
-                break;\r
-            case 2:\r
-                if (ch >= '0' && ch <= '7') {\r
-                    iEscCode = iEscCode * 8 + ch - '0';\r
-                    status = 3;\r
-                } else {\r
-                    buf.AppendChar(iEscCode);\r
-                    status = 0;\r
-                    continue;\r
-                }\r
-                break;\r
-            case 3:\r
-                if (ch >= '0' && ch <= '7') {\r
-                    iEscCode = iEscCode * 8 + ch - '0';\r
-                    buf.AppendChar(iEscCode);\r
-                    status = 0;\r
-                } else {\r
-                    buf.AppendChar(iEscCode);\r
-                    status = 0;\r
-                    continue;\r
-                }\r
-                break;\r
-            case 4:\r
-                status = 0;\r
-                if (ch != '\n') {\r
-                    continue;\r
-                }\r
-                break;\r
-        }\r
-        if (!GetNextChar(ch)) {\r
-            break;\r
-        }\r
-    }\r
-    GetNextChar(ch);\r
-    return buf.GetByteString();\r
-}\r
-CFX_ByteString CPDF_SyntaxParser::ReadHexString()\r
-{\r
-    FX_BYTE ch;\r
-    if (!GetNextChar(ch)) {\r
-        return CFX_ByteString();\r
-    }\r
-    CFX_BinaryBuf buf;\r
-    FX_BOOL bFirst = TRUE;\r
-    FX_BYTE code = 0;\r
-    while (1) {\r
-        if (ch == '>') {\r
-            break;\r
-        }\r
-        if (ch >= '0' && ch <= '9') {\r
-            if (bFirst) {\r
-                code = (ch - '0') * 16;\r
-            } else {\r
-                code += ch - '0';\r
-                buf.AppendByte((FX_BYTE)code);\r
-            }\r
-            bFirst = !bFirst;\r
-        } else if (ch >= 'A' && ch <= 'F') {\r
-            if (bFirst) {\r
-                code = (ch - 'A' + 10) * 16;\r
-            } else {\r
-                code += ch - 'A' + 10;\r
-                buf.AppendByte((FX_BYTE)code);\r
-            }\r
-            bFirst = !bFirst;\r
-        } else if (ch >= 'a' && ch <= 'f') {\r
-            if (bFirst) {\r
-                code = (ch - 'a' + 10) * 16;\r
-            } else {\r
-                code += ch - 'a' + 10;\r
-                buf.AppendByte((FX_BYTE)code);\r
-            }\r
-            bFirst = !bFirst;\r
-        }\r
-        if (!GetNextChar(ch)) {\r
-            break;\r
-        }\r
-    }\r
-    if (!bFirst) {\r
-        buf.AppendByte((FX_BYTE)code);\r
-    }\r
-    return buf.GetByteString();\r
-}\r
-void CPDF_SyntaxParser::ToNextLine()\r
-{\r
-    FX_BYTE ch;\r
-    while (1) {\r
-        if (!GetNextChar(ch)) {\r
-            return;\r
-        }\r
-        if (ch == '\n') {\r
-            return;\r
-        }\r
-        if (ch == '\r') {\r
-            GetNextChar(ch);\r
-            if (ch == '\n') {\r
-                return;\r
-            } else {\r
-                m_Pos --;\r
-                return;\r
-            }\r
-        }\r
-    }\r
-}\r
-void CPDF_SyntaxParser::ToNextWord()\r
-{\r
-    FX_BYTE ch;\r
-    if (!GetNextChar(ch)) {\r
-        return;\r
-    }\r
-    FX_BYTE type = _PDF_CharType[ch];\r
-    while (1) {\r
-        while (type == 'W') {\r
-            m_dwWordPos = m_Pos;\r
-            if (!GetNextChar(ch)) {\r
-                return;\r
-            }\r
-            type = _PDF_CharType[ch];\r
-        }\r
-        if (ch != '%') {\r
-            break;\r
-        }\r
-        while (1) {\r
-            if (!GetNextChar(ch)) {\r
-                return;\r
-            }\r
-            if (ch == '\r' || ch == '\n') {\r
-                break;\r
-            }\r
-        }\r
-        type = _PDF_CharType[ch];\r
-    }\r
-    m_Pos --;\r
-}\r
-CFX_ByteString CPDF_SyntaxParser::GetNextWord(FX_BOOL& bIsNumber)\r
-{\r
-    GetNextWord();\r
-    bIsNumber = m_bIsNumber;\r
-    return CFX_ByteString((FX_LPCSTR)m_WordBuffer, m_WordSize);\r
-}\r
-CFX_ByteString CPDF_SyntaxParser::GetKeyword()\r
-{\r
-    GetNextWord();\r
-    return CFX_ByteString((FX_LPCSTR)m_WordBuffer, m_WordSize);\r
-}\r
-CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjects* pObjList, FX_DWORD objnum, FX_DWORD gennum, FX_INT32 level, PARSE_CONTEXT* pContext, FX_BOOL bDecrypt)\r
-{\r
-    if (level > _PARSER_OBJECT_LEVLE_) {\r
-        return NULL;\r
-    }\r
-    FX_FILESIZE SavedPos = m_Pos;\r
-    FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY);\r
-    FX_BOOL bIsNumber;\r
-    CFX_ByteString word = GetNextWord(bIsNumber);\r
-    CPDF_Object* pRet = NULL;\r
-    if (word.GetLength() == 0) {\r
-        if (bTypeOnly) {\r
-            return (CPDF_Object*)PDFOBJ_INVALID;\r
-        }\r
-        return NULL;\r
-    }\r
-    FX_FILESIZE wordOffset = m_Pos - word.GetLength();\r
-    if (bIsNumber) {\r
-        FX_FILESIZE SavedPos = m_Pos;\r
-        CFX_ByteString nextword = GetNextWord(bIsNumber);\r
-        if (bIsNumber) {\r
-            CFX_ByteString nextword2 = GetNextWord(bIsNumber);\r
-            if (nextword2 == FX_BSTRC("R")) {\r
-                FX_DWORD objnum = FXSYS_atoi(word);\r
-                if (bTypeOnly) {\r
-                    return (CPDF_Object*)PDFOBJ_REFERENCE;\r
-                }\r
-                pRet = CPDF_Reference::Create(pObjList, objnum);\r
-                return pRet;\r
-            } else {\r
-                m_Pos = SavedPos;\r
-                if (bTypeOnly) {\r
-                    return (CPDF_Object*)PDFOBJ_NUMBER;\r
-                }\r
-                pRet = CPDF_Number::Create(word);\r
-                return pRet;\r
-            }\r
-        } else {\r
-            m_Pos = SavedPos;\r
-            if (bTypeOnly) {\r
-                return (CPDF_Object*)PDFOBJ_NUMBER;\r
-            }\r
-            pRet = CPDF_Number::Create(word);\r
-            return pRet;\r
-        }\r
-    }\r
-    if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) {\r
-        if (bTypeOnly) {\r
-            return (CPDF_Object*)PDFOBJ_BOOLEAN;\r
-        }\r
-        pRet = CPDF_Boolean::Create(word == FX_BSTRC("true"));\r
-        return pRet;\r
-    }\r
-    if (word == FX_BSTRC("null")) {\r
-        if (bTypeOnly) {\r
-            return (CPDF_Object*)PDFOBJ_NULL;\r
-        }\r
-        pRet = CPDF_Null::Create();\r
-        return pRet;\r
-    }\r
-    if (word == FX_BSTRC("(")) {\r
-        if (bTypeOnly) {\r
-            return (CPDF_Object*)PDFOBJ_STRING;\r
-        }\r
-        FX_FILESIZE SavedPos = m_Pos - 1;\r
-        CFX_ByteString str = ReadString();\r
-        if (m_pCryptoHandler && bDecrypt) {\r
-            m_pCryptoHandler->Decrypt(objnum, gennum, str);\r
-        }\r
-        pRet = CPDF_String::Create(str, FALSE);\r
-        return pRet;\r
-    }\r
-    if (word == FX_BSTRC("<")) {\r
-        if (bTypeOnly) {\r
-            return (CPDF_Object*)PDFOBJ_STRING;\r
-        }\r
-        FX_FILESIZE SavedPos = m_Pos - 1;\r
-        CFX_ByteString str = ReadHexString();\r
-        if (m_pCryptoHandler && bDecrypt) {\r
-            m_pCryptoHandler->Decrypt(objnum, gennum, str);\r
-        }\r
-        pRet = CPDF_String::Create(str, TRUE);\r
-        return pRet;\r
-    }\r
-    if (word == FX_BSTRC("[")) {\r
-        if (bTypeOnly) {\r
-            return (CPDF_Object*)PDFOBJ_ARRAY;\r
-        }\r
-        CPDF_Array* pArray = CPDF_Array::Create();\r
-        FX_FILESIZE firstPos = m_Pos - 1;\r
-        while (1) {\r
-            FX_FILESIZE SavedPos = m_Pos;\r
-            CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, level + 1);\r
-            if (pObj == NULL) {\r
-                return pArray;\r
-            }\r
-            pArray->Add(pObj);\r
-        }\r
-    }\r
-    if (word[0] == '/') {\r
-        if (bTypeOnly) {\r
-            return (CPDF_Object*)PDFOBJ_NAME;\r
-        }\r
-        pRet = CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)));\r
-        return pRet;\r
-    }\r
-    if (word == FX_BSTRC("<<")) {\r
-        FX_FILESIZE saveDictOffset = m_Pos - 2;\r
-        FX_DWORD dwDictSize = 0;\r
-        if (bTypeOnly) {\r
-            return (CPDF_Object*)PDFOBJ_DICTIONARY;\r
-        }\r
-        if (pContext) {\r
-            pContext->m_DictStart = SavedPos;\r
-        }\r
-        CPDF_Dictionary* pDict = CPDF_Dictionary::Create();\r
-        FX_INT32 nKeys = 0;\r
-        FX_FILESIZE dwSignValuePos = 0;\r
-        while (1) {\r
-            FX_BOOL bIsNumber;\r
-            CFX_ByteString key = GetNextWord(bIsNumber);\r
-            if (key.IsEmpty()) {\r
-                pDict->Release();\r
-                return NULL;\r
-            }\r
-            FX_FILESIZE SavedPos = m_Pos - key.GetLength();\r
-            if (key == FX_BSTRC(">>")) {\r
-                dwDictSize = m_Pos - saveDictOffset;\r
-                break;\r
-            }\r
-            if (key == FX_BSTRC("endobj")) {\r
-                dwDictSize = m_Pos - 6 - saveDictOffset;\r
-                m_Pos = SavedPos;\r
-                break;\r
-            }\r
-            if (key[0] != '/') {\r
-                continue;\r
-            }\r
-            nKeys ++;\r
-            key = PDF_NameDecode(key);\r
-            if (key == FX_BSTRC("/Contents")) {\r
-                dwSignValuePos = m_Pos;\r
-            }\r
-            CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, level + 1);\r
-            if (pObj == NULL) {\r
-                continue;\r
-            }\r
-            if (key.GetLength() == 1) {\r
-                pDict->SetAt(CFX_ByteStringC(((FX_LPCSTR)key) + 1, key.GetLength() - 1), pObj);\r
-            } else {\r
-                if (nKeys < 32) {\r
-                    pDict->SetAt(CFX_ByteStringC(((FX_LPCSTR)key) + 1, key.GetLength() - 1), pObj);\r
-                } else {\r
-                    pDict->AddValue(CFX_ByteStringC(((FX_LPCSTR)key) + 1, key.GetLength() - 1), pObj);\r
-                }\r
-            }\r
-        }\r
-        if (IsSignatureDict(pDict)) {\r
-            FX_FILESIZE dwSavePos = m_Pos;\r
-            m_Pos = dwSignValuePos;\r
-            CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, level + 1, NULL, FALSE);\r
-            pDict->SetAt(FX_BSTRC("Contents"), pObj);\r
-            m_Pos = dwSavePos;\r
-        }\r
-        if (pContext) {\r
-            pContext->m_DictEnd = m_Pos;\r
-            if (pContext->m_Flags & PDFPARSE_NOSTREAM) {\r
-                return pDict;\r
-            }\r
-        }\r
-        FX_FILESIZE SavedPos = m_Pos;\r
-        FX_BOOL bIsNumber;\r
-        CFX_ByteString nextword = GetNextWord(bIsNumber);\r
-        if (nextword == FX_BSTRC("stream")) {\r
-            CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum);\r
-            if (pStream) {\r
-                return pStream;\r
-            }\r
-            pDict->Release();\r
-            return NULL;\r
-        } else {\r
-            m_Pos = SavedPos;\r
-            return pDict;\r
-        }\r
-    }\r
-    if (word == FX_BSTRC(">>")) {\r
-        m_Pos = SavedPos;\r
-        return NULL;\r
-    }\r
-    if (bTypeOnly) {\r
-        return (CPDF_Object*)PDFOBJ_INVALID;\r
-    }\r
-    return NULL;\r
-}\r
-CPDF_Object* CPDF_SyntaxParser::GetObjectByStrict(CPDF_IndirectObjects* pObjList, FX_DWORD objnum, FX_DWORD gennum,\r
-        FX_INT32 level, struct PARSE_CONTEXT* pContext)\r
-{\r
-    if (level > _PARSER_OBJECT_LEVLE_) {\r
-        return NULL;\r
-    }\r
-    FX_FILESIZE SavedPos = m_Pos;\r
-    FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY);\r
-    FX_BOOL bIsNumber;\r
-    CFX_ByteString word = GetNextWord(bIsNumber);\r
-    if (word.GetLength() == 0) {\r
-        if (bTypeOnly) {\r
-            return (CPDF_Object*)PDFOBJ_INVALID;\r
-        }\r
-        return NULL;\r
-    }\r
-    if (bIsNumber) {\r
-        FX_FILESIZE SavedPos = m_Pos;\r
-        CFX_ByteString nextword = GetNextWord(bIsNumber);\r
-        if (bIsNumber) {\r
-            CFX_ByteString nextword2 = GetNextWord(bIsNumber);\r
-            if (nextword2 == FX_BSTRC("R")) {\r
-                FX_DWORD objnum = FXSYS_atoi(word);\r
-                if (bTypeOnly) {\r
-                    return (CPDF_Object*)PDFOBJ_REFERENCE;\r
-                }\r
-                return CPDF_Reference::Create(pObjList, objnum);\r
-            } else {\r
-                m_Pos = SavedPos;\r
-                if (bTypeOnly) {\r
-                    return (CPDF_Object*)PDFOBJ_NUMBER;\r
-                }\r
-                return CPDF_Number::Create(word);\r
-            }\r
-        } else {\r
-            m_Pos = SavedPos;\r
-            if (bTypeOnly) {\r
-                return (CPDF_Object*)PDFOBJ_NUMBER;\r
-            }\r
-            return CPDF_Number::Create(word);\r
-        }\r
-    }\r
-    if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) {\r
-        if (bTypeOnly) {\r
-            return (CPDF_Object*)PDFOBJ_BOOLEAN;\r
-        }\r
-        return CPDF_Boolean::Create(word == FX_BSTRC("true"));\r
-    }\r
-    if (word == FX_BSTRC("null")) {\r
-        if (bTypeOnly) {\r
-            return (CPDF_Object*)PDFOBJ_NULL;\r
-        }\r
-        return CPDF_Null::Create();\r
-    }\r
-    if (word == FX_BSTRC("(")) {\r
-        if (bTypeOnly) {\r
-            return (CPDF_Object*)PDFOBJ_STRING;\r
-        }\r
-        CFX_ByteString str = ReadString();\r
-        if (m_pCryptoHandler) {\r
-            m_pCryptoHandler->Decrypt(objnum, gennum, str);\r
-        }\r
-        return CPDF_String::Create(str, FALSE);\r
-    }\r
-    if (word == FX_BSTRC("<")) {\r
-        if (bTypeOnly) {\r
-            return (CPDF_Object*)PDFOBJ_STRING;\r
-        }\r
-        CFX_ByteString str = ReadHexString();\r
-        if (m_pCryptoHandler) {\r
-            m_pCryptoHandler->Decrypt(objnum, gennum, str);\r
-        }\r
-        return CPDF_String::Create(str, TRUE);\r
-    }\r
-    if (word == FX_BSTRC("[")) {\r
-        if (bTypeOnly) {\r
-            return (CPDF_Object*)PDFOBJ_ARRAY;\r
-        }\r
-        CPDF_Array* pArray = CPDF_Array::Create();\r
-        while (1) {\r
-            CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, level + 1);\r
-            if (pObj == NULL) {\r
-                if (m_WordBuffer[0] == ']') {\r
-                    return pArray;\r
-                }\r
-                pArray->Release();\r
-                return NULL;\r
-            }\r
-            pArray->Add(pObj);\r
-        }\r
-    }\r
-    if (word[0] == '/') {\r
-        if (bTypeOnly) {\r
-            return (CPDF_Object*)PDFOBJ_NAME;\r
-        }\r
-        return CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)));\r
-    }\r
-    if (word == FX_BSTRC("<<")) {\r
-        if (bTypeOnly) {\r
-            return (CPDF_Object*)PDFOBJ_DICTIONARY;\r
-        }\r
-        if (pContext) {\r
-            pContext->m_DictStart = SavedPos;\r
-        }\r
-        CPDF_Dictionary* pDict = CPDF_Dictionary::Create();\r
-        while (1) {\r
-            FX_BOOL bIsNumber;\r
-            FX_FILESIZE SavedPos = m_Pos;\r
-            CFX_ByteString key = GetNextWord(bIsNumber);\r
-            if (key.IsEmpty()) {\r
-                pDict->Release();\r
-                return NULL;\r
-            }\r
-            if (key == FX_BSTRC(">>")) {\r
-                break;\r
-            }\r
-            if (key == FX_BSTRC("endobj")) {\r
-                m_Pos = SavedPos;\r
-                break;\r
-            }\r
-            if (key[0] != '/') {\r
-                continue;\r
-            }\r
-            key = PDF_NameDecode(key);\r
-            CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, level + 1);\r
-            if (pObj == NULL) {\r
-                pDict->Release();\r
-                FX_BYTE ch;\r
-                while (1) {\r
-                    if (!GetNextChar(ch)) {\r
-                        break;\r
-                    }\r
-                    if (ch == 0x0A || ch == 0x0D) {\r
-                        break;\r
-                    }\r
-                }\r
-                return NULL;\r
-            }\r
-            if (key.GetLength() == 1) {\r
-                pDict->SetAt(CFX_ByteStringC(((FX_LPCSTR)key) + 1, key.GetLength() - 1), pObj);\r
-            } else {\r
-                pDict->AddValue(CFX_ByteStringC(((FX_LPCSTR)key) + 1, key.GetLength() - 1), pObj);\r
-            }\r
-        }\r
-        if (pContext) {\r
-            pContext->m_DictEnd = m_Pos;\r
-            if (pContext->m_Flags & PDFPARSE_NOSTREAM) {\r
-                return pDict;\r
-            }\r
-        }\r
-        FX_FILESIZE SavedPos = m_Pos;\r
-        FX_BOOL bIsNumber;\r
-        CFX_ByteString nextword = GetNextWord(bIsNumber);\r
-        if (nextword == FX_BSTRC("stream")) {\r
-            CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum);\r
-            if (pStream) {\r
-                return pStream;\r
-            }\r
-            pDict->Release();\r
-            return NULL;\r
-        } else {\r
-            m_Pos = SavedPos;\r
-            return pDict;\r
-        }\r
-    }\r
-    if (word == FX_BSTRC(">>")) {\r
-        m_Pos = SavedPos;\r
-        return NULL;\r
-    }\r
-    if (bTypeOnly) {\r
-        return (CPDF_Object*)PDFOBJ_INVALID;\r
-    }\r
-    return NULL;\r
-}\r
-CPDF_Stream* CPDF_SyntaxParser::ReadStream(CPDF_Dictionary* pDict, PARSE_CONTEXT* pContext,\r
-        FX_DWORD objnum, FX_DWORD gennum)\r
-{\r
-    CPDF_Object* pLenObj = pDict->GetElement(FX_BSTRC("Length"));\r
-    FX_DWORD len = 0;\r
-    if (pLenObj && (pLenObj->GetType() != PDFOBJ_REFERENCE ||\r
-                    (((CPDF_Reference*)pLenObj)->GetObjList() != NULL) &&\r
-                    ((CPDF_Reference*)pLenObj)->GetRefObjNum() != objnum)) {\r
-        FX_FILESIZE pos = m_Pos;\r
-        if (pLenObj) {\r
-            len = pLenObj->GetInteger();\r
-        }\r
-        m_Pos = pos;\r
-        if (len > 0x40000000) {\r
-            return NULL;\r
-        }\r
-    }\r
-    ToNextLine();\r
-    FX_FILESIZE StreamStartPos = m_Pos;\r
-    if (pContext) {\r
-        pContext->m_DataStart = m_Pos;\r
-    }\r
-    m_Pos += len;\r
-    CPDF_CryptoHandler* pCryptoHandler = objnum == (FX_DWORD)m_MetadataObjnum ? NULL : m_pCryptoHandler;\r
-    if (pCryptoHandler == NULL) {\r
-        FX_FILESIZE SavedPos = m_Pos;\r
-        GetNextWord();\r
-        if (m_WordSize < 9 || FXSYS_memcmp32(m_WordBuffer, "endstream", 9)) {\r
-            m_Pos = StreamStartPos;\r
-            FX_FILESIZE offset = FindTag(FX_BSTRC("endstream"), 0);\r
-            if (offset >= 0) {\r
-                FX_FILESIZE curPos = m_Pos;\r
-                m_Pos = StreamStartPos;\r
-                FX_FILESIZE endobjOffset = FindTag(FX_BSTRC("endobj"), 0);\r
-                if (endobjOffset < offset && endobjOffset >= 0) {\r
-                    offset = endobjOffset;\r
-                } else {\r
-                    m_Pos = curPos;\r
-                }\r
-                FX_BYTE byte1, byte2;\r
-                GetCharAt(StreamStartPos + offset - 1, byte1);\r
-                GetCharAt(StreamStartPos + offset - 2, byte2);\r
-                if (byte1 == 0x0a && byte2 == 0x0d) {\r
-                    len -= 2;\r
-                } else if (byte1 == 0x0a || byte1 == 0x0d) {\r
-                    len --;\r
-                }\r
-                len = (FX_DWORD)offset;\r
-                pDict->SetAtInteger(FX_BSTRC("Length"), len);\r
-            } else {\r
-                m_Pos = StreamStartPos;\r
-                if (FindTag(FX_BSTRC("endobj"), 0) < 0) {\r
-                    return NULL;\r
-                }\r
-            }\r
-        }\r
-    }\r
-    m_Pos = StreamStartPos;\r
-    CPDF_Stream* pStream;\r
-#if defined(_FPDFAPI_MINI_) && !defined(_FXCORE_FEATURE_ALL_)\r
-    pStream = FX_NEW CPDF_Stream(m_pFileAccess, pCryptoHandler, m_HeaderOffset + m_Pos, len, pDict, gennum);\r
-    m_Pos += len;\r
-#else\r
-    FX_LPBYTE pData = FX_Alloc(FX_BYTE, len);\r
-    if (!pData) {\r
-        return NULL;\r
-    }\r
-    ReadBlock(pData, len);\r
-    if (pCryptoHandler) {\r
-        CFX_BinaryBuf dest_buf;\r
-        dest_buf.EstimateSize(pCryptoHandler->DecryptGetSize(len));\r
-        FX_LPVOID context = pCryptoHandler->DecryptStart(objnum, gennum);\r
-        pCryptoHandler->DecryptStream(context, pData, len, dest_buf);\r
-        pCryptoHandler->DecryptFinish(context, dest_buf);\r
-        FX_Free(pData);\r
-        pData = dest_buf.GetBuffer();\r
-        len = dest_buf.GetSize();\r
-        dest_buf.DetachBuffer();\r
-    }\r
-    pStream = FX_NEW CPDF_Stream(pData, len, pDict);\r
-#endif\r
-    if (pContext) {\r
-        pContext->m_DataEnd = pContext->m_DataStart + len;\r
-    }\r
-    StreamStartPos = m_Pos;\r
-    GetNextWord();\r
-    if (m_WordSize == 6 && 0 == FXSYS_memcmp32(m_WordBuffer, "endobj", 6)) {\r
-        m_Pos = StreamStartPos;\r
-    }\r
-    return pStream;\r
-}\r
-void CPDF_SyntaxParser::InitParser(IFX_FileRead* pFileAccess, FX_DWORD HeaderOffset)\r
-{\r
-    if (m_pFileBuf) {\r
-        FX_Free(m_pFileBuf);\r
-        m_pFileBuf = NULL;\r
-    }\r
-    m_pFileBuf = FX_Alloc(FX_BYTE, m_BufSize);\r
-    m_HeaderOffset = HeaderOffset;\r
-    m_FileLen = pFileAccess->GetSize();\r
-    m_Pos = 0;\r
-    m_pFileAccess = pFileAccess;\r
-    m_BufOffset = 0;\r
-    pFileAccess->ReadBlock(m_pFileBuf, 0, (size_t)((FX_FILESIZE)m_BufSize > m_FileLen ? m_FileLen : m_BufSize));\r
-}\r
-FX_INT32 CPDF_SyntaxParser::GetDirectNum()\r
-{\r
-    GetNextWord();\r
-    if (!m_bIsNumber) {\r
-        return 0;\r
-    }\r
-    m_WordBuffer[m_WordSize] = 0;\r
-    return FXSYS_atoi((FX_LPCSTR)m_WordBuffer);\r
-}\r
-FX_BOOL CPDF_SyntaxParser::IsWholeWord(FX_FILESIZE startpos, FX_FILESIZE limit, FX_LPCBYTE tag, FX_DWORD taglen)\r
-{\r
-    FX_BYTE type = _PDF_CharType[tag[0]];\r
-    FX_BOOL bCheckLeft = type != 'D' && type != 'W';\r
-    type = _PDF_CharType[tag[taglen - 1]];\r
-    FX_BOOL bCheckRight = type != 'D' || type != 'W';\r
-    FX_BYTE ch;\r
-    if (bCheckRight && startpos + (FX_INT32)taglen <= limit && GetCharAt(startpos + (FX_INT32)taglen, ch)) {\r
-        FX_BYTE type = _PDF_CharType[ch];\r
-        if (type == 'N' || type == 'R') {\r
-            return FALSE;\r
-        }\r
-    }\r
-    if (bCheckLeft && startpos > 0 && GetCharAt(startpos - 1, ch)) {\r
-        FX_BYTE type = _PDF_CharType[ch];\r
-        if (type == 'N' || type == 'R') {\r
-            return FALSE;\r
-        }\r
-    }\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_SyntaxParser::SearchWord(FX_BSTR tag, FX_BOOL bWholeWord, FX_BOOL bForward, FX_FILESIZE limit)\r
-{\r
-    FX_INT32 taglen = tag.GetLength();\r
-    if (taglen == 0) {\r
-        return FALSE;\r
-    }\r
-    FX_FILESIZE pos = m_Pos;\r
-    FX_INT32 offset = 0;\r
-    if (!bForward) {\r
-        offset = taglen - 1;\r
-    }\r
-    FX_LPCBYTE tag_data = tag;\r
-    FX_BYTE byte;\r
-    while (1) {\r
-        if (bForward) {\r
-            if (limit) {\r
-                if (pos >= m_Pos + limit) {\r
-                    return FALSE;\r
-                }\r
-            }\r
-            if (!GetCharAt(pos, byte)) {\r
-                return FALSE;\r
-            }\r
-        } else {\r
-            if (limit) {\r
-                if (pos <= m_Pos - limit) {\r
-                    return FALSE;\r
-                }\r
-            }\r
-            if (!GetCharAtBackward(pos, byte)) {\r
-                return FALSE;\r
-            }\r
-        }\r
-        if (byte == tag_data[offset]) {\r
-            if (bForward) {\r
-                offset ++;\r
-                if (offset < taglen) {\r
-                    pos ++;\r
-                    continue;\r
-                }\r
-            } else {\r
-                offset --;\r
-                if (offset >= 0) {\r
-                    pos --;\r
-                    continue;\r
-                }\r
-            }\r
-            FX_FILESIZE startpos = bForward ? pos - taglen + 1 : pos;\r
-            if (!bWholeWord || IsWholeWord(startpos, limit, tag, taglen)) {\r
-                m_Pos = startpos;\r
-                return TRUE;\r
-            }\r
-        }\r
-        if (bForward) {\r
-            offset = byte == tag_data[0] ? 1 : 0;\r
-            pos ++;\r
-        } else {\r
-            offset = byte == tag_data[taglen - 1] ? taglen - 2 : taglen - 1;\r
-            pos --;\r
-        }\r
-        if (pos < 0) {\r
-            return FALSE;\r
-        }\r
-    }\r
-    return FALSE;\r
-}\r
-struct _SearchTagRecord {\r
-    FX_LPCBYTE m_pTag;\r
-    FX_DWORD   m_Len;\r
-    FX_DWORD   m_Offset;\r
-};\r
-FX_INT32 CPDF_SyntaxParser::SearchMultiWord(FX_BSTR tags, FX_BOOL bWholeWord, FX_FILESIZE limit)\r
-{\r
-    FX_INT32 ntags = 1, i;\r
-    for (i = 0; i < tags.GetLength(); i ++)\r
-        if (tags[i] == 0) {\r
-            ntags ++;\r
-        }\r
-    _SearchTagRecord* pPatterns = FX_Alloc(_SearchTagRecord, ntags);\r
-    FX_DWORD start = 0, itag = 0, max_len = 0;\r
-    for (i = 0; i <= tags.GetLength(); i ++) {\r
-        if (tags[i] == 0) {\r
-            FX_DWORD len = i - start;\r
-            if (len > max_len) {\r
-                max_len = len;\r
-            }\r
-            pPatterns[itag].m_pTag = tags.GetPtr() + start;\r
-            pPatterns[itag].m_Len = len;\r
-            pPatterns[itag].m_Offset = 0;\r
-            start = i + 1;\r
-            itag ++;\r
-        }\r
-    }\r
-    FX_FILESIZE pos = m_Pos;\r
-    FX_BYTE byte;\r
-    GetCharAt(pos++, byte);\r
-    FX_INT32 found = -1;\r
-    while (1) {\r
-        for (i = 0; i < ntags; i ++) {\r
-            if (pPatterns[i].m_pTag[pPatterns[i].m_Offset] == byte) {\r
-                pPatterns[i].m_Offset ++;\r
-                if (pPatterns[i].m_Offset == pPatterns[i].m_Len) {\r
-                    if (!bWholeWord || IsWholeWord(pos - pPatterns[i].m_Len, limit, pPatterns[i].m_pTag, pPatterns[i].m_Len)) {\r
-                        found = i;\r
-                        goto end;\r
-                    } else {\r
-                        if (pPatterns[i].m_pTag[0] == byte) {\r
-                            pPatterns[i].m_Offset = 1;\r
-                        } else {\r
-                            pPatterns[i].m_Offset = 0;\r
-                        }\r
-                    }\r
-                }\r
-            } else {\r
-                if (pPatterns[i].m_pTag[0] == byte) {\r
-                    pPatterns[i].m_Offset = 1;\r
-                } else {\r
-                    pPatterns[i].m_Offset = 0;\r
-                }\r
-            }\r
-        }\r
-        if (limit && pos >= m_Pos + limit) {\r
-            goto end;\r
-        }\r
-        if (!GetCharAt(pos, byte)) {\r
-            goto end;\r
-        }\r
-        pos ++;\r
-    }\r
-end:\r
-    FX_Free(pPatterns);\r
-    return found;\r
-}\r
-FX_FILESIZE CPDF_SyntaxParser::FindTag(FX_BSTR tag, FX_FILESIZE limit)\r
-{\r
-    FX_INT32 taglen = tag.GetLength();\r
-    FX_INT32 match = 0;\r
-    limit += m_Pos;\r
-    FX_FILESIZE startpos = m_Pos;\r
-    while (1) {\r
-        FX_BYTE ch;\r
-        if (!GetNextChar(ch)) {\r
-            return -1;\r
-        }\r
-        if (ch == tag[match]) {\r
-            match ++;\r
-            if (match == taglen) {\r
-                return m_Pos - startpos - taglen;\r
-            }\r
-        } else {\r
-            match = ch == tag[0] ? 1 : 0;\r
-        }\r
-        if (limit && m_Pos == limit) {\r
-            return -1;\r
-        }\r
-    }\r
-    return -1;\r
-}\r
-void CPDF_SyntaxParser::GetBinary(FX_BYTE* buffer, FX_DWORD size)\r
-{\r
-    FX_DWORD offset = 0;\r
-    FX_BYTE ch;\r
-    while (1) {\r
-        if (!GetNextChar(ch)) {\r
-            return;\r
-        }\r
-        buffer[offset++] = ch;\r
-        if (offset == size) {\r
-            break;\r
-        }\r
-    }\r
-}\r
-CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead)\r
-{\r
-    m_pFileAvail = pFileAvail;\r
-    m_pFileRead = pFileRead;\r
-    m_Pos = 0;\r
-    m_dwFileLen = 0;\r
-    if (m_pFileRead) {\r
-        m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize();\r
-    }\r
-    m_dwCurrentOffset = 0;\r
-    m_WordSize = 0;\r
-    m_dwXRefOffset = 0;\r
-    m_bufferOffset = 0;\r
-    m_dwFirstPageNo = 0;\r
-    m_bufferSize = 0;\r
-    m_PagesObjNum = 0;\r
-    m_dwCurrentXRefSteam = 0;\r
-    m_dwAcroFormObjNum = 0;\r
-    m_dwInfoObjNum = 0;\r
-    m_pDocument = 0;\r
-    m_dwEncryptObjNum = 0;\r
-    m_dwPrevXRefOffset = 0;\r
-    m_dwLastXRefOffset = 0;\r
-    m_bDocAvail = FALSE;\r
-    m_bMainXRefLoad = FALSE;\r
-    m_bDocAvail = FALSE;\r
-    m_bLinearized = FALSE;\r
-    m_bPagesLoad = FALSE;\r
-    m_bPagesTreeLoad = FALSE;\r
-    m_bMainXRefLoadedOK = FALSE;\r
-    m_bAnnotsLoad = FALSE;\r
-    m_bHaveAcroForm = FALSE;\r
-    m_bAcroFormLoad = FALSE;\r
-    m_bPageLoadedOK = FALSE;\r
-    m_bNeedDownLoadResource = FALSE;\r
-    m_bLinearizedFormParamLoad = FALSE;\r
-    m_pLinearized = NULL;\r
-    m_pRoot = NULL;\r
-    m_pTrailer = NULL;\r
-    m_pCurrentParser = NULL;\r
-    m_pAcroForm = NULL;\r
-    m_pPageDict = NULL;\r
-    m_pPageResource = NULL;\r
-    m_pageMapCheckState = NULL;\r
-    m_docStatus = PDF_DATAAVAIL_HEADER;\r
-    m_parser.m_bOwnFileRead = FALSE;\r
-    m_bTotalLoadPageTree = FALSE;\r
-    m_bCurPageDictLoadOK = FALSE;\r
-    m_bLinearedDataOK = FALSE;\r
-    m_pagesLoadState = NULL;\r
-}\r
-CPDF_DataAvail::~CPDF_DataAvail()\r
-{\r
-    if (m_pLinearized) {\r
-        m_pLinearized->Release();\r
-    }\r
-    if (m_pRoot) {\r
-        m_pRoot->Release();\r
-    }\r
-    if (m_pTrailer) {\r
-        m_pTrailer->Release();\r
-    }\r
-    if (m_pageMapCheckState) {\r
-        delete m_pageMapCheckState;\r
-    }\r
-    if (m_pagesLoadState) {\r
-        delete m_pagesLoadState;\r
-    }\r
-    FX_INT32 i = 0;\r
-    FX_INT32 iSize = m_arrayAcroforms.GetSize();\r
-    for (i = 0; i < iSize; ++i) {\r
-        ((CPDF_Object *)m_arrayAcroforms.GetAt(i))->Release();\r
-    }\r
-}\r
-void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc)\r
-{\r
-    m_pDocument = pDoc;\r
-}\r
-FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset)\r
-{\r
-    CPDF_Parser *pParser = (CPDF_Parser *)(m_pDocument->GetParser());\r
-    if (pParser == NULL) {\r
-        return 0;\r
-    }\r
-    if (objnum >= (FX_DWORD)pParser->m_CrossRef.GetSize()) {\r
-        return 0;\r
-    }\r
-    if (pParser->m_V5Type[objnum] == 2) {\r
-        objnum = (FX_DWORD)pParser->m_CrossRef[objnum];\r
-    }\r
-    if (pParser->m_V5Type[objnum] == 1 || pParser->m_V5Type[objnum] == 255) {\r
-        offset = pParser->m_CrossRef[objnum];\r
-        if (offset == 0) {\r
-            return 0;\r
-        }\r
-        FX_LPVOID pResult = FXSYS_bsearch(&offset, pParser->m_SortedOffset.GetData(), pParser->m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);\r
-        if (pResult == NULL) {\r
-            return 0;\r
-        }\r
-        if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)pParser->m_SortedOffset.GetData() == pParser->m_SortedOffset.GetSize() - 1) {\r
-            return 0;\r
-        }\r
-        return (FX_DWORD)(((FX_FILESIZE*)pResult)[1] - offset);\r
-    }\r
-    return 0;\r
-}\r
-FX_BOOL CPDF_DataAvail::IsObjectsAvail(CFX_PtrArray& obj_array, FX_BOOL bParsePage, IFX_DownloadHints* pHints, CFX_PtrArray &ret_array)\r
-{\r
-    if (!obj_array.GetSize()) {\r
-        return TRUE;\r
-    }\r
-    FX_DWORD count = 0;\r
-    CFX_PtrArray new_obj_array;\r
-    FX_INT32 i = 0;\r
-    for (i = 0; i < obj_array.GetSize(); i++) {\r
-        CPDF_Object *pObj = (CPDF_Object *)obj_array[i];\r
-        if (!pObj) {\r
-            continue;\r
-        }\r
-        FX_INT32 type = pObj->GetType();\r
-        switch (type) {\r
-            case PDFOBJ_ARRAY: {\r
-                    CPDF_Array *pArray = pObj->GetArray();\r
-                    for (FX_DWORD k = 0; k < pArray->GetCount(); k++) {\r
-                        new_obj_array.Add(pArray->GetElement(k));\r
-                    }\r
-                }\r
-                break;\r
-            case PDFOBJ_STREAM:\r
-                pObj = pObj->GetDict();\r
-            case PDFOBJ_DICTIONARY: {\r
-                    CPDF_Dictionary *pDict = pObj->GetDict();\r
-                    if (pDict->GetString("Type") == "Page" && !bParsePage) {\r
-                        continue;\r
-                    }\r
-                    FX_POSITION pos = pDict->GetStartPos();\r
-                    while (pos) {\r
-                        CPDF_Object *value;\r
-                        CFX_ByteString key;\r
-                        value = pDict->GetNextElement(pos, key);\r
-                        if (key != "Parent") {\r
-                            new_obj_array.Add(value);\r
-                        }\r
-                    }\r
-                }\r
-                break;\r
-            case PDFOBJ_REFERENCE: {\r
-                    CPDF_Reference *pRef = (CPDF_Reference*)pObj;\r
-                    FX_DWORD dwNum = pRef->GetRefObjNum();\r
-                    FX_FILESIZE offset;\r
-                    FX_DWORD size = GetObjectSize(pRef->GetRefObjNum(), offset);\r
-                    if (!size) {\r
-                        break;\r
-                    }\r
-                    size = (FX_DWORD)((FX_FILESIZE)(offset + size + 512) > m_dwFileLen ? m_dwFileLen - offset : size + 512);\r
-                    if (!m_pFileAvail->IsDataAvail(offset, size)) {\r
-                        pHints->AddSegment(offset, size);\r
-                        ret_array.Add(pObj);\r
-                        count++;\r
-                    } else if (!m_objnum_array.Find(dwNum)) {\r
-                        m_objnum_array.AddObjNum(dwNum);\r
-                        CPDF_Object *pReferred = m_pDocument->GetIndirectObject(pRef->GetRefObjNum(), NULL);\r
-                        if (pReferred) {\r
-                            new_obj_array.Add(pReferred);\r
-                        }\r
-                    }\r
-                }\r
-                break;\r
-        }\r
-    }\r
-    if (count > 0) {\r
-        FX_INT32 iSize = new_obj_array.GetSize();\r
-        for (i = 0; i < iSize; ++i) {\r
-            CPDF_Object *pObj = (CPDF_Object *)new_obj_array[i];\r
-            FX_INT32 type = pObj->GetType();\r
-            if (type == PDFOBJ_REFERENCE) {\r
-                CPDF_Reference *pRef = (CPDF_Reference *)pObj;\r
-                FX_DWORD dwNum = pRef->GetRefObjNum();\r
-                if (!m_objnum_array.Find(dwNum)) {\r
-                    ret_array.Add(pObj);\r
-                }\r
-            } else {\r
-                ret_array.Add(pObj);\r
-            }\r
-        }\r
-        return FALSE;\r
-    }\r
-    obj_array.RemoveAll();\r
-    obj_array.Append(new_obj_array);\r
-    return IsObjectsAvail(obj_array, FALSE, pHints, ret_array);\r
-}\r
-FX_BOOL CPDF_DataAvail::IsDocAvail(IFX_DownloadHints* pHints)\r
-{\r
-    if (!m_dwFileLen && m_pFileRead) {\r
-        m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize();\r
-        if (!m_dwFileLen) {\r
-            return TRUE;\r
-        }\r
-    }\r
-    while (!m_bDocAvail) {\r
-        if (!CheckDocStatus(pHints)) {\r
-            return FALSE;\r
-        }\r
-    }\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject(IFX_DownloadHints* pHints)\r
-{\r
-    if (!m_objs_array.GetSize()) {\r
-        m_objs_array.RemoveAll();\r
-        m_objnum_array.RemoveAll();\r
-        CFX_PtrArray obj_array;\r
-        obj_array.Append(m_arrayAcroforms);\r
-        FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array);\r
-        if (bRet) {\r
-            m_objs_array.RemoveAll();\r
-        }\r
-        return bRet;\r
-    } else {\r
-        CFX_PtrArray new_objs_array;\r
-        FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);\r
-        if (bRet) {\r
-            FX_INT32 iSize = m_arrayAcroforms.GetSize();\r
-            for (FX_INT32 i = 0; i < iSize; ++i) {\r
-                ((CPDF_Object *)m_arrayAcroforms.GetAt(i))->Release();\r
-            }\r
-            m_arrayAcroforms.RemoveAll();\r
-        } else {\r
-            m_objs_array.RemoveAll();\r
-            m_objs_array.Append(new_objs_array);\r
-        }\r
-        return bRet;\r
-    }\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckAcroForm(IFX_DownloadHints* pHints)\r
-{\r
-    FX_BOOL bExist = FALSE;\r
-    m_pAcroForm = GetObject(m_dwAcroFormObjNum, pHints, &bExist);\r
-    if (!bExist) {\r
-        m_docStatus = PDF_DATAAVAIL_PAGETREE;\r
-        return TRUE;\r
-    }\r
-    if (!m_pAcroForm) {\r
-        if (m_docStatus == PDF_DATAAVAIL_ERROR) {\r
-            m_docStatus = PDF_DATAAVAIL_LOADALLFILE;\r
-            return TRUE;\r
-        }\r
-        return FALSE;\r
-    }\r
-    m_arrayAcroforms.Add(m_pAcroForm);\r
-    m_docStatus = PDF_DATAAVAIL_PAGETREE;\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints *pHints)\r
-{\r
-    switch (m_docStatus) {\r
-        case PDF_DATAAVAIL_HEADER:\r
-            return CheckHeader(pHints);\r
-        case PDF_DATAAVAIL_FIRSTPAGE:\r
-        case PDF_DATAAVAIL_FIRSTPAGE_PREPARE:\r
-            return CheckFirstPage(pHints);\r
-        case PDF_DATAAVAIL_END:\r
-            return CheckEnd(pHints);\r
-        case PDF_DATAAVAIL_CROSSREF:\r
-            return CheckCrossRef(pHints);\r
-        case PDF_DATAAVAIL_CROSSREF_ITEM:\r
-            return CheckCrossRefItem(pHints);\r
-        case PDF_DATAAVAIL_CROSSREF_STREAM:\r
-            return CheckAllCrossRefStream(pHints);\r
-        case PDF_DATAAVAIL_TRAILER:\r
-            return CheckTrailer(pHints);\r
-        case PDF_DATAAVAIL_TRAILER_APPEND:\r
-            return CheckTrailerAppend(pHints);\r
-        case PDF_DATAAVAIL_LOADALLCRSOSSREF:\r
-            return LoadAllXref(pHints);\r
-        case PDF_DATAAVAIL_LOADALLFILE:\r
-            return LoadAllFile(pHints);\r
-        case PDF_DATAAVAIL_ROOT:\r
-            return CheckRoot(pHints);\r
-        case PDF_DATAAVAIL_INFO:\r
-            return CheckInfo(pHints);\r
-        case PDF_DATAAVAIL_ACROFORM:\r
-            return CheckAcroForm(pHints);\r
-        case PDF_DATAAVAIL_PAGETREE:\r
-            if (m_bTotalLoadPageTree) {\r
-                return CheckPages(pHints);\r
-            } else {\r
-                return LoadDocPages(pHints);\r
-            }\r
-        case PDF_DATAAVAIL_PAGE:\r
-            if (m_bTotalLoadPageTree) {\r
-                return CheckPage(pHints);\r
-            } else {\r
-                m_docStatus = PDF_DATAAVAIL_PAGE_LATERLOAD;\r
-                return TRUE;\r
-            }\r
-        case PDF_DATAAVAIL_ERROR:\r
-            return LoadAllFile(pHints);\r
-        case PDF_DATAAVAIL_PAGE_LATERLOAD:\r
-            m_docStatus = PDF_DATAAVAIL_PAGE;\r
-        default:\r
-            m_bDocAvail = TRUE;\r
-            return TRUE;\r
-    }\r
-}\r
-FX_BOOL        CPDF_DataAvail::CheckPageStatus(IFX_DownloadHints* pHints)\r
-{\r
-    switch (m_docStatus) {\r
-        case PDF_DATAAVAIL_PAGETREE:\r
-            return CheckPages(pHints);\r
-        case PDF_DATAAVAIL_PAGE:\r
-            return CheckPage(pHints);\r
-        case PDF_DATAAVAIL_ERROR:\r
-            return LoadAllFile(pHints);\r
-        default:\r
-            m_bPagesTreeLoad = TRUE;\r
-            m_bPagesLoad = TRUE;\r
-            return TRUE;\r
-    }\r
-}\r
-FX_BOOL CPDF_DataAvail::LoadAllFile(IFX_DownloadHints* pHints)\r
-{\r
-    if (m_pFileAvail->IsDataAvail(0, (FX_DWORD)m_dwFileLen)) {\r
-        m_docStatus = PDF_DATAAVAIL_DONE;\r
-        return TRUE;\r
-    }\r
-    pHints->AddSegment(0, (FX_DWORD)m_dwFileLen);\r
-    return FALSE;\r
-}\r
-FX_BOOL CPDF_DataAvail::LoadAllXref(IFX_DownloadHints* pHints)\r
-{\r
-    m_parser.m_Syntax.InitParser(m_pFileRead, (FX_DWORD)m_dwHeaderOffset);\r
-    m_parser.m_bOwnFileRead = FALSE;\r
-    if (!m_parser.LoadAllCrossRefV4(m_dwLastXRefOffset) && !m_parser.LoadAllCrossRefV5(m_dwLastXRefOffset)) {\r
-        m_docStatus = PDF_DATAAVAIL_LOADALLFILE;\r
-        return FALSE;\r
-    }\r
-    FXSYS_qsort(m_parser.m_SortedOffset.GetData(), m_parser.m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);\r
-    m_dwRootObjNum = m_parser.GetRootObjNum();\r
-    m_dwInfoObjNum = m_parser.GetInfoObjNum();\r
-    m_pCurrentParser = &m_parser;\r
-    m_docStatus = PDF_DATAAVAIL_ROOT;\r
-    return TRUE;\r
-}\r
-CPDF_Object* CPDF_DataAvail::GetObject(FX_DWORD objnum, IFX_DownloadHints* pHints, FX_BOOL *pExistInFile)\r
-{\r
-    CPDF_Object *pRet = NULL;\r
-    if (pExistInFile) {\r
-        *pExistInFile = TRUE;\r
-    }\r
-    if (m_pDocument == NULL) {\r
-        FX_FILESIZE offset = m_parser.GetObjectOffset(objnum);\r
-        if (offset < 0) {\r
-            *pExistInFile = FALSE;\r
-            return NULL;\r
-        }\r
-        FX_DWORD size = (FX_DWORD)m_parser.GetObjectSize(objnum);\r
-        size = (FX_DWORD)(((FX_FILESIZE)(offset + size + 512)) > m_dwFileLen ? m_dwFileLen - offset : size + 512);\r
-        if (!m_pFileAvail->IsDataAvail(offset, size)) {\r
-            pHints->AddSegment(offset, size);\r
-            return NULL;\r
-        }\r
-        pRet = m_parser.ParseIndirectObject(NULL, objnum);\r
-        if (!pRet && pExistInFile) {\r
-            *pExistInFile = FALSE;\r
-        }\r
-        return pRet;\r
-    }\r
-    FX_FILESIZE offset;\r
-    FX_DWORD size = GetObjectSize(objnum, offset);\r
-    size = (FX_DWORD)((FX_FILESIZE)(offset + size + 512) > m_dwFileLen ? m_dwFileLen - offset : size + 512);\r
-    if (!m_pFileAvail->IsDataAvail(offset, size)) {\r
-        pHints->AddSegment(offset, size);\r
-        return NULL;\r
-    }\r
-    CPDF_Parser *pParser = (CPDF_Parser *)(m_pDocument->GetParser());\r
-    pRet = pParser->ParseIndirectObject(NULL, objnum, NULL);\r
-    if (!pRet && pExistInFile) {\r
-        *pExistInFile = FALSE;\r
-    }\r
-    return pRet;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckInfo(IFX_DownloadHints* pHints)\r
-{\r
-    FX_BOOL bExist = FALSE;\r
-    CPDF_Object *pInfo = GetObject(m_dwInfoObjNum, pHints, &bExist);\r
-    if (!bExist) {\r
-        if (m_bHaveAcroForm) {\r
-            m_docStatus = PDF_DATAAVAIL_ACROFORM;\r
-        } else {\r
-            m_docStatus = PDF_DATAAVAIL_PAGETREE;\r
-        }\r
-        return TRUE;\r
-    }\r
-    if (!pInfo) {\r
-        if (m_docStatus == PDF_DATAAVAIL_ERROR) {\r
-            m_docStatus = PDF_DATAAVAIL_LOADALLFILE;\r
-            return TRUE;\r
-        }\r
-        if (m_Pos == m_dwFileLen) {\r
-            m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        }\r
-        return FALSE;\r
-    }\r
-    if (pInfo) {\r
-        pInfo->Release();\r
-    }\r
-    if (m_bHaveAcroForm) {\r
-        m_docStatus = PDF_DATAAVAIL_ACROFORM;\r
-    } else {\r
-        m_docStatus = PDF_DATAAVAIL_PAGETREE;\r
-    }\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckRoot(IFX_DownloadHints* pHints)\r
-{\r
-    FX_BOOL bExist = FALSE;\r
-    m_pRoot = GetObject(m_dwRootObjNum, pHints, &bExist);\r
-    if (!bExist) {\r
-        m_docStatus = PDF_DATAAVAIL_LOADALLFILE;\r
-        return TRUE;\r
-    }\r
-    if (!m_pRoot) {\r
-        if (m_docStatus == PDF_DATAAVAIL_ERROR) {\r
-            m_docStatus = PDF_DATAAVAIL_LOADALLFILE;\r
-            return TRUE;\r
-        }\r
-        return FALSE;\r
-    }\r
-    CPDF_Reference* pRef = (CPDF_Reference*)m_pRoot->GetDict()->GetElement(FX_BSTRC("Pages"));\r
-    if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        return FALSE;\r
-    }\r
-    m_PagesObjNum = pRef->GetRefObjNum();\r
-    CPDF_Reference* pAcroFormRef = (CPDF_Reference*)m_pRoot->GetDict()->GetElement(FX_BSTRC("AcroForm"));\r
-    if (pAcroFormRef && pAcroFormRef->GetType() == PDFOBJ_REFERENCE) {\r
-        m_bHaveAcroForm = TRUE;\r
-        m_dwAcroFormObjNum = pAcroFormRef->GetRefObjNum();\r
-    }\r
-    if (m_dwInfoObjNum) {\r
-        m_docStatus = PDF_DATAAVAIL_INFO;\r
-    } else {\r
-        if (m_bHaveAcroForm) {\r
-            m_docStatus = PDF_DATAAVAIL_ACROFORM;\r
-        } else {\r
-            m_docStatus = PDF_DATAAVAIL_PAGETREE;\r
-        }\r
-    }\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_DataAvail::PreparePageItem()\r
-{\r
-    CPDF_Dictionary *pRoot = m_pDocument->GetRoot();\r
-    CPDF_Reference* pRef = (CPDF_Reference*)pRoot->GetElement(FX_BSTRC("Pages"));\r
-    if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        return FALSE;\r
-    }\r
-    m_PagesObjNum = pRef->GetRefObjNum();\r
-    m_pCurrentParser = (CPDF_Parser *)m_pDocument->GetParser();\r
-    m_docStatus = PDF_DATAAVAIL_PAGETREE;\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_DataAvail::IsFirstCheck(int iPage)\r
-{\r
-    if (NULL == m_pageMapCheckState) {\r
-        m_pageMapCheckState = FX_NEW CFX_CMapDWordToDWord();\r
-    }\r
-    FX_DWORD dwValue = 0;\r
-    if (!m_pageMapCheckState->Lookup(iPage, dwValue)) {\r
-        m_pageMapCheckState->SetAt(iPage, 1);\r
-        return TRUE;\r
-    }\r
-    if (dwValue != 0) {\r
-        return FALSE;\r
-    }\r
-    m_pageMapCheckState->SetAt(iPage, 1);\r
-    return TRUE;\r
-}\r
-void CPDF_DataAvail::ResetFirstCheck(int iPage)\r
-{\r
-    if (NULL == m_pageMapCheckState) {\r
-        m_pageMapCheckState = FX_NEW CFX_CMapDWordToDWord();\r
-    }\r
-    FX_DWORD dwValue = 1;\r
-    if (!m_pageMapCheckState->Lookup(iPage, dwValue)) {\r
-        return;\r
-    }\r
-    m_pageMapCheckState->SetAt(iPage, 0);\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckPage(IFX_DownloadHints* pHints)\r
-{\r
-    FX_DWORD i = 0;\r
-    FX_DWORD iLen = m_PageObjList.GetSize();\r
-    CFX_DWordArray UnavailObjList;\r
-    for (; i < iLen; ++i) {\r
-        FX_DWORD dwPageObjNum = m_PageObjList.GetAt(i);\r
-        FX_BOOL bExist = FALSE;\r
-        CPDF_Object *pObj = GetObject(dwPageObjNum, pHints, &bExist);\r
-        if (!pObj) {\r
-            if (bExist) {\r
-                UnavailObjList.Add(dwPageObjNum);\r
-            }\r
-            continue;\r
-        }\r
-        if (pObj->GetType() == PDFOBJ_ARRAY) {\r
-            CPDF_Array *pArray = pObj->GetArray();\r
-            if (pArray) {\r
-                FX_INT32 iSize = pArray->GetCount();\r
-                CPDF_Object *pItem = NULL;\r
-                for (FX_INT32 j = 0; j < iSize; ++j) {\r
-                    pItem = pArray->GetElement(j);\r
-                    if (pItem && pItem->GetType() == PDFOBJ_REFERENCE) {\r
-                        UnavailObjList.Add(((CPDF_Reference *)pItem)->GetRefObjNum());\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        if (pObj->GetType() != PDFOBJ_DICTIONARY) {\r
-            pObj->Release();\r
-            continue;\r
-        }\r
-        CFX_ByteString type = pObj->GetDict()->GetString(FX_BSTRC("Type"));\r
-        if (type == FX_BSTRC("Pages")) {\r
-            m_PagesArray.Add(pObj);\r
-            continue;\r
-        }\r
-        pObj->Release();\r
-    }\r
-    m_PageObjList.RemoveAll();\r
-    if (UnavailObjList.GetSize()) {\r
-        m_PageObjList.Append(UnavailObjList);\r
-        return FALSE;\r
-    }\r
-    i = 0;\r
-    iLen = m_PagesArray.GetSize();\r
-    for (; i < iLen; ++i) {\r
-        CPDF_Object *pPages = (CPDF_Object *)m_PagesArray.GetAt(i);\r
-        if (!pPages) {\r
-            continue;\r
-        }\r
-        if (!GetPageKids(m_pCurrentParser, pPages)) {\r
-            pPages->Release();\r
-            while (i++ < iLen) {\r
-                pPages = (CPDF_Object *)m_PagesArray.GetAt(i);\r
-                pPages->Release();\r
-            }\r
-            m_PagesArray.RemoveAll();\r
-            m_docStatus = PDF_DATAAVAIL_ERROR;\r
-            return FALSE;\r
-        }\r
-        pPages->Release();\r
-    }\r
-    m_PagesArray.RemoveAll();\r
-    if (!m_PageObjList.GetSize()) {\r
-        m_docStatus = PDF_DATAAVAIL_DONE;\r
-        return TRUE;\r
-    }\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_DataAvail::GetPageKids(CPDF_Parser *pParser, CPDF_Object *pPages)\r
-{\r
-    if (!pParser) {\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        return FALSE;\r
-    }\r
-    CPDF_Object *pKids = pPages->GetDict()->GetElement(FX_BSTRC("Kids"));\r
-    if (!pKids) {\r
-        return TRUE;\r
-    }\r
-    switch (pKids->GetType()) {\r
-        case PDFOBJ_REFERENCE: {\r
-                CPDF_Reference *pKid = (CPDF_Reference *)pKids;\r
-                m_PageObjList.Add(pKid->GetRefObjNum());\r
-            }\r
-            break;\r
-        case PDFOBJ_ARRAY: {\r
-                CPDF_Array *pKidsArray = (CPDF_Array *)pKids;\r
-                for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) {\r
-                    CPDF_Reference *pKid = (CPDF_Reference *)pKidsArray->GetElement(i);\r
-                    m_PageObjList.Add(pKid->GetRefObjNum());\r
-                }\r
-            }\r
-            break;\r
-        default:\r
-            m_docStatus = PDF_DATAAVAIL_ERROR;\r
-            return FALSE;\r
-    }\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckPages(IFX_DownloadHints* pHints)\r
-{\r
-    FX_BOOL bExist = FALSE;\r
-    CPDF_Object *pPages = GetObject(m_PagesObjNum, pHints, &bExist);\r
-    if (!bExist) {\r
-        m_docStatus = PDF_DATAAVAIL_LOADALLFILE;\r
-        return TRUE;\r
-    }\r
-    if (!pPages) {\r
-        if (m_docStatus == PDF_DATAAVAIL_ERROR) {\r
-            m_docStatus = PDF_DATAAVAIL_LOADALLFILE;\r
-            return TRUE;\r
-        }\r
-        return FALSE;\r
-    }\r
-    FX_BOOL bNeedLoad = FALSE;\r
-    if (!GetPageKids(m_pCurrentParser, pPages)) {\r
-        pPages->Release();\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        return FALSE;\r
-    }\r
-    pPages->Release();\r
-    m_docStatus = PDF_DATAAVAIL_PAGE;\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckHeader(IFX_DownloadHints* pHints)\r
-{\r
-    FX_DWORD req_size = 1024;\r
-    if ((FX_FILESIZE)req_size > m_dwFileLen) {\r
-        req_size = (FX_DWORD)m_dwFileLen;\r
-    }\r
-    if (m_pFileAvail->IsDataAvail(0, req_size)) {\r
-        FX_BYTE buffer[1024];\r
-        m_pFileRead->ReadBlock(buffer, 0, req_size);\r
-        if (IsLinearizedFile(buffer, req_size)) {\r
-            m_docStatus = PDF_DATAAVAIL_FIRSTPAGE;\r
-        } else {\r
-            if (m_docStatus == PDF_DATAAVAIL_ERROR) {\r
-                return FALSE;\r
-            }\r
-            m_docStatus = PDF_DATAAVAIL_END;\r
-        }\r
-        return TRUE;\r
-    }\r
-    pHints->AddSegment(0, req_size);\r
-    return FALSE;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckFirstPage(IFX_DownloadHints *pHints)\r
-{\r
-    FX_DWORD dwFirstPageEndOffset = 0;\r
-    CPDF_Object *pEndOffSet = m_pLinearized->GetDict()->GetElement(FX_BSTRC("E"));\r
-    if (!pEndOffSet) {\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        return FALSE;\r
-    }\r
-    CPDF_Object *pXRefOffset  = m_pLinearized->GetDict()->GetElement(FX_BSTRC("T"));\r
-    if (!pXRefOffset) {\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        return FALSE;\r
-    }\r
-    CPDF_Object *pFileLen = m_pLinearized->GetDict()->GetElement(FX_BSTRC("L"));\r
-    if (!pFileLen) {\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        return FALSE;\r
-    }\r
-    FX_BOOL bNeedDownLoad = FALSE;\r
-    if (pEndOffSet->GetType() == PDFOBJ_NUMBER) {\r
-        FX_DWORD dwEnd = pEndOffSet->GetInteger();\r
-        dwEnd += 512;\r
-        if ((FX_FILESIZE)dwEnd > m_dwFileLen) {\r
-            dwEnd = (FX_DWORD)m_dwFileLen;\r
-        }\r
-        FX_INT32 iStartPos = (FX_INT32)(m_dwFileLen > 1024 ? 1024 : m_dwFileLen);\r
-        FX_INT32 iSize = dwEnd > 1024 ? dwEnd - 1024 : 0;\r
-        if (!m_pFileAvail->IsDataAvail(iStartPos, iSize)) {\r
-            pHints->AddSegment(iStartPos, iSize);\r
-            bNeedDownLoad = TRUE;\r
-        }\r
-    }\r
-    m_dwLastXRefOffset = 0;\r
-    FX_FILESIZE dwFileLen = 0;\r
-    if (pXRefOffset->GetType() == PDFOBJ_NUMBER) {\r
-        m_dwLastXRefOffset = pXRefOffset->GetInteger();\r
-    }\r
-    if (pFileLen->GetType() == PDFOBJ_NUMBER) {\r
-        dwFileLen = pFileLen->GetInteger();\r
-    }\r
-    if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, (FX_DWORD)(dwFileLen - m_dwLastXRefOffset))) {\r
-        if (m_docStatus == PDF_DATAAVAIL_FIRSTPAGE)    {\r
-            FX_DWORD dwSize = (FX_DWORD)(dwFileLen - m_dwLastXRefOffset);\r
-            FX_FILESIZE offset = m_dwLastXRefOffset;\r
-            if (dwSize < 512 && dwFileLen > 512) {\r
-                dwSize = 512;\r
-                offset = dwFileLen - 512;\r
-            }\r
-            pHints->AddSegment(offset, dwSize);\r
-        }\r
-    } else {\r
-        m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE;\r
-    }\r
-    if (!bNeedDownLoad && m_docStatus == PDF_DATAAVAIL_FIRSTPAGE_PREPARE) {\r
-        m_docStatus = PDF_DATAAVAIL_DONE;\r
-        return TRUE;\r
-    }\r
-    m_docStatus = PDF_DATAAVAIL_FIRSTPAGE_PREPARE;\r
-    return FALSE;\r
-}\r
-CPDF_Object    * CPDF_DataAvail::ParseIndirectObjectAt(FX_FILESIZE pos, FX_DWORD objnum)\r
-{\r
-    FX_FILESIZE SavedPos = m_syntaxParser.SavePos();\r
-    m_syntaxParser.RestorePos(pos);\r
-    FX_BOOL bIsNumber;\r
-    CFX_ByteString word = m_syntaxParser.GetNextWord(bIsNumber);\r
-    if (!bIsNumber) {\r
-        return NULL;\r
-    }\r
-    FX_DWORD real_objnum = FXSYS_atoi(word);\r
-    if (objnum && real_objnum != objnum) {\r
-        return NULL;\r
-    }\r
-    word = m_syntaxParser.GetNextWord(bIsNumber);\r
-    if (!bIsNumber) {\r
-        return NULL;\r
-    }\r
-    FX_DWORD gennum = FXSYS_atoi(word);\r
-    if (m_syntaxParser.GetKeyword() != FX_BSTRC("obj")) {\r
-        m_syntaxParser.RestorePos(SavedPos);\r
-        return NULL;\r
-    }\r
-    CPDF_Object* pObj = m_syntaxParser.GetObject(NULL, objnum, gennum, 0);\r
-    m_syntaxParser.RestorePos(SavedPos);\r
-    return pObj;\r
-}\r
-FX_INT32 CPDF_DataAvail::IsLinearizedPDF()\r
-{\r
-    FX_DWORD req_size = 1024;\r
-    if (!m_pFileAvail->IsDataAvail(0, req_size)) {\r
-        return PDF_UNKNOW_LINEARIZED;\r
-    }\r
-    if (!m_pFileRead) {\r
-        return PDF_NOT_LINEARIZED;\r
-    }\r
-    FX_FILESIZE dwSize = m_pFileRead->GetSize();\r
-    if (dwSize < (FX_FILESIZE)req_size) {\r
-        return PDF_UNKNOW_LINEARIZED;\r
-    }\r
-    FX_BYTE buffer[1024];\r
-    m_pFileRead->ReadBlock(buffer, 0, req_size);\r
-    if (IsLinearizedFile(buffer, req_size)) {\r
-        return PDF_IS_LINEARIZED;\r
-    }\r
-    return PDF_NOT_LINEARIZED;\r
-}\r
-FX_BOOL CPDF_DataAvail::IsLinearizedFile(FX_LPBYTE pData, FX_DWORD dwLen)\r
-{\r
-    CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(pData, (size_t)dwLen, FALSE));\r
-    FX_INT32 offset = GetHeaderOffset((IFX_FileStream*)file);\r
-    if (offset == -1) {\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        return FALSE;\r
-    }\r
-    m_dwHeaderOffset = offset;\r
-    m_syntaxParser.InitParser((IFX_FileStream*)file, offset);\r
-    m_syntaxParser.RestorePos(m_syntaxParser.m_HeaderOffset + 9);\r
-    FX_BOOL bNumber = FALSE;\r
-    FX_FILESIZE dwSavePos = m_syntaxParser.SavePos();\r
-    CFX_ByteString wordObjNum = m_syntaxParser.GetNextWord(bNumber);\r
-    if (!bNumber) {\r
-        return FALSE;\r
-    }\r
-    FX_DWORD objnum = FXSYS_atoi(wordObjNum);\r
-    if (m_pLinearized) {\r
-        m_pLinearized->Release();\r
-        m_pLinearized = NULL;\r
-    }\r
-    m_pLinearized = ParseIndirectObjectAt(m_syntaxParser.m_HeaderOffset + 9, objnum);\r
-    if (!m_pLinearized) {\r
-        return FALSE;\r
-    }\r
-    if (m_pLinearized->GetDict()->GetElement(FX_BSTRC("Linearized"))) {\r
-        CPDF_Object *pLen = m_pLinearized->GetDict()->GetElement(FX_BSTRC("L"));\r
-        if (!pLen) {\r
-            return FALSE;\r
-        }\r
-        if ((FX_FILESIZE)pLen->GetInteger() != m_pFileRead->GetSize()) {\r
-            return FALSE;\r
-        }\r
-        m_bLinearized = TRUE;\r
-        CPDF_Object *pNo = m_pLinearized->GetDict()->GetElement(FX_BSTRC("P"));\r
-        if (pNo && pNo->GetType() == PDFOBJ_NUMBER) {\r
-            m_dwFirstPageNo = pNo->GetInteger();\r
-        }\r
-        return TRUE;\r
-    }\r
-    return FALSE;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckEnd(IFX_DownloadHints* pHints)\r
-{\r
-    FX_DWORD req_pos = (FX_DWORD)(m_dwFileLen > 1024 ? m_dwFileLen - 1024 : 0);\r
-    FX_DWORD dwSize = (FX_DWORD)(m_dwFileLen - req_pos);\r
-    if (m_pFileAvail->IsDataAvail(req_pos, dwSize)) {\r
-        FX_BYTE buffer[1024];\r
-        m_pFileRead->ReadBlock(buffer, req_pos, dwSize);\r
-        CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(buffer, (size_t)dwSize, FALSE));\r
-        m_syntaxParser.InitParser((IFX_FileStream*)file, 0);\r
-        m_syntaxParser.RestorePos(dwSize - 1);\r
-        if (m_syntaxParser.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, dwSize)) {\r
-            FX_BOOL bNumber;\r
-            m_syntaxParser.GetNextWord(bNumber);\r
-            CFX_ByteString xrefpos_str = m_syntaxParser.GetNextWord(bNumber);\r
-            if (!bNumber) {\r
-                m_docStatus = PDF_DATAAVAIL_ERROR;\r
-                return FALSE;\r
-            }\r
-            m_dwXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str);\r
-            if (!m_dwXRefOffset || m_dwXRefOffset > m_dwFileLen) {\r
-                m_docStatus = PDF_DATAAVAIL_LOADALLFILE;\r
-                return TRUE;\r
-            }\r
-            m_dwLastXRefOffset = m_dwXRefOffset;\r
-            SetStartOffset(m_dwXRefOffset);\r
-            m_docStatus = PDF_DATAAVAIL_CROSSREF;\r
-            return TRUE;\r
-        } else {\r
-            m_docStatus = PDF_DATAAVAIL_LOADALLFILE;\r
-            return TRUE;\r
-        }\r
-    }\r
-    pHints->AddSegment(req_pos, dwSize);\r
-    return FALSE;\r
-}\r
-FX_DWORD CPDF_DataAvail::CheckCrossRefStream(IFX_DownloadHints* pHints, FX_FILESIZE &xref_offset)\r
-{\r
-    xref_offset = 0;\r
-    FX_DWORD req_size = (FX_DWORD)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);\r
-    if (m_pFileAvail->IsDataAvail(m_Pos, req_size)) {\r
-        FX_INT32 iSize = (FX_INT32)(m_Pos + req_size - m_dwCurrentXRefSteam);\r
-        CFX_BinaryBuf buf(iSize);\r
-        FX_LPBYTE pBuf = buf.GetBuffer();\r
-        m_pFileRead->ReadBlock(pBuf, m_dwCurrentXRefSteam, iSize);\r
-        CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE));\r
-        m_parser.m_Syntax.InitParser((IFX_FileStream*)file, 0);\r
-        FX_BOOL bNumber = FALSE;\r
-        FX_FILESIZE dwSavePos = m_parser.m_Syntax.SavePos();\r
-        CFX_ByteString objnum = m_parser.m_Syntax.GetNextWord(bNumber);\r
-        if (!bNumber) {\r
-            return -1;\r
-        }\r
-        FX_DWORD objNum = FXSYS_atoi(objnum);\r
-        CPDF_Object *pObj = m_parser.ParseIndirectObjectAt(NULL, 0, objNum, NULL);\r
-        if (!pObj) {\r
-            m_Pos += m_parser.m_Syntax.SavePos();\r
-            return 0;\r
-        }\r
-        CPDF_Object *pName = pObj->GetDict()->GetElement(FX_BSTRC("Type"));\r
-        if (pName && pName->GetType() == PDFOBJ_NAME) {\r
-            if (pName->GetString() == FX_BSTRC("XRef")) {\r
-                m_Pos += m_parser.m_Syntax.SavePos();\r
-                xref_offset = pObj->GetDict()->GetInteger(FX_BSTRC("Prev"));\r
-                pObj->Release();\r
-                return 1;\r
-            } else {\r
-                pObj->Release();\r
-                return -1;\r
-            }\r
-        }\r
-        pObj->Release();\r
-        return -1;\r
-    }\r
-    pHints->AddSegment(m_Pos, req_size);\r
-    return 0;\r
-}\r
-inline void CPDF_DataAvail::SetStartOffset(FX_FILESIZE dwOffset)\r
-{\r
-    m_Pos = dwOffset;\r
-}\r
-#define MAX_WORD_BUFFER 256\r
-FX_BOOL CPDF_DataAvail::GetNextToken(CFX_ByteString &token)\r
-{\r
-    m_WordSize = 0;\r
-    FX_BYTE ch;\r
-    if (!GetNextChar(ch)) {\r
-        return FALSE;\r
-    }\r
-    FX_BYTE type = _PDF_CharType[ch];\r
-    while (1) {\r
-        while (type == 'W') {\r
-            if (!GetNextChar(ch)) {\r
-                return FALSE;\r
-            }\r
-            type = _PDF_CharType[ch];\r
-        }\r
-        if (ch != '%') {\r
-            break;\r
-        }\r
-        while (1) {\r
-            if (!GetNextChar(ch)) {\r
-                return FALSE;\r
-            }\r
-            if (ch == '\r' || ch == '\n') {\r
-                break;\r
-            }\r
-        }\r
-        type = _PDF_CharType[ch];\r
-    }\r
-    if (type == 'D') {\r
-        m_WordBuffer[m_WordSize++] = ch;\r
-        if (ch == '/') {\r
-            while (1) {\r
-                if (!GetNextChar(ch)) {\r
-                    return FALSE;\r
-                }\r
-                type = _PDF_CharType[ch];\r
-                if (type != 'R' && type != 'N') {\r
-                    m_Pos --;\r
-                    CFX_ByteString ret(m_WordBuffer, m_WordSize);\r
-                    token = ret;\r
-                    return TRUE;\r
-                }\r
-                if (m_WordSize < MAX_WORD_BUFFER) {\r
-                    m_WordBuffer[m_WordSize++] = ch;\r
-                }\r
-            }\r
-        } else if (ch == '<') {\r
-            if (!GetNextChar(ch)) {\r
-                return FALSE;\r
-            }\r
-            if (ch == '<') {\r
-                m_WordBuffer[m_WordSize++] = ch;\r
-            } else {\r
-                m_Pos --;\r
-            }\r
-        } else if (ch == '>') {\r
-            if (!GetNextChar(ch)) {\r
-                return FALSE;\r
-            }\r
-            if (ch == '>') {\r
-                m_WordBuffer[m_WordSize++] = ch;\r
-            } else {\r
-                m_Pos --;\r
-            }\r
-        }\r
-        CFX_ByteString ret(m_WordBuffer, m_WordSize);\r
-        token = ret;\r
-        return TRUE;\r
-    }\r
-    while (1) {\r
-        if (m_WordSize < MAX_WORD_BUFFER) {\r
-            m_WordBuffer[m_WordSize++] = ch;\r
-        }\r
-        if (!GetNextChar(ch)) {\r
-            return FALSE;\r
-        }\r
-        type = _PDF_CharType[ch];\r
-        if (type == 'D' || type == 'W') {\r
-            m_Pos --;\r
-            break;\r
-        }\r
-    }\r
-    CFX_ByteString ret(m_WordBuffer, m_WordSize);\r
-    token = ret;\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_DataAvail::GetNextChar(FX_BYTE &ch)\r
-{\r
-    FX_FILESIZE pos = m_Pos;\r
-    if (pos >= m_dwFileLen) {\r
-        return FALSE;\r
-    }\r
-    if (m_bufferOffset >= pos || (FX_FILESIZE)(m_bufferOffset + m_bufferSize) <= pos) {\r
-        FX_FILESIZE read_pos = pos;\r
-        FX_DWORD read_size = 512;\r
-        if ((FX_FILESIZE)read_size > m_dwFileLen) {\r
-            read_size = (FX_DWORD)m_dwFileLen;\r
-        }\r
-        if ((FX_FILESIZE)(read_pos + read_size) > m_dwFileLen) {\r
-            read_pos = m_dwFileLen - read_size;\r
-        }\r
-        if (!m_pFileRead->ReadBlock(m_bufferData, read_pos, read_size)) {\r
-            return FALSE;\r
-        }\r
-        m_bufferOffset = read_pos;\r
-        m_bufferSize = read_size;\r
-    }\r
-    ch = m_bufferData[pos - m_bufferOffset];\r
-    m_Pos ++;\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckCrossRefItem(IFX_DownloadHints *pHints)\r
-{\r
-    FX_INT32 iSize = 0;\r
-    CFX_ByteString token;\r
-    while (1) {\r
-        if (!GetNextToken(token)) {\r
-            iSize = (FX_INT32)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);\r
-            pHints->AddSegment(m_Pos, iSize);\r
-            return FALSE;\r
-        }\r
-        if (token == "trailer") {\r
-            m_dwTrailerOffset = m_Pos;\r
-            m_docStatus = PDF_DATAAVAIL_TRAILER;\r
-            return TRUE;\r
-        }\r
-    }\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckAllCrossRefStream(IFX_DownloadHints *pHints)\r
-{\r
-    FX_FILESIZE xref_offset = 0;\r
-    FX_DWORD dwRet = CheckCrossRefStream(pHints, xref_offset);\r
-    if (dwRet == 1) {\r
-        if (!xref_offset) {\r
-            m_docStatus = PDF_DATAAVAIL_LOADALLCRSOSSREF;\r
-        } else {\r
-            m_dwCurrentXRefSteam = xref_offset;\r
-            m_Pos = xref_offset;\r
-        }\r
-        return TRUE;\r
-    } else if (dwRet == -1) {\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-    }\r
-    return FALSE;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckCrossRef(IFX_DownloadHints* pHints)\r
-{\r
-    FX_FILESIZE dwSavePos = m_Pos;\r
-    FX_INT32 iSize = 0;\r
-    CFX_ByteString token;\r
-    if (!GetNextToken(token)) {\r
-        iSize = (FX_INT32)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);\r
-        pHints->AddSegment(m_Pos, iSize);\r
-        return FALSE;\r
-    }\r
-    if (token == "xref") {\r
-        m_CrossOffset.InsertAt(0, m_dwXRefOffset);\r
-        while (1) {\r
-            if (!GetNextToken(token)) {\r
-                iSize = (FX_INT32)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);\r
-                pHints->AddSegment(m_Pos, iSize);\r
-                m_docStatus = PDF_DATAAVAIL_CROSSREF_ITEM;\r
-                return FALSE;\r
-            }\r
-            if (token == "trailer") {\r
-                m_dwTrailerOffset = m_Pos;\r
-                m_docStatus = PDF_DATAAVAIL_TRAILER;\r
-                return TRUE;\r
-            }\r
-        }\r
-    } else {\r
-        m_docStatus = PDF_DATAAVAIL_LOADALLFILE;\r
-        return TRUE;\r
-    }\r
-    return FALSE;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckTrailerAppend(IFX_DownloadHints* pHints)\r
-{\r
-    if (m_Pos < m_dwFileLen) {\r
-        FX_FILESIZE dwAppendPos = m_Pos + m_syntaxParser.SavePos();\r
-        FX_INT32 iSize = (FX_INT32)(dwAppendPos + 512 > m_dwFileLen ? m_dwFileLen - dwAppendPos : 512);\r
-        if (!m_pFileAvail->IsDataAvail(dwAppendPos, iSize)) {\r
-            pHints->AddSegment(dwAppendPos, iSize);\r
-            return FALSE;\r
-        }\r
-    }\r
-    if (m_dwPrevXRefOffset) {\r
-        SetStartOffset(m_dwPrevXRefOffset);\r
-        m_docStatus = PDF_DATAAVAIL_CROSSREF;\r
-    } else {\r
-        m_docStatus = PDF_DATAAVAIL_LOADALLCRSOSSREF;\r
-    }\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckTrailer(IFX_DownloadHints* pHints)\r
-{\r
-    FX_INT32 iTrailerSize = (FX_INT32)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512);\r
-    if (m_pFileAvail->IsDataAvail(m_Pos, iTrailerSize)) {\r
-        FX_INT32 iSize = (FX_INT32)(m_Pos + iTrailerSize - m_dwTrailerOffset);\r
-        CFX_BinaryBuf buf(iSize);\r
-        FX_LPBYTE pBuf = buf.GetBuffer();\r
-        if (!pBuf) {\r
-            m_docStatus = PDF_DATAAVAIL_ERROR;\r
-            return FALSE;\r
-        }\r
-        if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize)) {\r
-            return FALSE;\r
-        }\r
-        CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream(pBuf, (size_t)iSize, FALSE));\r
-        m_syntaxParser.InitParser((IFX_FileStream*)file, 0);\r
-        CPDF_Object *pTrailer = m_syntaxParser.GetObject(NULL, 0, 0, 0);\r
-        if (!pTrailer) {\r
-            m_Pos += m_syntaxParser.SavePos();\r
-            pHints->AddSegment(m_Pos, iTrailerSize);\r
-            return FALSE;\r
-        }\r
-        CPDF_Dictionary *pTrailerDict = pTrailer->GetDict();\r
-        if (pTrailerDict) {\r
-            CPDF_Object *pEncrypt = pTrailerDict->GetElement("Encrypt");\r
-            if (pEncrypt && pEncrypt->GetType() == PDFOBJ_REFERENCE) {\r
-                m_docStatus = PDF_DATAAVAIL_LOADALLFILE;\r
-                pTrailer->Release();\r
-                return TRUE;\r
-            }\r
-        }\r
-        FX_DWORD xrefpos = GetDirectInteger(pTrailer->GetDict(), FX_BSTRC("Prev"));\r
-        if (xrefpos) {\r
-            m_dwPrevXRefOffset = GetDirectInteger(pTrailer->GetDict(), FX_BSTRC("XRefStm"));\r
-            pTrailer->Release();\r
-            if (m_dwPrevXRefOffset) {\r
-                m_docStatus = PDF_DATAAVAIL_LOADALLFILE;\r
-            } else {\r
-                m_dwPrevXRefOffset = xrefpos;\r
-                if (m_dwPrevXRefOffset >= m_dwFileLen) {\r
-                    m_docStatus = PDF_DATAAVAIL_LOADALLFILE;\r
-                } else {\r
-                    SetStartOffset(m_dwPrevXRefOffset);\r
-                    m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND;\r
-                }\r
-            }\r
-            return TRUE;\r
-        } else {\r
-            m_dwPrevXRefOffset = 0;\r
-            m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND;\r
-            pTrailer->Release();\r
-        }\r
-        return TRUE;\r
-    }\r
-    pHints->AddSegment(m_Pos, iTrailerSize);\r
-    return FALSE;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckPage(FX_INT32 iPage, IFX_DownloadHints* pHints)\r
-{\r
-    while (TRUE) {\r
-        switch (m_docStatus) {\r
-            case PDF_DATAAVAIL_PAGETREE:\r
-                if (!LoadDocPages(pHints)) {\r
-                    return FALSE;\r
-                }\r
-                break;\r
-            case PDF_DATAAVAIL_PAGE:\r
-                if (!LoadDocPage(iPage, pHints)) {\r
-                    return FALSE;\r
-                }\r
-                break;\r
-            case PDF_DATAAVAIL_ERROR:\r
-                return LoadAllFile(pHints);\r
-            default:\r
-                m_bPagesTreeLoad = TRUE;\r
-                m_bPagesLoad = TRUE;\r
-                m_bCurPageDictLoadOK = TRUE;\r
-                m_docStatus = PDF_DATAAVAIL_PAGE;\r
-                return TRUE;\r
-        }\r
-    }\r
-}\r
-FX_BOOL        CPDF_DataAvail::CheckArrayPageNode(FX_DWORD dwPageNo, CPDF_PageNode *pPageNode, IFX_DownloadHints* pHints)\r
-{\r
-    FX_BOOL bExist = FALSE;\r
-    CPDF_Object *pPages = GetObject(dwPageNo, pHints, &bExist);\r
-    if (!bExist) {\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        return FALSE;\r
-    }\r
-    if (!pPages) {\r
-        if (m_docStatus == PDF_DATAAVAIL_ERROR) {\r
-            m_docStatus = PDF_DATAAVAIL_ERROR;\r
-            return FALSE;\r
-        }\r
-        return FALSE;\r
-    }\r
-    if (pPages->GetType() != PDFOBJ_ARRAY) {\r
-        pPages->Release();\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        return FALSE;\r
-    }\r
-    pPageNode->m_type = PDF_PAGENODE_PAGES;\r
-    CPDF_Array* pArray = (CPDF_Array*)pPages;\r
-    for (FX_DWORD i = 0; i < pArray->GetCount(); ++i) {\r
-        CPDF_Object *pKid = (CPDF_Object *)pArray->GetElement(i);\r
-        if (!pKid || pKid->GetType() != PDFOBJ_REFERENCE) {\r
-            continue;\r
-        }\r
-        CPDF_PageNode *pNode = FX_NEW CPDF_PageNode();\r
-        pPageNode->m_childNode.Add(pNode);\r
-        pNode->m_dwPageNo = ((CPDF_Reference*)pKid)->GetRefObjNum();\r
-    }\r
-    pPages->Release();\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckUnkownPageNode(FX_DWORD dwPageNo, CPDF_PageNode *pPageNode, IFX_DownloadHints* pHints)\r
-{\r
-    FX_BOOL bExist = FALSE;\r
-    CPDF_Object *pPage = GetObject(dwPageNo, pHints, &bExist);\r
-    if (!bExist) {\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        return FALSE;\r
-    }\r
-    if (!pPage) {\r
-        if (m_docStatus == PDF_DATAAVAIL_ERROR) {\r
-            m_docStatus = PDF_DATAAVAIL_ERROR;\r
-            return FALSE;\r
-        }\r
-        return FALSE;\r
-    }\r
-    if (pPage->GetType() == PDFOBJ_ARRAY) {\r
-        pPageNode->m_dwPageNo = dwPageNo;\r
-        pPageNode->m_type = PDF_PAGENODE_ARRAY;\r
-        pPage->Release();\r
-        return TRUE;\r
-    }\r
-    if (pPage->GetType() != PDFOBJ_DICTIONARY) {\r
-        pPage->Release();\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        return FALSE;\r
-    }\r
-    pPageNode->m_dwPageNo = dwPageNo;\r
-    CFX_ByteString type = pPage->GetDict()->GetString(FX_BSTRC("Type"));\r
-    if (type == FX_BSTRC("Pages")) {\r
-        pPageNode->m_type = PDF_PAGENODE_PAGES;\r
-        CPDF_Object *pKids = pPage->GetDict()->GetElement(FX_BSTRC("Kids"));\r
-        if (!pKids) {\r
-            m_docStatus = PDF_DATAAVAIL_PAGE;\r
-            return TRUE;\r
-        }\r
-        switch (pKids->GetType()) {\r
-            case PDFOBJ_REFERENCE: {\r
-                    CPDF_Reference *pKid = (CPDF_Reference *)pKids;\r
-                    CPDF_PageNode *pNode = FX_NEW CPDF_PageNode();\r
-                    pPageNode->m_childNode.Add(pNode);\r
-                    pNode->m_dwPageNo = pKid->GetRefObjNum();\r
-                }\r
-                break;\r
-            case PDFOBJ_ARRAY: {\r
-                    CPDF_Array *pKidsArray = (CPDF_Array *)pKids;\r
-                    for (FX_DWORD i = 0; i < pKidsArray->GetCount(); ++i) {\r
-                        CPDF_Object *pKid = (CPDF_Object *)pKidsArray->GetElement(i);\r
-                        if (!pKid || pKid->GetType() != PDFOBJ_REFERENCE) {\r
-                            continue;\r
-                        }\r
-                        CPDF_PageNode *pNode = FX_NEW CPDF_PageNode();\r
-                        pPageNode->m_childNode.Add(pNode);\r
-                        pNode->m_dwPageNo = ((CPDF_Reference*)pKid)->GetRefObjNum();\r
-                    }\r
-                }\r
-                break;\r
-            default:\r
-                break;\r
-        }\r
-    } else if (type == FX_BSTRC("Page")) {\r
-        pPageNode->m_type = PDF_PAGENODE_PAGE;\r
-    } else {\r
-        pPage->Release();\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        return FALSE;\r
-    }\r
-    pPage->Release();\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckPageNode(CPDF_PageNode &pageNodes, FX_INT32 iPage, FX_INT32 &iCount, IFX_DownloadHints* pHints)\r
-{\r
-    FX_INT32 iSize = pageNodes.m_childNode.GetSize();\r
-    if (!iSize) {\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        return FALSE;\r
-    }\r
-    for (FX_INT32 i = 0; i < iSize; ++i) {\r
-        CPDF_PageNode *pNode = (CPDF_PageNode*)pageNodes.m_childNode.GetAt(i);\r
-        if (!pNode) {\r
-            continue;\r
-        }\r
-        switch (pNode->m_type) {\r
-            case PDF_PAGENODE_UNKOWN:\r
-                if (!CheckUnkownPageNode(pNode->m_dwPageNo, pNode, pHints)) {\r
-                    return FALSE;\r
-                }\r
-                --i;\r
-                break;\r
-            case PDF_PAGENODE_PAGE:\r
-                iCount++;\r
-                if (iPage == iCount && m_pDocument) {\r
-                    m_pDocument->m_PageList.SetAt(iPage, pNode->m_dwPageNo);\r
-                }\r
-                break;\r
-            case PDF_PAGENODE_PAGES:\r
-                if (!CheckPageNode(*pNode, iPage, iCount, pHints)) {\r
-                    return FALSE;\r
-                }\r
-                break;\r
-            case PDF_PAGENODE_ARRAY:\r
-                if (!CheckArrayPageNode(pNode->m_dwPageNo, pNode, pHints)) {\r
-                    return FALSE;\r
-                }\r
-                --i;\r
-                break;\r
-        }\r
-        if (iPage == iCount) {\r
-            m_docStatus = PDF_DATAAVAIL_DONE;\r
-            return TRUE;\r
-        }\r
-    }\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_DataAvail::LoadDocPage(FX_INT32 iPage, IFX_DownloadHints* pHints)\r
-{\r
-    if (m_pDocument->GetPageCount() <= iPage || m_pDocument->m_PageList.GetAt(iPage)) {\r
-        m_docStatus = PDF_DATAAVAIL_DONE;\r
-        return TRUE;\r
-    }\r
-    if (m_pageNodes.m_type == PDF_PAGENODE_PAGE) {\r
-        if (iPage == 0) {\r
-            m_docStatus = PDF_DATAAVAIL_DONE;\r
-            return TRUE;\r
-        }\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        return TRUE;\r
-    }\r
-    FX_INT32 iCount = -1;\r
-    return CheckPageNode(m_pageNodes, iPage, iCount, pHints);\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckPageCount(IFX_DownloadHints* pHints)\r
-{\r
-    FX_BOOL bExist = FALSE;\r
-    CPDF_Object *pPages = GetObject(m_PagesObjNum, pHints, &bExist);\r
-    if (!bExist) {\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        return FALSE;\r
-    }\r
-    if (!pPages) {\r
-        return FALSE;\r
-    }\r
-    CPDF_Dictionary* pPagesDict = pPages->GetDict();\r
-    if (!pPagesDict) {\r
-        pPages->Release();\r
-        m_docStatus = PDF_DATAAVAIL_ERROR;\r
-        return FALSE;\r
-    }\r
-    if (!pPagesDict->KeyExist(FX_BSTRC("Kids"))) {\r
-        pPages->Release();\r
-        return TRUE;\r
-    }\r
-    int count = pPagesDict->GetInteger(FX_BSTRC("Count"));\r
-    if (count > 0) {\r
-        pPages->Release();\r
-        return TRUE;\r
-    }\r
-    pPages->Release();\r
-    return FALSE;\r
-}\r
-FX_BOOL CPDF_DataAvail::LoadDocPages(IFX_DownloadHints* pHints)\r
-{\r
-    if (!CheckUnkownPageNode(m_PagesObjNum, &m_pageNodes, pHints)) {\r
-        return FALSE;\r
-    }\r
-    if (CheckPageCount(pHints)) {\r
-        m_docStatus = PDF_DATAAVAIL_PAGE;\r
-        return TRUE;\r
-    } else {\r
-        m_bTotalLoadPageTree = TRUE;\r
-    }\r
-    return FALSE;\r
-}\r
-FX_BOOL CPDF_DataAvail::LoadPages(IFX_DownloadHints* pHints)\r
-{\r
-    while (!m_bPagesTreeLoad) {\r
-        if (!CheckPageStatus(pHints)) {\r
-            return FALSE;\r
-        }\r
-    }\r
-    if (m_bPagesLoad) {\r
-        return TRUE;\r
-    }\r
-    m_pDocument->LoadPages();\r
-    return FALSE;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckLinearizedData(IFX_DownloadHints* pHints)\r
-{\r
-    if (m_bLinearedDataOK) {\r
-        return TRUE;\r
-    }\r
-    if (!m_pFileAvail->IsDataAvail(m_dwLastXRefOffset, (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset))) {\r
-        pHints->AddSegment(m_dwLastXRefOffset, (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset));\r
-        return FALSE;\r
-    }\r
-    FX_DWORD dwRet = 0;\r
-    if (!m_bMainXRefLoad) {\r
-        dwRet = ((CPDF_Parser *)m_pDocument->GetParser())->LoadLinearizedMainXRefTable();\r
-        if (dwRet == PDFPARSE_ERROR_SUCCESS) {\r
-            if (!PreparePageItem()) {\r
-                return FALSE;\r
-            }\r
-            m_bMainXRefLoadedOK = TRUE;\r
-        }\r
-        m_bMainXRefLoad = TRUE;\r
-    }\r
-    m_bLinearedDataOK = TRUE;\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckPageAnnots(FX_INT32 iPage, IFX_DownloadHints* pHints)\r
-{\r
-    if (!m_objs_array.GetSize()) {\r
-        m_objs_array.RemoveAll();\r
-        m_objnum_array.RemoveAll();\r
-        CPDF_Dictionary *pPageDict = m_pDocument->GetPage(iPage);\r
-        if (!pPageDict) {\r
-            return TRUE;\r
-        }\r
-        CPDF_Object *pAnnots = pPageDict->GetElement(FX_BSTRC("Annots"));\r
-        if (!pAnnots) {\r
-            return TRUE;\r
-        }\r
-        CFX_PtrArray obj_array;\r
-        obj_array.Add(pAnnots);\r
-        FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array);\r
-        if (bRet) {\r
-            m_objs_array.RemoveAll();\r
-        }\r
-        return bRet;\r
-    } else {\r
-        CFX_PtrArray new_objs_array;\r
-        FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);\r
-        m_objs_array.RemoveAll();\r
-        if (!bRet) {\r
-            m_objs_array.Append(new_objs_array);\r
-        }\r
-        return bRet;\r
-    }\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckLinearizedFirstPage(FX_INT32 iPage, IFX_DownloadHints* pHints)\r
-{\r
-    if (!m_bAnnotsLoad) {\r
-        if (!CheckPageAnnots(iPage, pHints)) {\r
-            return FALSE;\r
-        }\r
-        m_bAnnotsLoad = TRUE;\r
-    }\r
-    if (m_bAnnotsLoad)\r
-        if (!CheckLinearizedData(pHints)) {\r
-            return FALSE;\r
-        }\r
-    m_bPageLoadedOK = FALSE;\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_DataAvail::HaveResourceAncestor(CPDF_Dictionary *pDict)\r
-{\r
-    CPDF_Object *pParent = pDict->GetElement("Parent");\r
-    if (!pParent) {\r
-        return FALSE;\r
-    }\r
-    CPDF_Dictionary *pParentDict = pParent->GetDict();\r
-    if (!pParentDict) {\r
-        return FALSE;\r
-    }\r
-    CPDF_Object *pRet = pParentDict->GetElement("Resource");\r
-    if (pRet) {\r
-        m_pPageResource = pRet;\r
-        return TRUE;\r
-    } else {\r
-        return HaveResourceAncestor(pParentDict);\r
-    }\r
-}\r
-FX_BOOL CPDF_DataAvail::IsPageAvail(FX_INT32 iPage, IFX_DownloadHints* pHints)\r
-{\r
-    if (!m_pDocument) {\r
-        return FALSE;\r
-    }\r
-    if (IsFirstCheck(iPage)) {\r
-        m_bCurPageDictLoadOK = FALSE;\r
-        m_bPageLoadedOK = FALSE;\r
-        m_bAnnotsLoad = FALSE;\r
-        m_bNeedDownLoadResource = FALSE;\r
-        m_objs_array.RemoveAll();\r
-        m_objnum_array.RemoveAll();\r
-    }\r
-    if (m_pagesLoadState == NULL) {\r
-        m_pagesLoadState = FX_NEW CFX_CMapDWordToDWord();\r
-    }\r
-    FX_DWORD dwPageLoad = 0;\r
-    if (m_pagesLoadState->Lookup(iPage, dwPageLoad) && dwPageLoad != 0) {\r
-        return TRUE;\r
-    }\r
-    if (m_bLinearized) {\r
-        if ((FX_DWORD)iPage == m_dwFirstPageNo) {\r
-            m_pagesLoadState->SetAt(iPage, TRUE);\r
-            return TRUE;\r
-        }\r
-        if (!CheckLinearizedData(pHints)) {\r
-            return FALSE;\r
-        }\r
-        if (m_bMainXRefLoadedOK) {\r
-            if (m_bTotalLoadPageTree) {\r
-                if (!LoadPages(pHints)) {\r
-                    return FALSE;\r
-                }\r
-            } else {\r
-                if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) {\r
-                    return FALSE;\r
-                }\r
-            }\r
-        } else {\r
-            if (!LoadAllFile(pHints)) {\r
-                return FALSE;\r
-            }\r
-            ((CPDF_Parser *)m_pDocument->GetParser())->RebuildCrossRef();\r
-            ResetFirstCheck(iPage);\r
-            return TRUE;\r
-        }\r
-    } else {\r
-        if (!m_bTotalLoadPageTree) {\r
-            if (!m_bCurPageDictLoadOK && !CheckPage(iPage, pHints)) {\r
-                return FALSE;\r
-            }\r
-        }\r
-    }\r
-    if (m_bHaveAcroForm && !m_bAcroFormLoad) {\r
-        if (!CheckAcroFormSubObject(pHints)) {\r
-            return FALSE;\r
-        }\r
-        m_bAcroFormLoad = TRUE;\r
-    }\r
-    if (!m_bPageLoadedOK) {\r
-        if (!m_objs_array.GetSize()) {\r
-            m_objs_array.RemoveAll();\r
-            m_objnum_array.RemoveAll();\r
-            m_pPageDict = m_pDocument->GetPage(iPage);\r
-            if (!m_pPageDict) {\r
-                ResetFirstCheck(iPage);\r
-                return TRUE;\r
-            }\r
-            CFX_PtrArray obj_array;\r
-            obj_array.Add(m_pPageDict);\r
-            FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array);\r
-            if (bRet) {\r
-                m_objs_array.RemoveAll();\r
-                m_bPageLoadedOK = TRUE;\r
-            } else {\r
-                return bRet;\r
-            }\r
-        } else {\r
-            CFX_PtrArray new_objs_array;\r
-            FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);\r
-            m_objs_array.RemoveAll();\r
-            if (bRet) {\r
-                m_bPageLoadedOK = TRUE;\r
-            } else {\r
-                m_objs_array.Append(new_objs_array);\r
-                return bRet;\r
-            }\r
-        }\r
-    }\r
-    if (m_bPageLoadedOK) {\r
-        if (!m_bAnnotsLoad) {\r
-            if (!CheckPageAnnots(iPage, pHints)) {\r
-                return FALSE;\r
-            }\r
-            m_bAnnotsLoad = TRUE;\r
-        }\r
-    }\r
-    if (m_pPageDict && !m_bNeedDownLoadResource) {\r
-        CPDF_Object *pRes = m_pPageDict->GetElement("Resource");\r
-        if (!pRes) {\r
-            m_bNeedDownLoadResource = HaveResourceAncestor(m_pPageDict);\r
-        }\r
-        m_bNeedDownLoadResource = FALSE;\r
-    }\r
-    if (m_bNeedDownLoadResource) {\r
-        FX_BOOL bRet = CheckResources(pHints);\r
-        if (!bRet) {\r
-            return FALSE;\r
-        }\r
-        m_bNeedDownLoadResource = FALSE;\r
-    }\r
-    m_bPageLoadedOK = FALSE;\r
-    m_bAnnotsLoad = FALSE;\r
-    m_bCurPageDictLoadOK = FALSE;\r
-    ResetFirstCheck(iPage);\r
-    m_pagesLoadState->SetAt(iPage, TRUE);\r
-    return TRUE;\r
-}\r
-FX_BOOL CPDF_DataAvail::CheckResources(IFX_DownloadHints* pHints)\r
-{\r
-    if (!m_objs_array.GetSize()) {\r
-        m_objs_array.RemoveAll();\r
-        CFX_PtrArray obj_array;\r
-        obj_array.Add(m_pPageResource);\r
-        FX_BOOL bRet = IsObjectsAvail(obj_array, TRUE, pHints, m_objs_array);\r
-        if (bRet) {\r
-            m_objs_array.RemoveAll();\r
-        }\r
-        return bRet;\r
-    } else {\r
-        CFX_PtrArray new_objs_array;\r
-        FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);\r
-        m_objs_array.RemoveAll();\r
-        if (!bRet) {\r
-            m_objs_array.Append(new_objs_array);\r
-        }\r
-        return bRet;\r
-    }\r
-}\r
-void CPDF_DataAvail::GetLinearizedMainXRefInfo(FX_FILESIZE *pPos, FX_DWORD *pSize)\r
-{\r
-    if (pPos) {\r
-        *pPos = m_dwLastXRefOffset;\r
-    }\r
-    if (pSize) {\r
-        *pSize = (FX_DWORD)(m_dwFileLen - m_dwLastXRefOffset);\r
-    }\r
-}\r
-FX_INT32 CPDF_DataAvail::IsFormAvail(IFX_DownloadHints *pHints)\r
-{\r
-    if (!m_pDocument) {\r
-        return PDFFORM_AVAIL;\r
-    }\r
-    if (!m_bLinearizedFormParamLoad) {\r
-        CPDF_Dictionary *pRoot = m_pDocument->GetRoot();\r
-        if (!pRoot) {\r
-            return PDFFORM_AVAIL;\r
-        }\r
-        CPDF_Object *pAcroForm = pRoot->GetElement(FX_BSTRC("AcroForm"));\r
-        if (!pAcroForm) {\r
-            return PDFFORM_NOTEXIST;\r
-        }\r
-        if (!m_bMainXRefLoad && !CheckLinearizedData(pHints)) {\r
-            return PDFFORM_NOTAVAIL;\r
-        }\r
-        if (!m_objs_array.GetSize()) {\r
-            m_objs_array.Add(pAcroForm->GetDict());\r
-        }\r
-        m_bLinearizedFormParamLoad = TRUE;\r
-    }\r
-    CFX_PtrArray new_objs_array;\r
-    FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);\r
-    m_objs_array.RemoveAll();\r
-    if (!bRet) {\r
-        m_objs_array.Append(new_objs_array);\r
-        return PDFFORM_NOTAVAIL;\r
-    }\r
-    return PDFFORM_AVAIL;\r
-}\r
-void CPDF_SortObjNumArray::AddObjNum(FX_DWORD dwObjNum)\r
-{\r
-    FX_INT32 iNext = 0;\r
-    if (BinarySearch(dwObjNum, iNext)) {\r
-        return;\r
-    }\r
-    m_number_array.InsertAt(iNext, dwObjNum);\r
-}\r
-FX_BOOL CPDF_SortObjNumArray::Find(FX_DWORD dwObjNum)\r
-{\r
-    FX_INT32 iNext = 0;\r
-    return BinarySearch(dwObjNum, iNext);\r
-}\r
-FX_BOOL CPDF_SortObjNumArray::BinarySearch(FX_DWORD value, FX_INT32 &iNext)\r
-{\r
-    FX_INT32 iLen = m_number_array.GetSize();\r
-    FX_INT32 iLow = 0;\r
-    FX_INT32 iHigh = iLen - 1;\r
-    FX_INT32 iMid = 0;\r
-    while (iLow <= iHigh) {\r
-        iMid = (iLow + iHigh) / 2;\r
-        FX_DWORD tt = m_number_array.GetAt(iMid);\r
-        if (m_number_array.GetAt(iMid) == value) {\r
-            iNext = iMid;\r
-            return TRUE;\r
-        } else if (m_number_array.GetAt(iMid) > value) {\r
-            iHigh = iMid - 1;\r
-        } else if (m_number_array.GetAt(iMid) < value) {\r
-            iLow = iMid + 1;\r
-        }\r
-    }\r
-    iNext = iLow;\r
-    return FALSE;\r
-}\r
-CPDF_PageNode::~CPDF_PageNode()\r
-{\r
-    FX_INT32 iSize = m_childNode.GetSize();\r
-    for (FX_INT32 i = 0; i < iSize; ++i) {\r
-        CPDF_PageNode *pNode = (CPDF_PageNode*)m_childNode[i];\r
-        if (pNode) {\r
-            delete pNode;\r
-        }\r
-    }\r
-    m_childNode.RemoveAll();\r
-}\r
+// 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_parser.h"
+#include "../../../include/fpdfapi/fpdf_module.h"
+#include "../../../include/fpdfapi/fpdf_page.h"
+#include "../fpdf_page/pageint.h"
+#include <limits.h>
+#define _PARSER_OBJECT_LEVLE_          64
+extern const FX_LPCSTR _PDF_CharType;
+FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict)
+{
+    CPDF_Object* pType = pDict->GetElementValue(FX_BSTRC("Type"));
+    if (!pType) {
+        pType = pDict->GetElementValue(FX_BSTRC("FT"));
+        if (!pType) {
+            return FALSE;
+        }
+    }
+    if (pType->GetString() == FX_BSTRC("Sig")) {
+        return TRUE;
+    }
+    return FALSE;
+}
+static FX_INT32 _CompareDWord(const void* p1, const void* p2)
+{
+    return (*(FX_DWORD*)p1) - (*(FX_DWORD*)p2);
+}
+static int _CompareFileSize(const void* p1, const void* p2)
+{
+    FX_FILESIZE ret = (*(FX_FILESIZE*)p1) - (*(FX_FILESIZE*)p2);
+    if (ret > 0) {
+        return 1;
+    }
+    if (ret < 0) {
+        return -1;
+    }
+    return 0;
+}
+CPDF_Parser::CPDF_Parser()
+{
+    m_pDocument = NULL;
+    m_pTrailer = NULL;
+    m_pEncryptDict = NULL;
+    m_pSecurityHandler = NULL;
+    m_pLinearized = NULL;
+    m_dwFirstPageNo = 0;
+    m_dwXrefStartObjNum = 0;
+    m_bOwnFileRead = TRUE;
+    m_bForceUseSecurityHandler = FALSE;
+}
+CPDF_Parser::~CPDF_Parser()
+{
+    CloseParser(FALSE);
+}
+FX_DWORD CPDF_Parser::GetLastObjNum()
+{
+    FX_DWORD dwSize = m_CrossRef.GetSize();
+    return dwSize ? dwSize - 1 : 0;
+}
+void CPDF_Parser::SetEncryptDictionary(CPDF_Dictionary* pDict)
+{
+    m_pEncryptDict = pDict;
+}
+void CPDF_Parser::CloseParser(FX_BOOL bReParse)
+{
+    m_bVersionUpdated = FALSE;
+    if (m_pDocument && !bReParse) {
+        delete m_pDocument;
+        m_pDocument = NULL;
+    }
+    if (m_pTrailer) {
+        m_pTrailer->Release();
+        m_pTrailer = NULL;
+    }
+    ReleaseEncryptHandler();
+    SetEncryptDictionary(NULL);
+    if (m_bOwnFileRead && m_Syntax.m_pFileAccess) {
+        m_Syntax.m_pFileAccess->Release();
+        m_Syntax.m_pFileAccess = NULL;
+    }
+    FX_POSITION pos = m_ObjectStreamMap.GetStartPosition();
+    while (pos) {
+        FX_LPVOID objnum;
+        CPDF_StreamAcc* pStream;
+        m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream);
+        delete pStream;
+    }
+    m_ObjectStreamMap.RemoveAll();
+    m_SortedOffset.RemoveAll();
+    m_CrossRef.RemoveAll();
+    m_V5Type.RemoveAll();
+    m_ObjVersion.RemoveAll();
+    FX_INT32 iLen = m_Trailers.GetSize();
+    for (FX_INT32 i = 0; i < iLen; ++i) {
+        if (CPDF_Dictionary* trailer = m_Trailers.GetAt(i))
+            trailer->Release();
+    }
+    m_Trailers.RemoveAll();
+    if (m_pLinearized) {
+        m_pLinearized->Release();
+        m_pLinearized = NULL;
+    }
+}
+static FX_INT32 GetHeaderOffset(IFX_FileRead* pFile)
+{
+    FX_DWORD tag = FXDWORD_FROM_LSBFIRST(0x46445025);
+    FX_BYTE buf[4];
+    FX_INT32 offset = 0;
+    while (1) {
+        if (!pFile->ReadBlock(buf, offset, 4)) {
+            return -1;
+        }
+        if (*(FX_DWORD*)buf == tag) {
+            return offset;
+        }
+        offset ++;
+        if (offset > 1024) {
+            return -1;
+        }
+    }
+    return -1;
+}
+FX_DWORD CPDF_Parser::StartParse(FX_LPCSTR filename, FX_BOOL bReParse)
+{
+    IFX_FileRead* pFileAccess = FX_CreateFileRead(filename);
+    if (!pFileAccess) {
+        return PDFPARSE_ERROR_FILE;
+    }
+    return StartParse(pFileAccess, bReParse);
+}
+FX_DWORD CPDF_Parser::StartParse(FX_LPCWSTR filename, FX_BOOL bReParse)
+{
+    IFX_FileRead* pFileAccess = FX_CreateFileRead(filename);
+    if (!pFileAccess) {
+        return PDFPARSE_ERROR_FILE;
+    }
+    return StartParse(pFileAccess, bReParse);
+}
+CPDF_SecurityHandler* FPDF_CreateStandardSecurityHandler();
+CPDF_SecurityHandler* FPDF_CreatePubKeyHandler(void*);
+FX_DWORD CPDF_Parser::StartParse(IFX_FileRead* pFileAccess, FX_BOOL bReParse, FX_BOOL bOwnFileRead)
+{
+    CloseParser(bReParse);
+    m_bXRefStream = FALSE;
+    m_LastXRefOffset = 0;
+    m_bOwnFileRead = bOwnFileRead;
+    FX_INT32 offset = GetHeaderOffset(pFileAccess);
+    if (offset == -1) {
+        if (bOwnFileRead && pFileAccess) {
+            pFileAccess->Release();
+        }
+        return PDFPARSE_ERROR_FORMAT;
+    }
+    m_Syntax.InitParser(pFileAccess, offset);
+    FX_BYTE ch;
+    m_Syntax.GetCharAt(5, ch);
+    m_FileVersion = (ch - '0') * 10;
+    m_Syntax.GetCharAt(7, ch);
+    m_FileVersion += ch - '0';
+    m_Syntax.RestorePos(m_Syntax.m_FileLen - m_Syntax.m_HeaderOffset - 9);
+    if (!bReParse) {
+        m_pDocument = FX_NEW CPDF_Document(this);
+    }
+    FX_BOOL bXRefRebuilt = FALSE;
+    if (m_Syntax.SearchWord(FX_BSTRC("startxref"), TRUE, FALSE, 4096)) {
+        FX_FILESIZE startxref_offset = m_Syntax.SavePos();
+        FX_LPVOID pResult = FXSYS_bsearch(&startxref_offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
+        if (pResult == NULL) {
+            m_SortedOffset.Add(startxref_offset);
+        }
+        m_Syntax.GetKeyword();
+        FX_BOOL bNumber;
+        CFX_ByteString xrefpos_str = m_Syntax.GetNextWord(bNumber);
+        if (!bNumber) {
+            return PDFPARSE_ERROR_FORMAT;
+        }
+        m_LastXRefOffset = (FX_FILESIZE)FXSYS_atoi64(xrefpos_str);
+        if (!LoadAllCrossRefV4(m_LastXRefOffset) && !LoadAllCrossRefV5(m_LastXRefOffset)) {
+            if (!RebuildCrossRef()) {
+                return PDFPARSE_ERROR_FORMAT;
+            }
+            bXRefRebuilt = TRUE;
+            m_LastXRefOffset = 0;
+        }
+    } else {
+        if (!RebuildCrossRef()) {
+            return PDFPARSE_ERROR_FORMAT;
+        }
+        bXRefRebuilt = TRUE;
+    }
+    FX_DWORD dwRet = SetEncryptHandler();
+    if (dwRet != PDFPARSE_ERROR_SUCCESS) {
+        return dwRet;
+    }
+    m_pDocument->LoadDoc();
+    if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) {
+        if (bXRefRebuilt) {
+            return PDFPARSE_ERROR_FORMAT;
+        }
+        ReleaseEncryptHandler();
+        if (!RebuildCrossRef()) {
+            return PDFPARSE_ERROR_FORMAT;
+        }
+        dwRet = SetEncryptHandler();
+        if (dwRet != PDFPARSE_ERROR_SUCCESS) {
+            return dwRet;
+        }
+        m_pDocument->LoadDoc();
+        if (m_pDocument->GetRoot() == NULL) {
+            return PDFPARSE_ERROR_FORMAT;
+        }
+    }
+    FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
+    FX_DWORD RootObjNum = GetRootObjNum();
+    if (RootObjNum == 0) {
+        ReleaseEncryptHandler();
+        RebuildCrossRef();
+        RootObjNum = GetRootObjNum();
+        if (RootObjNum == 0) {
+            return PDFPARSE_ERROR_FORMAT;
+        }
+        dwRet = SetEncryptHandler();
+        if (dwRet != PDFPARSE_ERROR_SUCCESS) {
+            return dwRet;
+        }
+    }
+    if (m_pSecurityHandler && !m_pSecurityHandler->IsMetadataEncrypted()) {
+        CPDF_Reference* pMetadata = (CPDF_Reference*)m_pDocument->GetRoot()->GetElement(FX_BSTRC("Metadata"));
+        if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) {
+            m_Syntax.m_MetadataObjnum = pMetadata->GetRefObjNum();
+        }
+    }
+    return PDFPARSE_ERROR_SUCCESS;
+}
+FX_DWORD CPDF_Parser::SetEncryptHandler()
+{
+    ReleaseEncryptHandler();
+    SetEncryptDictionary(NULL);
+    if (m_pTrailer == NULL) {
+        return PDFPARSE_ERROR_FORMAT;
+    }
+    CPDF_Object* pEncryptObj = m_pTrailer->GetElement(FX_BSTRC("Encrypt"));
+    if (pEncryptObj) {
+        if (pEncryptObj->GetType() == PDFOBJ_DICTIONARY) {
+            SetEncryptDictionary((CPDF_Dictionary*)pEncryptObj);
+        } else if (pEncryptObj->GetType() == PDFOBJ_REFERENCE) {
+            pEncryptObj = m_pDocument->GetIndirectObject(((CPDF_Reference*)pEncryptObj)->GetRefObjNum());
+            if (pEncryptObj) {
+                SetEncryptDictionary(pEncryptObj->GetDict());
+            }
+        }
+    }
+    if (m_bForceUseSecurityHandler) {
+        FX_DWORD err = PDFPARSE_ERROR_HANDLER;
+        if (m_pSecurityHandler == NULL) {
+            return PDFPARSE_ERROR_HANDLER;
+        }
+        if (!m_pSecurityHandler->OnInit(this, m_pEncryptDict)) {
+            return err;
+        }
+        CPDF_CryptoHandler* pCryptoHandler = m_pSecurityHandler->CreateCryptoHandler();
+        if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) {
+            delete pCryptoHandler;
+            pCryptoHandler = NULL;
+            return PDFPARSE_ERROR_HANDLER;
+        }
+        m_Syntax.SetEncrypt(pCryptoHandler);
+    } else if (m_pEncryptDict) {
+        CFX_ByteString filter = m_pEncryptDict->GetString(FX_BSTRC("Filter"));
+        CPDF_SecurityHandler* pSecurityHandler = NULL;
+        FX_DWORD err = PDFPARSE_ERROR_HANDLER;
+        if (filter == FX_BSTRC("Standard")) {
+            pSecurityHandler = FPDF_CreateStandardSecurityHandler();
+            err = PDFPARSE_ERROR_PASSWORD;
+        }
+        if (pSecurityHandler == NULL) {
+            return PDFPARSE_ERROR_HANDLER;
+        }
+        if (!pSecurityHandler->OnInit(this, m_pEncryptDict)) {
+            delete pSecurityHandler;
+            pSecurityHandler = NULL;
+            return err;
+        }
+        m_pSecurityHandler = pSecurityHandler;
+        CPDF_CryptoHandler* pCryptoHandler = pSecurityHandler->CreateCryptoHandler();
+        if (!pCryptoHandler->Init(m_pEncryptDict, m_pSecurityHandler)) {
+            delete pCryptoHandler;
+            pCryptoHandler = NULL;
+            return PDFPARSE_ERROR_HANDLER;
+        }
+        m_Syntax.SetEncrypt(pCryptoHandler);
+    }
+    return PDFPARSE_ERROR_SUCCESS;
+}
+void CPDF_Parser::ReleaseEncryptHandler()
+{
+    if (m_Syntax.m_pCryptoHandler) {
+        delete m_Syntax.m_pCryptoHandler;
+        m_Syntax.m_pCryptoHandler = NULL;
+    }
+    if (m_pSecurityHandler && !m_bForceUseSecurityHandler) {
+        delete m_pSecurityHandler;
+        m_pSecurityHandler = NULL;
+    }
+}
+FX_FILESIZE CPDF_Parser::GetObjectOffset(FX_DWORD objnum)
+{
+    if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
+        return 0;
+    }
+    if (m_V5Type[objnum] == 1) {
+        return m_CrossRef[objnum];
+    }
+    if (m_V5Type[objnum] == 2) {
+        return m_CrossRef[(FX_INT32)m_CrossRef[objnum]];
+    }
+    return 0;
+}
+static FX_INT32 GetDirectInteger(CPDF_Dictionary* pDict, FX_BSTR key)
+{
+    CPDF_Object* pObj = pDict->GetElement(key);
+    if (pObj == NULL) {
+        return 0;
+    }
+    if (pObj->GetType() == PDFOBJ_NUMBER) {
+        return ((CPDF_Number*)pObj)->GetInteger();
+    }
+    return 0;
+}
+static FX_BOOL CheckDirectType(CPDF_Dictionary* pDict, FX_BSTR key, FX_INT32 iType)
+{
+    CPDF_Object* pObj = pDict->GetElement(key);
+    if (!pObj) {
+        return TRUE;
+    }
+    return pObj->GetType() == iType;
+}
+FX_BOOL CPDF_Parser::LoadAllCrossRefV4(FX_FILESIZE xrefpos)
+{
+    if (!LoadCrossRefV4(xrefpos, 0, TRUE, FALSE)) {
+        return FALSE;
+    }
+    m_pTrailer = LoadTrailerV4();
+    if (m_pTrailer == NULL) {
+        return FALSE;
+    }
+    FX_INT32 xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size"));
+    if (xrefsize <= 0 || xrefsize > (1 << 20)) {
+        return FALSE;
+    }
+    m_CrossRef.SetSize(xrefsize);
+    m_V5Type.SetSize(xrefsize);
+    CFX_FileSizeArray CrossRefList, XRefStreamList;
+    CrossRefList.Add(xrefpos);
+    XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm")));
+    if (!CheckDirectType(m_pTrailer, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) {
+        return FALSE;
+    }
+    FX_FILESIZE newxrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev"));
+    if (newxrefpos == xrefpos) {
+        return FALSE;
+    }
+    xrefpos = newxrefpos;
+    while (xrefpos) {
+        CrossRefList.InsertAt(0, xrefpos);
+        LoadCrossRefV4(xrefpos, 0, TRUE, FALSE);
+        CPDF_Dictionary* pDict = LoadTrailerV4();
+        if (pDict == NULL) {
+            return FALSE;
+        }
+        if (!CheckDirectType(pDict, FX_BSTRC("Prev"), PDFOBJ_NUMBER)) {
+            pDict->Release();
+            return FALSE;
+        }
+        newxrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev"));
+        if (newxrefpos == xrefpos) {
+            pDict->Release();
+            return FALSE;
+        }
+        xrefpos = newxrefpos;
+        XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm")));
+        m_Trailers.Add(pDict);
+    }
+    for (FX_INT32 i = 0; i < CrossRefList.GetSize(); i ++)
+        if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) {
+            return FALSE;
+        }
+    return TRUE;
+}
+FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV4(FX_FILESIZE xrefpos, FX_DWORD dwObjCount)
+{
+    if (!LoadLinearizedCrossRefV4(xrefpos, dwObjCount)) {
+        return FALSE;
+    }
+    m_pTrailer = LoadTrailerV4();
+    if (m_pTrailer == NULL) {
+        return FALSE;
+    }
+    FX_INT32 xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size"));
+    if (xrefsize == 0) {
+        return FALSE;
+    }
+    CFX_FileSizeArray CrossRefList, XRefStreamList;
+    CrossRefList.Add(xrefpos);
+    XRefStreamList.Add(GetDirectInteger(m_pTrailer, FX_BSTRC("XRefStm")));
+    xrefpos = GetDirectInteger(m_pTrailer, FX_BSTRC("Prev"));
+    while (xrefpos) {
+        CrossRefList.InsertAt(0, xrefpos);
+        LoadCrossRefV4(xrefpos, 0, TRUE, FALSE);
+        CPDF_Dictionary* pDict = LoadTrailerV4();
+        if (pDict == NULL) {
+            return FALSE;
+        }
+        xrefpos = GetDirectInteger(pDict, FX_BSTRC("Prev"));
+        XRefStreamList.InsertAt(0, pDict->GetInteger(FX_BSTRC("XRefStm")));
+        m_Trailers.Add(pDict);
+    }
+    for (FX_INT32 i = 1; i < CrossRefList.GetSize(); i ++)
+        if (!LoadCrossRefV4(CrossRefList[i], XRefStreamList[i], FALSE, i == 0)) {
+            return FALSE;
+        }
+    return TRUE;
+}
+FX_BOOL CPDF_Parser::LoadLinearizedCrossRefV4(FX_FILESIZE pos, FX_DWORD dwObjCount)
+{
+    FX_FILESIZE dwStartPos = pos - m_Syntax.m_HeaderOffset;
+    m_Syntax.RestorePos(dwStartPos);
+    FX_LPVOID pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
+    if (pResult == NULL) {
+        m_SortedOffset.Add(pos);
+    }
+    FX_DWORD start_objnum = 0;
+    FX_DWORD count = dwObjCount;
+    FX_FILESIZE SavedPos = m_Syntax.SavePos();
+    FX_INT32 recordsize = 20;
+    char* pBuf = FX_Alloc(char, 1024 * recordsize + 1);
+    pBuf[1024 * recordsize] = '\0';
+    FX_INT32 nBlocks = count / 1024 + 1;
+    for (FX_INT32 block = 0; block < nBlocks; block ++) {
+        FX_INT32 block_size = block == nBlocks - 1 ? count % 1024 : 1024;
+        FX_DWORD dwReadSize = block_size * recordsize;
+        if ((FX_FILESIZE)(dwStartPos + dwReadSize) > m_Syntax.m_FileLen) {
+            FX_Free(pBuf);
+            return FALSE;
+        }
+        if (!m_Syntax.ReadBlock((FX_LPBYTE)pBuf, dwReadSize)) {
+            FX_Free(pBuf);
+            return FALSE;
+        }
+        for (FX_INT32 i = 0; i < block_size; i ++) {
+            FX_DWORD objnum = start_objnum + block * 1024 + i;
+            char* pEntry = pBuf + i * recordsize;
+            if (pEntry[17] == 'f') {
+                m_CrossRef.SetAtGrow(objnum, 0);
+                m_V5Type.SetAtGrow(objnum, 0);
+            } else {
+                FX_INT32 offset = FXSYS_atoi(pEntry);
+                if (offset == 0) {
+                    for (FX_INT32 c = 0; c < 10; c ++) {
+                        if (pEntry[c] < '0' || pEntry[c] > '9') {
+                            FX_Free(pBuf);
+                            return FALSE;
+                        }
+                    }
+                }
+                m_CrossRef.SetAtGrow(objnum, offset);
+                FX_INT32 version = FXSYS_atoi(pEntry + 11);
+                if (version >= 1) {
+                    m_bVersionUpdated = TRUE;
+                }
+                m_ObjVersion.SetAtGrow(objnum, version);
+                if (m_CrossRef[objnum] < m_Syntax.m_FileLen) {
+                    FX_LPVOID pResult = FXSYS_bsearch(&m_CrossRef[objnum], m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
+                    if (pResult == NULL) {
+                        m_SortedOffset.Add(m_CrossRef[objnum]);
+                    }
+                }
+                m_V5Type.SetAtGrow(objnum, 1);
+            }
+        }
+    }
+    FX_Free(pBuf);
+    m_Syntax.RestorePos(SavedPos + count * recordsize);
+    return TRUE;
+}
+FX_BOOL CPDF_Parser::LoadCrossRefV4(FX_FILESIZE pos, FX_FILESIZE streampos, FX_BOOL bSkip, FX_BOOL bFirst)
+{
+    m_Syntax.RestorePos(pos);
+    if (m_Syntax.GetKeyword() != FX_BSTRC("xref")) {
+        return FALSE;
+    }
+    FX_LPVOID pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
+    if (pResult == NULL) {
+        m_SortedOffset.Add(pos);
+    }
+    if (streampos) {
+        FX_LPVOID pResult = FXSYS_bsearch(&streampos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
+        if (pResult == NULL) {
+            m_SortedOffset.Add(streampos);
+        }
+    }
+    while (1) {
+        FX_FILESIZE SavedPos = m_Syntax.SavePos();
+        FX_BOOL bIsNumber;
+        CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
+        if (word.IsEmpty()) {
+            return FALSE;
+        }
+        if (!bIsNumber) {
+            m_Syntax.RestorePos(SavedPos);
+            break;
+        }
+        FX_DWORD start_objnum = FXSYS_atoi(word);
+        if (start_objnum >= (1 << 20)) {
+            return FALSE;
+        }
+        FX_DWORD count = m_Syntax.GetDirectNum();
+        m_Syntax.ToNextWord();
+        SavedPos = m_Syntax.SavePos();
+        FX_BOOL bFirstItem = FALSE;
+        FX_INT32 recordsize = 20;
+        if (bFirst) {
+            bFirstItem = TRUE;
+        }
+        m_dwXrefStartObjNum = start_objnum;
+        if (!bSkip) {
+            char* pBuf = FX_Alloc(char, 1024 * recordsize + 1);
+            pBuf[1024 * recordsize] = '\0';
+            FX_INT32 nBlocks = count / 1024 + 1;
+            FX_BOOL bFirstBlock = TRUE;
+            for (FX_INT32 block = 0; block < nBlocks; block ++) {
+                FX_INT32 block_size = block == nBlocks - 1 ? count % 1024 : 1024;
+                m_Syntax.ReadBlock((FX_LPBYTE)pBuf, block_size * recordsize);
+                for (FX_INT32 i = 0; i < block_size; i ++) {
+                    FX_DWORD objnum = start_objnum + block * 1024 + i;
+                    char* pEntry = pBuf + i * recordsize;
+                    if (pEntry[17] == 'f') {
+                        if (bFirstItem) {
+                            objnum = 0;
+                            bFirstItem = FALSE;
+                        }
+                        if (bFirstBlock) {
+                            FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry);
+                            FX_INT32 version = FXSYS_atoi(pEntry + 11);
+                            if (offset == 0 && version == 65535 && start_objnum != 0) {
+                                start_objnum--;
+                                objnum = 0;
+                            }
+                        }
+                        m_CrossRef.SetAtGrow(objnum, 0);
+                        m_V5Type.SetAtGrow(objnum, 0);
+                    } else {
+                        FX_FILESIZE offset = (FX_FILESIZE)FXSYS_atoi64(pEntry);
+                        if (offset == 0) {
+                            for (FX_INT32 c = 0; c < 10; c ++) {
+                                if (pEntry[c] < '0' || pEntry[c] > '9') {
+                                    FX_Free(pBuf);
+                                    return FALSE;
+                                }
+                            }
+                        }
+                        m_CrossRef.SetAtGrow(objnum, offset);
+                        FX_INT32 version = FXSYS_atoi(pEntry + 11);
+                        if (version >= 1) {
+                            m_bVersionUpdated = TRUE;
+                        }
+                        m_ObjVersion.SetAtGrow(objnum, version);
+                        if (m_CrossRef[objnum] < m_Syntax.m_FileLen) {
+                            FX_LPVOID pResult = FXSYS_bsearch(&m_CrossRef[objnum], m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
+                            if (pResult == NULL) {
+                                m_SortedOffset.Add(m_CrossRef[objnum]);
+                            }
+                        }
+                        m_V5Type.SetAtGrow(objnum, 1);
+                    }
+                    if (bFirstBlock) {
+                        bFirstBlock = FALSE;
+                    }
+                }
+            }
+            FX_Free(pBuf);
+        }
+        m_Syntax.RestorePos(SavedPos + count * recordsize);
+    }
+    if (streampos)
+        if (!LoadCrossRefV5(streampos, streampos, FALSE)) {
+            return FALSE;
+        }
+    return TRUE;
+}
+FX_BOOL CPDF_Parser::LoadAllCrossRefV5(FX_FILESIZE xrefpos)
+{
+    if (!LoadCrossRefV5(xrefpos, xrefpos, TRUE)) {
+        return FALSE;
+    }
+    while (xrefpos)
+        if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) {
+            return FALSE;
+        }
+    m_ObjectStreamMap.InitHashTable(101, FALSE);
+    m_bXRefStream = TRUE;
+    return TRUE;
+}
+FX_BOOL CPDF_Parser::RebuildCrossRef()
+{
+    m_CrossRef.RemoveAll();
+    m_V5Type.RemoveAll();
+    m_SortedOffset.RemoveAll();
+    m_ObjVersion.RemoveAll();
+    if (m_pTrailer) {
+        m_pTrailer->Release();
+        m_pTrailer = NULL;
+    }
+    FX_INT32 status = 0;
+    FX_INT32 inside_index = 0;
+    FX_DWORD objnum, gennum;
+    FX_INT32 depth = 0;
+    FX_LPBYTE buffer = FX_Alloc(FX_BYTE, 4096);
+    FX_FILESIZE pos = m_Syntax.m_HeaderOffset;
+    FX_FILESIZE start_pos, start_pos1;
+    FX_FILESIZE last_obj = -1, last_xref = -1, last_trailer = -1;
+    FX_BOOL bInUpdate = FALSE;
+    while (pos < m_Syntax.m_FileLen) {
+        FX_BOOL bOverFlow = FALSE;
+        FX_DWORD size = (FX_DWORD)(m_Syntax.m_FileLen - pos);
+        if (size > 4096) {
+            size = 4096;
+        }
+        if (!m_Syntax.m_pFileAccess->ReadBlock(buffer, pos, size)) {
+            break;
+        }
+        for (FX_DWORD i = 0; i < size; i ++) {
+            FX_BYTE byte = buffer[i];
+            FX_LPBYTE pData = buffer + i;
+            switch (status) {
+                case 0:
+                    if (_PDF_CharType[byte] == 'W') {
+                        status = 1;
+                    }
+                    if (byte <= '9' && byte >= '0') {
+                        --i;
+                        status = 1;
+                    }
+                    if (byte == '%') {
+                        inside_index = 0;
+                        status = 9;
+                    }
+                    if (byte == '(') {
+                        status = 10;
+                        depth = 1;
+                    }
+                    if (byte == '<') {
+                        inside_index = 1;
+                        status = 11;
+                    }
+                    if (byte == '\\') {
+                        status = 13;
+                    }
+                    if (byte == 't') {
+                        status = 7;
+                        inside_index = 1;
+                    }
+                    break;
+                case 1:
+                    if (_PDF_CharType[byte] == 'W') {
+                        break;
+                    } else if (byte <= '9' && byte >= '0') {
+                        start_pos = pos + i;
+                        status = 2;
+                        objnum = byte - '0';
+                    } else if (byte == 't') {
+                        status = 7;
+                        inside_index = 1;
+                    } else if (byte == 'x') {
+                        status = 8;
+                        inside_index = 1;
+                    } else {
+                        --i;
+                        status = 0;
+                    }
+                    break;
+                case 2:
+                    if (byte <= '9' && byte >= '0') {
+                        objnum = objnum * 10 + byte - '0';
+                        break;
+                    } else if (_PDF_CharType[byte] == 'W') {
+                        status = 3;
+                    } else {
+                        --i;
+                        status = 14;
+                        inside_index = 0;
+                    }
+                    break;
+                case 3:
+                    if (byte <= '9' && byte >= '0') {
+                        start_pos1 = pos + i;
+                        status = 4;
+                        gennum = byte - '0';
+                    } else if (_PDF_CharType[byte] == 'W') {
+                        break;
+                    } else if (byte == 't') {
+                        status = 7;
+                        inside_index = 1;
+                    } else {
+                        --i;
+                        status = 0;
+                    }
+                    break;
+                case 4:
+                    if (byte <= '9' && byte >= '0') {
+                        gennum = gennum * 10 + byte - '0';
+                        break;
+                    } else if (_PDF_CharType[byte] == 'W') {
+                        status = 5;
+                    } else {
+                        --i;
+                        status = 0;
+                    }
+                    break;
+                case 5:
+                    if (byte == 'o') {
+                        status = 6;
+                        inside_index = 1;
+                    } else if (_PDF_CharType[byte] == 'W') {
+                        break;
+                    } else if (byte <= '9' && byte >= '0') {
+                        objnum = gennum;
+                        gennum = byte - '0';
+                        start_pos = start_pos1;
+                        start_pos1 = pos + i;
+                        status = 4;
+                    } else if (byte == 't') {
+                        status = 7;
+                        inside_index = 1;
+                    } else {
+                        --i;
+                        status = 0;
+                    }
+                    break;
+                case 6:
+                    switch (inside_index) {
+                        case 1:
+                            if (byte != 'b') {
+                                --i;
+                                status = 0;
+                            } else {
+                                inside_index ++;
+                            }
+                            break;
+                        case 2:
+                            if (byte != 'j') {
+                                --i;
+                                status = 0;
+                            } else {
+                                inside_index ++;
+                            }
+                            break;
+                        case 3:
+                            if (_PDF_CharType[byte] == 'W' || _PDF_CharType[byte] == 'D') {
+                                if (objnum > 0x1000000) {
+                                    status = 0;
+                                    break;
+                                }
+                                FX_FILESIZE obj_pos = start_pos - m_Syntax.m_HeaderOffset;
+                                last_obj = start_pos;
+                                FX_LPVOID pResult = FXSYS_bsearch(&obj_pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
+                                if (pResult == NULL) {
+                                    m_SortedOffset.Add(obj_pos);
+                                }
+                                FX_FILESIZE obj_end = 0;
+                                CPDF_Object *pObject = ParseIndirectObjectAtByStrict(m_pDocument, obj_pos, objnum, NULL, &obj_end);
+                                if (pObject) {
+                                    int iType =        pObject->GetType();
+                                    if (iType == PDFOBJ_STREAM) {
+                                        CPDF_Stream* pStream = (CPDF_Stream*)pObject;
+                                        CPDF_Dictionary* pDict = pStream->GetDict();
+                                        if (pDict) {
+                                            if (pDict->KeyExist(FX_BSTRC("Type"))) {
+                                                CFX_ByteString bsValue = pDict->GetString(FX_BSTRC("Type"));
+                                                if (bsValue == FX_BSTRC("XRef") && pDict->KeyExist(FX_BSTRC("Size"))) {
+                                                    CPDF_Object* pRoot = pDict->GetElement(FX_BSTRC("Root"));
+                                                    if (pRoot && pRoot->GetDict() && pRoot->GetDict()->GetElement(FX_BSTRC("Pages"))) {
+                                                        if (m_pTrailer) {
+                                                            m_pTrailer->Release();
+                                                        }
+                                                        m_pTrailer = (CPDF_Dictionary*)pDict->Clone();
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                                FX_FILESIZE offset = 0;
+                                m_Syntax.RestorePos(obj_pos);
+                                offset = m_Syntax.FindTag(FX_BSTRC("obj"), 0);
+                                if (offset == -1) {
+                                    offset = 0;
+                                } else {
+                                    offset += 3;
+                                }
+                                FX_FILESIZE nLen = obj_end - obj_pos - offset;
+                                if ((FX_DWORD)nLen > size - i) {
+                                    pos = obj_end + m_Syntax.m_HeaderOffset;
+                                    bOverFlow = TRUE;
+                                } else {
+                                    i += (FX_DWORD)nLen;
+                                }
+                                if (m_CrossRef.GetSize() > (FX_INT32)objnum && m_CrossRef[objnum]) {
+                                    if (pObject) {
+                                        FX_DWORD oldgen = m_ObjVersion.GetAt(objnum);
+                                        m_CrossRef[objnum] = obj_pos;
+                                        m_ObjVersion.SetAt(objnum, (FX_SHORT)gennum);
+                                        if (oldgen != gennum) {
+                                            m_bVersionUpdated = TRUE;
+                                        }
+                                    }
+                                } else {
+                                    m_CrossRef.SetAtGrow(objnum, obj_pos);
+                                    m_V5Type.SetAtGrow(objnum, 1);
+                                    m_ObjVersion.SetAtGrow(objnum, (FX_SHORT)gennum);
+                                }
+                                if (pObject) {
+                                    pObject->Release();
+                                }
+                            }
+                            --i;
+                            status = 0;
+                            break;
+                    }
+                    break;
+                case 7:
+                    if (inside_index == 7) {
+                        if (_PDF_CharType[byte] == 'W' || _PDF_CharType[byte] == 'D') {
+                            last_trailer = pos + i - 7;
+                            m_Syntax.RestorePos(pos + i - m_Syntax.m_HeaderOffset);
+                            CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0);
+                            if (pObj) {
+                                if (pObj->GetType() != PDFOBJ_DICTIONARY && pObj->GetType() != PDFOBJ_STREAM) {
+                                    pObj->Release();
+                                } else {
+                                    CPDF_Dictionary* pTrailer = NULL;
+                                    if (pObj->GetType() == PDFOBJ_STREAM) {
+                                        pTrailer = ((CPDF_Stream*)pObj)->GetDict();
+                                    } else {
+                                        pTrailer = (CPDF_Dictionary*)pObj;
+                                    }
+                                    if (pTrailer) {
+                                        if (m_pTrailer) {
+                                            CPDF_Object* pRoot = pTrailer->GetElement(FX_BSTRC("Root"));
+                                            if (pRoot == NULL || (pRoot->GetType() == PDFOBJ_REFERENCE &&
+                                                                  (FX_DWORD)m_CrossRef.GetSize() > ((CPDF_Reference*)pRoot)->GetRefObjNum() &&
+                                                                  m_CrossRef.GetAt(((CPDF_Reference*)pRoot)->GetRefObjNum()) != 0)) {
+                                                FX_POSITION pos = pTrailer->GetStartPos();
+                                                while (pos) {
+                                                    CFX_ByteString key;
+                                                    CPDF_Object* pObj = pTrailer->GetNextElement(pos, key);
+                                                    m_pTrailer->SetAt(key, pObj->Clone(), m_pDocument);
+                                                }
+                                                pObj->Release();
+                                            } else {
+                                                pObj->Release();
+                                            }
+                                        } else {
+                                            if (pObj->GetType() == PDFOBJ_STREAM) {
+                                                m_pTrailer = (CPDF_Dictionary*)pTrailer->Clone();
+                                                pObj->Release();
+                                            } else {
+                                                m_pTrailer = pTrailer;
+                                            }
+                                            FX_FILESIZE dwSavePos = m_Syntax.SavePos();
+                                            CFX_ByteString strWord = m_Syntax.GetKeyword();
+                                            if (!strWord.Compare(FX_BSTRC("startxref"))) {
+                                                FX_BOOL bNumber = FALSE;
+                                                CFX_ByteString bsOffset = m_Syntax.GetNextWord(bNumber);
+                                                if (bNumber) {
+                                                    m_LastXRefOffset = FXSYS_atoi(bsOffset);
+                                                }
+                                            }
+                                            m_Syntax.RestorePos(dwSavePos);
+                                        }
+                                    } else {
+                                        pObj->Release();
+                                    }
+                                    bInUpdate = TRUE;
+                                }
+                            }
+                        }
+                        --i;
+                        status = 0;
+                    } else if (byte == "trailer"[inside_index]) {
+                        inside_index ++;
+                    } else {
+                        --i;
+                        status = 0;
+                    }
+                    break;
+                case 8:
+                    if (inside_index == 4) {
+                        last_xref = pos + i - 4;
+                        status = 1;
+                    } else if (byte == "xref"[inside_index]) {
+                        inside_index ++;
+                    } else {
+                        --i;
+                        status = 0;
+                    }
+                    break;
+                case 9:
+                    if (byte == '\r' || byte == '\n') {
+                        status = 0;
+                    }
+                    break;
+                case 10:
+                    if (byte == ')') {
+                        if (depth > 0) {
+                            depth--;
+                        }
+                    } else if (byte == '(') {
+                        depth++;
+                    }
+                    if (!depth) {
+                        status = 0;
+                    }
+                    break;
+                case 11:
+                    if (byte == '<' && inside_index == 1) {
+                        status = 12;
+                    } else if (byte == '>') {
+                        status = 0;
+                    }
+                    inside_index = 0;
+                    break;
+                case 12:
+                    --i;
+                    status = 0;
+                    break;
+                case 13:
+                    if (_PDF_CharType[byte] == 'D' || _PDF_CharType[byte] == 'W') {
+                        --i;
+                        status = 0;
+                    }
+                    break;
+                case 14:
+                    if (_PDF_CharType[byte] == 'W') {
+                        status = 0;
+                    } else if (byte == '%' || byte == '(' || byte == '<' || byte == '\\') {
+                        status = 0;
+                        --i;
+                    } else if (inside_index == 6) {
+                        status = 0;
+                        --i;
+                    } else if (byte == "endobj"[inside_index]) {
+                        inside_index++;
+                    }
+                    break;
+            }
+            if (bOverFlow) {
+                size = 0;
+                break;
+            }
+        }
+        pos += size;
+    }
+    if (last_xref != -1 && last_xref > last_obj) {
+        last_trailer = last_xref;
+    } else if (last_trailer == -1 || last_xref < last_obj) {
+        last_trailer = m_Syntax.m_FileLen;
+    }
+    FX_FILESIZE offset = last_trailer - m_Syntax.m_HeaderOffset;
+    FX_LPVOID pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
+    if (pResult == NULL) {
+        m_SortedOffset.Add(offset);
+    }
+    FX_Free(buffer);
+    return TRUE;
+}
+static FX_DWORD _GetVarInt(FX_LPCBYTE p, FX_INT32 n)
+{
+    FX_DWORD result = 0;
+    for (FX_INT32 i = 0; i < n; i ++) {
+        result = result * 256 + p[i];
+    }
+    return result;
+}
+FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE pos, FX_FILESIZE& prev, FX_BOOL bMainXRef)
+{
+    CPDF_Stream* pStream = (CPDF_Stream*)ParseIndirectObjectAt(m_pDocument, pos, 0, NULL);
+    if (!pStream) {
+        return FALSE;
+    }
+    if (m_pDocument) {
+        m_pDocument->InsertIndirectObject(pStream->m_ObjNum, pStream);
+    }
+    if (pStream->GetType() != PDFOBJ_STREAM) {
+        return FALSE;
+    }
+    prev = pStream->GetDict()->GetInteger(FX_BSTRC("Prev"));
+    FX_INT32 size = pStream->GetDict()->GetInteger(FX_BSTRC("Size"));
+    if (size < 0) {
+        pStream->Release();
+        return FALSE;
+    }
+    if (bMainXRef) {
+        m_pTrailer = (CPDF_Dictionary*)pStream->GetDict()->Clone();
+        m_CrossRef.SetSize(size);
+        if (m_V5Type.SetSize(size)) {
+            FXSYS_memset32(m_V5Type.GetData(), 0, size);
+        }
+    } else {
+        m_Trailers.Add((CPDF_Dictionary*)pStream->GetDict()->Clone());
+    }
+    CFX_DWordArray IndexArray, WidthArray;
+    FX_DWORD nSegs = 0;
+    CPDF_Array* pArray = pStream->GetDict()->GetArray(FX_BSTRC("Index"));
+    if (pArray == NULL) {
+        IndexArray.Add(0);
+        IndexArray.Add(size);
+        nSegs = 1;
+    } else {
+        for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) {
+            IndexArray.Add(pArray->GetInteger(i));
+        }
+        nSegs = pArray->GetCount() / 2;
+    }
+    pArray = pStream->GetDict()->GetArray(FX_BSTRC("W"));
+    if (pArray == NULL) {
+        pStream->Release();
+        return FALSE;
+    }
+    FX_DWORD totalwidth = 0;
+    FX_DWORD i;
+    for (i = 0; i < pArray->GetCount(); i ++) {
+        WidthArray.Add(pArray->GetInteger(i));
+        if (totalwidth + WidthArray[i] < totalwidth) {
+            pStream->Release();
+            return FALSE;
+        }
+        totalwidth += WidthArray[i];
+    }
+    if (totalwidth == 0 || WidthArray.GetSize() < 3) {
+        pStream->Release();
+        return FALSE;
+    }
+    CPDF_StreamAcc acc;
+    acc.LoadAllData(pStream);
+    FX_LPCBYTE pData = acc.GetData();
+    FX_DWORD dwTotalSize = acc.GetSize();
+    FX_DWORD segindex = 0;
+    for (i = 0; i < nSegs; i ++) {
+        FX_INT32 startnum = IndexArray[i * 2];
+        if (startnum < 0) {
+            continue;
+        }
+        m_dwXrefStartObjNum = startnum;
+        FX_DWORD count = IndexArray[i * 2 + 1];
+        if (segindex + count < segindex || segindex + count == 0 ||
+                (FX_DWORD)totalwidth >= UINT_MAX / (segindex + count) || (segindex + count) * (FX_DWORD)totalwidth > dwTotalSize) {
+            continue;
+        }
+        FX_LPCBYTE segstart = pData + segindex * (FX_DWORD)totalwidth;
+        if ((FX_DWORD)startnum + count < (FX_DWORD)startnum ||
+                (FX_DWORD)startnum + count > (FX_DWORD)m_V5Type.GetSize()) {
+            continue;
+        }
+        for (FX_DWORD j = 0; j < count; j ++) {
+            FX_INT32 type = 1;
+            FX_LPCBYTE entrystart = segstart + j * totalwidth;
+            if (WidthArray[0]) {
+                type = _GetVarInt(entrystart, WidthArray[0]);
+            }
+            if (m_V5Type[startnum + j] == 255) {
+                FX_FILESIZE offset = _GetVarInt(entrystart + WidthArray[0], WidthArray[1]);
+                m_CrossRef[startnum + j] = offset;
+                FX_LPVOID pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
+                if (pResult == NULL) {
+                    m_SortedOffset.Add(offset);
+                }
+                continue;
+            }
+            if (m_V5Type[startnum + j]) {
+                continue;
+            }
+            m_V5Type[startnum + j] = type;
+            if (type == 0) {
+                m_CrossRef[startnum + j] = 0;
+            } else {
+                FX_FILESIZE offset = _GetVarInt(entrystart + WidthArray[0], WidthArray[1]);
+                m_CrossRef[startnum + j] = offset;
+                if (type == 1) {
+                    FX_LPVOID pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
+                    if (pResult == NULL) {
+                        m_SortedOffset.Add(offset);
+                    }
+                } else {
+                    if (offset < 0 || offset >= m_V5Type.GetSize()) {
+                        pStream->Release();
+                        return FALSE;
+                    }
+                    m_V5Type[offset] = 255;
+                }
+            }
+        }
+        segindex += count;
+    }
+    pStream->Release();
+    return TRUE;
+}
+CPDF_Array* CPDF_Parser::GetIDArray()
+{
+    CPDF_Object* pID = m_pTrailer ? m_pTrailer->GetElement(FX_BSTRC("ID")) : NULL;
+    if (pID == NULL) {
+        return NULL;
+    }
+    if (pID->GetType() == PDFOBJ_REFERENCE) {
+        pID = ParseIndirectObject(NULL, ((CPDF_Reference*)pID)->GetRefObjNum());
+        m_pTrailer->SetAt(FX_BSTRC("ID"), pID);
+    }
+    if (pID == NULL || pID->GetType() != PDFOBJ_ARRAY) {
+        return NULL;
+    }
+    return (CPDF_Array*)pID;
+}
+FX_DWORD CPDF_Parser::GetRootObjNum()
+{
+    CPDF_Reference* pRef = m_pTrailer ? (CPDF_Reference*)m_pTrailer->GetElement(FX_BSTRC("Root")) : NULL;
+    if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {
+        return 0;
+    }
+    return pRef->GetRefObjNum();
+}
+FX_DWORD CPDF_Parser::GetInfoObjNum()
+{
+    CPDF_Reference* pRef = m_pTrailer ? (CPDF_Reference*)m_pTrailer->GetElement(FX_BSTRC("Info")) : NULL;
+    if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {
+        return 0;
+    }
+    return pRef->GetRefObjNum();
+}
+FX_BOOL CPDF_Parser::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm)
+{
+    bForm = FALSE;
+    if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
+        return TRUE;
+    }
+    if (m_V5Type[objnum] == 0) {
+        return TRUE;
+    }
+    if (m_V5Type[objnum] == 2) {
+        return TRUE;
+    }
+    FX_FILESIZE pos = m_CrossRef[objnum];
+    FX_LPVOID pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
+    if (pResult == NULL) {
+        return TRUE;
+    }
+    if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == m_SortedOffset.GetSize() - 1) {
+        return FALSE;
+    }
+    FX_FILESIZE size = ((FX_FILESIZE*)pResult)[1] - pos;
+    FX_FILESIZE SavedPos = m_Syntax.SavePos();
+    m_Syntax.RestorePos(pos);
+    bForm = m_Syntax.SearchMultiWord(FX_BSTRC("/Form\0stream"), TRUE, size) == 0;
+    m_Syntax.RestorePos(SavedPos);
+    return TRUE;
+}
+CPDF_Object* CPDF_Parser::ParseIndirectObject(CPDF_IndirectObjects* pObjList, FX_DWORD objnum, PARSE_CONTEXT* pContext)
+{
+    if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
+        return NULL;
+    }
+    if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) {
+        FX_FILESIZE pos = m_CrossRef[objnum];
+        if (pos <= 0) {
+            return NULL;
+        }
+        return ParseIndirectObjectAt(pObjList, pos, objnum, pContext);
+    }
+    if (m_V5Type[objnum] == 2) {
+        CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]);
+        if (pObjStream == NULL) {
+            return NULL;
+        }
+        FX_INT32 n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N"));
+        FX_INT32 offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First"));
+        CPDF_SyntaxParser syntax;
+        CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream((FX_LPBYTE)pObjStream->GetData(), (size_t)pObjStream->GetSize(), FALSE));
+        syntax.InitParser((IFX_FileStream*)file, 0);
+        CPDF_Object* pRet = NULL;
+        while (n) {
+            FX_DWORD thisnum = syntax.GetDirectNum();
+            FX_DWORD thisoff = syntax.GetDirectNum();
+            if (thisnum == objnum) {
+                syntax.RestorePos(offset + thisoff);
+                pRet = syntax.GetObject(pObjList, 0, 0, 0, pContext);
+                break;
+            }
+            n --;
+        }
+        return pRet;
+    }
+    return NULL;
+}
+CPDF_StreamAcc* CPDF_Parser::GetObjectStream(FX_DWORD objnum)
+{
+    CPDF_StreamAcc* pStreamAcc = NULL;
+    if (m_ObjectStreamMap.Lookup((void*)(FX_UINTPTR)objnum, (void*&)pStreamAcc)) {
+        return pStreamAcc;
+    }
+    const CPDF_Stream* pStream = (CPDF_Stream*)m_pDocument->GetIndirectObject(objnum);
+    if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) {
+        return NULL;
+    }
+    pStreamAcc = FX_NEW CPDF_StreamAcc;
+    pStreamAcc->LoadAllData(pStream);
+    m_ObjectStreamMap.SetAt((void*)(FX_UINTPTR)objnum, pStreamAcc);
+    return pStreamAcc;
+}
+FX_FILESIZE CPDF_Parser::GetObjectSize(FX_DWORD objnum)
+{
+    if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
+        return 0;
+    }
+    if (m_V5Type[objnum] == 2) {
+        objnum = (FX_DWORD)m_CrossRef[objnum];
+    }
+    if (m_V5Type[objnum] == 1 || m_V5Type[objnum] == 255) {
+        FX_FILESIZE offset = m_CrossRef[objnum];
+        if (offset == 0) {
+            return 0;
+        }
+        FX_LPVOID pResult = FXSYS_bsearch(&offset, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
+        if (pResult == NULL) {
+            return 0;
+        }
+        if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)m_SortedOffset.GetData() == m_SortedOffset.GetSize() - 1) {
+            return 0;
+        }
+        return ((FX_FILESIZE*)pResult)[1] - offset;
+    }
+    return 0;
+}
+void CPDF_Parser::GetIndirectBinary(FX_DWORD objnum, FX_LPBYTE& pBuffer, FX_DWORD& size)
+{
+    pBuffer = NULL;
+    size = 0;
+    if (objnum >= (FX_DWORD)m_CrossRef.GetSize()) {
+        return;
+    }
+    if (m_V5Type[objnum] == 2) {
+        CPDF_StreamAcc* pObjStream = GetObjectStream((FX_DWORD)m_CrossRef[objnum]);
+        if (pObjStream == NULL) {
+            return;
+        }
+        FX_INT32 n = pObjStream->GetDict()->GetInteger(FX_BSTRC("N"));
+        FX_INT32 offset = pObjStream->GetDict()->GetInteger(FX_BSTRC("First"));
+        CPDF_SyntaxParser syntax;
+        FX_LPCBYTE pData = pObjStream->GetData();
+        FX_DWORD totalsize = pObjStream->GetSize();
+        CFX_SmartPointer<IFX_FileStream> file(FX_CreateMemoryStream((FX_LPBYTE)pData, (size_t)totalsize, FALSE));
+        syntax.InitParser((IFX_FileStream*)file, 0);
+        while (n) {
+            FX_DWORD thisnum = syntax.GetDirectNum();
+            FX_DWORD thisoff = syntax.GetDirectNum();
+            if (thisnum == objnum) {
+                if (n == 1) {
+                    size = totalsize - (thisoff + offset);
+                } else {
+                    FX_DWORD nextnum = syntax.GetDirectNum();
+                    FX_DWORD nextoff = syntax.GetDirectNum();
+                    size = nextoff - thisoff;
+                }
+                pBuffer = FX_Alloc(FX_BYTE, size);
+                FXSYS_memcpy32(pBuffer, pData + thisoff + offset, size);
+                return;
+            }
+            n --;
+        }
+        return;
+    }
+    if (m_V5Type[objnum] == 1) {
+        FX_FILESIZE pos = m_CrossRef[objnum];
+        if (pos == 0) {
+            return;
+        }
+        FX_FILESIZE SavedPos = m_Syntax.SavePos();
+        m_Syntax.RestorePos(pos);
+        FX_BOOL bIsNumber;
+        CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
+        if (!bIsNumber) {
+            m_Syntax.RestorePos(SavedPos);
+            return;
+        }
+        FX_DWORD real_objnum = FXSYS_atoi(word);
+        if (real_objnum && real_objnum != objnum) {
+            m_Syntax.RestorePos(SavedPos);
+            return;
+        }
+        word = m_Syntax.GetNextWord(bIsNumber);
+        if (!bIsNumber) {
+            m_Syntax.RestorePos(SavedPos);
+            return;
+        }
+        if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {
+            m_Syntax.RestorePos(SavedPos);
+            return;
+        }
+        FX_LPVOID pResult = FXSYS_bsearch(&pos, m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
+        if (pResult == NULL) {
+            m_Syntax.RestorePos(SavedPos);
+            return;
+        }
+        FX_FILESIZE nextoff = ((FX_FILESIZE*)pResult)[1];
+        FX_BOOL bNextOffValid = FALSE;
+        if (nextoff != pos) {
+            m_Syntax.RestorePos(nextoff);
+            word = m_Syntax.GetNextWord(bIsNumber);
+            if (word == FX_BSTRC("xref")) {
+                bNextOffValid = TRUE;
+            } else if (bIsNumber) {
+                word = m_Syntax.GetNextWord(bIsNumber);
+                if (bIsNumber && m_Syntax.GetKeyword() == FX_BSTRC("obj")) {
+                    bNextOffValid = TRUE;
+                }
+            }
+        }
+        if (!bNextOffValid) {
+            m_Syntax.RestorePos(pos);
+            while (1) {
+                if (m_Syntax.GetKeyword() == FX_BSTRC("endobj")) {
+                    break;
+                }
+                if (m_Syntax.SavePos() == m_Syntax.m_FileLen) {
+                    break;
+                }
+            }
+            nextoff = m_Syntax.SavePos();
+        }
+        size = (FX_DWORD)(nextoff - pos);
+        pBuffer = FX_Alloc(FX_BYTE, size);
+        m_Syntax.RestorePos(pos);
+        m_Syntax.ReadBlock(pBuffer, size);
+        m_Syntax.RestorePos(SavedPos);
+    }
+}
+CPDF_Object* CPDF_Parser::ParseIndirectObjectAt(CPDF_IndirectObjects* pObjList, FX_FILESIZE pos, FX_DWORD objnum,
+        PARSE_CONTEXT* pContext)
+{
+    FX_FILESIZE SavedPos = m_Syntax.SavePos();
+    m_Syntax.RestorePos(pos);
+    FX_BOOL bIsNumber;
+    CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
+    if (!bIsNumber) {
+        m_Syntax.RestorePos(SavedPos);
+        return NULL;
+    }
+    FX_FILESIZE objOffset = m_Syntax.SavePos();
+    objOffset -= word.GetLength();
+    FX_DWORD real_objnum = FXSYS_atoi(word);
+    if (objnum && real_objnum != objnum) {
+        m_Syntax.RestorePos(SavedPos);
+        return NULL;
+    }
+    word = m_Syntax.GetNextWord(bIsNumber);
+    if (!bIsNumber) {
+        m_Syntax.RestorePos(SavedPos);
+        return NULL;
+    }
+    FX_DWORD gennum = FXSYS_atoi(word);
+    if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {
+        m_Syntax.RestorePos(SavedPos);
+        return NULL;
+    }
+    CPDF_Object* pObj = m_Syntax.GetObject(pObjList, objnum, gennum, 0, pContext);
+    FX_FILESIZE endOffset = m_Syntax.SavePos();
+    CFX_ByteString bsWord = m_Syntax.GetKeyword();
+    if (bsWord == FX_BSTRC("endobj")) {
+        endOffset = m_Syntax.SavePos();
+    }
+    FX_DWORD objSize = endOffset - objOffset;
+    m_Syntax.RestorePos(SavedPos);
+    if (pObj && !objnum) {
+        pObj->m_ObjNum = real_objnum;
+    }
+    return pObj;
+}
+CPDF_Object* CPDF_Parser::ParseIndirectObjectAtByStrict(CPDF_IndirectObjects* pObjList, FX_FILESIZE pos, FX_DWORD objnum,
+        struct PARSE_CONTEXT* pContext, FX_FILESIZE *pResultPos)
+{
+    FX_FILESIZE SavedPos = m_Syntax.SavePos();
+    m_Syntax.RestorePos(pos);
+    FX_BOOL bIsNumber;
+    CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
+    if (!bIsNumber) {
+        m_Syntax.RestorePos(SavedPos);
+        return NULL;
+    }
+    FX_DWORD real_objnum = FXSYS_atoi(word);
+    if (objnum && real_objnum != objnum) {
+        m_Syntax.RestorePos(SavedPos);
+        return NULL;
+    }
+    word = m_Syntax.GetNextWord(bIsNumber);
+    if (!bIsNumber) {
+        m_Syntax.RestorePos(SavedPos);
+        return NULL;
+    }
+    FX_DWORD gennum = FXSYS_atoi(word);
+    if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {
+        m_Syntax.RestorePos(SavedPos);
+        return NULL;
+    }
+    CPDF_Object* pObj = m_Syntax.GetObjectByStrict(pObjList, objnum, gennum, 0, pContext);
+    if (pResultPos) {
+        *pResultPos = m_Syntax.m_Pos;
+    }
+    m_Syntax.RestorePos(SavedPos);
+    return pObj;
+}
+CPDF_Dictionary* CPDF_Parser::LoadTrailerV4()
+{
+    if (m_Syntax.GetKeyword() != FX_BSTRC("trailer")) {
+        return NULL;
+    }
+    CPDF_Object* pObj = m_Syntax.GetObject(m_pDocument, 0, 0, 0);
+    if (pObj == NULL || pObj->GetType() != PDFOBJ_DICTIONARY) {
+        if (pObj) {
+            pObj->Release();
+        }
+        return NULL;
+    }
+    return (CPDF_Dictionary*)pObj;
+}
+FX_DWORD CPDF_Parser::GetPermissions(FX_BOOL bCheckRevision)
+{
+    if (m_pSecurityHandler == NULL) {
+        return (FX_DWORD) - 1;
+    }
+    FX_DWORD dwPermission = m_pSecurityHandler->GetPermissions();
+    if (m_pEncryptDict && m_pEncryptDict->GetString(FX_BSTRC("Filter")) == FX_BSTRC("Standard")) {
+        dwPermission &= 0xFFFFFFFC;
+        dwPermission |= 0xFFFFF0C0;
+        if(bCheckRevision && m_pEncryptDict->GetInteger(FX_BSTRC("R")) == 2) {
+            dwPermission &= 0xFFFFF0FF;
+        }
+    }
+    return dwPermission;
+}
+FX_BOOL CPDF_Parser::IsOwner()
+{
+    return m_pSecurityHandler == NULL ? TRUE : m_pSecurityHandler->IsOwner();
+}
+void CPDF_Parser::SetSecurityHandler(CPDF_SecurityHandler* pSecurityHandler, FX_BOOL bForced)
+{
+    ASSERT(m_pSecurityHandler == NULL);
+    if (m_pSecurityHandler && !m_bForceUseSecurityHandler) {
+        delete m_pSecurityHandler;
+        m_pSecurityHandler = NULL;
+    }
+    m_bForceUseSecurityHandler = bForced;
+    m_pSecurityHandler = pSecurityHandler;
+    if (m_bForceUseSecurityHandler) {
+        return;
+    }
+    m_Syntax.m_pCryptoHandler = pSecurityHandler->CreateCryptoHandler();
+    m_Syntax.m_pCryptoHandler->Init(NULL, pSecurityHandler);
+}
+FX_BOOL CPDF_Parser::IsLinearizedFile(IFX_FileRead* pFileAccess, FX_DWORD offset)
+{
+    m_Syntax.InitParser(pFileAccess, offset);
+    m_Syntax.RestorePos(m_Syntax.m_HeaderOffset + 9);
+    FX_FILESIZE SavedPos = m_Syntax.SavePos();
+    FX_BOOL bIsNumber;
+    CFX_ByteString word = m_Syntax.GetNextWord(bIsNumber);
+    if (!bIsNumber) {
+        return FALSE;
+    }
+    FX_DWORD objnum = FXSYS_atoi(word);
+    word = m_Syntax.GetNextWord(bIsNumber);
+    if (!bIsNumber) {
+        return FALSE;
+    }
+    FX_DWORD gennum = FXSYS_atoi(word);
+    if (m_Syntax.GetKeyword() != FX_BSTRC("obj")) {
+        m_Syntax.RestorePos(SavedPos);
+        return FALSE;
+    }
+    m_pLinearized = m_Syntax.GetObject(NULL, objnum, gennum, 0);
+    if (!m_pLinearized) {
+        return FALSE;
+    }
+    if (m_pLinearized->GetDict() && m_pLinearized->GetDict()->GetElement(FX_BSTRC("Linearized"))) {
+        m_Syntax.GetNextWord(bIsNumber);
+        CPDF_Object *pLen = m_pLinearized->GetDict()->GetElement(FX_BSTRC("L"));
+        if (!pLen) {
+            m_pLinearized->Release();
+            return FALSE;
+        }
+        if (pLen->GetInteger() != (int)pFileAccess->GetSize()) {
+            return FALSE;
+        }
+        CPDF_Object *pNo = m_pLinearized->GetDict()->GetElement(FX_BSTRC("P"));
+        if (pNo && pNo->GetType() == PDFOBJ_NUMBER) {
+            m_dwFirstPageNo = pNo->GetInteger();
+        }
+        CPDF_Object *pTable = m_pLinearized->GetDict()->GetElement(FX_BSTRC("T"));
+        if (pTable && pTable->GetType() == PDFOBJ_NUMBER) {
+            m_LastXRefOffset = pTable->GetInteger();
+        }
+        return TRUE;
+    }
+    m_pLinearized->Release();
+    m_pLinearized = NULL;
+    return FALSE;
+}
+FX_DWORD CPDF_Parser::StartAsynParse(IFX_FileRead* pFileAccess, FX_BOOL bReParse, FX_BOOL bOwnFileRead)
+{
+    CloseParser(bReParse);
+    m_bXRefStream = FALSE;
+    m_LastXRefOffset = 0;
+    m_bOwnFileRead = bOwnFileRead;
+    FX_INT32 offset = GetHeaderOffset(pFileAccess);
+    if (offset == -1) {
+        return PDFPARSE_ERROR_FORMAT;
+    }
+    if (!IsLinearizedFile(pFileAccess, offset)) {
+        m_Syntax.m_pFileAccess = NULL;
+        return StartParse(pFileAccess, bReParse, bOwnFileRead);
+    }
+    if (!bReParse) {
+        m_pDocument = FX_NEW CPDF_Document(this);
+    }
+    FX_FILESIZE dwFirstXRefOffset = m_Syntax.SavePos();
+    FX_BOOL bXRefRebuilt = FALSE;
+    FX_BOOL bLoadV4 = FALSE;
+    if (!(bLoadV4 = LoadCrossRefV4(dwFirstXRefOffset, 0, FALSE, FALSE)) && !LoadCrossRefV5(dwFirstXRefOffset, dwFirstXRefOffset, TRUE)) {
+        if (!RebuildCrossRef()) {
+            return PDFPARSE_ERROR_FORMAT;
+        }
+        bXRefRebuilt = TRUE;
+        m_LastXRefOffset = 0;
+    }
+    if (bLoadV4) {
+        m_pTrailer = LoadTrailerV4();
+        if (m_pTrailer == NULL) {
+            return FALSE;
+        }
+        FX_INT32 xrefsize = GetDirectInteger(m_pTrailer, FX_BSTRC("Size"));
+        if (xrefsize == 0) {
+            return FALSE;
+        }
+        m_CrossRef.SetSize(xrefsize);
+        m_V5Type.SetSize(xrefsize);
+    }
+    FX_DWORD dwRet = SetEncryptHandler();
+    if (dwRet != PDFPARSE_ERROR_SUCCESS) {
+        return dwRet;
+    }
+    m_pDocument->LoadAsynDoc(m_pLinearized->GetDict());
+    if (m_pDocument->GetRoot() == NULL || m_pDocument->GetPageCount() == 0) {
+        if (bXRefRebuilt) {
+            return PDFPARSE_ERROR_FORMAT;
+        }
+        ReleaseEncryptHandler();
+        if (!RebuildCrossRef()) {
+            return PDFPARSE_ERROR_FORMAT;
+        }
+        dwRet = SetEncryptHandler();
+        if (dwRet != PDFPARSE_ERROR_SUCCESS) {
+            return dwRet;
+        }
+        m_pDocument->LoadAsynDoc(m_pLinearized->GetDict());
+        if (m_pDocument->GetRoot() == NULL) {
+            return PDFPARSE_ERROR_FORMAT;
+        }
+    }
+    FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
+    FX_DWORD RootObjNum = GetRootObjNum();
+    if (RootObjNum == 0) {
+        ReleaseEncryptHandler();
+        RebuildCrossRef();
+        RootObjNum = GetRootObjNum();
+        if (RootObjNum == 0) {
+            return PDFPARSE_ERROR_FORMAT;
+        }
+        dwRet = SetEncryptHandler();
+        if (dwRet != PDFPARSE_ERROR_SUCCESS) {
+            return dwRet;
+        }
+    }
+    if (m_pSecurityHandler && m_pSecurityHandler->IsMetadataEncrypted()) {
+        CPDF_Reference* pMetadata = (CPDF_Reference*)m_pDocument->GetRoot()->GetElement(FX_BSTRC("Metadata"));
+        if (pMetadata && pMetadata->GetType() == PDFOBJ_REFERENCE) {
+            m_Syntax.m_MetadataObjnum = pMetadata->GetRefObjNum();
+        }
+    }
+    return PDFPARSE_ERROR_SUCCESS;
+}
+FX_BOOL CPDF_Parser::LoadLinearizedAllCrossRefV5(FX_FILESIZE xrefpos)
+{
+    if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) {
+        return FALSE;
+    }
+    while (xrefpos)
+        if (!LoadCrossRefV5(xrefpos, xrefpos, FALSE)) {
+            return FALSE;
+        }
+    m_ObjectStreamMap.InitHashTable(101, FALSE);
+    m_bXRefStream = TRUE;
+    return TRUE;
+}
+FX_DWORD CPDF_Parser::LoadLinearizedMainXRefTable()
+{
+    FX_DWORD dwSaveMetadataObjnum = m_Syntax.m_MetadataObjnum;
+    m_Syntax.m_MetadataObjnum = 0;
+    if (m_pTrailer) {
+        m_pTrailer->Release();
+        m_pTrailer = NULL;
+    }
+    m_Syntax.RestorePos(m_LastXRefOffset - m_Syntax.m_HeaderOffset);
+    FX_FILESIZE dwSavedPos = m_Syntax.SavePos();
+    FX_BYTE ch = 0;
+    FX_DWORD dwCount = 0;
+    m_Syntax.GetNextChar(ch);
+    FX_INT32 type = _PDF_CharType[ch];
+    while (type == 'W') {
+        ++dwCount;
+        if (m_Syntax.m_FileLen >= (FX_FILESIZE)(m_Syntax.SavePos() + m_Syntax.m_HeaderOffset)) {
+            break;
+        }
+        m_Syntax.GetNextChar(ch);
+        type = _PDF_CharType[ch];
+    }
+    m_LastXRefOffset += dwCount;
+    FX_POSITION pos = m_ObjectStreamMap.GetStartPosition();
+    while (pos) {
+        FX_LPVOID objnum;
+        CPDF_StreamAcc* pStream;
+        m_ObjectStreamMap.GetNextAssoc(pos, objnum, (void*&)pStream);
+        delete pStream;
+    }
+    m_ObjectStreamMap.RemoveAll();
+    if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) {
+        m_LastXRefOffset = 0;
+        m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum;
+        return PDFPARSE_ERROR_FORMAT;
+    }
+    FXSYS_qsort(m_SortedOffset.GetData(), m_SortedOffset.GetSize(), sizeof(FX_DWORD), _CompareDWord);
+    m_Syntax.m_MetadataObjnum = dwSaveMetadataObjnum;
+    return PDFPARSE_ERROR_SUCCESS;
+}
+CPDF_SyntaxParser::CPDF_SyntaxParser()
+{
+    m_pFileAccess = NULL;
+    m_pCryptoHandler = NULL;
+    m_pFileBuf = NULL;
+    m_BufSize = CPDF_ModuleMgr::Get()->m_FileBufSize;
+    m_pFileBuf = NULL;
+    m_MetadataObjnum = 0;
+    m_dwWordPos = 0;
+#if defined(_FPDFAPI_MINI_)
+    m_bFileStream = TRUE;
+#else
+    m_bFileStream = FALSE;
+#endif
+}
+CPDF_SyntaxParser::~CPDF_SyntaxParser()
+{
+    if (m_pFileBuf) {
+        FX_Free(m_pFileBuf);
+    }
+}
+FX_BOOL CPDF_SyntaxParser::GetCharAt(FX_FILESIZE pos, FX_BYTE& ch)
+{
+    FX_FILESIZE save_pos = m_Pos;
+    m_Pos = pos;
+    FX_BOOL ret = GetNextChar(ch);
+    m_Pos = save_pos;
+    return ret;
+}
+FX_BOOL CPDF_SyntaxParser::GetNextChar(FX_BYTE& ch)
+{
+    FX_FILESIZE pos = m_Pos + m_HeaderOffset;
+    if (pos >= m_FileLen) {
+        return FALSE;
+    }
+    if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) {
+        FX_FILESIZE read_pos = pos;
+        FX_DWORD read_size = m_BufSize;
+        if ((FX_FILESIZE)read_size > m_FileLen) {
+            read_size = (FX_DWORD)m_FileLen;
+        }
+        if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) {
+            if (m_FileLen < (FX_FILESIZE)read_size) {
+                read_pos = 0;
+                read_size = (FX_DWORD)m_FileLen;
+            } else {
+                read_pos = m_FileLen - read_size;
+            }
+        }
+        if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) {
+            return FALSE;
+        }
+        m_BufOffset = read_pos;
+    }
+    ch = m_pFileBuf[pos - m_BufOffset];
+    m_Pos ++;
+    return TRUE;
+}
+FX_BOOL CPDF_SyntaxParser::GetCharAtBackward(FX_FILESIZE pos, FX_BYTE& ch)
+{
+    pos += m_HeaderOffset;
+    if (pos >= m_FileLen) {
+        return FALSE;
+    }
+    if (m_BufOffset >= pos || (FX_FILESIZE)(m_BufOffset + m_BufSize) <= pos) {
+        FX_FILESIZE read_pos;
+        if (pos < (FX_FILESIZE)m_BufSize) {
+            read_pos = 0;
+        } else {
+            read_pos = pos - m_BufSize + 1;
+        }
+        FX_DWORD read_size = m_BufSize;
+        if ((FX_FILESIZE)(read_pos + read_size) > m_FileLen) {
+            if (m_FileLen < (FX_FILESIZE)read_size) {
+                read_pos = 0;
+                read_size = (FX_DWORD)m_FileLen;
+            } else {
+                read_pos = m_FileLen - read_size;
+            }
+        }
+        if (!m_pFileAccess->ReadBlock(m_pFileBuf, read_pos, read_size)) {
+            return FALSE;
+        }
+        m_BufOffset = read_pos;
+    }
+    ch = m_pFileBuf[pos - m_BufOffset];
+    return TRUE;
+}
+FX_BOOL CPDF_SyntaxParser::ReadBlock(FX_LPBYTE pBuf, FX_DWORD size)
+{
+    if (!m_pFileAccess->ReadBlock(pBuf, m_Pos + m_HeaderOffset, size)) {
+        return FALSE;
+    }
+    m_Pos += size;
+    return TRUE;
+}
+#define MAX_WORD_BUFFER 256
+void CPDF_SyntaxParser::GetNextWord()
+{
+    m_WordSize = 0;
+    m_bIsNumber = TRUE;
+    FX_BYTE ch;
+    if (!GetNextChar(ch)) {
+        return;
+    }
+    FX_BYTE type = _PDF_CharType[ch];
+    while (1) {
+        while (type == 'W') {
+            if (!GetNextChar(ch)) {
+                return;
+            }
+            type = _PDF_CharType[ch];
+        }
+        if (ch != '%') {
+            break;
+        }
+        while (1) {
+            if (!GetNextChar(ch)) {
+                return;
+            }
+            if (ch == '\r' || ch == '\n') {
+                break;
+            }
+        }
+        type = _PDF_CharType[ch];
+    }
+    if (type == 'D') {
+        m_bIsNumber = FALSE;
+        m_WordBuffer[m_WordSize++] = ch;
+        if (ch == '/') {
+            while (1) {
+                if (!GetNextChar(ch)) {
+                    return;
+                }
+                type = _PDF_CharType[ch];
+                if (type != 'R' && type != 'N') {
+                    m_Pos --;
+                    return;
+                }
+                if (m_WordSize < MAX_WORD_BUFFER) {
+                    m_WordBuffer[m_WordSize++] = ch;
+                }
+            }
+        } else if (ch == '<') {
+            if (!GetNextChar(ch)) {
+                return;
+            }
+            if (ch == '<') {
+                m_WordBuffer[m_WordSize++] = ch;
+            } else {
+                m_Pos --;
+            }
+        } else if (ch == '>') {
+            if (!GetNextChar(ch)) {
+                return;
+            }
+            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 (type != 'N') {
+            m_bIsNumber = FALSE;
+        }
+        if (!GetNextChar(ch)) {
+            return;
+        }
+        type = _PDF_CharType[ch];
+        if (type == 'D' || type == 'W') {
+            m_Pos --;
+            break;
+        }
+    }
+}
+CFX_ByteString CPDF_SyntaxParser::ReadString()
+{
+    FX_BYTE ch;
+    if (!GetNextChar(ch)) {
+        return CFX_ByteString();
+    }
+    CFX_ByteTextBuf buf;
+    FX_INT32 parlevel = 0;
+    FX_INT32 status = 0, iEscCode = 0;
+    while (1) {
+        switch (status) {
+            case 0:
+                if (ch == ')') {
+                    if (parlevel == 0) {
+                        return buf.GetByteString();
+                    }
+                    parlevel --;
+                    buf.AppendChar(')');
+                } else if (ch == '(') {
+                    parlevel ++;
+                    buf.AppendChar('(');
+                } else if (ch == '\\') {
+                    status = 1;
+                } else {
+                    buf.AppendChar(ch);
+                }
+                break;
+            case 1:
+                if (ch >= '0' && ch <= '7') {
+                    iEscCode = ch - '0';
+                    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 + ch - '0';
+                    status = 3;
+                } else {
+                    buf.AppendChar(iEscCode);
+                    status = 0;
+                    continue;
+                }
+                break;
+            case 3:
+                if (ch >= '0' && ch <= '7') {
+                    iEscCode = iEscCode * 8 + ch - '0';
+                    buf.AppendChar(iEscCode);
+                    status = 0;
+                } else {
+                    buf.AppendChar(iEscCode);
+                    status = 0;
+                    continue;
+                }
+                break;
+            case 4:
+                status = 0;
+                if (ch != '\n') {
+                    continue;
+                }
+                break;
+        }
+        if (!GetNextChar(ch)) {
+            break;
+        }
+    }
+    GetNextChar(ch);
+    return buf.GetByteString();
+}
+CFX_ByteString CPDF_SyntaxParser::ReadHexString()
+{
+    FX_BYTE ch;
+    if (!GetNextChar(ch)) {
+        return CFX_ByteString();
+    }
+    CFX_BinaryBuf buf;
+    FX_BOOL bFirst = TRUE;
+    FX_BYTE code = 0;
+    while (1) {
+        if (ch == '>') {
+            break;
+        }
+        if (ch >= '0' && ch <= '9') {
+            if (bFirst) {
+                code = (ch - '0') * 16;
+            } else {
+                code += ch - '0';
+                buf.AppendByte((FX_BYTE)code);
+            }
+            bFirst = !bFirst;
+        } else if (ch >= 'A' && ch <= 'F') {
+            if (bFirst) {
+                code = (ch - 'A' + 10) * 16;
+            } else {
+                code += ch - 'A' + 10;
+                buf.AppendByte((FX_BYTE)code);
+            }
+            bFirst = !bFirst;
+        } else if (ch >= 'a' && ch <= 'f') {
+            if (bFirst) {
+                code = (ch - 'a' + 10) * 16;
+            } else {
+                code += ch - 'a' + 10;
+                buf.AppendByte((FX_BYTE)code);
+            }
+            bFirst = !bFirst;
+        }
+        if (!GetNextChar(ch)) {
+            break;
+        }
+    }
+    if (!bFirst) {
+        buf.AppendByte((FX_BYTE)code);
+    }
+    return buf.GetByteString();
+}
+void CPDF_SyntaxParser::ToNextLine()
+{
+    FX_BYTE ch;
+    while (1) {
+        if (!GetNextChar(ch)) {
+            return;
+        }
+        if (ch == '\n') {
+            return;
+        }
+        if (ch == '\r') {
+            GetNextChar(ch);
+            if (ch == '\n') {
+                return;
+            } else {
+                m_Pos --;
+                return;
+            }
+        }
+    }
+}
+void CPDF_SyntaxParser::ToNextWord()
+{
+    FX_BYTE ch;
+    if (!GetNextChar(ch)) {
+        return;
+    }
+    FX_BYTE type = _PDF_CharType[ch];
+    while (1) {
+        while (type == 'W') {
+            m_dwWordPos = m_Pos;
+            if (!GetNextChar(ch)) {
+                return;
+            }
+            type = _PDF_CharType[ch];
+        }
+        if (ch != '%') {
+            break;
+        }
+        while (1) {
+            if (!GetNextChar(ch)) {
+                return;
+            }
+            if (ch == '\r' || ch == '\n') {
+                break;
+            }
+        }
+        type = _PDF_CharType[ch];
+    }
+    m_Pos --;
+}
+CFX_ByteString CPDF_SyntaxParser::GetNextWord(FX_BOOL& bIsNumber)
+{
+    GetNextWord();
+    bIsNumber = m_bIsNumber;
+    return CFX_ByteString((FX_LPCSTR)m_WordBuffer, m_WordSize);
+}
+CFX_ByteString CPDF_SyntaxParser::GetKeyword()
+{
+    GetNextWord();
+    return CFX_ByteString((FX_LPCSTR)m_WordBuffer, m_WordSize);
+}
+CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjects* pObjList, FX_DWORD objnum, FX_DWORD gennum, FX_INT32 level, PARSE_CONTEXT* pContext, FX_BOOL bDecrypt)
+{
+    if (level > _PARSER_OBJECT_LEVLE_) {
+        return NULL;
+    }
+    FX_FILESIZE SavedPos = m_Pos;
+    FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY);
+    FX_BOOL bIsNumber;
+    CFX_ByteString word = GetNextWord(bIsNumber);
+    CPDF_Object* pRet = NULL;
+    if (word.GetLength() == 0) {
+        if (bTypeOnly) {
+            return (CPDF_Object*)PDFOBJ_INVALID;
+        }
+        return NULL;
+    }
+    FX_FILESIZE wordOffset = m_Pos - word.GetLength();
+    if (bIsNumber) {
+        FX_FILESIZE SavedPos = m_Pos;
+        CFX_ByteString nextword = GetNextWord(bIsNumber);
+        if (bIsNumber) {
+            CFX_ByteString nextword2 = GetNextWord(bIsNumber);
+            if (nextword2 == FX_BSTRC("R")) {
+                FX_DWORD objnum = FXSYS_atoi(word);
+                if (bTypeOnly) {
+                    return (CPDF_Object*)PDFOBJ_REFERENCE;
+                }
+                pRet = CPDF_Reference::Create(pObjList, objnum);
+                return pRet;
+            } else {
+                m_Pos = SavedPos;
+                if (bTypeOnly) {
+                    return (CPDF_Object*)PDFOBJ_NUMBER;
+                }
+                pRet = CPDF_Number::Create(word);
+                return pRet;
+            }
+        } else {
+            m_Pos = SavedPos;
+            if (bTypeOnly) {
+                return (CPDF_Object*)PDFOBJ_NUMBER;
+            }
+            pRet = CPDF_Number::Create(word);
+            return pRet;
+        }
+    }
+    if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) {
+        if (bTypeOnly) {
+            return (CPDF_Object*)PDFOBJ_BOOLEAN;
+        }
+        pRet = CPDF_Boolean::Create(word == FX_BSTRC("true"));
+        return pRet;
+    }
+    if (word == FX_BSTRC("null")) {
+        if (bTypeOnly) {
+            return (CPDF_Object*)PDFOBJ_NULL;
+        }
+        pRet = CPDF_Null::Create();
+        return pRet;
+    }
+    if (word == FX_BSTRC("(")) {
+        if (bTypeOnly) {
+            return (CPDF_Object*)PDFOBJ_STRING;
+        }
+        FX_FILESIZE SavedPos = m_Pos - 1;
+        CFX_ByteString str = ReadString();
+        if (m_pCryptoHandler && bDecrypt) {
+            m_pCryptoHandler->Decrypt(objnum, gennum, str);
+        }
+        pRet = CPDF_String::Create(str, FALSE);
+        return pRet;
+    }
+    if (word == FX_BSTRC("<")) {
+        if (bTypeOnly) {
+            return (CPDF_Object*)PDFOBJ_STRING;
+        }
+        FX_FILESIZE SavedPos = m_Pos - 1;
+        CFX_ByteString str = ReadHexString();
+        if (m_pCryptoHandler && bDecrypt) {
+            m_pCryptoHandler->Decrypt(objnum, gennum, str);
+        }
+        pRet = CPDF_String::Create(str, TRUE);
+        return pRet;
+    }
+    if (word == FX_BSTRC("[")) {
+        if (bTypeOnly) {
+            return (CPDF_Object*)PDFOBJ_ARRAY;
+        }
+        CPDF_Array* pArray = CPDF_Array::Create();
+        FX_FILESIZE firstPos = m_Pos - 1;
+        while (1) {
+            FX_FILESIZE SavedPos = m_Pos;
+            CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, level + 1);
+            if (pObj == NULL) {
+                return pArray;
+            }
+            pArray->Add(pObj);
+        }
+    }
+    if (word[0] == '/') {
+        if (bTypeOnly) {
+            return (CPDF_Object*)PDFOBJ_NAME;
+        }
+        pRet = CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)));
+        return pRet;
+    }
+    if (word == FX_BSTRC("<<")) {
+        FX_FILESIZE saveDictOffset = m_Pos - 2;
+        FX_DWORD dwDictSize = 0;
+        if (bTypeOnly) {
+            return (CPDF_Object*)PDFOBJ_DICTIONARY;
+        }
+        if (pContext) {
+            pContext->m_DictStart = SavedPos;
+        }
+        CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
+        FX_INT32 nKeys = 0;
+        FX_FILESIZE dwSignValuePos = 0;
+        while (1) {
+            FX_BOOL bIsNumber;
+            CFX_ByteString key = GetNextWord(bIsNumber);
+            if (key.IsEmpty()) {
+                if (pDict)
+                    pDict->Release();
+                return NULL;
+            }
+            FX_FILESIZE SavedPos = m_Pos - key.GetLength();
+            if (key == FX_BSTRC(">>")) {
+                dwDictSize = m_Pos - saveDictOffset;
+                break;
+            }
+            if (key == FX_BSTRC("endobj")) {
+                dwDictSize = m_Pos - 6 - saveDictOffset;
+                m_Pos = SavedPos;
+                break;
+            }
+            if (key[0] != '/') {
+                continue;
+            }
+            nKeys ++;
+            key = PDF_NameDecode(key);
+            if (key == FX_BSTRC("/Contents")) {
+                dwSignValuePos = m_Pos;
+            }
+            CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, level + 1);
+            if (pObj == NULL) {
+                continue;
+            }
+            if (key.GetLength() == 1) {
+                pDict->SetAt(CFX_ByteStringC(((FX_LPCSTR)key) + 1, key.GetLength() - 1), pObj);
+            } else {
+                if (nKeys < 32) {
+                    pDict->SetAt(CFX_ByteStringC(((FX_LPCSTR)key) + 1, key.GetLength() - 1), pObj);
+                } else {
+                    pDict->AddValue(CFX_ByteStringC(((FX_LPCSTR)key) + 1, key.GetLength() - 1), pObj);
+                }
+            }
+        }
+        if (IsSignatureDict(pDict)) {
+            FX_FILESIZE dwSavePos = m_Pos;
+            m_Pos = dwSignValuePos;
+            CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, level + 1, NULL, FALSE);
+            pDict->SetAt(FX_BSTRC("Contents"), pObj);
+            m_Pos = dwSavePos;
+        }
+        if (pContext) {
+            pContext->m_DictEnd = m_Pos;
+            if (pContext->m_Flags & PDFPARSE_NOSTREAM) {
+                return pDict;
+            }
+        }
+        FX_FILESIZE SavedPos = m_Pos;
+        FX_BOOL bIsNumber;
+        CFX_ByteString nextword = GetNextWord(bIsNumber);
+        if (nextword == FX_BSTRC("stream")) {
+            CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum);
+            if (pStream) {
+                return pStream;
+            }
+            if (pDict)
+                pDict->Release();
+            return NULL;
+        } else {
+            m_Pos = SavedPos;
+            return pDict;
+        }
+    }
+    if (word == FX_BSTRC(">>")) {
+        m_Pos = SavedPos;
+        return NULL;
+    }
+    if (bTypeOnly) {
+        return (CPDF_Object*)PDFOBJ_INVALID;
+    }
+    return NULL;
+}
+CPDF_Object* CPDF_SyntaxParser::GetObjectByStrict(CPDF_IndirectObjects* pObjList, FX_DWORD objnum, FX_DWORD gennum,
+        FX_INT32 level, struct PARSE_CONTEXT* pContext)
+{
+    if (level > _PARSER_OBJECT_LEVLE_) {
+        return NULL;
+    }
+    FX_FILESIZE SavedPos = m_Pos;
+    FX_BOOL bTypeOnly = pContext && (pContext->m_Flags & PDFPARSE_TYPEONLY);
+    FX_BOOL bIsNumber;
+    CFX_ByteString word = GetNextWord(bIsNumber);
+    if (word.GetLength() == 0) {
+        if (bTypeOnly) {
+            return (CPDF_Object*)PDFOBJ_INVALID;
+        }
+        return NULL;
+    }
+    if (bIsNumber) {
+        FX_FILESIZE SavedPos = m_Pos;
+        CFX_ByteString nextword = GetNextWord(bIsNumber);
+        if (bIsNumber) {
+            CFX_ByteString nextword2 = GetNextWord(bIsNumber);
+            if (nextword2 == FX_BSTRC("R")) {
+                FX_DWORD objnum = FXSYS_atoi(word);
+                if (bTypeOnly) {
+                    return (CPDF_Object*)PDFOBJ_REFERENCE;
+                }
+                return CPDF_Reference::Create(pObjList, objnum);
+            } else {
+                m_Pos = SavedPos;
+                if (bTypeOnly) {
+                    return (CPDF_Object*)PDFOBJ_NUMBER;
+                }
+                return CPDF_Number::Create(word);
+            }
+        } else {
+            m_Pos = SavedPos;
+            if (bTypeOnly) {
+                return (CPDF_Object*)PDFOBJ_NUMBER;
+            }
+            return CPDF_Number::Create(word);
+        }
+    }
+    if (word == FX_BSTRC("true") || word == FX_BSTRC("false")) {
+        if (bTypeOnly) {
+            return (CPDF_Object*)PDFOBJ_BOOLEAN;
+        }
+        return CPDF_Boolean::Create(word == FX_BSTRC("true"));
+    }
+    if (word == FX_BSTRC("null")) {
+        if (bTypeOnly) {
+            return (CPDF_Object*)PDFOBJ_NULL;
+        }
+        return CPDF_Null::Create();
+    }
+    if (word == FX_BSTRC("(")) {
+        if (bTypeOnly) {
+            return (CPDF_Object*)PDFOBJ_STRING;
+        }
+        CFX_ByteString str = ReadString();
+        if (m_pCryptoHandler) {
+            m_pCryptoHandler->Decrypt(objnum, gennum, str);
+        }
+        return CPDF_String::Create(str, FALSE);
+    }
+    if (word == FX_BSTRC("<")) {
+        if (bTypeOnly) {
+            return (CPDF_Object*)PDFOBJ_STRING;
+        }
+        CFX_ByteString str = ReadHexString();
+        if (m_pCryptoHandler) {
+            m_pCryptoHandler->Decrypt(objnum, gennum, str);
+        }
+        return CPDF_String::Create(str, TRUE);
+    }
+    if (word == FX_BSTRC("[")) {
+        if (bTypeOnly) {
+            return (CPDF_Object*)PDFOBJ_ARRAY;
+        }
+        CPDF_Array* pArray = CPDF_Array::Create();
+        while (1) {
+            CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, level + 1);
+            if (pObj == NULL) {
+                if (m_WordBuffer[0] == ']') {
+                    return pArray;
+                }
+                if (pArray)
+                    pArray->Release();
+                return NULL;
+            }
+            pArray->Add(pObj);
+        }
+    }
+    if (word[0] == '/') {
+        if (bTypeOnly) {
+            return (CPDF_Object*)PDFOBJ_NAME;
+        }
+        return CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)));
+    }
+    if (word == FX_BSTRC("<<")) {
+        if (bTypeOnly) {
+            return (CPDF_Object*)PDFOBJ_DICTIONARY;
+        }
+        if (pContext) {
+            pContext->m_DictStart = SavedPos;
+        }
+        CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
+        while (1) {
+            FX_BOOL bIsNumber;
+            FX_FILESIZE SavedPos = m_Pos;
+            CFX_ByteString key = GetNextWord(bIsNumber);
+            if (key.IsEmpty()) {
+                if (pDict)
+                    pDict->Release();
+                return NULL;
+            }
+            if (key == FX_BSTRC(">>")) {
+                break;
+            }
+            if (key == FX_BSTRC("endobj")) {
+                m_Pos = SavedPos;
+                break;
+            }
+            if (key[0] != '/') {
+                continue;
+            }
+            key = PDF_NameDecode(key);
+            CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, level + 1);
+            if (pObj == NULL) {
+                if (pDict)
+                    pDict->Release();
+                FX_BYTE ch;
+                while (1) {
+                    if (!GetNextChar(ch)) {
+                        break;
+                    }
+                    if (ch == 0x0A || ch == 0x0D) {
+                        break;
+                    }
+                }
+                return NULL;
+            }
+            if (key.GetLength() == 1) {
+                pDict->SetAt(CFX_ByteStringC(((FX_LPCSTR)key) + 1, key.GetLength() - 1), pObj);
+            } else {
+                pDict->AddValue(CFX_ByteStringC(((FX_LPCSTR)key) + 1, key.GetLength() - 1), pObj);
+            }
+        }
+        if (pContext) {
+            pContext->m_DictEnd = m_Pos;
+            if (pContext->m_Flags & PDFPARSE_NOSTREAM) {
+                return pDict;
+            }
+        }
+        FX_FILESIZE SavedPos = m_Pos;
+        FX_BOOL bIsNumber;
+        CFX_ByteString nextword = GetNextWord(bIsNumber);
+        if (nextword == FX_BSTRC("stream")) {
+            CPDF_Stream* pStream = ReadStream(pDict, pContext, objnum, gennum);
+            if (pStream) {
+                return pStream;
+            }
+            if (pDict)
+                pDict->Release();
+            return NULL;
+        } else {
+            m_Pos = SavedPos;
+            return pDict;
+        }
+    }
+    if (word == FX_BSTRC(">>")) {
+        m_Pos = SavedPos;
+        return NULL;
+    }
+    if (bTypeOnly) {
+        return (CPDF_Object*)PDFOBJ_INVALID;
+    }
+    return NULL;
+}
+CPDF_Stream* CPDF_SyntaxParser::ReadStream(CPDF_Dictionary* pDict, PARSE_CONTEXT* pContext,
+        FX_DWORD objnum, FX_DWORD gennum)
+{
+    CPDF_Object* pLenObj = pDict->GetElement(FX_BSTRC("Length"));
+    FX_DWORD len = 0;
+    if (pLenObj && ((pLenObj->GetType() != PDFOBJ_REFERENCE) ||
+                    ((((CPDF_Reference*)pLenObj)->GetObjList() != NULL) &&
+                     ((CPDF_Reference*)pLenObj)->GetRefObjNum() != objnum))) {
+        FX_FILESIZE pos = m_Pos;
+        if (pLenObj) {
+            len = pLenObj->GetInteger();
+        }
+        m_Pos = pos;
+        if (len > 0x40000000) {
+            return NULL;
+        }
+    }
+    ToNextLine();
+    FX_FILESIZE StreamStartPos = m_Pos;
+    if (pContext) {
+        pContext->m_DataStart = m_Pos;
+    }
+    m_Pos += len;
+    CPDF_CryptoHandler* pCryptoHandler = objnum == (FX_DWORD)m_MetadataObjnum ? NULL : m_pCryptoHandler;
+    if (pCryptoHandler == NULL) {
+        FX_FILESIZE SavedPos = m_Pos;
+        GetNextWord();
+        if (m_WordSize < 9 || FXSYS_memcmp32(m_WordBuffer, "endstream", 9)) {
+            m_Pos = StreamStartPos;
+            FX_FILESIZE offset = FindTag(FX_BSTRC("endstream"), 0);
+            if (offset >= 0) {
+                FX_FILESIZE curPos = m_Pos;
+                m_Pos = StreamStartPos;
+                FX_FILESIZE endobjOffset = FindTag(FX_BSTRC("endobj"), 0);
+                if (endobjOffset < offset && endobjOffset >= 0) {
+                    offset = endobjOffset;
+                } else {
+                    m_Pos = curPos;
+                }
+                FX_BYTE byte1, byte2;
+                GetCharAt(StreamStartPos + offset - 1, byte1);
+                GetCharAt(StreamStartPos + offset - 2, byte2);
+                if (byte1 == 0x0a && byte2 == 0x0d) {
+                    len -= 2;
+                } else if (byte1 == 0x0a || byte1 == 0x0d) {
+                    len --;
+                }
+                len = (FX_DWORD)offset;
+                pDict->SetAtInteger(FX_BSTRC("Length"), len);
+            } else {
+                m_Pos = StreamStartPos;
+                if (FindTag(FX_BSTRC("endobj"), 0) < 0) {
+                    return NULL;
+                }
+            }
+        }
+    }
+    m_Pos = StreamStartPos;
+    CPDF_Stream* pStream;
+#if defined(_FPDFAPI_MINI_) && !defined(_FXCORE_FEATURE_ALL_)
+    pStream = FX_NEW CPDF_Stream(m_pFileAccess, pCryptoHandler, m_HeaderOffset + m_Pos, len, pDict, gennum);
+    m_Pos += len;
+#else
+    FX_LPBYTE pData = FX_Alloc(FX_BYTE, len);
+    if (!pData) {
+        return NULL;
+    }
+    ReadBlock(pData, len);
+    if (pCryptoHandler) {
+        CFX_BinaryBuf dest_buf;
+        dest_buf.EstimateSize(pCryptoHandler->DecryptGetSize(len));
+        FX_LPVOID context = pCryptoHandler->DecryptStart(objnum, gennum);
+        pCryptoHandler->DecryptStream(context, pData, len, dest_buf);
+        pCryptoHandler->DecryptFinish(context, dest_buf);
+        FX_Free(pData);
+        pData = dest_buf.GetBuffer();
+        len = dest_buf.GetSize();
+        dest_buf.DetachBuffer();
+    }
+    pStream = FX_NEW CPDF_Stream(pData, len, pDict);
+#endif
+    if (pContext) {
+        pContext->m_DataEnd = pContext->m_DataStart + len;
+    }
+    StreamStartPos = m_Pos;
+    GetNextWord();
+    if (m_WordSize == 6 && 0 == FXSYS_memcmp32(m_WordBuffer, "endobj", 6)) {
+        m_Pos = StreamStartPos;
+    }
+    return pStream;
+}
+void CPDF_SyntaxParser::InitParser(IFX_FileRead* pFileAccess, FX_DWORD HeaderOffset)
+{
+    if (m_pFileBuf) {
+        FX_Free(m_pFileBuf);
+        m_pFileBuf = NULL;
+    }
+    m_pFileBuf = FX_Alloc(FX_BYTE, m_BufSize);
+    m_HeaderOffset = HeaderOffset;
+    m_FileLen = pFileAccess->GetSize();
+    m_Pos = 0;
+    m_pFileAccess = pFileAccess;
+    m_BufOffset = 0;
+    pFileAccess->ReadBlock(m_pFileBuf, 0, (size_t)((FX_FILESIZE)m_BufSize > m_FileLen ? m_FileLen : m_BufSize));
+}
+FX_INT32 CPDF_SyntaxParser::GetDirectNum()
+{
+    GetNextWord();
+    if (!m_bIsNumber) {
+        return 0;
+    }
+    m_WordBuffer[m_WordSize] = 0;
+    return FXSYS_atoi((FX_LPCSTR)m_WordBuffer);
+}
+FX_BOOL CPDF_SyntaxParser::IsWholeWord(FX_FILESIZE startpos, FX_FILESIZE limit, FX_LPCBYTE tag, FX_DWORD taglen)
+{
+    FX_BYTE type = _PDF_CharType[tag[0]];
+    FX_BOOL bCheckLeft = type != 'D' && type != 'W';
+    type = _PDF_CharType[tag[taglen - 1]];
+    FX_BOOL bCheckRight = type != 'D' || type != 'W';
+    FX_BYTE ch;
+    if (bCheckRight && startpos + (FX_INT32)taglen <= limit && GetCharAt(startpos + (FX_INT32)taglen, ch)) {
+        FX_BYTE type = _PDF_CharType[ch];
+        if (type == 'N' || type == 'R') {
+            return FALSE;
+        }
+    }
+    if (bCheckLeft && startpos > 0 && GetCharAt(startpos - 1, ch)) {
+        FX_BYTE type = _PDF_CharType[ch];
+        if (type == 'N' || type == 'R') {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+FX_BOOL CPDF_SyntaxParser::SearchWord(FX_BSTR tag, FX_BOOL bWholeWord, FX_BOOL bForward, FX_FILESIZE limit)
+{
+    FX_INT32 taglen = tag.GetLength();
+    if (taglen == 0) {
+        return FALSE;
+    }
+    FX_FILESIZE pos = m_Pos;
+    FX_INT32 offset = 0;
+    if (!bForward) {
+        offset = taglen - 1;
+    }
+    FX_LPCBYTE tag_data = tag;
+    FX_BYTE byte;
+    while (1) {
+        if (bForward) {
+            if (limit) {
+                if (pos >= m_Pos + limit) {
+                    return FALSE;
+                }
+            }
+            if (!GetCharAt(pos, byte)) {
+                return FALSE;
+            }
+        } else {
+            if (limit) {
+                if (pos <= m_Pos - limit) {
+                    return FALSE;
+                }
+            }
+            if (!GetCharAtBackward(pos, byte)) {
+                return FALSE;
+            }
+        }
+        if (byte == tag_data[offset]) {
+            if (bForward) {
+                offset ++;
+                if (offset < taglen) {
+                    pos ++;
+                    continue;
+                }
+            } else {
+                offset --;
+                if (offset >= 0) {
+                    pos --;
+                    continue;
+                }
+            }
+            FX_FILESIZE startpos = bForward ? pos - taglen + 1 : pos;
+            if (!bWholeWord || IsWholeWord(startpos, limit, tag, taglen)) {
+                m_Pos = startpos;
+                return TRUE;
+            }
+        }
+        if (bForward) {
+            offset = byte == tag_data[0] ? 1 : 0;
+            pos ++;
+        } else {
+            offset = byte == tag_data[taglen - 1] ? taglen - 2 : taglen - 1;
+            pos --;
+        }
+        if (pos < 0) {
+            return FALSE;
+        }
+    }
+    return FALSE;
+}
+struct _SearchTagRecord {
+    FX_LPCBYTE m_pTag;
+    FX_DWORD   m_Len;
+    FX_DWORD   m_Offset;
+};
+FX_INT32 CPDF_SyntaxParser::SearchMultiWord(FX_BSTR tags, FX_BOOL bWholeWord, FX_FILESIZE limit)
+{
+    FX_INT32 ntags = 1, i;
+    for (i = 0; i < tags.GetLength(); i ++)
+        if (tags[i] == 0) {
+            ntags ++;
+        }
+    _SearchTagRecord* pPatterns = FX_Alloc(_SearchTagRecord, ntags);
+    FX_DWORD start = 0, itag = 0, max_len = 0;
+    for (i = 0; i <= tags.GetLength(); i ++) {
+        if (tags[i] == 0) {
+            FX_DWORD len = i - start;
+            if (len > max_len) {
+                max_len = len;
+            }
+            pPatterns[itag].m_pTag = tags.GetPtr() + start;
+            pPatterns[itag].m_Len = len;
+            pPatterns[itag].m_Offset = 0;
+            start = i + 1;
+            itag ++;
+        }
+    }
+    FX_FILESIZE pos = m_Pos;
+    FX_BYTE byte;
+    GetCharAt(pos++, byte);
+    FX_INT32 found = -1;
+    while (1) {
+        for (i = 0; i < ntags; i ++) {
+            if (pPatterns[i].m_pTag[pPatterns[i].m_Offset] == byte) {
+                pPatterns[i].m_Offset ++;
+                if (pPatterns[i].m_Offset == pPatterns[i].m_Len) {
+                    if (!bWholeWord || IsWholeWord(pos - pPatterns[i].m_Len, limit, pPatterns[i].m_pTag, pPatterns[i].m_Len)) {
+                        found = i;
+                        goto end;
+                    } else {
+                        if (pPatterns[i].m_pTag[0] == byte) {
+                            pPatterns[i].m_Offset = 1;
+                        } else {
+                            pPatterns[i].m_Offset = 0;
+                        }
+                    }
+                }
+            } else {
+                if (pPatterns[i].m_pTag[0] == byte) {
+                    pPatterns[i].m_Offset = 1;
+                } else {
+                    pPatterns[i].m_Offset = 0;
+                }
+            }
+        }
+        if (limit && pos >= m_Pos + limit) {
+            goto end;
+        }
+        if (!GetCharAt(pos, byte)) {
+            goto end;
+        }
+        pos ++;
+    }
+end:
+    FX_Free(pPatterns);
+    return found;
+}
+FX_FILESIZE CPDF_SyntaxParser::FindTag(FX_BSTR tag, FX_FILESIZE limit)
+{
+    FX_INT32 taglen = tag.GetLength();
+    FX_INT32 match = 0;
+    limit += m_Pos;
+    FX_FILESIZE startpos = m_Pos;
+    while (1) {
+        FX_BYTE ch;
+        if (!GetNextChar(ch)) {
+            return -1;
+        }
+        if (ch == tag[match]) {
+            match ++;
+            if (match == taglen) {
+                return m_Pos - startpos - taglen;
+            }
+        } else {
+            match = ch == tag[0] ? 1 : 0;
+        }
+        if (limit && m_Pos == limit) {
+            return -1;
+        }
+    }
+    return -1;
+}
+void CPDF_SyntaxParser::GetBinary(FX_BYTE* buffer, FX_DWORD size)
+{
+    FX_DWORD offset = 0;
+    FX_BYTE ch;
+    while (1) {
+        if (!GetNextChar(ch)) {
+            return;
+        }
+        buffer[offset++] = ch;
+        if (offset == size) {
+            break;
+        }
+    }
+}
+CPDF_DataAvail::CPDF_DataAvail(IFX_FileAvail* pFileAvail, IFX_FileRead* pFileRead)
+{
+    m_pFileAvail = pFileAvail;
+    m_pFileRead = pFileRead;
+    m_Pos = 0;
+    m_dwFileLen = 0;
+    if (m_pFileRead) {
+        m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize();
+    }
+    m_dwCurrentOffset = 0;
+    m_WordSize = 0;
+    m_dwXRefOffset = 0;
+    m_bufferOffset = 0;
+    m_dwFirstPageNo = 0;
+    m_bufferSize = 0;
+    m_PagesObjNum = 0;
+    m_dwCurrentXRefSteam = 0;
+    m_dwAcroFormObjNum = 0;
+    m_dwInfoObjNum = 0;
+    m_pDocument = 0;
+    m_dwEncryptObjNum = 0;
+    m_dwPrevXRefOffset = 0;
+    m_dwLastXRefOffset = 0;
+    m_bDocAvail = FALSE;
+    m_bMainXRefLoad = FALSE;
+    m_bDocAvail = FALSE;
+    m_bLinearized = FALSE;
+    m_bPagesLoad = FALSE;
+    m_bPagesTreeLoad = FALSE;
+    m_bMainXRefLoadedOK = FALSE;
+    m_bAnnotsLoad = FALSE;
+    m_bHaveAcroForm = FALSE;
+    m_bAcroFormLoad = FALSE;
+    m_bPageLoadedOK = FALSE;
+    m_bNeedDownLoadResource = FALSE;
+    m_bLinearizedFormParamLoad = FALSE;
+    m_pLinearized = NULL;
+    m_pRoot = NULL;
+    m_pTrailer = NULL;
+    m_pCurrentParser = NULL;
+    m_pAcroForm = NULL;
+    m_pPageDict = NULL;
+    m_pPageResource = NULL;
+    m_pageMapCheckState = NULL;
+    m_docStatus = PDF_DATAAVAIL_HEADER;
+    m_parser.m_bOwnFileRead = FALSE;
+    m_bTotalLoadPageTree = FALSE;
+    m_bCurPageDictLoadOK = FALSE;
+    m_bLinearedDataOK = FALSE;
+    m_pagesLoadState = NULL;
+}
+CPDF_DataAvail::~CPDF_DataAvail()
+{
+    if (m_pLinearized) {
+        m_pLinearized->Release();
+    }
+    if (m_pRoot) {
+        m_pRoot->Release();
+    }
+    if (m_pTrailer) {
+        m_pTrailer->Release();
+    }
+    if (m_pageMapCheckState) {
+        delete m_pageMapCheckState;
+    }
+    if (m_pagesLoadState) {
+        delete m_pagesLoadState;
+    }
+    FX_INT32 i = 0;
+    FX_INT32 iSize = m_arrayAcroforms.GetSize();
+    for (i = 0; i < iSize; ++i) {
+        ((CPDF_Object *)m_arrayAcroforms.GetAt(i))->Release();
+    }
+}
+void CPDF_DataAvail::SetDocument(CPDF_Document* pDoc)
+{
+    m_pDocument = pDoc;
+}
+FX_DWORD CPDF_DataAvail::GetObjectSize(FX_DWORD objnum, FX_FILESIZE& offset)
+{
+    CPDF_Parser *pParser = (CPDF_Parser *)(m_pDocument->GetParser());
+    if (pParser == NULL) {
+        return 0;
+    }
+    if (objnum >= (FX_DWORD)pParser->m_CrossRef.GetSize()) {
+        return 0;
+    }
+    if (pParser->m_V5Type[objnum] == 2) {
+        objnum = (FX_DWORD)pParser->m_CrossRef[objnum];
+    }
+    if (pParser->m_V5Type[objnum] == 1 || pParser->m_V5Type[objnum] == 255) {
+        offset = pParser->m_CrossRef[objnum];
+        if (offset == 0) {
+            return 0;
+        }
+        FX_LPVOID pResult = FXSYS_bsearch(&offset, pParser->m_SortedOffset.GetData(), pParser->m_SortedOffset.GetSize(), sizeof(FX_FILESIZE), _CompareFileSize);
+        if (pResult == NULL) {
+            return 0;
+        }
+        if ((FX_FILESIZE*)pResult - (FX_FILESIZE*)pParser->m_SortedOffset.GetData() == pParser->m_SortedOffset.GetSize() - 1) {
+            return 0;
+        }
+        return (FX_DWORD)(((FX_FILESIZE*)pResult)[1] - offset);
+    }
+    return 0;
+}
+FX_BOOL CPDF_DataAvail::IsObjectsAvail(CFX_PtrArray& obj_array, FX_BOOL bParsePage, IFX_DownloadHints* pHints, CFX_PtrArray &ret_array)
+{
+    if (!obj_array.GetSize()) {
+        return TRUE;
+    }
+    FX_DWORD count = 0;
+    CFX_PtrArray new_obj_array;
+    FX_INT32 i = 0;
+    for (i = 0; i < obj_array.GetSize(); i++) {
+        CPDF_Object *pObj = (CPDF_Object *)obj_array[i];
+        if (!pObj) {
+            continue;
+        }
+        FX_INT32 type = pObj->GetType();
+        switch (type) {
+            case PDFOBJ_ARRAY: {
+                    CPDF_Array *pArray = pObj->GetArray();
+                    for (FX_DWORD k = 0; k < pArray->GetCount(); k++) {
+                        new_obj_array.Add(pArray->GetElement(k));
+                    }
+                }
+                break;
+            case PDFOBJ_STREAM:
+                pObj = pObj->GetDict();
+            case PDFOBJ_DICTIONARY: {
+                    CPDF_Dictionary *pDict = pObj->GetDict();
+                    if (pDict && pDict->GetString("Type") == "Page" && !bParsePage) {
+                        continue;
+                    }
+                    FX_POSITION pos = pDict->GetStartPos();
+                    while (pos) {
+                        CPDF_Object *value;
+                        CFX_ByteString key;
+                        value = pDict->GetNextElement(pos, key);
+                        if (key != "Parent") {
+                            new_obj_array.Add(value);
+                        }
+                    }
+                }
+                break;
+            case PDFOBJ_REFERENCE: {
+                    CPDF_Reference *pRef = (CPDF_Reference*)pObj;
+                    FX_DWORD dwNum = pRef->GetRefObjNum();
+                    FX_FILESIZE offset;
+                    FX_DWORD size = GetObjectSize(pRef->GetRefObjNum(), offset);
+                    if (!size) {
+                        break;
+                    }
+                    size = (FX_DWORD)((FX_FILESIZE)(offset + size + 512) > m_dwFileLen ? m_dwFileLen - offset : size + 512);
+                    if (!m_pFileAvail->IsDataAvail(offset, size)) {
+                        pHints->AddSegment(offset, size);
+                        ret_array.Add(pObj);
+                        count++;
+                    } else if (!m_objnum_array.Find(dwNum)) {
+                        m_objnum_array.AddObjNum(dwNum);
+                        CPDF_Object *pReferred = m_pDocument->GetIndirectObject(pRef->GetRefObjNum(), NULL);
+                        if (pReferred) {
+                            new_obj_array.Add(pReferred);
+                        }
+                    }
+                }
+                break;
+        }
+    }
+    if (count > 0) {
+        FX_INT32 iSize = new_obj_array.GetSize();
+        for (i = 0; i < iSize; ++i) {
+            CPDF_Object *pObj = (CPDF_Object *)new_obj_array[i];
+            FX_INT32 type = pObj->GetType();
+            if (type == PDFOBJ_REFERENCE) {
+                CPDF_Reference *pRef = (CPDF_Reference *)pObj;
+                FX_DWORD dwNum = pRef->GetRefObjNum();
+                if (!m_objnum_array.Find(dwNum)) {
+                    ret_array.Add(pObj);
+                }
+            } else {
+                ret_array.Add(pObj);
+            }
+        }
+        return FALSE;
+    }
+    obj_array.RemoveAll();
+    obj_array.Append(new_obj_array);
+    return IsObjectsAvail(obj_array, FALSE, pHints, ret_array);
+}
+FX_BOOL CPDF_DataAvail::IsDocAvail(IFX_DownloadHints* pHints)
+{
+    if (!m_dwFileLen && m_pFileRead) {
+        m_dwFileLen = (FX_DWORD)m_pFileRead->GetSize();
+        if (!m_dwFileLen) {
+            return TRUE;
+        }
+    }
+    while (!m_bDocAvail) {
+        if (!CheckDocStatus(pHints)) {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+FX_BOOL CPDF_DataAvail::CheckAcroFormSubObject(IFX_DownloadHints* pHints)
+{
+    if (!m_objs_array.GetSize()) {
+        m_objs_array.RemoveAll();
+        m_objnum_array.RemoveAll();
+        CFX_PtrArray obj_array;
+        obj_array.Append(m_arrayAcroforms);
+        FX_BOOL bRet = IsObjectsAvail(obj_array, FALSE, pHints, m_objs_array);
+        if (bRet) {
+            m_objs_array.RemoveAll();
+        }
+        return bRet;
+    } else {
+        CFX_PtrArray new_objs_array;
+        FX_BOOL bRet = IsObjectsAvail(m_objs_array, FALSE, pHints, new_objs_array);
+        if (bRet) {
+            FX_INT32 iSize = m_arrayAcroforms.GetSize();
+            for (FX_INT32 i = 0; i < iSize; ++i) {
+                ((CPDF_Object *)m_arrayAcroforms.GetAt(i))->Release();
+            }
+            m_arrayAcroforms.RemoveAll();
+        } else {
+            m_objs_array.RemoveAll();
+            m_objs_array.Append(new_objs_array);
+        }
+        return bRet;
+    }
+}
+FX_BOOL CPDF_DataAvail::CheckAcroForm(IFX_DownloadHints* pHints)
+{
+    FX_BOOL bExist = FALSE;
+    m_pAcroForm = GetObject(m_dwAcroFormObjNum, pHints, &bExist);
+    if (!bExist) {
+        m_docStatus = PDF_DATAAVAIL_PAGETREE;
+        return TRUE;
+    }
+    if (!m_pAcroForm) {
+        if (m_docStatus == PDF_DATAAVAIL_ERROR) {
+            m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
+            return TRUE;
+        }
+        return FALSE;
+    }
+    m_arrayAcroforms.Add(m_pAcroForm);
+    m_docStatus = PDF_DATAAVAIL_PAGETREE;
+    return TRUE;
+}
+FX_BOOL CPDF_DataAvail::CheckDocStatus(IFX_DownloadHints *pHints)
+{
+    switch (m_docStatus) {
+        case PDF_DATAAVAIL_HEADER:
+            return CheckHeader(pHints);
+        case PDF_DATAAVAIL_FIRSTPAGE:
+        case PDF_DATAAVAIL_FIRSTPAGE_PREPARE:
+            return CheckFirstPage(pHints);
+        case PDF_DATAAVAIL_END:
+            return CheckEnd(pHints);
+        case PDF_DATAAVAIL_CROSSREF:
+            return CheckCrossRef(pHints);
+        case PDF_DATAAVAIL_CROSSREF_ITEM:
+            return CheckCrossRefItem(pHints);
+        case PDF_DATAAVAIL_CROSSREF_STREAM:
+            return CheckAllCrossRefStream(pHints);
+        case PDF_DATAAVAIL_TRAILER:
+            return CheckTrailer(pHints);
+        case PDF_DATAAVAIL_TRAILER_APPEND:
+            return CheckTrailerAppend(pHints);
+        case PDF_DATAAVAIL_LOADALLCRSOSSREF:
+            return LoadAllXref(pHints);
+        case PDF_DATAAVAIL_LOADALLFILE:
+            return LoadAllFile(pHints);
+        case PDF_DATAAVAIL_ROOT:
+            return CheckRoot(pHints);
+        case PDF_DATAAVAIL_INFO:
+            return CheckInfo(pHints);
+        case PDF_DATAAVAIL_ACROFORM:
+            return CheckAcroForm(pHints);
+        case PDF_DATAAVAIL_PAGETREE:
+            if (m_bTotalLoadPageTree) {
+                return CheckPages(pHints);
+            } else {
+                return LoadDocPages(pHints);
+            }
+        case PDF_DATAAVAIL_PAGE:
+            if (m_bTotalLoadPageTree) {
+                return CheckPage(pHints);
+            } else {
+                m_docStatus = PDF_DATAAVAIL_PAGE_LATERLOAD;
+                return TRUE;
+            }
+        case PDF_DATAAVAIL_ERROR:
+            return LoadAllFile(pHints);
+        case PDF_DATAAVAIL_PAGE_LATERLOAD:
+            m_docStatus = PDF_DATAAVAIL_PAGE;
+        default:
+            m_bDocAvail = TRUE;
+            return TRUE;
+    }
+}
+FX_BOOL        CPDF_DataAvail::CheckPageStatus(IFX_DownloadHints* pHints)
+{
+    switch (m_docStatus) {
+        case PDF_DATAAVAIL_PAGETREE:
+            return CheckPages(pHints);
+        case PDF_DATAAVAIL_PAGE:
+            return CheckPage(pHints);
+        case P