summaryrefslogtreecommitdiff
path: root/core/fpdfapi/parser/cpdf_parser.cpp
diff options
context:
space:
mode:
authorArtem Strygin <art-snake@yandex-team.ru>2018-06-26 16:01:38 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-06-26 16:01:38 +0000
commite3d3ce04e585c4a6c5596056bdf1ced639c763d7 (patch)
tree55ba6fde26546f818d8ffadc879087ada34502ab /core/fpdfapi/parser/cpdf_parser.cpp
parent08b6819660a69cdc83bd133d1074da5813d9e414 (diff)
downloadpdfium-e3d3ce04e585c4a6c5596056bdf1ced639c763d7.tar.xz
Implement CPDF_ObjStream.
It is allow do not store raw objects streams within CPDF_Document for reduce memory usage. Change-Id: I4377bd5119d87314e76f14255171618cf6ee533d Reviewed-on: https://pdfium-review.googlesource.com/35430 Reviewed-by: dsinclair <dsinclair@chromium.org> Reviewed-by: Tom Sepez <tsepez@chromium.org> Commit-Queue: Art Snake <art-snake@yandex-team.ru>
Diffstat (limited to 'core/fpdfapi/parser/cpdf_parser.cpp')
-rw-r--r--core/fpdfapi/parser/cpdf_parser.cpp70
1 files changed, 26 insertions, 44 deletions
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index 73b4bcdc0c..6cdd6ab789 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -16,6 +16,7 @@
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/parser/cpdf_linearized_header.h"
#include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fpdfapi/parser/cpdf_object_stream.h"
#include "core/fpdfapi/parser/cpdf_read_validator.h"
#include "core/fpdfapi/parser/cpdf_reference.h"
#include "core/fpdfapi/parser/cpdf_security_handler.h"
@@ -46,14 +47,6 @@ uint32_t GetVarInt(const uint8_t* p, int32_t n) {
return result;
}
-int32_t GetStreamNCount(const RetainPtr<CPDF_StreamAcc>& pObjStream) {
- return pObjStream->GetDict()->GetIntegerFor("N");
-}
-
-int32_t GetStreamFirst(const RetainPtr<CPDF_StreamAcc>& pObjStream) {
- return pObjStream->GetDict()->GetIntegerFor("First");
-}
-
} // namespace
class CPDF_Parser::TrailerData {
@@ -1198,8 +1191,7 @@ std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObject(
return nullptr;
pdfium::ScopedSetInsertion<uint32_t> local_insert(&m_ParsingObjNums, objnum);
- if (GetObjectType(objnum) == ObjectType::kNotCompressed ||
- GetObjectType(objnum) == ObjectType::kNull) {
+ if (GetObjectType(objnum) == ObjectType::kNotCompressed) {
FX_FILESIZE pos = m_ObjectInfo[objnum].pos;
if (pos <= 0)
return nullptr;
@@ -1208,52 +1200,43 @@ std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObject(
if (GetObjectType(objnum) != ObjectType::kCompressed)
return nullptr;
- RetainPtr<CPDF_StreamAcc> pObjStream =
- GetObjectStream(m_ObjectInfo[objnum].pos);
+ const CPDF_ObjectStream* pObjStream =
+ GetObjectStream(pObjList, m_ObjectInfo[objnum].pos);
if (!pObjStream)
return nullptr;
- auto file = pdfium::MakeRetain<CFX_MemoryStream>(
- const_cast<uint8_t*>(pObjStream->GetData()),
- static_cast<size_t>(pObjStream->GetSize()), false);
- CPDF_SyntaxParser syntax;
- syntax.InitParser(file, 0);
- const int32_t offset = GetStreamFirst(pObjStream);
-
- // Read object numbers from |pObjStream| into a cache.
- if (!pdfium::ContainsKey(m_ObjCache, pObjStream)) {
- for (int32_t i = GetStreamNCount(pObjStream); i > 0; --i) {
- uint32_t thisnum = syntax.GetDirectNum();
- uint32_t thisoff = syntax.GetDirectNum();
- m_ObjCache[pObjStream][thisnum] = thisoff;
- }
- }
+ return pObjStream->ParseObject(pObjList, objnum);
+}
- const auto it = m_ObjCache[pObjStream].find(objnum);
- if (it == m_ObjCache[pObjStream].end())
+const CPDF_ObjectStream* CPDF_Parser::GetObjectStream(
+ CPDF_IndirectObjectHolder* pObjList,
+ uint32_t object_number) {
+ // Prevent circular parsing the same object.
+ if (pdfium::ContainsKey(m_ParsingObjNums, object_number))
return nullptr;
- syntax.SetPos(offset + it->second);
- return syntax.GetObjectBody(pObjList);
-}
+ pdfium::ScopedSetInsertion<uint32_t> local_insert(&m_ParsingObjNums,
+ object_number);
-RetainPtr<CPDF_StreamAcc> CPDF_Parser::GetObjectStream(uint32_t objnum) {
- auto it = m_ObjectStreamMap.find(objnum);
+ auto it = m_ObjectStreamMap.find(object_number);
if (it != m_ObjectStreamMap.end())
- return it->second;
+ return it->second.get();
- if (!m_pDocument)
+ const FX_FILESIZE object_pos = GetObjectPositionOrZero(object_number);
+ if (object_pos <= 0)
return nullptr;
- const CPDF_Stream* pStream =
- ToStream(m_pDocument->GetOrParseIndirectObject(objnum));
- if (!pStream)
+ std::unique_ptr<CPDF_Object> object =
+ ParseIndirectObjectAt(pObjList, object_pos, object_number);
+ if (!object)
return nullptr;
- auto pStreamAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
- pStreamAcc->LoadAllDataFiltered();
- m_ObjectStreamMap[objnum] = pStreamAcc;
- return pStreamAcc;
+ std::unique_ptr<CPDF_ObjectStream> objs_stream =
+ CPDF_ObjectStream::Create(ToStream(object.get()));
+ const CPDF_ObjectStream* result = objs_stream.get();
+ m_ObjectStreamMap[object_number] = std::move(objs_stream);
+
+ return result;
}
std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObjectAt(
@@ -1437,7 +1420,6 @@ CPDF_Parser::Error CPDF_Parser::LoadLinearizedMainXRefTable() {
const AutoRestorer<uint32_t> save_metadata_objnum(&m_MetadataObjnum);
m_MetadataObjnum = 0;
m_ObjectStreamMap.clear();
- m_ObjCache.clear();
if (!LoadLinearizedAllCrossRefV4(main_xref_offset.ValueOrDie()) &&
!LoadLinearizedAllCrossRefV5(main_xref_offset.ValueOrDie())) {