Reduce lookups in CPDF_Parser::ParseIndirectObject()

ParseIndirectObject() calls several helper functions that in turn calls
CPDF_CrossRefTable::GetObjectInfo(). Instead of doing multiple lookups
like this, just call GetObjectInfo() once and directly interpret the
result. After this, CPDF_Parser::GetObjectType() only has a single
caller left, so fold it into that caller.

Change-Id: If6ffa1bce8d58f90bab57c1ac8ea882ddf748a0d
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/121232
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Tom Sepez <tsepez@google.com>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index 28dcb14..c7f0044 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -183,14 +183,10 @@
   return (info && info->type == ObjectType::kNormal) ? info->pos : 0;
 }
 
-ObjectType CPDF_Parser::GetObjectType(uint32_t objnum) const {
+bool CPDF_Parser::IsObjectFree(uint32_t objnum) const {
   DCHECK(IsValidObjectNumber(objnum));
   const auto* info = m_CrossRefTable->GetObjectInfo(objnum);
-  return info ? info->type : ObjectType::kFree;
-}
-
-bool CPDF_Parser::IsObjectFree(uint32_t objnum) const {
-  return GetObjectType(objnum) == ObjectType::kFree;
+  return !info || info->type == ObjectType::kFree;
 }
 
 bool CPDF_Parser::InitSyntaxParser(RetainPtr<CPDF_ReadValidator> validator) {
@@ -1002,31 +998,40 @@
 }
 
 RetainPtr<CPDF_Object> CPDF_Parser::ParseIndirectObject(uint32_t objnum) {
-  if (!IsValidObjectNumber(objnum))
+  if (!IsValidObjectNumber(objnum)) {
     return nullptr;
+  }
 
   // Prevent circular parsing the same object.
-  if (pdfium::Contains(m_ParsingObjNums, objnum))
+  if (pdfium::Contains(m_ParsingObjNums, objnum)) {
     return nullptr;
+  }
 
   ScopedSetInsertion<uint32_t> local_insert(&m_ParsingObjNums, objnum);
-  if (GetObjectType(objnum) == ObjectType::kNormal) {
-    FX_FILESIZE pos = GetObjectPositionOrZero(objnum);
-    if (pos <= 0)
+  const auto* info = m_CrossRefTable->GetObjectInfo(objnum);
+  if (!info) {
+    return nullptr;
+  }
+
+  switch (info->type) {
+    case ObjectType::kFree: {
       return nullptr;
-    return ParseIndirectObjectAt(pos, objnum);
+    }
+    case ObjectType::kNormal: {
+      if (info->pos <= 0) {
+        return nullptr;
+      }
+      return ParseIndirectObjectAt(info->pos, objnum);
+    }
+    case ObjectType::kCompressed: {
+      const auto* obj_stream = GetObjectStream(info->archive.obj_num);
+      if (!obj_stream) {
+        return nullptr;
+      }
+      return obj_stream->ParseObject(m_pObjectsHolder, objnum,
+                                     info->archive.obj_index);
+    }
   }
-  if (GetObjectType(objnum) != ObjectType::kCompressed) {
-    return nullptr;
-  }
-
-  const auto& info = *m_CrossRefTable->GetObjectInfo(objnum);
-  const CPDF_ObjectStream* pObjStream = GetObjectStream(info.archive.obj_num);
-  if (!pObjStream)
-    return nullptr;
-
-  return pObjStream->ParseObject(m_pObjectsHolder, objnum,
-                                 info.archive.obj_index);
 }
 
 const CPDF_ObjectStream* CPDF_Parser::GetObjectStream(uint32_t object_number) {
diff --git a/core/fpdfapi/parser/cpdf_parser.h b/core/fpdfapi/parser/cpdf_parser.h
index cabc332..d659c9b 100644
--- a/core/fpdfapi/parser/cpdf_parser.h
+++ b/core/fpdfapi/parser/cpdf_parser.h
@@ -174,8 +174,6 @@
   bool InitSyntaxParser(RetainPtr<CPDF_ReadValidator> validator);
   bool ParseFileVersion();
 
-  CPDF_CrossRefTable::ObjectType GetObjectType(uint32_t objnum) const;
-
   std::unique_ptr<CPDF_SyntaxParser> m_pSyntax;
   std::unique_ptr<ParsedObjectsHolder> m_pOwnedObjectsHolder;
   UnownedPtr<ParsedObjectsHolder> m_pObjectsHolder;