1 // Copyright 2017 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "core/fpdfapi/parser/cpdf_flateencoder.h" 8 9 #include <memory> 10 #include <utility> 11 12 #include "constants/stream_dict_common.h" 13 #include "core/fpdfapi/parser/cpdf_dictionary.h" 14 #include "core/fpdfapi/parser/cpdf_name.h" 15 #include "core/fpdfapi/parser/cpdf_number.h" 16 #include "core/fpdfapi/parser/cpdf_stream.h" 17 #include "core/fpdfapi/parser/cpdf_stream_acc.h" 18 #include "core/fpdfapi/parser/fpdf_parser_decode.h" 19 CPDF_FlateEncoder(const CPDF_Stream * pStream,bool bFlateEncode)20CPDF_FlateEncoder::CPDF_FlateEncoder(const CPDF_Stream* pStream, 21 bool bFlateEncode) 22 : m_pAcc(pdfium::MakeRetain<CPDF_StreamAcc>(pStream)), m_dwSize(0) { 23 m_pAcc->LoadAllDataRaw(); 24 25 bool bHasFilter = pStream->HasFilter(); 26 if (bHasFilter && !bFlateEncode) { 27 auto pDestAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream); 28 pDestAcc->LoadAllDataFiltered(); 29 30 m_dwSize = pDestAcc->GetSize(); 31 m_pData = pDestAcc->DetachData(); 32 m_pClonedDict = ToDictionary(pStream->GetDict()->Clone()); 33 m_pClonedDict->RemoveFor("Filter"); 34 ASSERT(!m_pDict); 35 return; 36 } 37 if (bHasFilter || !bFlateEncode) { 38 m_pData = m_pAcc->GetData(); 39 m_dwSize = m_pAcc->GetSize(); 40 m_pDict.Reset(pStream->GetDict()); 41 ASSERT(!m_pClonedDict); 42 return; 43 } 44 45 // TODO(thestig): Move to Init() and check return value. 46 std::unique_ptr<uint8_t, FxFreeDeleter> buffer; 47 ::FlateEncode(m_pAcc->GetSpan(), &buffer, &m_dwSize); 48 49 m_pData = std::move(buffer); 50 m_pClonedDict = ToDictionary(pStream->GetDict()->Clone()); 51 m_pClonedDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(m_dwSize)); 52 m_pClonedDict->SetNewFor<CPDF_Name>("Filter", "FlateDecode"); 53 m_pClonedDict->RemoveFor(pdfium::stream::kDecodeParms); 54 ASSERT(!m_pDict); 55 } 56 ~CPDF_FlateEncoder()57CPDF_FlateEncoder::~CPDF_FlateEncoder() {} 58 CloneDict()59void CPDF_FlateEncoder::CloneDict() { 60 if (m_pClonedDict) { 61 ASSERT(!m_pDict); 62 return; 63 } 64 65 m_pClonedDict = ToDictionary(m_pDict->Clone()); 66 ASSERT(m_pClonedDict); 67 m_pDict.Reset(); 68 } 69 GetClonedDict()70CPDF_Dictionary* CPDF_FlateEncoder::GetClonedDict() { 71 ASSERT(!m_pDict); 72 return m_pClonedDict.Get(); 73 } 74 GetDict() const75const CPDF_Dictionary* CPDF_FlateEncoder::GetDict() const { 76 if (m_pClonedDict) { 77 ASSERT(!m_pDict); 78 return m_pClonedDict.Get(); 79 } 80 81 return m_pDict.Get(); 82 } 83