void CPDF_Document::LoadAsynDoc(CPDF_Dictionary* pLinearized) {
    m_bLinearized = TRUE;
    m_LastObjNum = m_pParser->GetLastObjNum();
    CPDF_Object* pIndirectObj =
        GetIndirectObject(m_pParser->GetRootObjNum(), nullptr);
    m_pRootDict = pIndirectObj ? pIndirectObj->GetDict() : nullptr;
    if (!m_pRootDict) {
        return;
    }
    pIndirectObj = GetIndirectObject(m_pParser->GetInfoObjNum(), nullptr);
    m_pInfoDict = pIndirectObj ? pIndirectObj->GetDict() : nullptr;
    CPDF_Array* pIDArray = m_pParser->GetIDArray();
    if (pIDArray) {
        m_ID1 = pIDArray->GetString(0);
        m_ID2 = pIDArray->GetString(1);
    }
    FX_DWORD dwPageCount = 0;
    CPDF_Object* pCount = pLinearized->GetElement("N");
    if (ToNumber(pCount))
        dwPageCount = pCount->GetInteger();

    m_PageList.SetSize(dwPageCount);
    CPDF_Object* pNo = pLinearized->GetElement("P");
    if (ToNumber(pNo))
        m_dwFirstPageNo = pNo->GetInteger();

    CPDF_Object* pObjNum = pLinearized->GetElement("O");
    if (ToNumber(pObjNum))
        m_dwFirstPageObjNum = pObjNum->GetInteger();
}
CPDF_Dictionary* CPDF_Document::GetPage(int iPage) {
    if (iPage < 0 || iPage >= m_PageList.GetSize())
        return nullptr;

    if (m_bLinearized && (iPage == (int)m_dwFirstPageNo)) {
        if (CPDF_Dictionary* pDict =
                    ToDictionary(GetIndirectObject(m_dwFirstPageObjNum, nullptr)))
            return pDict;
    }

    int objnum = m_PageList.GetAt(iPage);
    if (objnum) {
        if (CPDF_Dictionary* pDict =
                    ToDictionary(GetIndirectObject(objnum, nullptr))) {
            return pDict;
        }
    }

    CPDF_Dictionary* pRoot = GetRoot();
    if (!pRoot)
        return nullptr;

    CPDF_Dictionary* pPages = pRoot->GetDict("Pages");
    if (!pPages)
        return nullptr;

    CPDF_Dictionary* pPage = _FindPDFPage(pPages, iPage, iPage, 0);
    if (!pPage)
        return nullptr;

    m_PageList.SetAt(iPage, pPage->GetObjNum());
    return pPage;
}
void CPDF_IndirectObjectHolder::DeleteIndirectObject(uint32_t objnum) {
  CPDF_Object* pObj = GetIndirectObject(objnum);
  if (!pObj || pObj->GetObjNum() == CPDF_Object::kInvalidObjNum)
    return;

  m_IndirectObjs.erase(objnum);
}
void CPDF_Document::LoadDoc() {
    m_LastObjNum = m_pParser->GetLastObjNum();
    CPDF_Object* pRootObj =
        GetIndirectObject(m_pParser->GetRootObjNum(), nullptr);
    if (!pRootObj) {
        return;
    }
    m_pRootDict = pRootObj->GetDict();
    if (!m_pRootDict) {
        return;
    }
    CPDF_Object* pInfoObj =
        GetIndirectObject(m_pParser->GetInfoObjNum(), nullptr);
    if (pInfoObj) {
        m_pInfoDict = pInfoObj->GetDict();
    }
    CPDF_Array* pIDArray = m_pParser->GetIDArray();
    if (pIDArray) {
        m_ID1 = pIDArray->GetString(0);
        m_ID2 = pIDArray->GetString(1);
    }
    m_PageList.SetSize(_GetPageCount());
}
bool CPDF_IndirectObjectHolder::ReplaceIndirectObjectIfHigherGeneration(
    uint32_t objnum,
    std::unique_ptr<CPDF_Object> pObj) {
  ASSERT(objnum);
  if (!pObj)
    return false;

  CPDF_Object* pOldObj = GetIndirectObject(objnum);
  if (pOldObj && pObj->GetGenNum() <= pOldObj->GetGenNum())
    return false;

  pObj->m_ObjNum = objnum;
  m_IndirectObjs[objnum] = std::move(pObj);
  m_LastObjNum = std::max(m_LastObjNum, objnum);
  return true;
}
CPDF_Object* CPDF_IndirectObjectHolder::GetOrParseIndirectObject(
    uint32_t objnum) {
  if (objnum == 0)
    return nullptr;

  CPDF_Object* pObj = GetIndirectObject(objnum);
  if (pObj)
    return pObj->GetObjNum() != CPDF_Object::kInvalidObjNum ? pObj : nullptr;

  std::unique_ptr<CPDF_Object> pNewObj = ParseIndirectObject(objnum);
  if (!pNewObj)
    return nullptr;

  pNewObj->m_ObjNum = objnum;
  m_LastObjNum = std::max(m_LastObjNum, objnum);
  m_IndirectObjs[objnum] = std::move(pNewObj);
  return m_IndirectObjs[objnum].get();
}
bool CPDF_IndirectObjectHolder::ReplaceIndirectObjectIfHigherGeneration(
    uint32_t objnum,
    CPDF_Object* pObj) {
  if (!objnum || !pObj)
    return false;

  CPDF_Object* pOldObj = GetIndirectObject(objnum);
  if (pOldObj) {
    if (pObj->GetGenNum() <= pOldObj->GetGenNum()) {
      pObj->Destroy();
      return false;
    }
    pOldObj->Destroy();
  }
  pObj->m_ObjNum = objnum;
  m_IndirectObjs[objnum] = pObj;
  m_LastObjNum = std::max(m_LastObjNum, objnum);
  return true;
}
CPDF_Object* CPDF_IndirectObjectHolder::GetOrParseIndirectObject(
    uint32_t objnum) {
  if (objnum == 0)
    return nullptr;

  CPDF_Object* pObj = GetIndirectObject(objnum);
  if (pObj)
    return pObj->GetObjNum() != CPDF_Object::kInvalidObjNum ? pObj : nullptr;

  pObj = ParseIndirectObject(objnum);
  if (!pObj)
    return nullptr;

  pObj->m_ObjNum = objnum;
  m_LastObjNum = std::max(m_LastObjNum, objnum);
  if (m_IndirectObjs[objnum])
    m_IndirectObjs[objnum]->Destroy();

  m_IndirectObjs[objnum] = pObj;
  return pObj;
}