diff options
author | Artem Strygin <art-snake@yandex-team.ru> | 2018-06-26 16:01:38 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2018-06-26 16:01:38 +0000 |
commit | e3d3ce04e585c4a6c5596056bdf1ced639c763d7 (patch) | |
tree | 55ba6fde26546f818d8ffadc879087ada34502ab /core/fpdfapi/parser/cpdf_parser.cpp | |
parent | 08b6819660a69cdc83bd133d1074da5813d9e414 (diff) | |
download | pdfium-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.cpp | 70 |
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())) { |