Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cpdf_cross_ref_table.cpp
Go to the documentation of this file.
1// Copyright 2018 The PDFium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "core/fpdfapi/parser/cpdf_cross_ref_table.h"
6
7#include <utility>
8
9#include "core/fpdfapi/parser/cpdf_dictionary.h"
10#include "core/fpdfapi/parser/cpdf_parser.h"
11#include "third_party/base/check_op.h"
12#include "third_party/base/containers/contains.h"
13
14// static
15std::unique_ptr<CPDF_CrossRefTable> CPDF_CrossRefTable::MergeUp(
16 std::unique_ptr<CPDF_CrossRefTable> current,
17 std::unique_ptr<CPDF_CrossRefTable> top) {
18 if (!current)
19 return top;
20
21 if (!top)
22 return current;
23
24 current->Update(std::move(top));
25 return current;
26}
27
29
31 uint32_t trailer_object_number)
33 trailer_object_number_(trailer_object_number) {}
34
36
37void CPDF_CrossRefTable::AddCompressed(uint32_t obj_num,
38 uint32_t archive_obj_num,
39 uint32_t archive_obj_index) {
40 CHECK_LT(obj_num, CPDF_Parser::kMaxObjectNumber);
41 CHECK_LT(archive_obj_num, CPDF_Parser::kMaxObjectNumber);
42
43 auto& info = objects_info_[obj_num];
44 if (info.gennum > 0)
45 return;
46
47 // Don't add known object streams to object streams.
48 if (info.is_object_stream_flag) {
49 return;
50 }
51
52 info.type = ObjectType::kCompressed;
53 info.archive.obj_num = archive_obj_num;
54 info.archive.obj_index = archive_obj_index;
55 info.gennum = 0;
56
57 objects_info_[archive_obj_num].is_object_stream_flag = true;
58}
59
60void CPDF_CrossRefTable::AddNormal(uint32_t obj_num,
61 uint16_t gen_num,
62 bool is_object_stream,
63 FX_FILESIZE pos) {
64 CHECK_LT(obj_num, CPDF_Parser::kMaxObjectNumber);
65
66 auto& info = objects_info_[obj_num];
67 if (info.gennum > gen_num)
68 return;
69
70 if (info.type == ObjectType::kCompressed && gen_num == 0)
71 return;
72
73 info.type = ObjectType::kNormal;
74 info.is_object_stream_flag |= is_object_stream;
75 info.gennum = gen_num;
76 info.pos = pos;
77}
78
79void CPDF_CrossRefTable::SetFree(uint32_t obj_num) {
80 CHECK_LT(obj_num, CPDF_Parser::kMaxObjectNumber);
81
82 auto& info = objects_info_[obj_num];
83 info.type = ObjectType::kFree;
84 info.gennum = 0xFFFF;
85 info.pos = 0;
86}
87
88void CPDF_CrossRefTable::SetTrailer(RetainPtr<CPDF_Dictionary> trailer,
89 uint32_t trailer_object_number) {
90 trailer_ = std::move(trailer);
91 trailer_object_number_ = trailer_object_number;
92}
93
95 uint32_t obj_num) const {
96 const auto it = objects_info_.find(obj_num);
97 return it != objects_info_.end() ? &it->second : nullptr;
98}
99
101 std::unique_ptr<CPDF_CrossRefTable> new_cross_ref) {
102 UpdateInfo(std::move(new_cross_ref->objects_info_));
103 UpdateTrailer(std::move(new_cross_ref->trailer_));
104}
105
107 if (size == 0) {
108 objects_info_.clear();
109 return;
110 }
111
112 objects_info_.erase(objects_info_.lower_bound(size), objects_info_.end());
113
114 if (!pdfium::Contains(objects_info_, size - 1)) {
115 objects_info_[size - 1].pos = 0;
116 }
117}
118
119void CPDF_CrossRefTable::UpdateInfo(
120 std::map<uint32_t, ObjectInfo> new_objects_info) {
121 if (new_objects_info.empty()) {
122 return;
123 }
124
125 if (objects_info_.empty()) {
126 objects_info_ = std::move(new_objects_info);
127 return;
128 }
129
130 auto cur_it = objects_info_.begin();
131 auto new_it = new_objects_info.begin();
132 while (cur_it != objects_info_.end() && new_it != new_objects_info.end()) {
133 if (cur_it->first == new_it->first) {
134 if (new_it->second.type == ObjectType::kNormal &&
135 cur_it->second.type == ObjectType::kNormal &&
136 cur_it->second.is_object_stream_flag) {
137 new_it->second.is_object_stream_flag = true;
138 }
139 ++cur_it;
140 ++new_it;
141 } else if (cur_it->first < new_it->first) {
142 new_objects_info.insert(new_it, *cur_it);
143 ++cur_it;
144 } else {
145 new_it = new_objects_info.lower_bound(cur_it->first);
146 }
147 }
148 for (; cur_it != objects_info_.end(); ++cur_it) {
149 new_objects_info.insert(new_objects_info.end(), *cur_it);
150 }
151 objects_info_ = std::move(new_objects_info);
152}
153
154void CPDF_CrossRefTable::UpdateTrailer(RetainPtr<CPDF_Dictionary> new_trailer) {
155 if (!new_trailer)
156 return;
157
158 if (!trailer_) {
159 trailer_ = std::move(new_trailer);
160 return;
161 }
162
163 new_trailer->SetFor("XRefStm", trailer_->RemoveFor("XRefStm"));
164 new_trailer->SetFor("Prev", trailer_->RemoveFor("Prev"));
165
166 for (const auto& key : new_trailer->GetKeys())
167 trailer_->SetFor(key, new_trailer->RemoveFor(key.AsStringView()));
168}
void SetFree(uint32_t obj_num)
const ObjectInfo * GetObjectInfo(uint32_t obj_num) const
CPDF_CrossRefTable(RetainPtr< CPDF_Dictionary > trailer, uint32_t trailer_object_number)
void Update(std::unique_ptr< CPDF_CrossRefTable > new_cross_ref)
void AddCompressed(uint32_t obj_num, uint32_t archive_obj_num, uint32_t archive_obj_index)
void AddNormal(uint32_t obj_num, uint16_t gen_num, bool is_object_stream, FX_FILESIZE pos)
void SetTrailer(RetainPtr< CPDF_Dictionary > trailer, uint32_t trailer_object_number)
void SetObjectMapSize(uint32_t size)
static constexpr uint32_t kMaxObjectNumber
Definition cpdf_parser.h:57
#define FX_FILESIZE
Definition fx_types.h:19