diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/fpdfapi/edit/cpdf_creator.cpp | 330 | ||||
-rw-r--r-- | core/fpdfapi/edit/cpdf_creator.h | 13 | ||||
-rw-r--r-- | core/fpdfapi/edit/cpdf_objectstream.cpp | 87 | ||||
-rw-r--r-- | core/fpdfapi/edit/cpdf_objectstream.h | 53 | ||||
-rw-r--r-- | core/fpdfapi/edit/cpdf_xrefstream.cpp | 347 | ||||
-rw-r--r-- | core/fpdfapi/edit/cpdf_xrefstream.h | 62 |
6 files changed, 114 insertions, 778 deletions
diff --git a/core/fpdfapi/edit/cpdf_creator.cpp b/core/fpdfapi/edit/cpdf_creator.cpp index e782de3dbc..b318c7a7df 100644 --- a/core/fpdfapi/edit/cpdf_creator.cpp +++ b/core/fpdfapi/edit/cpdf_creator.cpp @@ -10,8 +10,6 @@ #include "core/fpdfapi/edit/cpdf_encryptor.h" #include "core/fpdfapi/edit/cpdf_flateencoder.h" -#include "core/fpdfapi/edit/cpdf_objectstream.h" -#include "core/fpdfapi/edit/cpdf_xrefstream.h" #include "core/fpdfapi/parser/cpdf_array.h" #include "core/fpdfapi/parser/cpdf_crypto_handler.h" #include "core/fpdfapi/parser/cpdf_document.h" @@ -24,7 +22,6 @@ namespace { -const uint32_t kXRefStreamMaxSize = 10000; const size_t kArchiveBufferSize = 32768; class CFX_FileBufferArchive : public IFX_ArchiveStream { @@ -161,40 +158,6 @@ CPDF_Creator::CPDF_Creator(CPDF_Document* pDoc, CPDF_Creator::~CPDF_Creator() {} -bool CPDF_Creator::IsXRefNeedEnd() { - if (!IsIncremental()) - return false; - return m_pXRefStream->CountIndexArrayItems() >= kXRefStreamMaxSize; -} - -bool CPDF_Creator::WriteIndirectObjectToStream(uint32_t objnum, - const uint8_t* pBuffer, - uint32_t dwSize) { - if (!m_pXRefStream) - return true; - - m_pXRefStream->AddObjectNumberToIndexArray(objnum); - if (!m_pXRefStream->CompressIndirectObject(objnum, pBuffer, dwSize, this)) - return false; - if (!IsXRefNeedEnd()) - return true; - if (!m_pXRefStream->End(this, false) || !m_pXRefStream->Start()) - return false; - return true; -} - -bool CPDF_Creator::AppendObjectNumberToXRef(uint32_t objnum) { - if (!m_pXRefStream) - return true; - - m_pXRefStream->AddObjectNumberToIndexArray(objnum); - if (!IsXRefNeedEnd()) - return true; - if (!m_pXRefStream->End(this, false) || !m_pXRefStream->Start()) - return false; - return true; -} - bool CPDF_Creator::WriteStream(const CPDF_Object* pStream, uint32_t objnum, CPDF_CryptoHandler* pCrypto) { @@ -231,41 +194,7 @@ bool CPDF_Creator::WriteIndirectObj(uint32_t objnum, const CPDF_Object* pObj) { return false; } - if (!m_Archive->WriteString("\r\nendobj\r\n") || - !AppendObjectNumberToXRef(objnum)) { - return false; - } - return true; -} - -bool CPDF_Creator::WriteIndirectObj(const CPDF_Object* pObj) { - uint32_t objnum = pObj->GetObjNum(); - if (!m_pXRefStream || (m_pParser && m_pParser->GetObjectGenNum(objnum) > 0) || - pObj->IsNumber()) { - return WriteIndirectObj(objnum, pObj); - } - - CPDF_Dictionary* pDict = pObj->GetDict(); - if (pObj->IsStream()) { - if (pDict && pDict->GetStringFor("Type") == "XRef") - return true; - return WriteIndirectObj(objnum, pObj); - } - - if (pDict && - (pDict == m_pDocument->GetRoot() || pDict == m_pEncryptDict || - pDict->IsSignatureDict() || pDict->GetStringFor("Type") == "Page")) { - return WriteIndirectObj(objnum, pObj); - } - - m_pXRefStream->AddObjectNumberToIndexArray(objnum); - if (!m_pXRefStream->CompressIndirectObject(objnum, pObj, this)) - return false; - if (!IsXRefNeedEnd()) - return true; - if (!m_pXRefStream->End(this, false) || !m_pXRefStream->Start()) - return false; - return true; + return m_Archive->WriteString("\r\nendobj\r\n"); } bool CPDF_Creator::WriteDirectObj(uint32_t objnum, @@ -388,13 +317,13 @@ bool CPDF_Creator::WriteOldIndirectObject(uint32_t objnum) { bool bExistInMap = !!m_pDocument->GetIndirectObject(objnum); const uint8_t object_type = m_pParser->GetObjectType(objnum); if (m_pParser->IsVersionUpdated() || m_bSecurityChanged || bExistInMap || - (object_type == 2 && m_pEncryptDict && !m_pXRefStream)) { + (object_type == 2 && m_pEncryptDict)) { CPDF_Object* pObj = m_pDocument->GetOrParseIndirectObject(objnum); if (!pObj) { m_ObjectOffsets.erase(objnum); return true; } - if (!WriteIndirectObj(pObj)) + if (!WriteIndirectObj(pObj->GetObjNum(), pObj)) return false; if (!bExistInMap) m_pDocument->DeleteIndirectObject(objnum); @@ -405,24 +334,15 @@ bool CPDF_Creator::WriteOldIndirectObject(uint32_t objnum) { if (!pBuffer) return true; if (object_type == 2) { - if (m_pXRefStream) { - if (!WriteIndirectObjectToStream(objnum, pBuffer, size)) { - FX_Free(pBuffer); - return false; - } - } else { - if (!m_Archive->WriteDWord(objnum) || - !m_Archive->WriteString(" 0 obj ") || - !m_Archive->WriteBlock(pBuffer, size) || - !m_Archive->WriteString("\r\nendobj\r\n")) { - return false; - } + if (!m_Archive->WriteDWord(objnum) || + !m_Archive->WriteString(" 0 obj ") || + !m_Archive->WriteBlock(pBuffer, size) || + !m_Archive->WriteString("\r\nendobj\r\n")) { + return false; } } else { - if (!m_Archive->WriteBlock(pBuffer, size) || - !AppendObjectNumberToXRef(objnum)) { + if (!m_Archive->WriteBlock(pBuffer, size)) return false; - } } FX_Free(pBuffer); } @@ -449,7 +369,7 @@ bool CPDF_Creator::WriteNewObjs() { continue; m_ObjectOffsets[objnum] = m_Archive->CurrentOffset(); - if (!WriteIndirectObj(pObj)) + if (!WriteIndirectObj(pObj->GetObjNum(), pObj)) return false; } return true; @@ -503,12 +423,6 @@ int32_t CPDF_Creator::WriteDoc_Stage1() { CPDF_Dictionary* pDict = m_pDocument->GetRoot(); m_pMetadata = pDict ? pDict->GetDirectObjectFor("Metadata") : nullptr; - if (HasObjectStream()) { - m_pXRefStream = pdfium::MakeUnique<CPDF_XRefStream>(); - m_pXRefStream->Start(); - if (IsIncremental() && m_pParser) - m_pXRefStream->SetPreviousOffset(m_pParser->GetLastXRefOffset()); - } m_iStage = 10; } if (m_iStage == 10) { @@ -561,12 +475,6 @@ int32_t CPDF_Creator::WriteDoc_Stage1() { continue; m_ObjectOffsets[num] = m_pParser->GetObjectPositionOrZero(num); - if (HasObjectStream()) - m_pXRefStream->AddObjectNumberToIndexArray(num); - } - if (HasObjectStream()) { - m_pXRefStream->EndXRefStream(this); - m_pXRefStream->Start(); } } m_iStage = 20; @@ -624,11 +532,7 @@ int32_t CPDF_Creator::WriteDoc_Stage3() { uint32_t dwLastObjNum = m_dwLastObjNum; if (m_iStage == 80) { m_XrefStart = m_Archive->CurrentOffset(); - if (HasObjectStream()) { - m_pXRefStream->End(this, true); - m_XrefStart = m_pXRefStream->GetPreviousOffset(); - m_iStage = 90; - } else if (!IsIncremental() || !m_pParser->IsXRefStream()) { + if (!IsIncremental() || !m_pParser->IsXRefStream()) { if (!IsIncremental() || m_pParser->GetLastXRefOffset() == 0) { CFX_ByteString str; str = pdfium::ContainsKey(m_ObjectOffsets, 1) @@ -722,139 +626,135 @@ int32_t CPDF_Creator::WriteDoc_Stage3() { int32_t CPDF_Creator::WriteDoc_Stage4() { ASSERT(m_iStage >= 90); - if (!HasObjectStream()) { - bool bXRefStream = IsIncremental() && m_pParser->IsXRefStream(); - if (!bXRefStream) { - if (!m_Archive->WriteString("trailer\r\n<<")) - return -1; - } else { - if (!m_Archive->WriteDWord(m_pDocument->GetLastObjNum() + 1) || - !m_Archive->WriteString(" 0 obj <<")) { - return -1; - } + bool bXRefStream = IsIncremental() && m_pParser->IsXRefStream(); + if (!bXRefStream) { + if (!m_Archive->WriteString("trailer\r\n<<")) + return -1; + } else { + if (!m_Archive->WriteDWord(m_pDocument->GetLastObjNum() + 1) || + !m_Archive->WriteString(" 0 obj <<")) { + return -1; } + } - if (m_pParser) { - CPDF_Dictionary* p = m_pParser->GetTrailer(); - for (const auto& it : *p) { - const CFX_ByteString& key = it.first; - CPDF_Object* pValue = it.second.get(); - // TODO(ochang): Consolidate with similar check in - // CPDF_XRefStream::WriteTrailer. - if (key == "Encrypt" || key == "Size" || key == "Filter" || - key == "Index" || key == "Length" || key == "Prev" || key == "W" || - key == "XRefStm" || key == "ID") { - continue; - } - if (!m_Archive->WriteString(("/")) || - !m_Archive->WriteString(PDF_NameEncode(key).AsStringC())) { - return -1; - } - if (!pValue->IsInline()) { - if (!m_Archive->WriteString(" ") || - !m_Archive->WriteDWord(pValue->GetObjNum()) || - !m_Archive->WriteString(" 0 R ")) { - return -1; - } - } else if (!pValue->WriteTo(m_Archive.get())) { - return -1; - } + if (m_pParser) { + CPDF_Dictionary* p = m_pParser->GetTrailer(); + for (const auto& it : *p) { + const CFX_ByteString& key = it.first; + CPDF_Object* pValue = it.second.get(); + if (key == "Encrypt" || key == "Size" || key == "Filter" || + key == "Index" || key == "Length" || key == "Prev" || key == "W" || + key == "XRefStm" || key == "ID") { + continue; } - } else { - if (!m_Archive->WriteString("\r\n/Root ") || - !m_Archive->WriteDWord(m_pDocument->GetRoot()->GetObjNum()) || - !m_Archive->WriteString(" 0 R\r\n")) { + if (!m_Archive->WriteString(("/")) || + !m_Archive->WriteString(PDF_NameEncode(key).AsStringC())) { return -1; } - if (m_pDocument->GetInfo()) { - if (!m_Archive->WriteString("/Info ") || - !m_Archive->WriteDWord(m_pDocument->GetInfo()->GetObjNum()) || - !m_Archive->WriteString(" 0 R\r\n")) { + if (!pValue->IsInline()) { + if (!m_Archive->WriteString(" ") || + !m_Archive->WriteDWord(pValue->GetObjNum()) || + !m_Archive->WriteString(" 0 R ")) { return -1; } + } else if (!pValue->WriteTo(m_Archive.get())) { + return -1; } } - if (m_pEncryptDict) { - if (!m_Archive->WriteString("/Encrypt")) - return -1; - - uint32_t dwObjNum = m_pEncryptDict->GetObjNum(); - if (dwObjNum == 0) - dwObjNum = m_pDocument->GetLastObjNum() + 1; - if (!m_Archive->WriteString(" ") || !m_Archive->WriteDWord(dwObjNum) || - !m_Archive->WriteString(" 0 R ")) { + } else { + if (!m_Archive->WriteString("\r\n/Root ") || + !m_Archive->WriteDWord(m_pDocument->GetRoot()->GetObjNum()) || + !m_Archive->WriteString(" 0 R\r\n")) { + return -1; + } + if (m_pDocument->GetInfo()) { + if (!m_Archive->WriteString("/Info ") || + !m_Archive->WriteDWord(m_pDocument->GetInfo()->GetObjNum()) || + !m_Archive->WriteString(" 0 R\r\n")) { return -1; } } + } + if (m_pEncryptDict) { + if (!m_Archive->WriteString("/Encrypt")) + return -1; - if (!m_Archive->WriteString("/Size ") || - !m_Archive->WriteDWord(m_dwLastObjNum + (bXRefStream ? 2 : 1))) { + uint32_t dwObjNum = m_pEncryptDict->GetObjNum(); + if (dwObjNum == 0) + dwObjNum = m_pDocument->GetLastObjNum() + 1; + if (!m_Archive->WriteString(" ") || !m_Archive->WriteDWord(dwObjNum) || + !m_Archive->WriteString(" 0 R ")) { return -1; } - if (IsIncremental()) { - FX_FILESIZE prev = m_pParser->GetLastXRefOffset(); - if (prev) { - if (!m_Archive->WriteString("/Prev ")) - return -1; + } + + if (!m_Archive->WriteString("/Size ") || + !m_Archive->WriteDWord(m_dwLastObjNum + (bXRefStream ? 2 : 1))) { + return -1; + } + if (IsIncremental()) { + FX_FILESIZE prev = m_pParser->GetLastXRefOffset(); + if (prev) { + if (!m_Archive->WriteString("/Prev ")) + return -1; - char offset_buf[20]; - memset(offset_buf, 0, sizeof(offset_buf)); - FXSYS_i64toa(prev, offset_buf, 10); - if (!m_Archive->WriteBlock(offset_buf, FXSYS_strlen(offset_buf))) + char offset_buf[20]; + memset(offset_buf, 0, sizeof(offset_buf)); + FXSYS_i64toa(prev, offset_buf, 10); + if (!m_Archive->WriteBlock(offset_buf, FXSYS_strlen(offset_buf))) + return -1; + } + } + if (m_pIDArray) { + if (!m_Archive->WriteString(("/ID")) || + !m_pIDArray->WriteTo(m_Archive.get())) { + return -1; + } + } + if (!bXRefStream) { + if (!m_Archive->WriteString(">>")) + return -1; + } else { + if (!m_Archive->WriteString("/W[0 4 1]/Index[")) + return -1; + if (IsIncremental() && m_pParser && m_pParser->GetLastXRefOffset() == 0) { + uint32_t i = 0; + for (i = 0; i < m_dwLastObjNum; i++) { + if (!pdfium::ContainsKey(m_ObjectOffsets, i)) + continue; + if (!m_Archive->WriteDWord(i) || !m_Archive->WriteString(" 1 ")) return -1; } - } - if (m_pIDArray) { - if (!m_Archive->WriteString(("/ID")) || - !m_pIDArray->WriteTo(m_Archive.get())) { + if (!m_Archive->WriteString("]/Length ") || + !m_Archive->WriteDWord(m_dwLastObjNum * 5) || + !m_Archive->WriteString(">>stream\r\n")) { return -1; } - } - if (!bXRefStream) { - if (!m_Archive->WriteString(">>")) - return -1; + for (i = 0; i < m_dwLastObjNum; i++) { + auto it = m_ObjectOffsets.find(i); + if (it == m_ObjectOffsets.end()) + continue; + OutputIndex(m_Archive.get(), it->second); + } } else { - if (!m_Archive->WriteString("/W[0 4 1]/Index[")) - return -1; - if (IsIncremental() && m_pParser && m_pParser->GetLastXRefOffset() == 0) { - uint32_t i = 0; - for (i = 0; i < m_dwLastObjNum; i++) { - if (!pdfium::ContainsKey(m_ObjectOffsets, i)) - continue; - if (!m_Archive->WriteDWord(i) || !m_Archive->WriteString(" 1 ")) - return -1; - } - if (!m_Archive->WriteString("]/Length ") || - !m_Archive->WriteDWord(m_dwLastObjNum * 5) || - !m_Archive->WriteString(">>stream\r\n")) { - return -1; - } - for (i = 0; i < m_dwLastObjNum; i++) { - auto it = m_ObjectOffsets.find(i); - if (it == m_ObjectOffsets.end()) - continue; - OutputIndex(m_Archive.get(), it->second); - } - } else { - size_t count = m_NewObjNumArray.size(); - size_t i = 0; - for (i = 0; i < count; i++) { - if (!m_Archive->WriteDWord(m_NewObjNumArray[i]) || - !m_Archive->WriteString(" 1 ")) { - return -1; - } - } - if (!m_Archive->WriteString("]/Length ") || - !m_Archive->WriteDWord(count * 5) || - !m_Archive->WriteString(">>stream\r\n")) { + size_t count = m_NewObjNumArray.size(); + size_t i = 0; + for (i = 0; i < count; i++) { + if (!m_Archive->WriteDWord(m_NewObjNumArray[i]) || + !m_Archive->WriteString(" 1 ")) { return -1; } - for (i = 0; i < count; ++i) - OutputIndex(m_Archive.get(), m_ObjectOffsets[m_NewObjNumArray[i]]); } - if (!m_Archive->WriteString("\r\nendstream")) + if (!m_Archive->WriteString("]/Length ") || + !m_Archive->WriteDWord(count * 5) || + !m_Archive->WriteString(">>stream\r\n")) { return -1; + } + for (i = 0; i < count; ++i) + OutputIndex(m_Archive.get(), m_ObjectOffsets[m_NewObjNumArray[i]]); } + if (!m_Archive->WriteString("\r\nendstream")) + return -1; } if (!m_Archive->WriteString("\r\nstartxref\r\n")) @@ -880,8 +780,6 @@ bool CPDF_Creator::Create(uint32_t flags) { m_NewObjNumArray.clear(); InitID(); - if (flags & FPDFCREATE_PROGRESSIVE) - return true; return Continue() > -1; } diff --git a/core/fpdfapi/edit/cpdf_creator.h b/core/fpdfapi/edit/cpdf_creator.h index 3d85d5e0a4..618fffde79 100644 --- a/core/fpdfapi/edit/cpdf_creator.h +++ b/core/fpdfapi/edit/cpdf_creator.h @@ -20,12 +20,9 @@ class CPDF_Dictionary; class CPDF_Document; class CPDF_Object; class CPDF_Parser; -class CPDF_XRefStream; #define FPDFCREATE_INCREMENTAL 1 #define FPDFCREATE_NO_ORIGINAL 2 -#define FPDFCREATE_PROGRESSIVE 4 -#define FPDFCREATE_OBJECTSTREAM 8 class CPDF_Creator { public: @@ -57,9 +54,6 @@ class CPDF_Creator { } bool IsIncremental() const { return !!(m_dwFlags & FPDFCREATE_INCREMENTAL); } bool IsOriginal() const { return !(m_dwFlags & FPDFCREATE_NO_ORIGINAL); } - bool HasObjectStream() const { - return !!(m_dwFlags & FPDFCREATE_OBJECTSTREAM); - } private: void Clear(); @@ -68,8 +62,6 @@ class CPDF_Creator { void InitNewObjNumOffsets(); void InitID(); - bool AppendObjectNumberToXRef(uint32_t objnum); - int32_t WriteDoc_Stage1(); int32_t WriteDoc_Stage2(); int32_t WriteDoc_Stage3(); @@ -78,12 +70,8 @@ class CPDF_Creator { bool WriteOldIndirectObject(uint32_t objnum); bool WriteOldObjs(); bool WriteNewObjs(); - bool WriteIndirectObj(const CPDF_Object* pObj); bool WriteDirectObj(uint32_t objnum, const CPDF_Object* pObj, bool bEncrypt); bool WriteIndirectObj(uint32_t objnum, const CPDF_Object* pObj); - bool WriteIndirectObjectToStream(uint32_t objnum, - const uint8_t* pBuffer, - uint32_t dwSize); bool WriteStream(const CPDF_Object* pStream, uint32_t objnum, @@ -98,7 +86,6 @@ class CPDF_Creator { uint32_t m_dwEncryptObjNum; CFX_RetainPtr<CPDF_CryptoHandler> m_pCryptoHandler; CPDF_Object* m_pMetadata; - std::unique_ptr<CPDF_XRefStream> m_pXRefStream; uint32_t m_dwLastObjNum; std::unique_ptr<IFX_ArchiveStream> m_Archive; FX_FILESIZE m_SavedOffset; diff --git a/core/fpdfapi/edit/cpdf_objectstream.cpp b/core/fpdfapi/edit/cpdf_objectstream.cpp deleted file mode 100644 index 208adacf47..0000000000 --- a/core/fpdfapi/edit/cpdf_objectstream.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2017 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 "core/fpdfapi/edit/cpdf_objectstream.h" - -#include "core/fpdfapi/edit/cpdf_creator.h" -#include "core/fpdfapi/edit/cpdf_encryptor.h" -#include "core/fpdfapi/edit/cpdf_flateencoder.h" -#include "core/fpdfapi/parser/fpdf_parser_utility.h" - -namespace { - -const int kObjectStreamMaxLength = 256 * 1024; - -} // namespace - -CPDF_ObjectStream::CPDF_ObjectStream() : m_dwObjNum(0), m_index(0) {} - -CPDF_ObjectStream::~CPDF_ObjectStream() {} - -bool CPDF_ObjectStream::IsNotFull() const { - return m_Buffer.GetLength() < kObjectStreamMaxLength; -} - -void CPDF_ObjectStream::Start() { - m_Items.clear(); - m_Buffer.Clear(); - m_dwObjNum = 0; - m_index = 0; -} - -void CPDF_ObjectStream::CompressIndirectObject(uint32_t dwObjNum, - const CPDF_Object* pObj) { - m_Items.push_back({dwObjNum, m_Buffer.GetLength()}); - m_Buffer << pObj; -} - -void CPDF_ObjectStream::CompressIndirectObject(uint32_t dwObjNum, - const uint8_t* pBuffer, - uint32_t dwSize) { - m_Items.push_back({dwObjNum, m_Buffer.GetLength()}); - m_Buffer.AppendBlock(pBuffer, dwSize); -} - -FX_FILESIZE CPDF_ObjectStream::End(CPDF_Creator* pCreator) { - ASSERT(pCreator); - - if (m_Items.empty()) - return 0; - - IFX_ArchiveStream* archive = pCreator->GetArchive(); - FX_FILESIZE ObjOffset = archive->CurrentOffset(); - if (!m_dwObjNum) - m_dwObjNum = pCreator->GetNextObjectNumber(); - - CFX_ByteTextBuf tempBuffer; - for (const auto& pair : m_Items) - tempBuffer << pair.objnum << " " << pair.offset << " "; - - if (!archive->WriteDWord(m_dwObjNum) || - !archive->WriteString(" 0 obj\r\n<</Type /ObjStm /N ") || - !archive->WriteDWord(pdfium::CollectionSize<uint32_t>(m_Items)) || - !archive->WriteString("/First ") || - !archive->WriteDWord(static_cast<uint32_t>(tempBuffer.GetLength())) || - !archive->WriteString("/Length ")) { - return -1; - } - tempBuffer << m_Buffer; - - CPDF_FlateEncoder encoder(tempBuffer.GetBuffer(), tempBuffer.GetLength(), - true, false); - CPDF_Encryptor encryptor(pCreator->GetCryptoHandler(), m_dwObjNum, - encoder.GetData(), encoder.GetSize()); - - if (!archive->WriteDWord(encryptor.GetSize()) || - !archive->WriteString("/Filter /FlateDecode") || - !archive->WriteString(">>stream\r\n") || - !archive->WriteBlock(encryptor.GetData(), encryptor.GetSize()) || - !archive->WriteString("\r\nendstream\r\nendobj\r\n")) { - return -1; - } - - return ObjOffset; -} diff --git a/core/fpdfapi/edit/cpdf_objectstream.h b/core/fpdfapi/edit/cpdf_objectstream.h deleted file mode 100644 index 5ad6ec8085..0000000000 --- a/core/fpdfapi/edit/cpdf_objectstream.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2017 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 - -#ifndef CORE_FPDFAPI_EDIT_CPDF_OBJECTSTREAM_H_ -#define CORE_FPDFAPI_EDIT_CPDF_OBJECTSTREAM_H_ - -#include <vector> - -#include "core/fxcrt/fx_basic.h" -#include "third_party/base/stl_util.h" - -class CPDF_Creator; -class CPDF_Object; - -class CPDF_ObjectStream { - public: - struct Item { - uint32_t objnum; - FX_STRSIZE offset; - }; - - CPDF_ObjectStream(); - ~CPDF_ObjectStream(); - - void Start(); - FX_FILESIZE End(CPDF_Creator* pCreator); - void CompressIndirectObject(uint32_t dwObjNum, const CPDF_Object* pObj); - void CompressIndirectObject(uint32_t dwObjNum, - const uint8_t* pBuffer, - uint32_t dwSize); - - bool IsNotFull() const; - int32_t ItemCount() const { return pdfium::CollectionSize<int32_t>(m_Items); } - void SetObjectNumber(uint32_t num) { m_dwObjNum = num; } - uint32_t GetObjectNumber() const { return m_dwObjNum; } - int32_t GetIndex() const { return m_index; } - void IncrementIndex() { m_index++; } - - uint32_t GetObjectNumberForItem(int index) const { - return m_Items[index].objnum; - } - - private: - std::vector<Item> m_Items; - CFX_ByteTextBuf m_Buffer; - uint32_t m_dwObjNum; - int32_t m_index; -}; - -#endif // CORE_FPDFAPI_EDIT_CPDF_OBJECTSTREAM_H_ diff --git a/core/fpdfapi/edit/cpdf_xrefstream.cpp b/core/fpdfapi/edit/cpdf_xrefstream.cpp deleted file mode 100644 index 67793b244d..0000000000 --- a/core/fpdfapi/edit/cpdf_xrefstream.cpp +++ /dev/null @@ -1,347 +0,0 @@ -// Copyright 2017 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 "core/fpdfapi/edit/cpdf_xrefstream.h" - -#include "core/fpdfapi/edit/cpdf_creator.h" -#include "core/fpdfapi/edit/cpdf_flateencoder.h" -#include "core/fpdfapi/parser/cpdf_array.h" -#include "core/fpdfapi/parser/cpdf_document.h" -#include "core/fpdfapi/parser/cpdf_parser.h" -#include "core/fpdfapi/parser/fpdf_parser_decode.h" - -namespace { - -const int32_t kObjectStreamMaxSize = 200; - -bool WriteTrailer(CPDF_Document* pDocument, - IFX_ArchiveStream* archive, - CPDF_Array* pIDArray) { - CPDF_Parser* pParser = pDocument->GetParser(); - if (pParser) { - CPDF_Dictionary* p = pParser->GetTrailer(); - for (const auto& it : *p) { - const CFX_ByteString& key = it.first; - CPDF_Object* pValue = it.second.get(); - if (key == "Encrypt" || key == "Size" || key == "Filter" || - key == "Index" || key == "Length" || key == "Prev" || key == "W" || - key == "XRefStm" || key == "Type" || key == "ID") { - continue; - } - if (key == "DecodeParms") - continue; - if (!archive->WriteString(("/")) || - !archive->WriteString(PDF_NameEncode(key).AsStringC())) { - return false; - } - - if (!pValue->IsInline()) { - if (!archive->WriteString(" ") || - !archive->WriteDWord(pValue->GetObjNum()) || - !archive->WriteString(" 0 R ")) { - return false; - } - } else if (!pValue->WriteTo(archive)) { - return false; - } - } - if (pIDArray) { - if (!archive->WriteString(("/ID")) || !pIDArray->WriteTo(archive)) - return false; - } - return true; - } - if (!archive->WriteString("\r\n/Root ") || - !archive->WriteDWord(pDocument->GetRoot()->GetObjNum()) || - !archive->WriteString(" 0 R\r\n")) { - return false; - } - - if (pDocument->GetInfo()) { - if (!archive->WriteString("/Info ") || - !archive->WriteDWord(pDocument->GetInfo()->GetObjNum()) || - !archive->WriteString(" 0 R\r\n")) { - return false; - } - } - if (pIDArray) { - if (!archive->WriteString(("/ID")) || !pIDArray->WriteTo(archive)) - return false; - } - return true; -} - -bool WriteEncryptDictObjectReference(uint32_t dwObjNum, - IFX_ArchiveStream* archive) { - ASSERT(archive); - - if (!archive->WriteString("/Encrypt") || !archive->WriteString(" ") || - !archive->WriteDWord(dwObjNum) || !archive->WriteString(" 0 R ")) { - return false; - } - return true; -} - -void AppendIndex0(CFX_ByteTextBuf& buffer, bool bFirstObject) { - buffer.AppendByte(0); - buffer.AppendByte(0); - buffer.AppendByte(0); - buffer.AppendByte(0); - buffer.AppendByte(0); - - const uint8_t byte = bFirstObject ? 0xFF : 0; - buffer.AppendByte(byte); - buffer.AppendByte(byte); -} - -void AppendIndex1(CFX_ByteTextBuf& buffer, FX_FILESIZE offset) { - buffer.AppendByte(1); - buffer.AppendByte(static_cast<uint8_t>(offset >> 24)); - buffer.AppendByte(static_cast<uint8_t>(offset >> 16)); - buffer.AppendByte(static_cast<uint8_t>(offset >> 8)); - buffer.AppendByte(static_cast<uint8_t>(offset)); - buffer.AppendByte(0); - buffer.AppendByte(0); -} - -void AppendIndex2(CFX_ByteTextBuf& buffer, uint32_t objnum, int32_t index) { - buffer.AppendByte(2); - buffer.AppendByte(static_cast<uint8_t>(objnum >> 24)); - buffer.AppendByte(static_cast<uint8_t>(objnum >> 16)); - buffer.AppendByte(static_cast<uint8_t>(objnum >> 8)); - buffer.AppendByte(static_cast<uint8_t>(objnum)); - buffer.AppendByte(static_cast<uint8_t>(index >> 8)); - buffer.AppendByte(static_cast<uint8_t>(index)); -} - -} // namespace - -CPDF_XRefStream::CPDF_XRefStream() - : m_PrevOffset(0), m_dwTempObjNum(0), m_iSeg(0) {} - -CPDF_XRefStream::~CPDF_XRefStream() {} - -bool CPDF_XRefStream::Start() { - m_IndexArray.clear(); - m_Buffer.Clear(); - m_iSeg = 0; - return true; -} - -bool CPDF_XRefStream::CompressIndirectObject(uint32_t dwObjNum, - const CPDF_Object* pObj, - CPDF_Creator* pCreator) { - ASSERT(pCreator); - - m_ObjStream.CompressIndirectObject(dwObjNum, pObj); - if (m_ObjStream.ItemCount() < kObjectStreamMaxSize && - m_ObjStream.IsNotFull()) { - return true; - } - return EndObjectStream(pCreator, true); -} - -bool CPDF_XRefStream::CompressIndirectObject(uint32_t dwObjNum, - const uint8_t* pBuffer, - uint32_t dwSize, - CPDF_Creator* pCreator) { - ASSERT(pCreator); - - m_ObjStream.CompressIndirectObject(dwObjNum, pBuffer, dwSize); - if (m_ObjStream.ItemCount() < kObjectStreamMaxSize && - m_ObjStream.IsNotFull()) { - return true; - } - return EndObjectStream(pCreator, true); -} - -bool CPDF_XRefStream::EndObjectStream(CPDF_Creator* pCreator, bool bEOF) { - FX_FILESIZE objOffset = 0; - if (bEOF) { - objOffset = m_ObjStream.End(pCreator); - if (objOffset < 0) - return false; - } - - if (!m_ObjStream.GetObjectNumber()) - m_ObjStream.SetObjectNumber(pCreator->GetNextObjectNumber()); - - int32_t iSize = m_ObjStream.ItemCount(); - size_t iSeg = m_IndexArray.size(); - if (!pCreator->IsIncremental()) { - if (m_dwTempObjNum == 0) { - AppendIndex0(m_Buffer, true); - m_dwTempObjNum++; - } - uint32_t end_num = m_IndexArray.back().objnum + m_IndexArray.back().count; - int index = 0; - for (; m_dwTempObjNum < end_num; m_dwTempObjNum++) { - if (pCreator->HasObjectNumber(m_dwTempObjNum)) { - if (index >= iSize || - m_dwTempObjNum != m_ObjStream.GetObjectNumberForItem(index)) { - AppendIndex1(m_Buffer, pCreator->GetObjectOffset(m_dwTempObjNum)); - } else { - AppendIndex2(m_Buffer, m_ObjStream.GetObjectNumber(), index++); - } - } else { - AppendIndex0(m_Buffer, false); - } - } - if (iSize > 0 && bEOF) - pCreator->SetObjectOffset(m_ObjStream.GetObjectNumber(), objOffset); - - m_iSeg = iSeg; - if (bEOF) - m_ObjStream.Start(); - - return true; - } - - for (auto it = m_IndexArray.begin() + m_iSeg; it != m_IndexArray.end(); - ++it) { - for (uint32_t m = it->objnum; m < it->objnum + it->count; ++m) { - if (m_ObjStream.GetIndex() >= iSize || - m != m_ObjStream.GetObjectNumberForItem(it - m_IndexArray.begin())) { - AppendIndex1(m_Buffer, pCreator->GetObjectOffset(m)); - } else { - AppendIndex2(m_Buffer, m_ObjStream.GetObjectNumber(), - m_ObjStream.GetIndex()); - m_ObjStream.IncrementIndex(); - } - } - } - if (iSize > 0 && bEOF) { - AppendIndex1(m_Buffer, objOffset); - m_IndexArray.push_back({m_ObjStream.GetObjectNumber(), 1}); - iSeg += 1; - } - m_iSeg = iSeg; - if (bEOF) - m_ObjStream.Start(); - - return true; -} - -bool CPDF_XRefStream::GenerateXRefStream(CPDF_Creator* pCreator, bool bEOF) { - uint32_t objnum = pCreator->GetNextObjectNumber(); - IFX_ArchiveStream* archive = pCreator->GetArchive(); - FX_FILESIZE offset_tmp = archive->CurrentOffset(); - - if (pCreator->IsIncremental()) { - AddObjectNumberToIndexArray(objnum); - } else { - for (; m_dwTempObjNum < pCreator->GetLastObjectNumber(); m_dwTempObjNum++) { - if (pCreator->HasObjectNumber(m_dwTempObjNum)) - AppendIndex1(m_Buffer, pCreator->GetObjectOffset(m_dwTempObjNum)); - else - AppendIndex0(m_Buffer, false); - } - } - - AppendIndex1(m_Buffer, offset_tmp); - - if (!archive->WriteDWord(objnum) || - !archive->WriteString(" 0 obj\r\n<</Type /XRef/W[1 4 2]/Index[")) { - return false; - } - - if (!pCreator->IsIncremental()) { - if (!archive->WriteDWord(0) || !archive->WriteString(" ") || - !archive->WriteDWord(objnum + 1)) { - return false; - } - } else { - for (const auto& pair : m_IndexArray) { - if (!archive->WriteDWord(pair.objnum) || !archive->WriteString(" ") || - !archive->WriteDWord(pair.count) || !archive->WriteString(" ")) { - return false; - } - } - } - if (!archive->WriteString("]/Size ") || !archive->WriteDWord(objnum + 1)) - return false; - - if (m_PrevOffset > 0) { - if (!archive->WriteString("/Prev ")) - return false; - - char offset_buf[20]; - memset(offset_buf, 0, sizeof(offset_buf)); - FXSYS_i64toa(m_PrevOffset, offset_buf, 10); - int32_t offset_len = (int32_t)FXSYS_strlen(offset_buf); - if (!archive->WriteBlock(offset_buf, offset_len)) - return false; - } - - CPDF_FlateEncoder encoder(m_Buffer.GetBuffer(), m_Buffer.GetLength(), true, - true); - if (!archive->WriteString("/Filter /FlateDecode") || - !archive->WriteString("/DecodeParms<</Columns 7/Predictor 12>>") || - !archive->WriteString("/Length ") || - !archive->WriteDWord(encoder.GetSize())) { - return false; - } - - if (bEOF) { - if (!WriteTrailer(pCreator->GetDocument(), archive, pCreator->GetIDArray())) - return false; - - if (CPDF_Dictionary* encryptDict = pCreator->GetEncryptDict()) { - uint32_t dwEncryptObjNum = encryptDict->GetObjNum(); - if (dwEncryptObjNum == 0) - dwEncryptObjNum = pCreator->GetEncryptObjectNumber(); - - if (!WriteEncryptDictObjectReference(dwEncryptObjNum, archive)) - return false; - } - } - - if (!archive->WriteString(">>stream\r\n") || - !archive->WriteBlock(encoder.GetData(), encoder.GetSize()) || - !archive->WriteString("\r\nendstream\r\nendobj\r\n")) { - return false; - } - - m_PrevOffset = offset_tmp; - return true; -} - -bool CPDF_XRefStream::End(CPDF_Creator* pCreator, bool bEOF) { - if (!EndObjectStream(pCreator, bEOF)) - return false; - return GenerateXRefStream(pCreator, bEOF); -} - -bool CPDF_XRefStream::EndXRefStream(CPDF_Creator* pCreator) { - if (!pCreator->IsIncremental()) { - AppendIndex0(m_Buffer, true); - for (uint32_t i = 1; i < pCreator->GetLastObjectNumber() + 1; i++) { - if (pCreator->HasObjectNumber(i)) - AppendIndex1(m_Buffer, pCreator->GetObjectOffset(i)); - else - AppendIndex0(m_Buffer, false); - } - } else { - for (const auto& pair : m_IndexArray) { - for (uint32_t j = pair.objnum; j < pair.objnum + pair.count; ++j) - AppendIndex1(m_Buffer, pCreator->GetObjectOffset(j)); - } - } - return GenerateXRefStream(pCreator, false); -} - -void CPDF_XRefStream::AddObjectNumberToIndexArray(uint32_t objnum) { - if (m_IndexArray.empty()) { - m_IndexArray.push_back({objnum, 1}); - return; - } - - uint32_t next_objnum = m_IndexArray.back().objnum + m_IndexArray.back().count; - if (objnum == next_objnum) - m_IndexArray.back().count += 1; - else - m_IndexArray.push_back({objnum, 1}); -} diff --git a/core/fpdfapi/edit/cpdf_xrefstream.h b/core/fpdfapi/edit/cpdf_xrefstream.h deleted file mode 100644 index 33869c656a..0000000000 --- a/core/fpdfapi/edit/cpdf_xrefstream.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2017 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 - -#ifndef CORE_FPDFAPI_EDIT_CPDF_XREFSTREAM_H_ -#define CORE_FPDFAPI_EDIT_CPDF_XREFSTREAM_H_ - -#include <vector> - -#include "core/fpdfapi/edit/cpdf_objectstream.h" -#include "core/fxcrt/fx_basic.h" - -class CPDF_Creator; -class CPDF_Object; - -class CPDF_XRefStream { - public: - struct Index { - uint32_t objnum; - uint32_t count; - }; - - CPDF_XRefStream(); - ~CPDF_XRefStream(); - - bool Start(); - bool CompressIndirectObject(uint32_t dwObjNum, - const CPDF_Object* pObj, - CPDF_Creator* pCreator); - bool CompressIndirectObject(uint32_t dwObjNum, - const uint8_t* pBuffer, - uint32_t dwSize, - CPDF_Creator* pCreator); - bool End(CPDF_Creator* pCreator, bool bEOF); - void AddObjectNumberToIndexArray(uint32_t objnum); - bool EndXRefStream(CPDF_Creator* pCreator); - - FX_FILESIZE GetPreviousOffset() const { return m_PrevOffset; } - void SetPreviousOffset(FX_FILESIZE offset) { m_PrevOffset = offset; } - - uint32_t CountIndexArrayItems() const { - uint32_t size = 0; - for (const auto& pair : m_IndexArray) - size += pair.count; - return size; - } - - private: - bool EndObjectStream(CPDF_Creator* pCreator, bool bEOF); - bool GenerateXRefStream(CPDF_Creator* pCreator, bool bEOF); - - std::vector<Index> m_IndexArray; - FX_FILESIZE m_PrevOffset; - uint32_t m_dwTempObjNum; - size_t m_iSeg; - CPDF_ObjectStream m_ObjStream; - CFX_ByteTextBuf m_Buffer; -}; - -#endif // CORE_FPDFAPI_EDIT_CPDF_XREFSTREAM_H_ |