• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)20 CPDF_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()57 CPDF_FlateEncoder::~CPDF_FlateEncoder() {}
58 
CloneDict()59 void 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()70 CPDF_Dictionary* CPDF_FlateEncoder::GetClonedDict() {
71   ASSERT(!m_pDict);
72   return m_pClonedDict.Get();
73 }
74 
GetDict() const75 const 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