Commit a8c93bd324d0362a26c1e6591eead5c52f865c0d

Authored by Jay Berkenbilt
1 parent 8288a4eb

Push QPDF member variables into a nested class

Pushing member variables into a nested class enables addition of new
member variables without breaking binary compatibility.
include/qpdf/QPDF.hh
@@ -635,11 +635,11 @@ class QPDF @@ -635,11 +635,11 @@ class QPDF
635 qpdf(qpdf), 635 qpdf(qpdf),
636 og(og) 636 og(og)
637 { 637 {
638 - qpdf->resolving.insert(og); 638 + qpdf->m->resolving.insert(og);
639 } 639 }
640 virtual ~ResolveRecorder() 640 virtual ~ResolveRecorder()
641 { 641 {
642 - this->qpdf->resolving.erase(og); 642 + this->qpdf->m->resolving.erase(og);
643 } 643 }
644 private: 644 private:
645 QPDF* qpdf; 645 QPDF* qpdf;
@@ -1113,79 +1113,95 @@ class QPDF @@ -1113,79 +1113,95 @@ class QPDF
1113 std::set<QPDFObjGen>& visited, bool top); 1113 std::set<QPDFObjGen>& visited, bool top);
1114 void filterCompressedObjects(std::map<int, int> const& object_stream_data); 1114 void filterCompressedObjects(std::map<int, int> const& object_stream_data);
1115 1115
  1116 + class Members
  1117 + {
  1118 + friend class QPDF;
  1119 +
  1120 + public:
  1121 + ~Members();
  1122 +
  1123 + private:
  1124 + Members();
  1125 + Members(Members const&);
  1126 +
  1127 + QPDFTokenizer tokenizer;
  1128 + PointerHolder<InputSource> file;
  1129 + std::string last_object_description;
  1130 + bool encrypted;
  1131 + bool encryption_initialized;
  1132 + bool ignore_xref_streams;
  1133 + bool suppress_warnings;
  1134 + std::ostream* out_stream;
  1135 + std::ostream* err_stream;
  1136 + bool attempt_recovery;
  1137 + int encryption_V;
  1138 + int encryption_R;
  1139 + bool encrypt_metadata;
  1140 + std::map<std::string, encryption_method_e> crypt_filters;
  1141 + encryption_method_e cf_stream;
  1142 + encryption_method_e cf_string;
  1143 + encryption_method_e cf_file;
  1144 + std::string provided_password;
  1145 + std::string user_password;
  1146 + std::string encryption_key;
  1147 + std::string cached_object_encryption_key;
  1148 + int cached_key_objid;
  1149 + int cached_key_generation;
  1150 + std::string pdf_version;
  1151 + std::map<QPDFObjGen, QPDFXRefEntry> xref_table;
  1152 + std::set<int> deleted_objects;
  1153 + std::map<QPDFObjGen, ObjCache> obj_cache;
  1154 + std::set<QPDFObjGen> resolving;
  1155 + QPDFObjectHandle trailer;
  1156 + std::vector<QPDFObjectHandle> all_pages;
  1157 + std::map<QPDFObjGen, int> pageobj_to_pages_pos;
  1158 + bool pushed_inherited_attributes_to_pages;
  1159 + std::vector<QPDFExc> warnings;
  1160 + std::map<QPDF*, ObjCopier> object_copiers;
  1161 + PointerHolder<QPDFObjectHandle::StreamDataProvider> copied_streams;
  1162 + // copied_stream_data_provider is owned by copied_streams
  1163 + CopiedStreamDataProvider* copied_stream_data_provider;
  1164 + std::set<QPDFObjGen> attachment_streams;
  1165 + bool reconstructed_xref;
  1166 +
  1167 + // Linearization data
  1168 + qpdf_offset_t first_xref_item_offset; // actual value from file
  1169 + bool uncompressed_after_compressed;
  1170 +
  1171 + // Linearization parameter dictionary and hint table data: may be
  1172 + // read from file or computed prior to writing a linearized file
  1173 + QPDFObjectHandle lindict;
  1174 + LinParameters linp;
  1175 + HPageOffset page_offset_hints;
  1176 + HSharedObject shared_object_hints;
  1177 + HGeneric outline_hints;
  1178 +
  1179 + // Computed linearization data: used to populate above tables
  1180 + // during writing and to compare with them during validation.
  1181 + // c_ means computed.
  1182 + LinParameters c_linp;
  1183 + CHPageOffset c_page_offset_data;
  1184 + CHSharedObject c_shared_object_data;
  1185 + HGeneric c_outline_data;
  1186 +
  1187 + // Object ordering data for linearized files: initialized by
  1188 + // calculateLinearizationData(). Part numbers refer to the PDF
  1189 + // 1.4 specification.
  1190 + std::vector<QPDFObjectHandle> part4;
  1191 + std::vector<QPDFObjectHandle> part6;
  1192 + std::vector<QPDFObjectHandle> part7;
  1193 + std::vector<QPDFObjectHandle> part8;
  1194 + std::vector<QPDFObjectHandle> part9;
  1195 +
  1196 + // Optimization data
  1197 + std::map<ObjUser, std::set<QPDFObjGen> > obj_user_to_objects;
  1198 + std::map<QPDFObjGen, std::set<ObjUser> > object_to_obj_users;
  1199 + };
1116 1200
1117 - QPDFTokenizer tokenizer;  
1118 - PointerHolder<InputSource> file;  
1119 - std::string last_object_description;  
1120 - bool encrypted;  
1121 - bool encryption_initialized;  
1122 - bool ignore_xref_streams;  
1123 - bool suppress_warnings;  
1124 - std::ostream* out_stream;  
1125 - std::ostream* err_stream;  
1126 - bool attempt_recovery;  
1127 - int encryption_V;  
1128 - int encryption_R;  
1129 - bool encrypt_metadata;  
1130 - std::map<std::string, encryption_method_e> crypt_filters;  
1131 - encryption_method_e cf_stream;  
1132 - encryption_method_e cf_string;  
1133 - encryption_method_e cf_file;  
1134 - std::string provided_password;  
1135 - std::string user_password;  
1136 - std::string encryption_key;  
1137 - std::string cached_object_encryption_key;  
1138 - int cached_key_objid;  
1139 - int cached_key_generation;  
1140 - std::string pdf_version;  
1141 - std::map<QPDFObjGen, QPDFXRefEntry> xref_table;  
1142 - std::set<int> deleted_objects;  
1143 - std::map<QPDFObjGen, ObjCache> obj_cache;  
1144 - std::set<QPDFObjGen> resolving;  
1145 - QPDFObjectHandle trailer;  
1146 - std::vector<QPDFObjectHandle> all_pages;  
1147 - std::map<QPDFObjGen, int> pageobj_to_pages_pos;  
1148 - bool pushed_inherited_attributes_to_pages;  
1149 - std::vector<QPDFExc> warnings;  
1150 - std::map<QPDF*, ObjCopier> object_copiers;  
1151 - PointerHolder<QPDFObjectHandle::StreamDataProvider> copied_streams;  
1152 - // copied_stream_data_provider is owned by copied_streams  
1153 - CopiedStreamDataProvider* copied_stream_data_provider;  
1154 - std::set<QPDFObjGen> attachment_streams;  
1155 - bool reconstructed_xref;  
1156 -  
1157 - // Linearization data  
1158 - qpdf_offset_t first_xref_item_offset; // actual value from file  
1159 - bool uncompressed_after_compressed;  
1160 -  
1161 - // Linearization parameter dictionary and hint table data: may be  
1162 - // read from file or computed prior to writing a linearized file  
1163 - QPDFObjectHandle lindict;  
1164 - LinParameters linp;  
1165 - HPageOffset page_offset_hints;  
1166 - HSharedObject shared_object_hints;  
1167 - HGeneric outline_hints;  
1168 -  
1169 - // Computed linearization data: used to populate above tables  
1170 - // during writing and to compare with them during validation. c_  
1171 - // means computed.  
1172 - LinParameters c_linp;  
1173 - CHPageOffset c_page_offset_data;  
1174 - CHSharedObject c_shared_object_data;  
1175 - HGeneric c_outline_data;  
1176 -  
1177 - // Object ordering data for linearized files: initialized by  
1178 - // calculateLinearizationData(). Part numbers refer to the PDF  
1179 - // 1.4 specification.  
1180 - std::vector<QPDFObjectHandle> part4;  
1181 - std::vector<QPDFObjectHandle> part6;  
1182 - std::vector<QPDFObjectHandle> part7;  
1183 - std::vector<QPDFObjectHandle> part8;  
1184 - std::vector<QPDFObjectHandle> part9;  
1185 -  
1186 - // Optimization data  
1187 - std::map<ObjUser, std::set<QPDFObjGen> > obj_user_to_objects;  
1188 - std::map<QPDFObjGen, std::set<ObjUser> > object_to_obj_users; 1201 + // Keep all member variables inside the Members object, which we
  1202 + // dynamically allocate. This makes it possible to add new private
  1203 + // members without breaking binary compatibility.
  1204 + PointerHolder<Members> m;
1189 }; 1205 };
1190 1206
1191 #endif // __QPDF_HH__ 1207 #endif // __QPDF_HH__
libqpdf/QPDF.cc
@@ -74,7 +74,7 @@ QPDF::QPDFVersion() @@ -74,7 +74,7 @@ QPDF::QPDFVersion()
74 return QPDF::qpdf_version; 74 return QPDF::qpdf_version;
75 } 75 }
76 76
77 -QPDF::QPDF() : 77 +QPDF::Members::Members() :
78 encrypted(false), 78 encrypted(false),
79 encryption_initialized(false), 79 encryption_initialized(false),
80 ignore_xref_streams(false), 80 ignore_xref_streams(false),
@@ -98,6 +98,15 @@ QPDF::QPDF() : @@ -98,6 +98,15 @@ QPDF::QPDF() :
98 { 98 {
99 } 99 }
100 100
  101 +QPDF::Members::~Members()
  102 +{
  103 +}
  104 +
  105 +QPDF::QPDF() :
  106 + m(new Members())
  107 +{
  108 +}
  109 +
101 QPDF::~QPDF() 110 QPDF::~QPDF()
102 { 111 {
103 // If two objects are mutually referential (through each object 112 // If two objects are mutually referential (through each object
@@ -114,10 +123,10 @@ QPDF::~QPDF() @@ -114,10 +123,10 @@ QPDF::~QPDF()
114 // reference will reread the object from the file, which would 123 // reference will reread the object from the file, which would
115 // have the effect of undoing any modifications that may have been 124 // have the effect of undoing any modifications that may have been
116 // made to any of the objects. 125 // made to any of the objects.
117 - this->xref_table.clear(); 126 + this->m->xref_table.clear();
118 for (std::map<QPDFObjGen, ObjCache>::iterator iter = 127 for (std::map<QPDFObjGen, ObjCache>::iterator iter =
119 - this->obj_cache.begin();  
120 - iter != obj_cache.end(); ++iter) 128 + this->m->obj_cache.begin();
  129 + iter != this->m->obj_cache.end(); ++iter)
121 { 130 {
122 QPDFObject::ObjAccessor::releaseResolved( 131 QPDFObject::ObjAccessor::releaseResolved(
123 (*iter).second.object.getPointer()); 132 (*iter).second.object.getPointer());
@@ -158,7 +167,7 @@ void @@ -158,7 +167,7 @@ void
158 QPDF::processInputSource(PointerHolder<InputSource> source, 167 QPDF::processInputSource(PointerHolder<InputSource> source,
159 char const* password) 168 char const* password)
160 { 169 {
161 - this->file = source; 170 + this->m->file = source;
162 parse(password); 171 parse(password);
163 } 172 }
164 173
@@ -171,41 +180,41 @@ QPDF::emptyPDF() @@ -171,41 +180,41 @@ QPDF::emptyPDF()
171 void 180 void
172 QPDF::setIgnoreXRefStreams(bool val) 181 QPDF::setIgnoreXRefStreams(bool val)
173 { 182 {
174 - this->ignore_xref_streams = val; 183 + this->m->ignore_xref_streams = val;
175 } 184 }
176 185
177 void 186 void
178 QPDF::setOutputStreams(std::ostream* out, std::ostream* err) 187 QPDF::setOutputStreams(std::ostream* out, std::ostream* err)
179 { 188 {
180 - this->out_stream = out ? out : &std::cout;  
181 - this->err_stream = err ? err : &std::cerr; 189 + this->m->out_stream = out ? out : &std::cout;
  190 + this->m->err_stream = err ? err : &std::cerr;
182 } 191 }
183 192
184 void 193 void
185 QPDF::setSuppressWarnings(bool val) 194 QPDF::setSuppressWarnings(bool val)
186 { 195 {
187 - this->suppress_warnings = val; 196 + this->m->suppress_warnings = val;
188 } 197 }
189 198
190 void 199 void
191 QPDF::setAttemptRecovery(bool val) 200 QPDF::setAttemptRecovery(bool val)
192 { 201 {
193 - this->attempt_recovery = val; 202 + this->m->attempt_recovery = val;
194 } 203 }
195 204
196 std::vector<QPDFExc> 205 std::vector<QPDFExc>
197 QPDF::getWarnings() 206 QPDF::getWarnings()
198 { 207 {
199 - std::vector<QPDFExc> result = this->warnings;  
200 - this->warnings.clear(); 208 + std::vector<QPDFExc> result = this->m->warnings;
  209 + this->m->warnings.clear();
201 return result; 210 return result;
202 } 211 }
203 212
204 bool 213 bool
205 QPDF::findHeader() 214 QPDF::findHeader()
206 { 215 {
207 - qpdf_offset_t global_offset = this->file->tell();  
208 - std::string line = this->file->readLine(1024); 216 + qpdf_offset_t global_offset = this->m->file->tell();
  217 + std::string line = this->m->file->readLine(1024);
209 char const* p = line.c_str(); 218 char const* p = line.c_str();
210 if (strncmp(p, "%PDF-", 5) != 0) 219 if (strncmp(p, "%PDF-", 5) != 0)
211 { 220 {
@@ -239,7 +248,7 @@ QPDF::findHeader() @@ -239,7 +248,7 @@ QPDF::findHeader()
239 } 248 }
240 if (valid) 249 if (valid)
241 { 250 {
242 - this->pdf_version = version; 251 + this->m->pdf_version = version;
243 if (global_offset != 0) 252 if (global_offset != 0)
244 { 253 {
245 // Empirical evidence strongly suggests that when there is 254 // Empirical evidence strongly suggests that when there is
@@ -247,7 +256,7 @@ QPDF::findHeader() @@ -247,7 +256,7 @@ QPDF::findHeader()
247 // offsets in the file are such that 0 points to the 256 // offsets in the file are such that 0 points to the
248 // beginning of the header. 257 // beginning of the header.
249 QTC::TC("qpdf", "QPDF global offset"); 258 QTC::TC("qpdf", "QPDF global offset");
250 - this->file = new OffsetInputSource(this->file, global_offset); 259 + this->m->file = new OffsetInputSource(this->m->file, global_offset);
251 } 260 }
252 } 261 }
253 return valid; 262 return valid;
@@ -256,14 +265,14 @@ QPDF::findHeader() @@ -256,14 +265,14 @@ QPDF::findHeader()
256 bool 265 bool
257 QPDF::findStartxref() 266 QPDF::findStartxref()
258 { 267 {
259 - QPDFTokenizer::Token t = readToken(this->file, true); 268 + QPDFTokenizer::Token t = readToken(this->m->file, true);
260 if (t == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "startxref")) 269 if (t == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "startxref"))
261 { 270 {
262 - t = readToken(this->file, true); 271 + t = readToken(this->m->file, true);
263 if (t.getType() == QPDFTokenizer::tt_integer) 272 if (t.getType() == QPDFTokenizer::tt_integer)
264 { 273 {
265 // Position in front of offset token 274 // Position in front of offset token
266 - this->file->seek(this->file->getLastOffset(), SEEK_SET); 275 + this->m->file->seek(this->m->file->getLastOffset(), SEEK_SET);
267 return true; 276 return true;
268 } 277 }
269 } 278 }
@@ -275,37 +284,37 @@ QPDF::parse(char const* password) @@ -275,37 +284,37 @@ QPDF::parse(char const* password)
275 { 284 {
276 if (password) 285 if (password)
277 { 286 {
278 - this->provided_password = password; 287 + this->m->provided_password = password;
279 } 288 }
280 289
281 // Find the header anywhere in the first 1024 bytes of the file. 290 // Find the header anywhere in the first 1024 bytes of the file.
282 PatternFinder hf(*this, &QPDF::findHeader); 291 PatternFinder hf(*this, &QPDF::findHeader);
283 - if (! this->file->findFirst("%PDF-", 0, 1024, hf)) 292 + if (! this->m->file->findFirst("%PDF-", 0, 1024, hf))
284 { 293 {
285 QTC::TC("qpdf", "QPDF not a pdf file"); 294 QTC::TC("qpdf", "QPDF not a pdf file");
286 - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 295 + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
287 "", 0, "can't find PDF header")); 296 "", 0, "can't find PDF header"));
288 // QPDFWriter writes files that usually require at least 297 // QPDFWriter writes files that usually require at least
289 // version 1.2 for /FlateDecode 298 // version 1.2 for /FlateDecode
290 - this->pdf_version = "1.2"; 299 + this->m->pdf_version = "1.2";
291 } 300 }
292 - if (atof(this->pdf_version.c_str()) < 1.2) 301 + if (atof(this->m->pdf_version.c_str()) < 1.2)
293 { 302 {
294 - this->tokenizer.allowPoundAnywhereInName(); 303 + this->m->tokenizer.allowPoundAnywhereInName();
295 } 304 }
296 305
297 // PDF spec says %%EOF must be found within the last 1024 bytes of 306 // PDF spec says %%EOF must be found within the last 1024 bytes of
298 // the file. We add an extra 30 characters to leave room for the 307 // the file. We add an extra 30 characters to leave room for the
299 // startxref stuff. 308 // startxref stuff.
300 - this->file->seek(0, SEEK_END);  
301 - qpdf_offset_t end_offset = this->file->tell(); 309 + this->m->file->seek(0, SEEK_END);
  310 + qpdf_offset_t end_offset = this->m->file->tell();
302 qpdf_offset_t start_offset = (end_offset > 1054 ? end_offset - 1054 : 0); 311 qpdf_offset_t start_offset = (end_offset > 1054 ? end_offset - 1054 : 0);
303 PatternFinder sf(*this, &QPDF::findStartxref); 312 PatternFinder sf(*this, &QPDF::findStartxref);
304 qpdf_offset_t xref_offset = 0; 313 qpdf_offset_t xref_offset = 0;
305 - if (this->file->findLast("startxref", start_offset, 0, sf)) 314 + if (this->m->file->findLast("startxref", start_offset, 0, sf))
306 { 315 {
307 xref_offset = QUtil::string_to_ll( 316 xref_offset = QUtil::string_to_ll(
308 - readToken(this->file).getValue().c_str()); 317 + readToken(this->m->file).getValue().c_str());
309 } 318 }
310 319
311 try 320 try
@@ -313,14 +322,14 @@ QPDF::parse(char const* password) @@ -313,14 +322,14 @@ QPDF::parse(char const* password)
313 if (xref_offset == 0) 322 if (xref_offset == 0)
314 { 323 {
315 QTC::TC("qpdf", "QPDF can't find startxref"); 324 QTC::TC("qpdf", "QPDF can't find startxref");
316 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0, 325 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0,
317 "can't find startxref"); 326 "can't find startxref");
318 } 327 }
319 read_xref(xref_offset); 328 read_xref(xref_offset);
320 } 329 }
321 catch (QPDFExc& e) 330 catch (QPDFExc& e)
322 { 331 {
323 - if (this->attempt_recovery) 332 + if (this->m->attempt_recovery)
324 { 333 {
325 reconstruct_xref(e); 334 reconstruct_xref(e);
326 QTC::TC("qpdf", "QPDF reconstructed xref table"); 335 QTC::TC("qpdf", "QPDF reconstructed xref table");
@@ -338,28 +347,29 @@ QPDF::parse(char const* password) @@ -338,28 +347,29 @@ QPDF::parse(char const* password)
338 void 347 void
339 QPDF::warn(QPDFExc const& e) 348 QPDF::warn(QPDFExc const& e)
340 { 349 {
341 - this->warnings.push_back(e);  
342 - if (! this->suppress_warnings) 350 + this->m->warnings.push_back(e);
  351 + if (! this->m->suppress_warnings)
343 { 352 {
344 - *err_stream << "WARNING: "  
345 - << this->warnings.back().what() << std::endl; 353 + *this->m->err_stream
  354 + << "WARNING: "
  355 + << this->m->warnings.back().what() << std::endl;
346 } 356 }
347 } 357 }
348 358
349 void 359 void
350 QPDF::setTrailer(QPDFObjectHandle obj) 360 QPDF::setTrailer(QPDFObjectHandle obj)
351 { 361 {
352 - if (this->trailer.isInitialized()) 362 + if (this->m->trailer.isInitialized())
353 { 363 {
354 return; 364 return;
355 } 365 }
356 - this->trailer = obj; 366 + this->m->trailer = obj;
357 } 367 }
358 368
359 void 369 void
360 QPDF::reconstruct_xref(QPDFExc& e) 370 QPDF::reconstruct_xref(QPDFExc& e)
361 { 371 {
362 - if (this->reconstructed_xref) 372 + if (this->m->reconstructed_xref)
363 { 373 {
364 // Avoid xref reconstruction infinite loops. This is getting 374 // Avoid xref reconstruction infinite loops. This is getting
365 // very hard to reproduce because qpdf is throwing many fewer 375 // very hard to reproduce because qpdf is throwing many fewer
@@ -367,19 +377,19 @@ QPDF::reconstruct_xref(QPDFExc&amp; e) @@ -367,19 +377,19 @@ QPDF::reconstruct_xref(QPDFExc&amp; e)
367 throw e; 377 throw e;
368 } 378 }
369 379
370 - this->reconstructed_xref = true; 380 + this->m->reconstructed_xref = true;
371 381
372 - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0, 382 + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0,
373 "file is damaged")); 383 "file is damaged"));
374 warn(e); 384 warn(e);
375 - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0, 385 + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0,
376 "Attempting to reconstruct cross-reference table")); 386 "Attempting to reconstruct cross-reference table"));
377 387
378 // Delete all references to type 1 (uncompressed) objects 388 // Delete all references to type 1 (uncompressed) objects
379 std::set<QPDFObjGen> to_delete; 389 std::set<QPDFObjGen> to_delete;
380 for (std::map<QPDFObjGen, QPDFXRefEntry>::iterator iter = 390 for (std::map<QPDFObjGen, QPDFXRefEntry>::iterator iter =
381 - this->xref_table.begin();  
382 - iter != this->xref_table.end(); ++iter) 391 + this->m->xref_table.begin();
  392 + iter != this->m->xref_table.end(); ++iter)
383 { 393 {
384 if (((*iter).second).getType() == 1) 394 if (((*iter).second).getType() == 1)
385 { 395 {
@@ -389,21 +399,22 @@ QPDF::reconstruct_xref(QPDFExc&amp; e) @@ -389,21 +399,22 @@ QPDF::reconstruct_xref(QPDFExc&amp; e)
389 for (std::set<QPDFObjGen>::iterator iter = to_delete.begin(); 399 for (std::set<QPDFObjGen>::iterator iter = to_delete.begin();
390 iter != to_delete.end(); ++iter) 400 iter != to_delete.end(); ++iter)
391 { 401 {
392 - this->xref_table.erase(*iter); 402 + this->m->xref_table.erase(*iter);
393 } 403 }
394 404
395 - this->file->seek(0, SEEK_END);  
396 - qpdf_offset_t eof = this->file->tell();  
397 - this->file->seek(0, SEEK_SET); 405 + this->m->file->seek(0, SEEK_END);
  406 + qpdf_offset_t eof = this->m->file->tell();
  407 + this->m->file->seek(0, SEEK_SET);
398 bool in_obj = false; 408 bool in_obj = false;
399 qpdf_offset_t line_start = 0; 409 qpdf_offset_t line_start = 0;
400 - while (this->file->tell() < eof)  
401 - {  
402 - this->file->findAndSkipNextEOL();  
403 - qpdf_offset_t next_line_start = this->file->tell();  
404 - this->file->seek(line_start, SEEK_SET);  
405 - QPDFTokenizer::Token t1 = readToken(this->file, true);  
406 - qpdf_offset_t token_start = this->file->tell() - t1.getValue().length(); 410 + while (this->m->file->tell() < eof)
  411 + {
  412 + this->m->file->findAndSkipNextEOL();
  413 + qpdf_offset_t next_line_start = this->m->file->tell();
  414 + this->m->file->seek(line_start, SEEK_SET);
  415 + QPDFTokenizer::Token t1 = readToken(this->m->file, true);
  416 + qpdf_offset_t token_start =
  417 + this->m->file->tell() - t1.getValue().length();
407 if (token_start >= next_line_start) 418 if (token_start >= next_line_start)
408 { 419 {
409 // don't process yet 420 // don't process yet
@@ -419,8 +430,8 @@ QPDF::reconstruct_xref(QPDFExc&amp; e) @@ -419,8 +430,8 @@ QPDF::reconstruct_xref(QPDFExc&amp; e)
419 { 430 {
420 if (t1.getType() == QPDFTokenizer::tt_integer) 431 if (t1.getType() == QPDFTokenizer::tt_integer)
421 { 432 {
422 - QPDFTokenizer::Token t2 = readToken(this->file, true);  
423 - QPDFTokenizer::Token t3 = readToken(this->file, true); 433 + QPDFTokenizer::Token t2 = readToken(this->m->file, true);
  434 + QPDFTokenizer::Token t3 = readToken(this->m->file, true);
424 if ((t2.getType() == QPDFTokenizer::tt_integer) && 435 if ((t2.getType() == QPDFTokenizer::tt_integer) &&
425 (t3 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "obj"))) 436 (t3 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "obj")))
426 { 437 {
@@ -430,11 +441,12 @@ QPDF::reconstruct_xref(QPDFExc&amp; e) @@ -430,11 +441,12 @@ QPDF::reconstruct_xref(QPDFExc&amp; e)
430 insertXrefEntry(obj, 1, token_start, gen, true); 441 insertXrefEntry(obj, 1, token_start, gen, true);
431 } 442 }
432 } 443 }
433 - else if ((! this->trailer.isInitialized()) &&  
434 - (t1 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "trailer"))) 444 + else if ((! this->m->trailer.isInitialized()) &&
  445 + (t1 == QPDFTokenizer::Token(
  446 + QPDFTokenizer::tt_word, "trailer")))
435 { 447 {
436 QPDFObjectHandle t = 448 QPDFObjectHandle t =
437 - readObject(this->file, "trailer", 0, 0, false); 449 + readObject(this->m->file, "trailer", 0, 0, false);
438 if (! t.isDictionary()) 450 if (! t.isDictionary())
439 { 451 {
440 // Oh well. It was worth a try. 452 // Oh well. It was worth a try.
@@ -445,11 +457,11 @@ QPDF::reconstruct_xref(QPDFExc&amp; e) @@ -445,11 +457,11 @@ QPDF::reconstruct_xref(QPDFExc&amp; e)
445 } 457 }
446 } 458 }
447 } 459 }
448 - this->file->seek(next_line_start, SEEK_SET); 460 + this->m->file->seek(next_line_start, SEEK_SET);
449 line_start = next_line_start; 461 line_start = next_line_start;
450 } 462 }
451 463
452 - if (! this->trailer.isInitialized()) 464 + if (! this->m->trailer.isInitialized())
453 { 465 {
454 // We could check the last encountered object to see if it was 466 // We could check the last encountered object to see if it was
455 // an xref stream. If so, we could try to get the trailer 467 // an xref stream. If so, we could try to get the trailer
@@ -457,7 +469,7 @@ QPDF::reconstruct_xref(QPDFExc&amp; e) @@ -457,7 +469,7 @@ QPDF::reconstruct_xref(QPDFExc&amp; e)
457 // with bad startxref pointers even when they have object 469 // with bad startxref pointers even when they have object
458 // streams. 470 // streams.
459 471
460 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0, 472 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0,
461 "unable to find trailer " 473 "unable to find trailer "
462 "dictionary while recovering damaged file"); 474 "dictionary while recovering damaged file");
463 } 475 }
@@ -479,8 +491,8 @@ QPDF::read_xref(qpdf_offset_t xref_offset) @@ -479,8 +491,8 @@ QPDF::read_xref(qpdf_offset_t xref_offset)
479 { 491 {
480 char buf[7]; 492 char buf[7];
481 memset(buf, 0, sizeof(buf)); 493 memset(buf, 0, sizeof(buf));
482 - this->file->seek(xref_offset, SEEK_SET);  
483 - this->file->read(buf, sizeof(buf) - 1); 494 + this->m->file->seek(xref_offset, SEEK_SET);
  495 + this->m->file->read(buf, sizeof(buf) - 1);
484 // The PDF spec says xref must be followed by a line 496 // The PDF spec says xref must be followed by a line
485 // terminator, but files exist in the wild where it is 497 // terminator, but files exist in the wild where it is
486 // terminated by arbitrary whitespace. 498 // terminated by arbitrary whitespace.
@@ -506,25 +518,25 @@ QPDF::read_xref(qpdf_offset_t xref_offset) @@ -506,25 +518,25 @@ QPDF::read_xref(qpdf_offset_t xref_offset)
506 } 518 }
507 } 519 }
508 520
509 - if (! this->trailer.isInitialized()) 521 + if (! this->m->trailer.isInitialized())
510 { 522 {
511 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0, 523 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0,
512 "unable to find trailer while reading xref"); 524 "unable to find trailer while reading xref");
513 } 525 }
514 - int size = this->trailer.getKey("/Size").getIntValue(); 526 + int size = this->m->trailer.getKey("/Size").getIntValue();
515 int max_obj = 0; 527 int max_obj = 0;
516 - if (! xref_table.empty()) 528 + if (! this->m->xref_table.empty())
517 { 529 {
518 - max_obj = (*(xref_table.rbegin())).first.getObj(); 530 + max_obj = (*(this->m->xref_table.rbegin())).first.getObj();
519 } 531 }
520 - if (! this->deleted_objects.empty()) 532 + if (! this->m->deleted_objects.empty())
521 { 533 {
522 - max_obj = std::max(max_obj, *(this->deleted_objects.rbegin())); 534 + max_obj = std::max(max_obj, *(this->m->deleted_objects.rbegin()));
523 } 535 }
524 if (size != max_obj + 1) 536 if (size != max_obj + 1)
525 { 537 {
526 QTC::TC("qpdf", "QPDF xref size mismatch"); 538 QTC::TC("qpdf", "QPDF xref size mismatch");
527 - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0, 539 + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0,
528 std::string("reported number of objects (") + 540 std::string("reported number of objects (") +
529 QUtil::int_to_string(size) + 541 QUtil::int_to_string(size) +
530 ") inconsistent with actual number of objects (" + 542 ") inconsistent with actual number of objects (" +
@@ -533,7 +545,7 @@ QPDF::read_xref(qpdf_offset_t xref_offset) @@ -533,7 +545,7 @@ QPDF::read_xref(qpdf_offset_t xref_offset)
533 545
534 // We no longer need the deleted_objects table, so go ahead and 546 // We no longer need the deleted_objects table, so go ahead and
535 // clear it out to make sure we never depend on its being set. 547 // clear it out to make sure we never depend on its being set.
536 - this->deleted_objects.clear(); 548 + this->m->deleted_objects.clear();
537 } 549 }
538 550
539 bool 551 bool
@@ -677,9 +689,9 @@ QPDF::parse_xrefEntry(std::string const&amp; line, @@ -677,9 +689,9 @@ QPDF::parse_xrefEntry(std::string const&amp; line,
677 689
678 if (invalid) 690 if (invalid)
679 { 691 {
680 - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 692 + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
681 "xref table", 693 "xref table",
682 - this->file->getLastOffset(), 694 + this->m->file->getLastOffset(),
683 "accepting invalid xref table entry")); 695 "accepting invalid xref table entry"));
684 } 696 }
685 697
@@ -694,13 +706,13 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) @@ -694,13 +706,13 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
694 { 706 {
695 std::vector<QPDFObjGen> deleted_items; 707 std::vector<QPDFObjGen> deleted_items;
696 708
697 - this->file->seek(xref_offset, SEEK_SET); 709 + this->m->file->seek(xref_offset, SEEK_SET);
698 bool done = false; 710 bool done = false;
699 while (! done) 711 while (! done)
700 { 712 {
701 char linebuf[51]; 713 char linebuf[51];
702 memset(linebuf, 0, sizeof(linebuf)); 714 memset(linebuf, 0, sizeof(linebuf));
703 - this->file->read(linebuf, sizeof(linebuf) - 1); 715 + this->m->file->read(linebuf, sizeof(linebuf) - 1);
704 std::string line = linebuf; 716 std::string line = linebuf;
705 int obj = 0; 717 int obj = 0;
706 int num = 0; 718 int num = 0;
@@ -708,19 +720,19 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) @@ -708,19 +720,19 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
708 if (! parse_xrefFirst(line, obj, num, bytes)) 720 if (! parse_xrefFirst(line, obj, num, bytes))
709 { 721 {
710 QTC::TC("qpdf", "QPDF invalid xref"); 722 QTC::TC("qpdf", "QPDF invalid xref");
711 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
712 - "xref table", this->file->getLastOffset(), 723 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  724 + "xref table", this->m->file->getLastOffset(),
713 "xref syntax invalid"); 725 "xref syntax invalid");
714 } 726 }
715 - this->file->seek(this->file->getLastOffset() + bytes, SEEK_SET); 727 + this->m->file->seek(this->m->file->getLastOffset() + bytes, SEEK_SET);
716 for (int i = obj; i < obj + num; ++i) 728 for (int i = obj; i < obj + num; ++i)
717 { 729 {
718 if (i == 0) 730 if (i == 0)
719 { 731 {
720 // This is needed by checkLinearization() 732 // This is needed by checkLinearization()
721 - this->first_xref_item_offset = this->file->tell(); 733 + this->m->first_xref_item_offset = this->m->file->tell();
722 } 734 }
723 - std::string xref_entry = this->file->readLine(30); 735 + std::string xref_entry = this->m->file->readLine(30);
724 // For xref_table, these will always be small enough to be ints 736 // For xref_table, these will always be small enough to be ints
725 qpdf_offset_t f1 = 0; 737 qpdf_offset_t f1 = 0;
726 int f2 = 0; 738 int f2 = 0;
@@ -729,8 +741,8 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) @@ -729,8 +741,8 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
729 { 741 {
730 QTC::TC("qpdf", "QPDF invalid xref entry"); 742 QTC::TC("qpdf", "QPDF invalid xref entry");
731 throw QPDFExc( 743 throw QPDFExc(
732 - qpdf_e_damaged_pdf, this->file->getName(),  
733 - "xref table", this->file->getLastOffset(), 744 + qpdf_e_damaged_pdf, this->m->file->getName(),
  745 + "xref table", this->m->file->getLastOffset(),
734 "invalid xref entry (obj=" + 746 "invalid xref entry (obj=" +
735 QUtil::int_to_string(i) + ")"); 747 QUtil::int_to_string(i) + ")");
736 } 748 }
@@ -745,45 +757,45 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) @@ -745,45 +757,45 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
745 insertXrefEntry(i, 1, f1, f2); 757 insertXrefEntry(i, 1, f1, f2);
746 } 758 }
747 } 759 }
748 - qpdf_offset_t pos = this->file->tell();  
749 - QPDFTokenizer::Token t = readToken(this->file); 760 + qpdf_offset_t pos = this->m->file->tell();
  761 + QPDFTokenizer::Token t = readToken(this->m->file);
750 if (t == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "trailer")) 762 if (t == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "trailer"))
751 { 763 {
752 done = true; 764 done = true;
753 } 765 }
754 else 766 else
755 { 767 {
756 - this->file->seek(pos, SEEK_SET); 768 + this->m->file->seek(pos, SEEK_SET);
757 } 769 }
758 } 770 }
759 771
760 // Set offset to previous xref table if any 772 // Set offset to previous xref table if any
761 QPDFObjectHandle cur_trailer = 773 QPDFObjectHandle cur_trailer =
762 - readObject(this->file, "trailer", 0, 0, false); 774 + readObject(this->m->file, "trailer", 0, 0, false);
763 if (! cur_trailer.isDictionary()) 775 if (! cur_trailer.isDictionary())
764 { 776 {
765 QTC::TC("qpdf", "QPDF missing trailer"); 777 QTC::TC("qpdf", "QPDF missing trailer");
766 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
767 - "", this->file->getLastOffset(), 778 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  779 + "", this->m->file->getLastOffset(),
768 "expected trailer dictionary"); 780 "expected trailer dictionary");
769 } 781 }
770 782
771 - if (! this->trailer.isInitialized()) 783 + if (! this->m->trailer.isInitialized())
772 { 784 {
773 setTrailer(cur_trailer); 785 setTrailer(cur_trailer);
774 786
775 - if (! this->trailer.hasKey("/Size")) 787 + if (! this->m->trailer.hasKey("/Size"))
776 { 788 {
777 QTC::TC("qpdf", "QPDF trailer lacks size"); 789 QTC::TC("qpdf", "QPDF trailer lacks size");
778 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
779 - "trailer", this->file->getLastOffset(), 790 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  791 + "trailer", this->m->file->getLastOffset(),
780 "trailer dictionary lacks /Size key"); 792 "trailer dictionary lacks /Size key");
781 } 793 }
782 - if (! this->trailer.getKey("/Size").isInteger()) 794 + if (! this->m->trailer.getKey("/Size").isInteger())
783 { 795 {
784 QTC::TC("qpdf", "QPDF trailer size not integer"); 796 QTC::TC("qpdf", "QPDF trailer size not integer");
785 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
786 - "trailer", this->file->getLastOffset(), 797 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  798 + "trailer", this->m->file->getLastOffset(),
787 "/Size key in trailer dictionary is not " 799 "/Size key in trailer dictionary is not "
788 "an integer"); 800 "an integer");
789 } 801 }
@@ -791,7 +803,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) @@ -791,7 +803,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
791 803
792 if (cur_trailer.hasKey("/XRefStm")) 804 if (cur_trailer.hasKey("/XRefStm"))
793 { 805 {
794 - if (this->ignore_xref_streams) 806 + if (this->m->ignore_xref_streams)
795 { 807 {
796 QTC::TC("qpdf", "QPDF ignoring XRefStm in trailer"); 808 QTC::TC("qpdf", "QPDF ignoring XRefStm in trailer");
797 } 809 }
@@ -807,7 +819,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) @@ -807,7 +819,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
807 } 819 }
808 else 820 else
809 { 821 {
810 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 822 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
811 "xref stream", xref_offset, 823 "xref stream", xref_offset,
812 "invalid /XRefStm"); 824 "invalid /XRefStm");
813 } 825 }
@@ -827,8 +839,8 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) @@ -827,8 +839,8 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
827 if (! cur_trailer.getKey("/Prev").isInteger()) 839 if (! cur_trailer.getKey("/Prev").isInteger())
828 { 840 {
829 QTC::TC("qpdf", "QPDF trailer prev not integer"); 841 QTC::TC("qpdf", "QPDF trailer prev not integer");
830 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
831 - "trailer", this->file->getLastOffset(), 842 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  843 + "trailer", this->m->file->getLastOffset(),
832 "/Prev key in trailer dictionary is not " 844 "/Prev key in trailer dictionary is not "
833 "an integer"); 845 "an integer");
834 } 846 }
@@ -847,7 +859,7 @@ qpdf_offset_t @@ -847,7 +859,7 @@ qpdf_offset_t
847 QPDF::read_xrefStream(qpdf_offset_t xref_offset) 859 QPDF::read_xrefStream(qpdf_offset_t xref_offset)
848 { 860 {
849 bool found = false; 861 bool found = false;
850 - if (! this->ignore_xref_streams) 862 + if (! this->m->ignore_xref_streams)
851 { 863 {
852 int xobj; 864 int xobj;
853 int xgen; 865 int xgen;
@@ -875,7 +887,7 @@ QPDF::read_xrefStream(qpdf_offset_t xref_offset) @@ -875,7 +887,7 @@ QPDF::read_xrefStream(qpdf_offset_t xref_offset)
875 if (! found) 887 if (! found)
876 { 888 {
877 QTC::TC("qpdf", "QPDF can't find xref"); 889 QTC::TC("qpdf", "QPDF can't find xref");
878 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 890 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
879 "", xref_offset, "xref not found"); 891 "", xref_offset, "xref not found");
880 } 892 }
881 893
@@ -896,7 +908,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj) @@ -896,7 +908,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
896 dict.getKey("/Size").isInteger() && 908 dict.getKey("/Size").isInteger() &&
897 (Index_obj.isArray() || Index_obj.isNull()))) 909 (Index_obj.isArray() || Index_obj.isNull())))
898 { 910 {
899 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 911 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
900 "xref stream", xref_offset, 912 "xref stream", xref_offset,
901 "Cross-reference stream does not have" 913 "Cross-reference stream does not have"
902 " proper /W and /Index keys"); 914 " proper /W and /Index keys");
@@ -910,7 +922,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj) @@ -910,7 +922,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
910 W[i] = W_obj.getArrayItem(i).getIntValue(); 922 W[i] = W_obj.getArrayItem(i).getIntValue();
911 if (W[i] > max_bytes) 923 if (W[i] > max_bytes)
912 { 924 {
913 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 925 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
914 "xref stream", xref_offset, 926 "xref stream", xref_offset,
915 "Cross-reference stream's /W contains" 927 "Cross-reference stream's /W contains"
916 " impossibly large values"); 928 " impossibly large values");
@@ -919,7 +931,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj) @@ -919,7 +931,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
919 } 931 }
920 if (entry_size == 0) 932 if (entry_size == 0)
921 { 933 {
922 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 934 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
923 "xref stream", xref_offset, 935 "xref stream", xref_offset,
924 "Cross-reference stream's /W indicates" 936 "Cross-reference stream's /W indicates"
925 " entry size of 0"); 937 " entry size of 0");
@@ -933,7 +945,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj) @@ -933,7 +945,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
933 int n_index = Index_obj.getArrayNItems(); 945 int n_index = Index_obj.getArrayNItems();
934 if ((n_index % 2) || (n_index < 2)) 946 if ((n_index % 2) || (n_index < 2))
935 { 947 {
936 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 948 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
937 "xref stream", xref_offset, 949 "xref stream", xref_offset,
938 "Cross-reference stream's /Index has an" 950 "Cross-reference stream's /Index has an"
939 " invalid number of values"); 951 " invalid number of values");
@@ -946,7 +958,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj) @@ -946,7 +958,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
946 } 958 }
947 else 959 else
948 { 960 {
949 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 961 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
950 "xref stream", xref_offset, 962 "xref stream", xref_offset,
951 "Cross-reference stream's /Index's item " + 963 "Cross-reference stream's /Index's item " +
952 QUtil::int_to_string(i) + 964 QUtil::int_to_string(i) +
@@ -969,7 +981,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj) @@ -969,7 +981,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
969 { 981 {
970 if (indx.at(i) > max_num_entries - num_entries) 982 if (indx.at(i) > max_num_entries - num_entries)
971 { 983 {
972 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 984 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
973 "xref stream", xref_offset, 985 "xref stream", xref_offset,
974 "Cross-reference stream claims to contain" 986 "Cross-reference stream claims to contain"
975 " too many entries: " + 987 " too many entries: " +
@@ -989,7 +1001,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj) @@ -989,7 +1001,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
989 1001
990 if (expected_size != actual_size) 1002 if (expected_size != actual_size)
991 { 1003 {
992 - QPDFExc x(qpdf_e_damaged_pdf, this->file->getName(), 1004 + QPDFExc x(qpdf_e_damaged_pdf, this->m->file->getName(),
993 "xref stream", xref_offset, 1005 "xref stream", xref_offset,
994 "Cross-reference stream data has the wrong size;" 1006 "Cross-reference stream data has the wrong size;"
995 " expected = " + QUtil::int_to_string(expected_size) + 1007 " expected = " + QUtil::int_to_string(expected_size) +
@@ -1050,7 +1062,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj) @@ -1050,7 +1062,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1050 { 1062 {
1051 if (fields[0] != 2) 1063 if (fields[0] != 2)
1052 { 1064 {
1053 - this->uncompressed_after_compressed = true; 1065 + this->m->uncompressed_after_compressed = true;
1054 } 1066 }
1055 } 1067 }
1056 else if (fields[0] == 2) 1068 else if (fields[0] == 2)
@@ -1060,13 +1072,13 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj) @@ -1060,13 +1072,13 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1060 if (obj == 0) 1072 if (obj == 0)
1061 { 1073 {
1062 // This is needed by checkLinearization() 1074 // This is needed by checkLinearization()
1063 - this->first_xref_item_offset = xref_offset; 1075 + this->m->first_xref_item_offset = xref_offset;
1064 } 1076 }
1065 insertXrefEntry(obj, static_cast<int>(fields[0]), 1077 insertXrefEntry(obj, static_cast<int>(fields[0]),
1066 fields[1], static_cast<int>(fields[2])); 1078 fields[1], static_cast<int>(fields[2]));
1067 } 1079 }
1068 1080
1069 - if (! this->trailer.isInitialized()) 1081 + if (! this->m->trailer.isInitialized())
1070 { 1082 {
1071 setTrailer(dict); 1083 setTrailer(dict);
1072 } 1084 }
@@ -1075,8 +1087,8 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj) @@ -1075,8 +1087,8 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle&amp; xref_obj)
1075 { 1087 {
1076 if (! dict.getKey("/Prev").isInteger()) 1088 if (! dict.getKey("/Prev").isInteger())
1077 { 1089 {
1078 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
1079 - "xref stream", this->file->getLastOffset(), 1090 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  1091 + "xref stream", this->m->file->getLastOffset(),
1080 "/Prev key in xref stream dictionary is not " 1092 "/Prev key in xref stream dictionary is not "
1081 "an integer"); 1093 "an integer");
1082 } 1094 }
@@ -1108,12 +1120,12 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite) @@ -1108,12 +1120,12 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite)
1108 { // private scope 1120 { // private scope
1109 int gen = (f0 == 2 ? 0 : f2); 1121 int gen = (f0 == 2 ? 0 : f2);
1110 QPDFObjGen og(obj, gen); 1122 QPDFObjGen og(obj, gen);
1111 - if (this->xref_table.count(og)) 1123 + if (this->m->xref_table.count(og))
1112 { 1124 {
1113 if (overwrite) 1125 if (overwrite)
1114 { 1126 {
1115 QTC::TC("qpdf", "QPDF xref overwrite object"); 1127 QTC::TC("qpdf", "QPDF xref overwrite object");
1116 - this->xref_table.erase(og); 1128 + this->m->xref_table.erase(og);
1117 } 1129 }
1118 else 1130 else
1119 { 1131 {
@@ -1121,7 +1133,7 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite) @@ -1121,7 +1133,7 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite)
1121 return; 1133 return;
1122 } 1134 }
1123 } 1135 }
1124 - if (this->deleted_objects.count(obj)) 1136 + if (this->m->deleted_objects.count(obj))
1125 { 1137 {
1126 QTC::TC("qpdf", "QPDF xref deleted object"); 1138 QTC::TC("qpdf", "QPDF xref deleted object");
1127 return; 1139 return;
@@ -1131,22 +1143,22 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite) @@ -1131,22 +1143,22 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite)
1131 switch (f0) 1143 switch (f0)
1132 { 1144 {
1133 case 0: 1145 case 0:
1134 - this->deleted_objects.insert(obj); 1146 + this->m->deleted_objects.insert(obj);
1135 break; 1147 break;
1136 1148
1137 case 1: 1149 case 1:
1138 // f2 is generation 1150 // f2 is generation
1139 QTC::TC("qpdf", "QPDF xref gen > 0", ((f2 > 0) ? 1 : 0)); 1151 QTC::TC("qpdf", "QPDF xref gen > 0", ((f2 > 0) ? 1 : 0));
1140 - this->xref_table[QPDFObjGen(obj, f2)] = QPDFXRefEntry(f0, f1, f2); 1152 + this->m->xref_table[QPDFObjGen(obj, f2)] = QPDFXRefEntry(f0, f1, f2);
1141 break; 1153 break;
1142 1154
1143 case 2: 1155 case 2:
1144 - this->xref_table[QPDFObjGen(obj, 0)] = QPDFXRefEntry(f0, f1, f2); 1156 + this->m->xref_table[QPDFObjGen(obj, 0)] = QPDFXRefEntry(f0, f1, f2);
1145 break; 1157 break;
1146 1158
1147 default: 1159 default:
1148 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
1149 - "xref stream", this->file->getLastOffset(), 1160 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  1161 + "xref stream", this->m->file->getLastOffset(),
1150 "unknown xref stream entry type " + 1162 "unknown xref stream entry type " +
1151 QUtil::int_to_string(f0)); 1163 QUtil::int_to_string(f0));
1152 break; 1164 break;
@@ -1157,21 +1169,24 @@ void @@ -1157,21 +1169,24 @@ void
1157 QPDF::showXRefTable() 1169 QPDF::showXRefTable()
1158 { 1170 {
1159 for (std::map<QPDFObjGen, QPDFXRefEntry>::iterator iter = 1171 for (std::map<QPDFObjGen, QPDFXRefEntry>::iterator iter =
1160 - this->xref_table.begin();  
1161 - iter != this->xref_table.end(); ++iter) 1172 + this->m->xref_table.begin();
  1173 + iter != this->m->xref_table.end(); ++iter)
1162 { 1174 {
1163 QPDFObjGen const& og = (*iter).first; 1175 QPDFObjGen const& og = (*iter).first;
1164 QPDFXRefEntry const& entry = (*iter).second; 1176 QPDFXRefEntry const& entry = (*iter).second;
1165 - *out_stream << og.getObj() << "/" << og.getGen() << ": "; 1177 + *this->m->out_stream << og.getObj() << "/" << og.getGen() << ": ";
1166 switch (entry.getType()) 1178 switch (entry.getType())
1167 { 1179 {
1168 case 1: 1180 case 1:
1169 - *out_stream << "uncompressed; offset = " << entry.getOffset(); 1181 + *this->m->out_stream
  1182 + << "uncompressed; offset = " << entry.getOffset();
1170 break; 1183 break;
1171 1184
1172 case 2: 1185 case 2:
1173 - *out_stream << "compressed; stream = " << entry.getObjStreamNumber()  
1174 - << ", index = " << entry.getObjStreamIndex(); 1186 + *this->m->out_stream
  1187 + << "compressed; stream = "
  1188 + << entry.getObjStreamNumber()
  1189 + << ", index = " << entry.getObjStreamIndex();
1175 break; 1190 break;
1176 1191
1177 default: 1192 default:
@@ -1179,7 +1194,7 @@ QPDF::showXRefTable() @@ -1179,7 +1194,7 @@ QPDF::showXRefTable()
1179 " showing xref_table"); 1194 " showing xref_table");
1180 break; 1195 break;
1181 } 1196 }
1182 - *out_stream << std::endl; 1197 + *this->m->out_stream << std::endl;
1183 } 1198 }
1184 } 1199 }
1185 1200
@@ -1188,8 +1203,8 @@ QPDF::getAllObjects() @@ -1188,8 +1203,8 @@ QPDF::getAllObjects()
1188 { 1203 {
1189 std::vector<QPDFObjectHandle> result; 1204 std::vector<QPDFObjectHandle> result;
1190 for (std::map<QPDFObjGen, QPDFXRefEntry>::iterator iter = 1205 for (std::map<QPDFObjGen, QPDFXRefEntry>::iterator iter =
1191 - this->xref_table.begin();  
1192 - iter != this->xref_table.end(); ++iter) 1206 + this->m->xref_table.begin();
  1207 + iter != this->m->xref_table.end(); ++iter)
1193 { 1208 {
1194 1209
1195 QPDFObjGen const& og = (*iter).first; 1210 QPDFObjGen const& og = (*iter).first;
@@ -1203,18 +1218,18 @@ void @@ -1203,18 +1218,18 @@ void
1203 QPDF::setLastObjectDescription(std::string const& description, 1218 QPDF::setLastObjectDescription(std::string const& description,
1204 int objid, int generation) 1219 int objid, int generation)
1205 { 1220 {
1206 - this->last_object_description.clear(); 1221 + this->m->last_object_description.clear();
1207 if (! description.empty()) 1222 if (! description.empty())
1208 { 1223 {
1209 - this->last_object_description += description; 1224 + this->m->last_object_description += description;
1210 if (objid > 0) 1225 if (objid > 0)
1211 { 1226 {
1212 - this->last_object_description += ": "; 1227 + this->m->last_object_description += ": ";
1213 } 1228 }
1214 } 1229 }
1215 if (objid > 0) 1230 if (objid > 0)
1216 { 1231 {
1217 - this->last_object_description += "object " + 1232 + this->m->last_object_description += "object " +
1218 QUtil::int_to_string(objid) + " " + 1233 QUtil::int_to_string(objid) + " " +
1219 QUtil::int_to_string(generation); 1234 QUtil::int_to_string(generation);
1220 } 1235 }
@@ -1231,20 +1246,20 @@ QPDF::readObject(PointerHolder&lt;InputSource&gt; input, @@ -1231,20 +1246,20 @@ QPDF::readObject(PointerHolder&lt;InputSource&gt; input,
1231 bool empty = false; 1246 bool empty = false;
1232 PointerHolder<StringDecrypter> decrypter_ph; 1247 PointerHolder<StringDecrypter> decrypter_ph;
1233 StringDecrypter* decrypter = 0; 1248 StringDecrypter* decrypter = 0;
1234 - if (this->encrypted && (! in_object_stream)) 1249 + if (this->m->encrypted && (! in_object_stream))
1235 { 1250 {
1236 decrypter_ph = new StringDecrypter(this, objid, generation); 1251 decrypter_ph = new StringDecrypter(this, objid, generation);
1237 decrypter = decrypter_ph.getPointer(); 1252 decrypter = decrypter_ph.getPointer();
1238 } 1253 }
1239 QPDFObjectHandle object = QPDFObjectHandle::parse( 1254 QPDFObjectHandle object = QPDFObjectHandle::parse(
1240 - input, description, this->tokenizer, empty, decrypter, this); 1255 + input, description, this->m->tokenizer, empty, decrypter, this);
1241 if (empty) 1256 if (empty)
1242 { 1257 {
1243 // Nothing in the PDF spec appears to allow empty objects, but 1258 // Nothing in the PDF spec appears to allow empty objects, but
1244 // they have been encountered in actual PDF files and Adobe 1259 // they have been encountered in actual PDF files and Adobe
1245 // Reader appears to ignore them. 1260 // Reader appears to ignore them.
1246 warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(), 1261 warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(),
1247 - this->last_object_description, 1262 + this->m->last_object_description,
1248 input->getLastOffset(), 1263 input->getLastOffset(),
1249 "empty object treated as null")); 1264 "empty object treated as null"));
1250 } 1265 }
@@ -1299,7 +1314,7 @@ QPDF::readObject(PointerHolder&lt;InputSource&gt; input, @@ -1299,7 +1314,7 @@ QPDF::readObject(PointerHolder&lt;InputSource&gt; input,
1299 warn(QPDFExc( 1314 warn(QPDFExc(
1300 qpdf_e_damaged_pdf, 1315 qpdf_e_damaged_pdf,
1301 input->getName(), 1316 input->getName(),
1302 - this->last_object_description, 1317 + this->m->last_object_description,
1303 input->tell(), 1318 input->tell(),
1304 "stream keyword followed" 1319 "stream keyword followed"
1305 " by carriage return only")); 1320 " by carriage return only"));
@@ -1315,7 +1330,7 @@ QPDF::readObject(PointerHolder&lt;InputSource&gt; input, @@ -1315,7 +1330,7 @@ QPDF::readObject(PointerHolder&lt;InputSource&gt; input,
1315 input->unreadCh(ch); 1330 input->unreadCh(ch);
1316 } 1331 }
1317 warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(), 1332 warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(),
1318 - this->last_object_description, 1333 + this->m->last_object_description,
1319 input->tell(), 1334 input->tell(),
1320 "stream keyword not followed" 1335 "stream keyword not followed"
1321 " by proper line terminator")); 1336 " by proper line terminator"));
@@ -1337,7 +1352,7 @@ QPDF::readObject(PointerHolder&lt;InputSource&gt; input, @@ -1337,7 +1352,7 @@ QPDF::readObject(PointerHolder&lt;InputSource&gt; input,
1337 { 1352 {
1338 QTC::TC("qpdf", "QPDF stream without length"); 1353 QTC::TC("qpdf", "QPDF stream without length");
1339 throw QPDFExc(qpdf_e_damaged_pdf, input->getName(), 1354 throw QPDFExc(qpdf_e_damaged_pdf, input->getName(),
1340 - this->last_object_description, offset, 1355 + this->m->last_object_description, offset,
1341 "stream dictionary lacks /Length key"); 1356 "stream dictionary lacks /Length key");
1342 } 1357 }
1343 1358
@@ -1346,7 +1361,7 @@ QPDF::readObject(PointerHolder&lt;InputSource&gt; input, @@ -1346,7 +1361,7 @@ QPDF::readObject(PointerHolder&lt;InputSource&gt; input,
1346 { 1361 {
1347 QTC::TC("qpdf", "QPDF stream length not integer"); 1362 QTC::TC("qpdf", "QPDF stream length not integer");
1348 throw QPDFExc(qpdf_e_damaged_pdf, input->getName(), 1363 throw QPDFExc(qpdf_e_damaged_pdf, input->getName(),
1349 - this->last_object_description, offset, 1364 + this->m->last_object_description, offset,
1350 "/Length key in stream dictionary is not " 1365 "/Length key in stream dictionary is not "
1351 "an integer"); 1366 "an integer");
1352 } 1367 }
@@ -1359,14 +1374,14 @@ QPDF::readObject(PointerHolder&lt;InputSource&gt; input, @@ -1359,14 +1374,14 @@ QPDF::readObject(PointerHolder&lt;InputSource&gt; input,
1359 { 1374 {
1360 QTC::TC("qpdf", "QPDF missing endstream"); 1375 QTC::TC("qpdf", "QPDF missing endstream");
1361 throw QPDFExc(qpdf_e_damaged_pdf, input->getName(), 1376 throw QPDFExc(qpdf_e_damaged_pdf, input->getName(),
1362 - this->last_object_description, 1377 + this->m->last_object_description,
1363 input->getLastOffset(), 1378 input->getLastOffset(),
1364 "expected endstream"); 1379 "expected endstream");
1365 } 1380 }
1366 } 1381 }
1367 catch (QPDFExc& e) 1382 catch (QPDFExc& e)
1368 { 1383 {
1369 - if (this->attempt_recovery) 1384 + if (this->m->attempt_recovery)
1370 { 1385 {
1371 warn(e); 1386 warn(e);
1372 length = recoverStreamLength( 1387 length = recoverStreamLength(
@@ -1396,12 +1411,12 @@ bool @@ -1396,12 +1411,12 @@ bool
1396 QPDF::findEndstream() 1411 QPDF::findEndstream()
1397 { 1412 {
1398 // Find endstream or endobj. Position the input at that token. 1413 // Find endstream or endobj. Position the input at that token.
1399 - QPDFTokenizer::Token t = readToken(this->file, true); 1414 + QPDFTokenizer::Token t = readToken(this->m->file, true);
1400 if ((t.getType() == QPDFTokenizer::tt_word) && 1415 if ((t.getType() == QPDFTokenizer::tt_word) &&
1401 ((t.getValue() == "endobj") || 1416 ((t.getValue() == "endobj") ||
1402 (t.getValue() == "endstream"))); 1417 (t.getValue() == "endstream")));
1403 { 1418 {
1404 - this->file->seek(this->file->getLastOffset(), SEEK_SET); 1419 + this->m->file->seek(this->m->file->getLastOffset(), SEEK_SET);
1405 return true; 1420 return true;
1406 } 1421 }
1407 return false; 1422 return false;
@@ -1415,19 +1430,19 @@ QPDF::recoverStreamLength(PointerHolder&lt;InputSource&gt; input, @@ -1415,19 +1430,19 @@ QPDF::recoverStreamLength(PointerHolder&lt;InputSource&gt; input,
1415 // Try to reconstruct stream length by looking for 1430 // Try to reconstruct stream length by looking for
1416 // endstream or endobj 1431 // endstream or endobj
1417 warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(), 1432 warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(),
1418 - this->last_object_description, stream_offset, 1433 + this->m->last_object_description, stream_offset,
1419 "attempting to recover stream length")); 1434 "attempting to recover stream length"));
1420 1435
1421 PatternFinder ef(*this, &QPDF::findEndstream); 1436 PatternFinder ef(*this, &QPDF::findEndstream);
1422 size_t length = 0; 1437 size_t length = 0;
1423 - if (this->file->findFirst("end", stream_offset, 0, ef)) 1438 + if (this->m->file->findFirst("end", stream_offset, 0, ef))
1424 { 1439 {
1425 - length = this->file->tell() - stream_offset; 1440 + length = this->m->file->tell() - stream_offset;
1426 // Reread endstream but, if it was endobj, don't skip that. 1441 // Reread endstream but, if it was endobj, don't skip that.
1427 - QPDFTokenizer::Token t = readToken(this->file); 1442 + QPDFTokenizer::Token t = readToken(this->m->file);
1428 if (t.getValue() == "endobj") 1443 if (t.getValue() == "endobj")
1429 { 1444 {
1430 - this->file->seek(this->file->getLastOffset(), SEEK_SET); 1445 + this->m->file->seek(this->m->file->getLastOffset(), SEEK_SET);
1431 } 1446 }
1432 } 1447 }
1433 1448
@@ -1438,8 +1453,8 @@ QPDF::recoverStreamLength(PointerHolder&lt;InputSource&gt; input, @@ -1438,8 +1453,8 @@ QPDF::recoverStreamLength(PointerHolder&lt;InputSource&gt; input,
1438 1453
1439 // Make sure this is inside this object 1454 // Make sure this is inside this object
1440 for (std::map<QPDFObjGen, QPDFXRefEntry>::iterator iter = 1455 for (std::map<QPDFObjGen, QPDFXRefEntry>::iterator iter =
1441 - this->xref_table.begin();  
1442 - iter != this->xref_table.end(); ++iter) 1456 + this->m->xref_table.begin();
  1457 + iter != this->m->xref_table.end(); ++iter)
1443 { 1458 {
1444 QPDFObjGen const& og = (*iter).first; 1459 QPDFObjGen const& og = (*iter).first;
1445 QPDFXRefEntry const& entry = (*iter).second; 1460 QPDFXRefEntry const& entry = (*iter).second;
@@ -1472,13 +1487,14 @@ QPDF::recoverStreamLength(PointerHolder&lt;InputSource&gt; input, @@ -1472,13 +1487,14 @@ QPDF::recoverStreamLength(PointerHolder&lt;InputSource&gt; input,
1472 if (length == 0) 1487 if (length == 0)
1473 { 1488 {
1474 warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(), 1489 warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(),
1475 - this->last_object_description, stream_offset,  
1476 - "unable to recover stream data; treating stream as empty")); 1490 + this->m->last_object_description, stream_offset,
  1491 + "unable to recover stream data;"
  1492 + " treating stream as empty"));
1477 } 1493 }
1478 else 1494 else
1479 { 1495 {
1480 warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(), 1496 warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(),
1481 - this->last_object_description, stream_offset, 1497 + this->m->last_object_description, stream_offset,
1482 "recovered stream length: " + 1498 "recovered stream length: " +
1483 QUtil::int_to_string(length))); 1499 QUtil::int_to_string(length)));
1484 } 1500 }
@@ -1490,8 +1506,8 @@ QPDF::recoverStreamLength(PointerHolder&lt;InputSource&gt; input, @@ -1490,8 +1506,8 @@ QPDF::recoverStreamLength(PointerHolder&lt;InputSource&gt; input,
1490 QPDFTokenizer::Token 1506 QPDFTokenizer::Token
1491 QPDF::readToken(PointerHolder<InputSource> input, bool allow_bad) 1507 QPDF::readToken(PointerHolder<InputSource> input, bool allow_bad)
1492 { 1508 {
1493 - return this->tokenizer.readToken(  
1494 - input, this->last_object_description, allow_bad); 1509 + return this->m->tokenizer.readToken(
  1510 + input, this->m->last_object_description, allow_bad);
1495 } 1511 }
1496 1512
1497 QPDFObjectHandle 1513 QPDFObjectHandle
@@ -1500,7 +1516,7 @@ QPDF::readObjectAtOffset(bool try_recovery, @@ -1500,7 +1516,7 @@ QPDF::readObjectAtOffset(bool try_recovery,
1500 int exp_objid, int exp_generation, 1516 int exp_objid, int exp_generation,
1501 int& objid, int& generation) 1517 int& objid, int& generation)
1502 { 1518 {
1503 - if (! this->attempt_recovery) 1519 + if (! this->m->attempt_recovery)
1504 { 1520 {
1505 try_recovery = false; 1521 try_recovery = false;
1506 } 1522 }
@@ -1514,17 +1530,17 @@ QPDF::readObjectAtOffset(bool try_recovery, @@ -1514,17 +1530,17 @@ QPDF::readObjectAtOffset(bool try_recovery,
1514 if (offset == 0) 1530 if (offset == 0)
1515 { 1531 {
1516 QTC::TC("qpdf", "QPDF bogus 0 offset", 0); 1532 QTC::TC("qpdf", "QPDF bogus 0 offset", 0);
1517 - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
1518 - this->last_object_description, 0, 1533 + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  1534 + this->m->last_object_description, 0,
1519 "object has offset 0")); 1535 "object has offset 0"));
1520 return QPDFObjectHandle::newNull(); 1536 return QPDFObjectHandle::newNull();
1521 } 1537 }
1522 1538
1523 - this->file->seek(offset, SEEK_SET); 1539 + this->m->file->seek(offset, SEEK_SET);
1524 1540
1525 - QPDFTokenizer::Token tobjid = readToken(this->file);  
1526 - QPDFTokenizer::Token tgen = readToken(this->file);  
1527 - QPDFTokenizer::Token tobj = readToken(this->file); 1541 + QPDFTokenizer::Token tobjid = readToken(this->m->file);
  1542 + QPDFTokenizer::Token tgen = readToken(this->m->file);
  1543 + QPDFTokenizer::Token tobj = readToken(this->m->file);
1528 1544
1529 bool objidok = (tobjid.getType() == QPDFTokenizer::tt_integer); 1545 bool objidok = (tobjid.getType() == QPDFTokenizer::tt_integer);
1530 int genok = (tgen.getType() == QPDFTokenizer::tt_integer); 1546 int genok = (tgen.getType() == QPDFTokenizer::tt_integer);
@@ -1539,8 +1555,8 @@ QPDF::readObjectAtOffset(bool try_recovery, @@ -1539,8 +1555,8 @@ QPDF::readObjectAtOffset(bool try_recovery,
1539 if (! (objidok && genok && objok)) 1555 if (! (objidok && genok && objok))
1540 { 1556 {
1541 QTC::TC("qpdf", "QPDF expected n n obj"); 1557 QTC::TC("qpdf", "QPDF expected n n obj");
1542 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
1543 - this->last_object_description, offset, 1558 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  1559 + this->m->last_object_description, offset,
1544 "expected n n obj"); 1560 "expected n n obj");
1545 } 1561 }
1546 objid = atoi(tobjid.getValue().c_str()); 1562 objid = atoi(tobjid.getValue().c_str());
@@ -1549,8 +1565,8 @@ QPDF::readObjectAtOffset(bool try_recovery, @@ -1549,8 +1565,8 @@ QPDF::readObjectAtOffset(bool try_recovery,
1549 if (objid == 0) 1565 if (objid == 0)
1550 { 1566 {
1551 QTC::TC("qpdf", "QPDF object id 0"); 1567 QTC::TC("qpdf", "QPDF object id 0");
1552 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
1553 - this->last_object_description, offset, 1568 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  1569 + this->m->last_object_description, offset,
1554 "object with ID 0"); 1570 "object with ID 0");
1555 } 1571 }
1556 1572
@@ -1558,8 +1574,8 @@ QPDF::readObjectAtOffset(bool try_recovery, @@ -1558,8 +1574,8 @@ QPDF::readObjectAtOffset(bool try_recovery,
1558 (! ((objid == exp_objid) && (generation == exp_generation)))) 1574 (! ((objid == exp_objid) && (generation == exp_generation))))
1559 { 1575 {
1560 QTC::TC("qpdf", "QPDF err wrong objid/generation"); 1576 QTC::TC("qpdf", "QPDF err wrong objid/generation");
1561 - QPDFExc e(qpdf_e_damaged_pdf, this->file->getName(),  
1562 - this->last_object_description, offset, 1577 + QPDFExc e(qpdf_e_damaged_pdf, this->m->file->getName(),
  1578 + this->m->last_object_description, offset,
1563 std::string("expected ") + 1579 std::string("expected ") +
1564 QUtil::int_to_string(exp_objid) + " " + 1580 QUtil::int_to_string(exp_objid) + " " +
1565 QUtil::int_to_string(exp_generation) + " obj"); 1581 QUtil::int_to_string(exp_generation) + " obj");
@@ -1583,10 +1599,10 @@ QPDF::readObjectAtOffset(bool try_recovery, @@ -1583,10 +1599,10 @@ QPDF::readObjectAtOffset(bool try_recovery,
1583 // Try again after reconstructing xref table 1599 // Try again after reconstructing xref table
1584 reconstruct_xref(e); 1600 reconstruct_xref(e);
1585 QPDFObjGen og(exp_objid, exp_generation); 1601 QPDFObjGen og(exp_objid, exp_generation);
1586 - if (this->xref_table.count(og) &&  
1587 - (this->xref_table[og].getType() == 1)) 1602 + if (this->m->xref_table.count(og) &&
  1603 + (this->m->xref_table[og].getType() == 1))
1588 { 1604 {
1589 - qpdf_offset_t new_offset = this->xref_table[og].getOffset(); 1605 + qpdf_offset_t new_offset = this->m->xref_table[og].getOffset();
1590 QPDFObjectHandle result = readObjectAtOffset( 1606 QPDFObjectHandle result = readObjectAtOffset(
1591 false, new_offset, description, 1607 false, new_offset, description,
1592 exp_objid, exp_generation, objid, generation); 1608 exp_objid, exp_generation, objid, generation);
@@ -1597,7 +1613,7 @@ QPDF::readObjectAtOffset(bool try_recovery, @@ -1597,7 +1613,7 @@ QPDF::readObjectAtOffset(bool try_recovery,
1597 { 1613 {
1598 QTC::TC("qpdf", "QPDF object gone after xref reconstruction"); 1614 QTC::TC("qpdf", "QPDF object gone after xref reconstruction");
1599 warn(QPDFExc( 1615 warn(QPDFExc(
1600 - qpdf_e_damaged_pdf, this->file->getName(), 1616 + qpdf_e_damaged_pdf, this->m->file->getName(),
1601 "", 0, 1617 "", 0,
1602 std::string( 1618 std::string(
1603 "object " + 1619 "object " +
@@ -1616,19 +1632,20 @@ QPDF::readObjectAtOffset(bool try_recovery, @@ -1616,19 +1632,20 @@ QPDF::readObjectAtOffset(bool try_recovery,
1616 } 1632 }
1617 1633
1618 QPDFObjectHandle oh = readObject( 1634 QPDFObjectHandle oh = readObject(
1619 - this->file, description, objid, generation, false); 1635 + this->m->file, description, objid, generation, false);
1620 1636
1621 - if (! (readToken(this->file) == 1637 + if (! (readToken(this->m->file) ==
1622 QPDFTokenizer::Token(QPDFTokenizer::tt_word, "endobj"))) 1638 QPDFTokenizer::Token(QPDFTokenizer::tt_word, "endobj")))
1623 { 1639 {
1624 QTC::TC("qpdf", "QPDF err expected endobj"); 1640 QTC::TC("qpdf", "QPDF err expected endobj");
1625 - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
1626 - this->last_object_description, this->file->getLastOffset(), 1641 + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  1642 + this->m->last_object_description,
  1643 + this->m->file->getLastOffset(),
1627 "expected endobj")); 1644 "expected endobj"));
1628 } 1645 }
1629 1646
1630 QPDFObjGen og(objid, generation); 1647 QPDFObjGen og(objid, generation);
1631 - if (! this->obj_cache.count(og)) 1648 + if (! this->m->obj_cache.count(og))
1632 { 1649 {
1633 // Store the object in the cache here so it gets cached 1650 // Store the object in the cache here so it gets cached
1634 // whether we first know the offset or whether we first know 1651 // whether we first know the offset or whether we first know
@@ -1640,30 +1657,30 @@ QPDF::readObjectAtOffset(bool try_recovery, @@ -1640,30 +1657,30 @@ QPDF::readObjectAtOffset(bool try_recovery,
1640 // linearization hint tables. Offsets and lengths of objects 1657 // linearization hint tables. Offsets and lengths of objects
1641 // may imply the end of an object to be anywhere between these 1658 // may imply the end of an object to be anywhere between these
1642 // values. 1659 // values.
1643 - qpdf_offset_t end_before_space = this->file->tell(); 1660 + qpdf_offset_t end_before_space = this->m->file->tell();
1644 1661
1645 // skip over spaces 1662 // skip over spaces
1646 while (true) 1663 while (true)
1647 { 1664 {
1648 char ch; 1665 char ch;
1649 - if (this->file->read(&ch, 1)) 1666 + if (this->m->file->read(&ch, 1))
1650 { 1667 {
1651 if (! isspace(static_cast<unsigned char>(ch))) 1668 if (! isspace(static_cast<unsigned char>(ch)))
1652 { 1669 {
1653 - this->file->seek(-1, SEEK_CUR); 1670 + this->m->file->seek(-1, SEEK_CUR);
1654 break; 1671 break;
1655 } 1672 }
1656 } 1673 }
1657 else 1674 else
1658 { 1675 {
1659 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
1660 - this->last_object_description, offset, 1676 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  1677 + this->m->last_object_description, offset,
1661 "EOF after endobj"); 1678 "EOF after endobj");
1662 } 1679 }
1663 } 1680 }
1664 - qpdf_offset_t end_after_space = this->file->tell(); 1681 + qpdf_offset_t end_after_space = this->m->file->tell();
1665 1682
1666 - this->obj_cache[og] = 1683 + this->m->obj_cache[og] =
1667 ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), 1684 ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh),
1668 end_before_space, end_after_space); 1685 end_before_space, end_after_space);
1669 } 1686 }
@@ -1678,14 +1695,14 @@ QPDF::resolve(int objid, int generation) @@ -1678,14 +1695,14 @@ QPDF::resolve(int objid, int generation)
1678 // to insert things into the object cache that don't actually 1695 // to insert things into the object cache that don't actually
1679 // exist in the file. 1696 // exist in the file.
1680 QPDFObjGen og(objid, generation); 1697 QPDFObjGen og(objid, generation);
1681 - if (this->resolving.count(og)) 1698 + if (this->m->resolving.count(og))
1682 { 1699 {
1683 // This can happen if an object references itself directly or 1700 // This can happen if an object references itself directly or
1684 // indirectly in some key that has to be resolved during 1701 // indirectly in some key that has to be resolved during
1685 // object parsing, such as stream length. 1702 // object parsing, such as stream length.
1686 QTC::TC("qpdf", "QPDF recursion loop in resolve"); 1703 QTC::TC("qpdf", "QPDF recursion loop in resolve");
1687 - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
1688 - "", this->file->getLastOffset(), 1704 + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  1705 + "", this->m->file->getLastOffset(),
1689 "loop detected resolving object " + 1706 "loop detected resolving object " +
1690 QUtil::int_to_string(objid) + " " + 1707 QUtil::int_to_string(objid) + " " +
1691 QUtil::int_to_string(generation))); 1708 QUtil::int_to_string(generation)));
@@ -1693,15 +1710,15 @@ QPDF::resolve(int objid, int generation) @@ -1693,15 +1710,15 @@ QPDF::resolve(int objid, int generation)
1693 } 1710 }
1694 ResolveRecorder rr(this, og); 1711 ResolveRecorder rr(this, og);
1695 1712
1696 - if (! this->obj_cache.count(og)) 1713 + if (! this->m->obj_cache.count(og))
1697 { 1714 {
1698 - if (! this->xref_table.count(og)) 1715 + if (! this->m->xref_table.count(og))
1699 { 1716 {
1700 // PDF spec says unknown objects resolve to the null object. 1717 // PDF spec says unknown objects resolve to the null object.
1701 return new QPDF_Null; 1718 return new QPDF_Null;
1702 } 1719 }
1703 1720
1704 - QPDFXRefEntry const& entry = this->xref_table[og]; 1721 + QPDFXRefEntry const& entry = this->m->xref_table[og];
1705 bool success = false; 1722 bool success = false;
1706 try 1723 try
1707 { 1724 {
@@ -1724,7 +1741,8 @@ QPDF::resolve(int objid, int generation) @@ -1724,7 +1741,8 @@ QPDF::resolve(int objid, int generation)
1724 break; 1741 break;
1725 1742
1726 default: 1743 default:
1727 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0, 1744 + throw QPDFExc(qpdf_e_damaged_pdf,
  1745 + this->m->file->getName(), "", 0,
1728 "object " + 1746 "object " +
1729 QUtil::int_to_string(objid) + "/" + 1747 QUtil::int_to_string(objid) + "/" +
1730 QUtil::int_to_string(generation) + 1748 QUtil::int_to_string(generation) +
@@ -1738,7 +1756,7 @@ QPDF::resolve(int objid, int generation) @@ -1738,7 +1756,7 @@ QPDF::resolve(int objid, int generation)
1738 } 1756 }
1739 catch (std::exception& e) 1757 catch (std::exception& e)
1740 { 1758 {
1741 - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0, 1759 + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0,
1742 "object " + 1760 "object " +
1743 QUtil::int_to_string(objid) + "/" + 1761 QUtil::int_to_string(objid) + "/" +
1744 QUtil::int_to_string(generation) + 1762 QUtil::int_to_string(generation) +
@@ -1748,12 +1766,12 @@ QPDF::resolve(int objid, int generation) @@ -1748,12 +1766,12 @@ QPDF::resolve(int objid, int generation)
1748 { 1766 {
1749 QTC::TC("qpdf", "QPDF resolve failure to null"); 1767 QTC::TC("qpdf", "QPDF resolve failure to null");
1750 QPDFObjectHandle oh = QPDFObjectHandle::newNull(); 1768 QPDFObjectHandle oh = QPDFObjectHandle::newNull();
1751 - this->obj_cache[og] = 1769 + this->m->obj_cache[og] =
1752 ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1); 1770 ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1);
1753 } 1771 }
1754 } 1772 }
1755 1773
1756 - return this->obj_cache[og].object; 1774 + return this->m->obj_cache[og].object;
1757 } 1775 }
1758 1776
1759 void 1777 void
@@ -1763,9 +1781,9 @@ QPDF::resolveObjectsInStream(int obj_stream_number) @@ -1763,9 +1781,9 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
1763 QPDFObjectHandle obj_stream = getObjectByID(obj_stream_number, 0); 1781 QPDFObjectHandle obj_stream = getObjectByID(obj_stream_number, 0);
1764 if (! obj_stream.isStream()) 1782 if (! obj_stream.isStream())
1765 { 1783 {
1766 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
1767 - this->last_object_description,  
1768 - this->file->getLastOffset(), 1784 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  1785 + this->m->last_object_description,
  1786 + this->m->file->getLastOffset(),
1769 "supposed object stream " + 1787 "supposed object stream " +
1770 QUtil::int_to_string(obj_stream_number) + 1788 QUtil::int_to_string(obj_stream_number) +
1771 " is not a stream"); 1789 " is not a stream");
@@ -1775,18 +1793,18 @@ QPDF::resolveObjectsInStream(int obj_stream_number) @@ -1775,18 +1793,18 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
1775 // object stream for the objects in the stream. 1793 // object stream for the objects in the stream.
1776 QPDFObjGen stream_og(obj_stream_number, 0); 1794 QPDFObjGen stream_og(obj_stream_number, 0);
1777 qpdf_offset_t end_before_space = 1795 qpdf_offset_t end_before_space =
1778 - this->obj_cache[stream_og].end_before_space; 1796 + this->m->obj_cache[stream_og].end_before_space;
1779 qpdf_offset_t end_after_space = 1797 qpdf_offset_t end_after_space =
1780 - this->obj_cache[stream_og].end_after_space; 1798 + this->m->obj_cache[stream_og].end_after_space;
1781 1799
1782 QPDFObjectHandle dict = obj_stream.getDict(); 1800 QPDFObjectHandle dict = obj_stream.getDict();
1783 if (! (dict.getKey("/Type").isName() && 1801 if (! (dict.getKey("/Type").isName() &&
1784 dict.getKey("/Type").getName() == "/ObjStm")) 1802 dict.getKey("/Type").getName() == "/ObjStm"))
1785 { 1803 {
1786 QTC::TC("qpdf", "QPDF ERR object stream with wrong type"); 1804 QTC::TC("qpdf", "QPDF ERR object stream with wrong type");
1787 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
1788 - this->last_object_description,  
1789 - this->file->getLastOffset(), 1805 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  1806 + this->m->last_object_description,
  1807 + this->m->file->getLastOffset(),
1790 "supposed object stream " + 1808 "supposed object stream " +
1791 QUtil::int_to_string(obj_stream_number) + 1809 QUtil::int_to_string(obj_stream_number) +
1792 " has wrong type"); 1810 " has wrong type");
@@ -1795,9 +1813,9 @@ QPDF::resolveObjectsInStream(int obj_stream_number) @@ -1795,9 +1813,9 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
1795 if (! (dict.getKey("/N").isInteger() && 1813 if (! (dict.getKey("/N").isInteger() &&
1796 dict.getKey("/First").isInteger())) 1814 dict.getKey("/First").isInteger()))
1797 { 1815 {
1798 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
1799 - this->last_object_description,  
1800 - this->file->getLastOffset(), 1816 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  1817 + this->m->last_object_description,
  1818 + this->m->file->getLastOffset(),
1801 "object stream " + 1819 "object stream " +
1802 QUtil::int_to_string(obj_stream_number) + 1820 QUtil::int_to_string(obj_stream_number) +
1803 " has incorrect keys"); 1821 " has incorrect keys");
@@ -1821,7 +1839,8 @@ QPDF::resolveObjectsInStream(int obj_stream_number) @@ -1821,7 +1839,8 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
1821 (toffset.getType() == QPDFTokenizer::tt_integer))) 1839 (toffset.getType() == QPDFTokenizer::tt_integer)))
1822 { 1840 {
1823 throw QPDFExc(qpdf_e_damaged_pdf, input->getName(), 1841 throw QPDFExc(qpdf_e_damaged_pdf, input->getName(),
1824 - this->last_object_description, input->getLastOffset(), 1842 + this->m->last_object_description,
  1843 + input->getLastOffset(),
1825 "expected integer in object stream header"); 1844 "expected integer in object stream header");
1826 } 1845 }
1827 1846
@@ -1840,14 +1859,14 @@ QPDF::resolveObjectsInStream(int obj_stream_number) @@ -1840,14 +1859,14 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
1840 { 1859 {
1841 int obj = (*iter).first; 1860 int obj = (*iter).first;
1842 QPDFObjGen og(obj, 0); 1861 QPDFObjGen og(obj, 0);
1843 - QPDFXRefEntry const& entry = this->xref_table[og]; 1862 + QPDFXRefEntry const& entry = this->m->xref_table[og];
1844 if ((entry.getType() == 2) && 1863 if ((entry.getType() == 2) &&
1845 (entry.getObjStreamNumber() == obj_stream_number)) 1864 (entry.getObjStreamNumber() == obj_stream_number))
1846 { 1865 {
1847 int offset = (*iter).second; 1866 int offset = (*iter).second;
1848 input->seek(offset, SEEK_SET); 1867 input->seek(offset, SEEK_SET);
1849 QPDFObjectHandle oh = readObject(input, "", obj, 0, true); 1868 QPDFObjectHandle oh = readObject(input, "", obj, 0, true);
1850 - this->obj_cache[og] = 1869 + this->m->obj_cache[og] =
1851 ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), 1870 ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh),
1852 end_before_space, end_after_space); 1871 end_before_space, end_after_space);
1853 } 1872 }
@@ -1862,16 +1881,16 @@ QPDFObjectHandle @@ -1862,16 +1881,16 @@ QPDFObjectHandle
1862 QPDF::makeIndirectObject(QPDFObjectHandle oh) 1881 QPDF::makeIndirectObject(QPDFObjectHandle oh)
1863 { 1882 {
1864 QPDFObjGen o1(0, 0); 1883 QPDFObjGen o1(0, 0);
1865 - if (! this->obj_cache.empty()) 1884 + if (! this->m->obj_cache.empty())
1866 { 1885 {
1867 - o1 = (*(this->obj_cache.rbegin())).first; 1886 + o1 = (*(this->m->obj_cache.rbegin())).first;
1868 } 1887 }
1869 - QPDFObjGen o2 = (*(this->xref_table.rbegin())).first; 1888 + QPDFObjGen o2 = (*(this->m->xref_table.rbegin())).first;
1870 QTC::TC("qpdf", "QPDF indirect last obj from xref", 1889 QTC::TC("qpdf", "QPDF indirect last obj from xref",
1871 (o2.getObj() > o1.getObj()) ? 1 : 0); 1890 (o2.getObj() > o1.getObj()) ? 1 : 0);
1872 int max_objid = std::max(o1.getObj(), o2.getObj()); 1891 int max_objid = std::max(o1.getObj(), o2.getObj());
1873 QPDFObjGen next(max_objid + 1, 0); 1892 QPDFObjGen next(max_objid + 1, 0);
1874 - this->obj_cache[next] = 1893 + this->m->obj_cache[next] =
1875 ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1); 1894 ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1);
1876 return QPDFObjectHandle::Factory::newIndirect( 1895 return QPDFObjectHandle::Factory::newIndirect(
1877 this, next.getObj(), next.getGen()); 1896 this, next.getObj(), next.getGen());
@@ -1910,7 +1929,7 @@ QPDF::replaceObject(int objid, int generation, QPDFObjectHandle oh) @@ -1910,7 +1929,7 @@ QPDF::replaceObject(int objid, int generation, QPDFObjectHandle oh)
1910 1929
1911 // Replace the object in the object cache 1930 // Replace the object in the object cache
1912 QPDFObjGen og(objid, generation); 1931 QPDFObjGen og(objid, generation);
1913 - this->obj_cache[og] = 1932 + this->m->obj_cache[og] =
1914 ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1); 1933 ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1);
1915 } 1934 }
1916 1935
@@ -1946,7 +1965,7 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign, bool allow_page) @@ -1946,7 +1965,7 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign, bool allow_page)
1946 "QPDF::copyForeign called with object from this QPDF"); 1965 "QPDF::copyForeign called with object from this QPDF");
1947 } 1966 }
1948 1967
1949 - ObjCopier& obj_copier = this->object_copiers[other]; 1968 + ObjCopier& obj_copier = this->m->object_copiers[other];
1950 if (! obj_copier.visiting.empty()) 1969 if (! obj_copier.visiting.empty())
1951 { 1970 {
1952 throw std::logic_error("obj_copier.visiting is not empty" 1971 throw std::logic_error("obj_copier.visiting is not empty"
@@ -2016,7 +2035,8 @@ QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier&amp; obj_copier, @@ -2016,7 +2035,8 @@ QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier&amp; obj_copier,
2016 QTC::TC("qpdf", "QPDF loop reserving objects"); 2035 QTC::TC("qpdf", "QPDF loop reserving objects");
2017 return; 2036 return;
2018 } 2037 }
2019 - if (obj_copier.object_map.find(foreign_og) != obj_copier.object_map.end()) 2038 + if (obj_copier.object_map.find(foreign_og) !=
  2039 + obj_copier.object_map.end())
2020 { 2040 {
2021 QTC::TC("qpdf", "QPDF already reserved object"); 2041 QTC::TC("qpdf", "QPDF already reserved object");
2022 return; 2042 return;
@@ -2139,15 +2159,16 @@ QPDF::replaceForeignIndirectObjects( @@ -2139,15 +2159,16 @@ QPDF::replaceForeignIndirectObjects(
2139 replaceForeignIndirectObjects( 2159 replaceForeignIndirectObjects(
2140 old_dict.getKey(*iter), obj_copier, false)); 2160 old_dict.getKey(*iter), obj_copier, false));
2141 } 2161 }
2142 - if (this->copied_stream_data_provider == 0) 2162 + if (this->m->copied_stream_data_provider == 0)
2143 { 2163 {
2144 - this->copied_stream_data_provider = new CopiedStreamDataProvider();  
2145 - this->copied_streams = this->copied_stream_data_provider; 2164 + this->m->copied_stream_data_provider =
  2165 + new CopiedStreamDataProvider();
  2166 + this->m->copied_streams = this->m->copied_stream_data_provider;
2146 } 2167 }
2147 QPDFObjGen local_og(result.getObjGen()); 2168 QPDFObjGen local_og(result.getObjGen());
2148 - this->copied_stream_data_provider->registerForeignStream( 2169 + this->m->copied_stream_data_provider->registerForeignStream(
2149 local_og, foreign); 2170 local_og, foreign);
2150 - result.replaceStreamData(this->copied_streams, 2171 + result.replaceStreamData(this->m->copied_streams,
2151 dict.getKey("/Filter"), 2172 dict.getKey("/Filter"),
2152 dict.getKey("/DecodeParms")); 2173 dict.getKey("/DecodeParms"));
2153 } 2174 }
@@ -2181,21 +2202,21 @@ QPDF::swapObjects(int objid1, int generation1, int objid2, int generation2) @@ -2181,21 +2202,21 @@ QPDF::swapObjects(int objid1, int generation1, int objid2, int generation2)
2181 resolve(objid2, generation2); 2202 resolve(objid2, generation2);
2182 QPDFObjGen og1(objid1, generation1); 2203 QPDFObjGen og1(objid1, generation1);
2183 QPDFObjGen og2(objid2, generation2); 2204 QPDFObjGen og2(objid2, generation2);
2184 - ObjCache t = this->obj_cache[og1];  
2185 - this->obj_cache[og1] = this->obj_cache[og2];  
2186 - this->obj_cache[og2] = t; 2205 + ObjCache t = this->m->obj_cache[og1];
  2206 + this->m->obj_cache[og1] = this->m->obj_cache[og2];
  2207 + this->m->obj_cache[og2] = t;
2187 } 2208 }
2188 2209
2189 std::string 2210 std::string
2190 QPDF::getFilename() const 2211 QPDF::getFilename() const
2191 { 2212 {
2192 - return this->file->getName(); 2213 + return this->m->file->getName();
2193 } 2214 }
2194 2215
2195 std::string 2216 std::string
2196 QPDF::getPDFVersion() const 2217 QPDF::getPDFVersion() const
2197 { 2218 {
2198 - return this->pdf_version; 2219 + return this->m->pdf_version;
2199 } 2220 }
2200 2221
2201 int 2222 int
@@ -2225,17 +2246,17 @@ QPDF::getExtensionLevel() @@ -2225,17 +2246,17 @@ QPDF::getExtensionLevel()
2225 QPDFObjectHandle 2246 QPDFObjectHandle
2226 QPDF::getTrailer() 2247 QPDF::getTrailer()
2227 { 2248 {
2228 - return this->trailer; 2249 + return this->m->trailer;
2229 } 2250 }
2230 2251
2231 QPDFObjectHandle 2252 QPDFObjectHandle
2232 QPDF::getRoot() 2253 QPDF::getRoot()
2233 { 2254 {
2234 - QPDFObjectHandle root = this->trailer.getKey("/Root"); 2255 + QPDFObjectHandle root = this->m->trailer.getKey("/Root");
2235 if (! root.isDictionary()) 2256 if (! root.isDictionary())
2236 { 2257 {
2237 - throw QPDFExc(qpdf_e_damaged_pdf, file->getName(),  
2238 - "", file->getLastOffset(), 2258 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  2259 + "", this->m->file->getLastOffset(),
2239 "unable to find /Root dictionary"); 2260 "unable to find /Root dictionary");
2240 } 2261 }
2241 return root; 2262 return root;
@@ -2245,8 +2266,8 @@ void @@ -2245,8 +2266,8 @@ void
2245 QPDF::getObjectStreamData(std::map<int, int>& omap) 2266 QPDF::getObjectStreamData(std::map<int, int>& omap)
2246 { 2267 {
2247 for (std::map<QPDFObjGen, QPDFXRefEntry>::iterator iter = 2268 for (std::map<QPDFObjGen, QPDFXRefEntry>::iterator iter =
2248 - this->xref_table.begin();  
2249 - iter != this->xref_table.end(); ++iter) 2269 + this->m->xref_table.begin();
  2270 + iter != this->m->xref_table.end(); ++iter)
2250 { 2271 {
2251 QPDFObjGen const& og = (*iter).first; 2272 QPDFObjGen const& og = (*iter).first;
2252 QPDFXRefEntry const& entry = (*iter).second; 2273 QPDFXRefEntry const& entry = (*iter).second;
@@ -2270,12 +2291,13 @@ QPDF::getCompressibleObjGens() @@ -2270,12 +2291,13 @@ QPDF::getCompressibleObjGens()
2270 // orphaned items. 2291 // orphaned items.
2271 2292
2272 // Exclude encryption dictionary, if any 2293 // Exclude encryption dictionary, if any
2273 - QPDFObjectHandle encryption_dict = trailer.getKey("/Encrypt"); 2294 + QPDFObjectHandle encryption_dict =
  2295 + this->m->trailer.getKey("/Encrypt");
2274 QPDFObjGen encryption_dict_og = encryption_dict.getObjGen(); 2296 QPDFObjGen encryption_dict_og = encryption_dict.getObjGen();
2275 2297
2276 std::set<QPDFObjGen> visited; 2298 std::set<QPDFObjGen> visited;
2277 std::list<QPDFObjectHandle> queue; 2299 std::list<QPDFObjectHandle> queue;
2278 - queue.push_front(this->trailer); 2300 + queue.push_front(this->m->trailer);
2279 std::vector<QPDFObjGen> result; 2301 std::vector<QPDFObjGen> result;
2280 while (! queue.empty()) 2302 while (! queue.empty())
2281 { 2303 {
@@ -2353,25 +2375,25 @@ QPDF::pipeStreamData(int objid, int generation, @@ -2353,25 +2375,25 @@ QPDF::pipeStreamData(int objid, int generation,
2353 { 2375 {
2354 bool success = false; 2376 bool success = false;
2355 std::vector<PointerHolder<Pipeline> > to_delete; 2377 std::vector<PointerHolder<Pipeline> > to_delete;
2356 - if (this->encrypted) 2378 + if (this->m->encrypted)
2357 { 2379 {
2358 decryptStream(pipeline, objid, generation, stream_dict, to_delete); 2380 decryptStream(pipeline, objid, generation, stream_dict, to_delete);
2359 } 2381 }
2360 2382
2361 try 2383 try
2362 { 2384 {
2363 - this->file->seek(offset, SEEK_SET); 2385 + this->m->file->seek(offset, SEEK_SET);
2364 char buf[10240]; 2386 char buf[10240];
2365 while (length > 0) 2387 while (length > 0)
2366 { 2388 {
2367 size_t to_read = (sizeof(buf) < length ? sizeof(buf) : length); 2389 size_t to_read = (sizeof(buf) < length ? sizeof(buf) : length);
2368 - size_t len = this->file->read(buf, to_read); 2390 + size_t len = this->m->file->read(buf, to_read);
2369 if (len == 0) 2391 if (len == 0)
2370 { 2392 {
2371 throw QPDFExc(qpdf_e_damaged_pdf, 2393 throw QPDFExc(qpdf_e_damaged_pdf,
2372 - this->file->getName(),  
2373 - this->last_object_description,  
2374 - this->file->getLastOffset(), 2394 + this->m->file->getName(),
  2395 + this->m->last_object_description,
  2396 + this->m->file->getLastOffset(),
2375 "unexpected EOF reading stream data"); 2397 "unexpected EOF reading stream data");
2376 } 2398 }
2377 length -= len; 2399 length -= len;
@@ -2392,8 +2414,8 @@ QPDF::pipeStreamData(int objid, int generation, @@ -2392,8 +2414,8 @@ QPDF::pipeStreamData(int objid, int generation,
2392 if (! suppress_warnings) 2414 if (! suppress_warnings)
2393 { 2415 {
2394 QTC::TC("qpdf", "QPDF decoding error warning"); 2416 QTC::TC("qpdf", "QPDF decoding error warning");
2395 - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
2396 - "", this->file->getLastOffset(), 2417 + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  2418 + "", this->m->file->getLastOffset(),
2397 "error decoding stream data for object " + 2419 "error decoding stream data for object " +
2398 QUtil::int_to_string(objid) + " " + 2420 QUtil::int_to_string(objid) + " " +
2399 QUtil::int_to_string(generation) + ": " + e.what())); 2421 QUtil::int_to_string(generation) + ": " + e.what()));
@@ -2442,7 +2464,7 @@ QPDF::findAttachmentStreams() @@ -2442,7 +2464,7 @@ QPDF::findAttachmentStreams()
2442 item.getKey("/EF").getKey("/F").isStream()) 2464 item.getKey("/EF").getKey("/F").isStream())
2443 { 2465 {
2444 QPDFObjectHandle stream = item.getKey("/EF").getKey("/F"); 2466 QPDFObjectHandle stream = item.getKey("/EF").getKey("/F");
2445 - this->attachment_streams.insert(stream.getObjGen()); 2467 + this->m->attachment_streams.insert(stream.getObjGen());
2446 } 2468 }
2447 } 2469 }
2448 } 2470 }
libqpdf/QPDF_encryption.cc
@@ -760,9 +760,9 @@ QPDF::interpretCF(QPDFObjectHandle cf) @@ -760,9 +760,9 @@ QPDF::interpretCF(QPDFObjectHandle cf)
760 if (cf.isName()) 760 if (cf.isName())
761 { 761 {
762 std::string filter = cf.getName(); 762 std::string filter = cf.getName();
763 - if (this->crypt_filters.count(filter) != 0) 763 + if (this->m->crypt_filters.count(filter) != 0)
764 { 764 {
765 - return this->crypt_filters[filter]; 765 + return this->m->crypt_filters[filter];
766 } 766 }
767 else if (filter == "/Identity") 767 else if (filter == "/Identity")
768 { 768 {
@@ -783,29 +783,29 @@ QPDF::interpretCF(QPDFObjectHandle cf) @@ -783,29 +783,29 @@ QPDF::interpretCF(QPDFObjectHandle cf)
783 void 783 void
784 QPDF::initializeEncryption() 784 QPDF::initializeEncryption()
785 { 785 {
786 - if (this->encryption_initialized) 786 + if (this->m->encryption_initialized)
787 { 787 {
788 return; 788 return;
789 } 789 }
790 - this->encryption_initialized = true; 790 + this->m->encryption_initialized = true;
791 791
792 // After we initialize encryption parameters, we must used stored 792 // After we initialize encryption parameters, we must used stored
793 // key information and never look at /Encrypt again. Otherwise, 793 // key information and never look at /Encrypt again. Otherwise,
794 // things could go wrong if someone mutates the encryption 794 // things could go wrong if someone mutates the encryption
795 // dictionary. 795 // dictionary.
796 796
797 - if (! this->trailer.hasKey("/Encrypt")) 797 + if (! this->m->trailer.hasKey("/Encrypt"))
798 { 798 {
799 return; 799 return;
800 } 800 }
801 801
802 - // Go ahead and set this->encryption here. That way, isEncrypted 802 + // Go ahead and set this->m->encrypted here. That way, isEncrypted
803 // will return true even if there were errors reading the 803 // will return true even if there were errors reading the
804 // encryption dictionary. 804 // encryption dictionary.
805 - this->encrypted = true; 805 + this->m->encrypted = true;
806 806
807 std::string id1; 807 std::string id1;
808 - QPDFObjectHandle id_obj = this->trailer.getKey("/ID"); 808 + QPDFObjectHandle id_obj = this->m->trailer.getKey("/ID");
809 if ((id_obj.isArray() && 809 if ((id_obj.isArray() &&
810 (id_obj.getArrayNItems() == 2) && 810 (id_obj.getArrayNItems() == 2) &&
811 id_obj.getArrayItem(0).isString())) 811 id_obj.getArrayItem(0).isString()))
@@ -817,31 +817,31 @@ QPDF::initializeEncryption() @@ -817,31 +817,31 @@ QPDF::initializeEncryption()
817 // Treating a missing ID as the empty string enables qpdf to 817 // Treating a missing ID as the empty string enables qpdf to
818 // decrypt some invalid encrypted files with no /ID that 818 // decrypt some invalid encrypted files with no /ID that
819 // poppler can read but Adobe Reader can't. 819 // poppler can read but Adobe Reader can't.
820 - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
821 - "trailer", this->file->getLastOffset(), 820 + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  821 + "trailer", this->m->file->getLastOffset(),
822 "invalid /ID in trailer dictionary")); 822 "invalid /ID in trailer dictionary"));
823 } 823 }
824 824
825 - QPDFObjectHandle encryption_dict = this->trailer.getKey("/Encrypt"); 825 + QPDFObjectHandle encryption_dict = this->m->trailer.getKey("/Encrypt");
826 if (! encryption_dict.isDictionary()) 826 if (! encryption_dict.isDictionary())
827 { 827 {
828 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
829 - this->last_object_description,  
830 - this->file->getLastOffset(), 828 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  829 + this->m->last_object_description,
  830 + this->m->file->getLastOffset(),
831 "/Encrypt in trailer dictionary is not a dictionary"); 831 "/Encrypt in trailer dictionary is not a dictionary");
832 } 832 }
833 833
834 if (! (encryption_dict.getKey("/Filter").isName() && 834 if (! (encryption_dict.getKey("/Filter").isName() &&
835 (encryption_dict.getKey("/Filter").getName() == "/Standard"))) 835 (encryption_dict.getKey("/Filter").getName() == "/Standard")))
836 { 836 {
837 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
838 - "encryption dictionary", this->file->getLastOffset(), 837 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  838 + "encryption dictionary", this->m->file->getLastOffset(),
839 "unsupported encryption filter"); 839 "unsupported encryption filter");
840 } 840 }
841 if (! encryption_dict.getKey("/SubFilter").isNull()) 841 if (! encryption_dict.getKey("/SubFilter").isNull())
842 { 842 {
843 - warn(QPDFExc(qpdf_e_unsupported, this->file->getName(),  
844 - "encryption dictionary", this->file->getLastOffset(), 843 + warn(QPDFExc(qpdf_e_unsupported, this->m->file->getName(),
  844 + "encryption dictionary", this->m->file->getLastOffset(),
845 "file uses encryption SubFilters," 845 "file uses encryption SubFilters,"
846 " which qpdf does not support")); 846 " which qpdf does not support"));
847 } 847 }
@@ -852,8 +852,8 @@ QPDF::initializeEncryption() @@ -852,8 +852,8 @@ QPDF::initializeEncryption()
852 encryption_dict.getKey("/U").isString() && 852 encryption_dict.getKey("/U").isString() &&
853 encryption_dict.getKey("/P").isInteger())) 853 encryption_dict.getKey("/P").isInteger()))
854 { 854 {
855 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
856 - "encryption dictionary", this->file->getLastOffset(), 855 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  856 + "encryption dictionary", this->m->file->getLastOffset(),
857 "some encryption dictionary parameters are missing " 857 "some encryption dictionary parameters are missing "
858 "or the wrong type"); 858 "or the wrong type");
859 } 859 }
@@ -869,15 +869,15 @@ QPDF::initializeEncryption() @@ -869,15 +869,15 @@ QPDF::initializeEncryption()
869 if (! (((R >= 2) && (R <= 6)) && 869 if (! (((R >= 2) && (R <= 6)) &&
870 ((V == 1) || (V == 2) || (V == 4) || (V == 5)))) 870 ((V == 1) || (V == 2) || (V == 4) || (V == 5))))
871 { 871 {
872 - throw QPDFExc(qpdf_e_unsupported, this->file->getName(),  
873 - "encryption dictionary", this->file->getLastOffset(), 872 + throw QPDFExc(qpdf_e_unsupported, this->m->file->getName(),
  873 + "encryption dictionary", this->m->file->getLastOffset(),
874 "Unsupported /R or /V in encryption dictionary; R = " + 874 "Unsupported /R or /V in encryption dictionary; R = " +
875 QUtil::int_to_string(R) + " (max 6), V = " + 875 QUtil::int_to_string(R) + " (max 6), V = " +
876 QUtil::int_to_string(V) + " (max 5)"); 876 QUtil::int_to_string(V) + " (max 5)");
877 } 877 }
878 878
879 - this->encryption_V = V;  
880 - this->encryption_R = R; 879 + this->m->encryption_V = V;
  880 + this->m->encryption_R = R;
881 881
882 // OE, UE, and Perms are only present if V >= 5. 882 // OE, UE, and Perms are only present if V >= 5.
883 std::string OE; 883 std::string OE;
@@ -890,8 +890,9 @@ QPDF::initializeEncryption() @@ -890,8 +890,9 @@ QPDF::initializeEncryption()
890 pad_short_parameter(U, key_bytes); 890 pad_short_parameter(U, key_bytes);
891 if (! ((O.length() == key_bytes) && (U.length() == key_bytes))) 891 if (! ((O.length() == key_bytes) && (U.length() == key_bytes)))
892 { 892 {
893 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
894 - "encryption dictionary", this->file->getLastOffset(), 893 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  894 + "encryption dictionary",
  895 + this->m->file->getLastOffset(),
895 "incorrect length for /O and/or /U in " 896 "incorrect length for /O and/or /U in "
896 "encryption dictionary"); 897 "encryption dictionary");
897 } 898 }
@@ -902,8 +903,9 @@ QPDF::initializeEncryption() @@ -902,8 +903,9 @@ QPDF::initializeEncryption()
902 encryption_dict.getKey("/UE").isString() && 903 encryption_dict.getKey("/UE").isString() &&
903 encryption_dict.getKey("/Perms").isString())) 904 encryption_dict.getKey("/Perms").isString()))
904 { 905 {
905 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
906 - "encryption dictionary", this->file->getLastOffset(), 906 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  907 + "encryption dictionary",
  908 + this->m->file->getLastOffset(),
907 "some V=5 encryption dictionary parameters are " 909 "some V=5 encryption dictionary parameters are "
908 "missing or the wrong type"); 910 "missing or the wrong type");
909 } 911 }
@@ -922,8 +924,9 @@ QPDF::initializeEncryption() @@ -922,8 +924,9 @@ QPDF::initializeEncryption()
922 (UE.length() < OUE_key_bytes_V5) || 924 (UE.length() < OUE_key_bytes_V5) ||
923 (Perms.length() < Perms_key_bytes_V5)) 925 (Perms.length() < Perms_key_bytes_V5))
924 { 926 {
925 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
926 - "encryption dictionary", this->file->getLastOffset(), 927 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  928 + "encryption dictionary",
  929 + this->m->file->getLastOffset(),
927 "incorrect length for some of" 930 "incorrect length for some of"
928 " /O, /U, /OE, /UE, or /Perms in" 931 " /O, /U, /OE, /UE, or /Perms in"
929 " encryption dictionary"); 932 " encryption dictionary");
@@ -936,16 +939,17 @@ QPDF::initializeEncryption() @@ -936,16 +939,17 @@ QPDF::initializeEncryption()
936 Length = encryption_dict.getKey("/Length").getIntValue(); 939 Length = encryption_dict.getKey("/Length").getIntValue();
937 if ((Length % 8) || (Length < 40) || (Length > 256)) 940 if ((Length % 8) || (Length < 40) || (Length > 256))
938 { 941 {
939 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
940 - "encryption dictionary", this->file->getLastOffset(), 942 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  943 + "encryption dictionary",
  944 + this->m->file->getLastOffset(),
941 "invalid /Length value in encryption dictionary"); 945 "invalid /Length value in encryption dictionary");
942 } 946 }
943 } 947 }
944 948
945 - this->encrypt_metadata = true; 949 + this->m->encrypt_metadata = true;
946 if ((V >= 4) && (encryption_dict.getKey("/EncryptMetadata").isBool())) 950 if ((V >= 4) && (encryption_dict.getKey("/EncryptMetadata").isBool()))
947 { 951 {
948 - this->encrypt_metadata = 952 + this->m->encrypt_metadata =
949 encryption_dict.getKey("/EncryptMetadata").getBoolValue(); 953 encryption_dict.getKey("/EncryptMetadata").getBoolValue();
950 } 954 }
951 955
@@ -986,40 +990,40 @@ QPDF::initializeEncryption() @@ -986,40 +990,40 @@ QPDF::initializeEncryption()
986 method = e_unknown; 990 method = e_unknown;
987 } 991 }
988 } 992 }
989 - this->crypt_filters[filter] = method; 993 + this->m->crypt_filters[filter] = method;
990 } 994 }
991 } 995 }
992 996
993 QPDFObjectHandle StmF = encryption_dict.getKey("/StmF"); 997 QPDFObjectHandle StmF = encryption_dict.getKey("/StmF");
994 QPDFObjectHandle StrF = encryption_dict.getKey("/StrF"); 998 QPDFObjectHandle StrF = encryption_dict.getKey("/StrF");
995 QPDFObjectHandle EFF = encryption_dict.getKey("/EFF"); 999 QPDFObjectHandle EFF = encryption_dict.getKey("/EFF");
996 - this->cf_stream = interpretCF(StmF);  
997 - this->cf_string = interpretCF(StrF); 1000 + this->m->cf_stream = interpretCF(StmF);
  1001 + this->m->cf_string = interpretCF(StrF);
998 if (EFF.isName()) 1002 if (EFF.isName())
999 { 1003 {
1000 - this->cf_file = interpretCF(EFF); 1004 + this->m->cf_file = interpretCF(EFF);
1001 } 1005 }
1002 else 1006 else
1003 { 1007 {
1004 - this->cf_file = this->cf_stream; 1008 + this->m->cf_file = this->m->cf_stream;
1005 } 1009 }
1006 } 1010 }
1007 1011
1008 EncryptionData data(V, R, Length / 8, P, O, U, OE, UE, Perms, 1012 EncryptionData data(V, R, Length / 8, P, O, U, OE, UE, Perms,
1009 - id1, this->encrypt_metadata); 1013 + id1, this->m->encrypt_metadata);
1010 if (check_owner_password( 1014 if (check_owner_password(
1011 - this->user_password, this->provided_password, data)) 1015 + this->m->user_password, this->m->provided_password, data))
1012 { 1016 {
1013 // password supplied was owner password; user_password has 1017 // password supplied was owner password; user_password has
1014 // been initialized for V < 5 1018 // been initialized for V < 5
1015 } 1019 }
1016 - else if (check_user_password(this->provided_password, data)) 1020 + else if (check_user_password(this->m->provided_password, data))
1017 { 1021 {
1018 - this->user_password = this->provided_password; 1022 + this->m->user_password = this->m->provided_password;
1019 } 1023 }
1020 else 1024 else
1021 { 1025 {
1022 - throw QPDFExc(qpdf_e_password, this->file->getName(), 1026 + throw QPDFExc(qpdf_e_password, this->m->file->getName(),
1023 "", 0, "invalid password"); 1027 "", 0, "invalid password");
1024 } 1028 }
1025 1029
@@ -1028,8 +1032,8 @@ QPDF::initializeEncryption() @@ -1028,8 +1032,8 @@ QPDF::initializeEncryption()
1028 // For V < 5, the user password is encrypted with the owner 1032 // For V < 5, the user password is encrypted with the owner
1029 // password, and the user password is always used for 1033 // password, and the user password is always used for
1030 // computing the encryption key. 1034 // computing the encryption key.
1031 - this->encryption_key = compute_encryption_key(  
1032 - this->user_password, data); 1035 + this->m->encryption_key = compute_encryption_key(
  1036 + this->m->user_password, data);
1033 } 1037 }
1034 else 1038 else
1035 { 1039 {
@@ -1037,12 +1041,13 @@ QPDF::initializeEncryption() @@ -1037,12 +1041,13 @@ QPDF::initializeEncryption()
1037 // compute the encryption key, and neither password can be 1041 // compute the encryption key, and neither password can be
1038 // used to recover the other. 1042 // used to recover the other.
1039 bool perms_valid; 1043 bool perms_valid;
1040 - this->encryption_key = recover_encryption_key_with_password(  
1041 - this->provided_password, data, perms_valid); 1044 + this->m->encryption_key = recover_encryption_key_with_password(
  1045 + this->m->provided_password, data, perms_valid);
1042 if (! perms_valid) 1046 if (! perms_valid)
1043 { 1047 {
1044 - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
1045 - "encryption dictionary", this->file->getLastOffset(), 1048 + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  1049 + "encryption dictionary",
  1050 + this->m->file->getLastOffset(),
1046 "/Perms field in encryption dictionary" 1051 "/Perms field in encryption dictionary"
1047 " doesn't match expected value")); 1052 " doesn't match expected value"));
1048 } 1053 }
@@ -1052,23 +1057,24 @@ QPDF::initializeEncryption() @@ -1052,23 +1057,24 @@ QPDF::initializeEncryption()
1052 std::string 1057 std::string
1053 QPDF::getKeyForObject(int objid, int generation, bool use_aes) 1058 QPDF::getKeyForObject(int objid, int generation, bool use_aes)
1054 { 1059 {
1055 - if (! this->encrypted) 1060 + if (! this->m->encrypted)
1056 { 1061 {
1057 throw std::logic_error( 1062 throw std::logic_error(
1058 "request for encryption key in non-encrypted PDF"); 1063 "request for encryption key in non-encrypted PDF");
1059 } 1064 }
1060 1065
1061 - if (! ((objid == this->cached_key_objid) &&  
1062 - (generation == this->cached_key_generation))) 1066 + if (! ((objid == this->m->cached_key_objid) &&
  1067 + (generation == this->m->cached_key_generation)))
1063 { 1068 {
1064 - this->cached_object_encryption_key =  
1065 - compute_data_key(this->encryption_key, objid, generation,  
1066 - use_aes, this->encryption_V, this->encryption_R);  
1067 - this->cached_key_objid = objid;  
1068 - this->cached_key_generation = generation; 1069 + this->m->cached_object_encryption_key =
  1070 + compute_data_key(this->m->encryption_key, objid, generation,
  1071 + use_aes, this->m->encryption_V,
  1072 + this->m->encryption_R);
  1073 + this->m->cached_key_objid = objid;
  1074 + this->m->cached_key_generation = generation;
1069 } 1075 }
1070 1076
1071 - return this->cached_object_encryption_key; 1077 + return this->m->cached_object_encryption_key;
1072 } 1078 }
1073 1079
1074 void 1080 void
@@ -1079,9 +1085,9 @@ QPDF::decryptString(std::string&amp; str, int objid, int generation) @@ -1079,9 +1085,9 @@ QPDF::decryptString(std::string&amp; str, int objid, int generation)
1079 return; 1085 return;
1080 } 1086 }
1081 bool use_aes = false; 1087 bool use_aes = false;
1082 - if (this->encryption_V >= 4) 1088 + if (this->m->encryption_V >= 4)
1083 { 1089 {
1084 - switch (this->cf_string) 1090 + switch (this->m->cf_string)
1085 { 1091 {
1086 case e_none: 1092 case e_none:
1087 return; 1093 return;
@@ -1098,15 +1104,15 @@ QPDF::decryptString(std::string&amp; str, int objid, int generation) @@ -1098,15 +1104,15 @@ QPDF::decryptString(std::string&amp; str, int objid, int generation)
1098 break; 1104 break;
1099 1105
1100 default: 1106 default:
1101 - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
1102 - this->last_object_description,  
1103 - this->file->getLastOffset(), 1107 + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  1108 + this->m->last_object_description,
  1109 + this->m->file->getLastOffset(),
1104 "unknown encryption filter for strings" 1110 "unknown encryption filter for strings"
1105 " (check /StrF in /Encrypt dictionary);" 1111 " (check /StrF in /Encrypt dictionary);"
1106 " strings may be decrypted improperly")); 1112 " strings may be decrypted improperly"));
1107 // To avoid repeated warnings, reset cf_string. Assume 1113 // To avoid repeated warnings, reset cf_string. Assume
1108 // we'd want to use AES if V == 4. 1114 // we'd want to use AES if V == 4.
1109 - this->cf_string = e_aes; 1115 + this->m->cf_string = e_aes;
1110 break; 1116 break;
1111 } 1117 }
1112 } 1118 }
@@ -1145,9 +1151,9 @@ QPDF::decryptString(std::string&amp; str, int objid, int generation) @@ -1145,9 +1151,9 @@ QPDF::decryptString(std::string&amp; str, int objid, int generation)
1145 } 1151 }
1146 catch (std::runtime_error& e) 1152 catch (std::runtime_error& e)
1147 { 1153 {
1148 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
1149 - this->last_object_description,  
1150 - this->file->getLastOffset(), 1154 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  1155 + this->m->last_object_description,
  1156 + this->m->file->getLastOffset(),
1151 "error decrypting string for object " + 1157 "error decrypting string for object " +
1152 QUtil::int_to_string(objid) + " " + 1158 QUtil::int_to_string(objid) + " " +
1153 QUtil::int_to_string(generation) + ": " + e.what()); 1159 QUtil::int_to_string(generation) + ": " + e.what());
@@ -1170,7 +1176,7 @@ QPDF::decryptStream(Pipeline*&amp; pipeline, int objid, int generation, @@ -1170,7 +1176,7 @@ QPDF::decryptStream(Pipeline*&amp; pipeline, int objid, int generation,
1170 return; 1176 return;
1171 } 1177 }
1172 bool use_aes = false; 1178 bool use_aes = false;
1173 - if (this->encryption_V >= 4) 1179 + if (this->m->encryption_V >= 4)
1174 { 1180 {
1175 encryption_method_e method = e_unknown; 1181 encryption_method_e method = e_unknown;
1176 std::string method_source = "/StmF from /Encrypt dictionary"; 1182 std::string method_source = "/StmF from /Encrypt dictionary";
@@ -1221,21 +1227,21 @@ QPDF::decryptStream(Pipeline*&amp; pipeline, int objid, int generation, @@ -1221,21 +1227,21 @@ QPDF::decryptStream(Pipeline*&amp; pipeline, int objid, int generation,
1221 1227
1222 if (method == e_unknown) 1228 if (method == e_unknown)
1223 { 1229 {
1224 - if ((! this->encrypt_metadata) && (type == "/Metadata")) 1230 + if ((! this->m->encrypt_metadata) && (type == "/Metadata"))
1225 { 1231 {
1226 QTC::TC("qpdf", "QPDF_encryption cleartext metadata"); 1232 QTC::TC("qpdf", "QPDF_encryption cleartext metadata");
1227 method = e_none; 1233 method = e_none;
1228 } 1234 }
1229 else 1235 else
1230 { 1236 {
1231 - if (this->attachment_streams.count( 1237 + if (this->m->attachment_streams.count(
1232 QPDFObjGen(objid, generation)) > 0) 1238 QPDFObjGen(objid, generation)) > 0)
1233 { 1239 {
1234 - method = this->cf_file; 1240 + method = this->m->cf_file;
1235 } 1241 }
1236 else 1242 else
1237 { 1243 {
1238 - method = this->cf_stream; 1244 + method = this->m->cf_stream;
1239 } 1245 }
1240 } 1246 }
1241 } 1247 }
@@ -1259,15 +1265,15 @@ QPDF::decryptStream(Pipeline*&amp; pipeline, int objid, int generation, @@ -1259,15 +1265,15 @@ QPDF::decryptStream(Pipeline*&amp; pipeline, int objid, int generation,
1259 1265
1260 default: 1266 default:
1261 // filter local to this stream. 1267 // filter local to this stream.
1262 - warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
1263 - this->last_object_description,  
1264 - this->file->getLastOffset(), 1268 + warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  1269 + this->m->last_object_description,
  1270 + this->m->file->getLastOffset(),
1265 "unknown encryption filter for streams" 1271 "unknown encryption filter for streams"
1266 " (check " + method_source + ");" 1272 " (check " + method_source + ");"
1267 " streams may be decrypted improperly")); 1273 " streams may be decrypted improperly"));
1268 // To avoid repeated warnings, reset cf_stream. Assume 1274 // To avoid repeated warnings, reset cf_stream. Assume
1269 // we'd want to use AES if V == 4. 1275 // we'd want to use AES if V == 4.
1270 - this->cf_stream = e_aes; 1276 + this->m->cf_stream = e_aes;
1271 break; 1277 break;
1272 } 1278 }
1273 } 1279 }
@@ -1331,13 +1337,13 @@ QPDF::compute_encryption_parameters_V5( @@ -1331,13 +1337,13 @@ QPDF::compute_encryption_parameters_V5(
1331 std::string const& 1337 std::string const&
1332 QPDF::getPaddedUserPassword() const 1338 QPDF::getPaddedUserPassword() const
1333 { 1339 {
1334 - return this->user_password; 1340 + return this->m->user_password;
1335 } 1341 }
1336 1342
1337 std::string 1343 std::string
1338 QPDF::getTrimmedUserPassword() const 1344 QPDF::getTrimmedUserPassword() const
1339 { 1345 {
1340 - std::string result = this->user_password; 1346 + std::string result = this->m->user_password;
1341 trim_user_password(result); 1347 trim_user_password(result);
1342 return result; 1348 return result;
1343 } 1349 }
@@ -1345,13 +1351,13 @@ QPDF::getTrimmedUserPassword() const @@ -1345,13 +1351,13 @@ QPDF::getTrimmedUserPassword() const
1345 std::string 1351 std::string
1346 QPDF::getEncryptionKey() const 1352 QPDF::getEncryptionKey() const
1347 { 1353 {
1348 - return this->encryption_key; 1354 + return this->m->encryption_key;
1349 } 1355 }
1350 1356
1351 bool 1357 bool
1352 QPDF::isEncrypted() const 1358 QPDF::isEncrypted() const
1353 { 1359 {
1354 - return this->encrypted; 1360 + return this->m->encrypted;
1355 } 1361 }
1356 1362
1357 bool 1363 bool
@@ -1368,7 +1374,7 @@ QPDF::isEncrypted(int&amp; R, int&amp; P, int&amp; V, @@ -1368,7 +1374,7 @@ QPDF::isEncrypted(int&amp; R, int&amp; P, int&amp; V,
1368 encryption_method_e& string_method, 1374 encryption_method_e& string_method,
1369 encryption_method_e& file_method) 1375 encryption_method_e& file_method)
1370 { 1376 {
1371 - if (this->encrypted) 1377 + if (this->m->encrypted)
1372 { 1378 {
1373 QPDFObjectHandle trailer = getTrailer(); 1379 QPDFObjectHandle trailer = getTrailer();
1374 QPDFObjectHandle encrypt = trailer.getKey("/Encrypt"); 1380 QPDFObjectHandle encrypt = trailer.getKey("/Encrypt");
@@ -1378,9 +1384,9 @@ QPDF::isEncrypted(int&amp; R, int&amp; P, int&amp; V, @@ -1378,9 +1384,9 @@ QPDF::isEncrypted(int&amp; R, int&amp; P, int&amp; V,
1378 P = Pkey.getIntValue(); 1384 P = Pkey.getIntValue();
1379 R = Rkey.getIntValue(); 1385 R = Rkey.getIntValue();
1380 V = Vkey.getIntValue(); 1386 V = Vkey.getIntValue();
1381 - stream_method = this->cf_stream;  
1382 - string_method = this->cf_stream;  
1383 - file_method = this->cf_file; 1387 + stream_method = this->m->cf_stream;
  1388 + string_method = this->m->cf_stream;
  1389 + file_method = this->m->cf_file;
1384 return true; 1390 return true;
1385 } 1391 }
1386 else 1392 else
libqpdf/QPDF_linearization.cc
@@ -72,7 +72,7 @@ QPDF::checkLinearization() @@ -72,7 +72,7 @@ QPDF::checkLinearization()
72 } 72 }
73 catch (QPDFExc& e) 73 catch (QPDFExc& e)
74 { 74 {
75 - *out_stream << e.what() << std::endl; 75 + *this->m->out_stream << e.what() << std::endl;
76 } 76 }
77 return result; 77 return result;
78 } 78 }
@@ -82,7 +82,7 @@ QPDF::isLinearized() @@ -82,7 +82,7 @@ QPDF::isLinearized()
82 { 82 {
83 // If the first object in the file is a dictionary with a suitable 83 // If the first object in the file is a dictionary with a suitable
84 // /Linearized key and has an /L key that accurately indicates the 84 // /Linearized key and has an /L key that accurately indicates the
85 - // file size, initialize this->lindict and return true. 85 + // file size, initialize this->m->lindict and return true.
86 86
87 // A linearized PDF spec's first object will be contained within 87 // A linearized PDF spec's first object will be contained within
88 // the first 1024 bytes of the file and will be a dictionary with 88 // the first 1024 bytes of the file and will be a dictionary with
@@ -95,10 +95,10 @@ QPDF::isLinearized() @@ -95,10 +95,10 @@ QPDF::isLinearized()
95 static int const tbuf_size = 1025; 95 static int const tbuf_size = 1025;
96 96
97 char* buf = new char[tbuf_size]; 97 char* buf = new char[tbuf_size];
98 - this->file->seek(0, SEEK_SET); 98 + this->m->file->seek(0, SEEK_SET);
99 PointerHolder<char> b(true, buf); 99 PointerHolder<char> b(true, buf);
100 memset(buf, '\0', tbuf_size); 100 memset(buf, '\0', tbuf_size);
101 - this->file->read(buf, tbuf_size - 1); 101 + this->m->file->read(buf, tbuf_size - 1);
102 102
103 int lindict_obj = -1; 103 int lindict_obj = -1;
104 char* p = buf; 104 char* p = buf;
@@ -115,16 +115,16 @@ QPDF::isLinearized() @@ -115,16 +115,16 @@ QPDF::isLinearized()
115 } 115 }
116 // Seek to the digit. Then skip over digits for a potential 116 // Seek to the digit. Then skip over digits for a potential
117 // next iteration. 117 // next iteration.
118 - this->file->seek(p - buf, SEEK_SET); 118 + this->m->file->seek(p - buf, SEEK_SET);
119 while (((p - buf) < tbuf_size) && QUtil::is_digit(*p)) 119 while (((p - buf) < tbuf_size) && QUtil::is_digit(*p))
120 { 120 {
121 ++p; 121 ++p;
122 } 122 }
123 123
124 - QPDFTokenizer::Token t1 = readToken(this->file, true);  
125 - QPDFTokenizer::Token t2 = readToken(this->file, true);  
126 - QPDFTokenizer::Token t3 = readToken(this->file, true);  
127 - QPDFTokenizer::Token t4 = readToken(this->file, true); 124 + QPDFTokenizer::Token t1 = readToken(this->m->file, true);
  125 + QPDFTokenizer::Token t2 = readToken(this->m->file, true);
  126 + QPDFTokenizer::Token t3 = readToken(this->m->file, true);
  127 + QPDFTokenizer::Token t4 = readToken(this->m->file, true);
128 if ((t1.getType() == QPDFTokenizer::tt_integer) && 128 if ((t1.getType() == QPDFTokenizer::tt_integer) &&
129 (t2.getType() == QPDFTokenizer::tt_integer) && 129 (t2.getType() == QPDFTokenizer::tt_integer) &&
130 (t3 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "obj")) && 130 (t3 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "obj")) &&
@@ -158,19 +158,19 @@ QPDF::isLinearized() @@ -158,19 +158,19 @@ QPDF::isLinearized()
158 if (L.isInteger()) 158 if (L.isInteger())
159 { 159 {
160 qpdf_offset_t Li = L.getIntValue(); 160 qpdf_offset_t Li = L.getIntValue();
161 - this->file->seek(0, SEEK_END);  
162 - if (Li != this->file->tell()) 161 + this->m->file->seek(0, SEEK_END);
  162 + if (Li != this->m->file->tell())
163 { 163 {
164 QTC::TC("qpdf", "QPDF /L mismatch"); 164 QTC::TC("qpdf", "QPDF /L mismatch");
165 return false; 165 return false;
166 } 166 }
167 else 167 else
168 { 168 {
169 - this->linp.file_size = Li; 169 + this->m->linp.file_size = Li;
170 } 170 }
171 } 171 }
172 172
173 - this->lindict = candidate; 173 + this->m->lindict = candidate;
174 174
175 return true; 175 return true;
176 } 176 }
@@ -191,12 +191,12 @@ QPDF::readLinearizationData() @@ -191,12 +191,12 @@ QPDF::readLinearizationData()
191 } 191 }
192 192
193 // /L is read and stored in linp by isLinearized() 193 // /L is read and stored in linp by isLinearized()
194 - QPDFObjectHandle H = lindict.getKey("/H");  
195 - QPDFObjectHandle O = lindict.getKey("/O");  
196 - QPDFObjectHandle E = lindict.getKey("/E");  
197 - QPDFObjectHandle N = lindict.getKey("/N");  
198 - QPDFObjectHandle T = lindict.getKey("/T");  
199 - QPDFObjectHandle P = lindict.getKey("/P"); 194 + QPDFObjectHandle H = this->m->lindict.getKey("/H");
  195 + QPDFObjectHandle O = this->m->lindict.getKey("/O");
  196 + QPDFObjectHandle E = this->m->lindict.getKey("/E");
  197 + QPDFObjectHandle N = this->m->lindict.getKey("/N");
  198 + QPDFObjectHandle T = this->m->lindict.getKey("/T");
  199 + QPDFObjectHandle P = this->m->lindict.getKey("/P");
200 200
201 if (! (H.isArray() && 201 if (! (H.isArray() &&
202 O.isInteger() && 202 O.isInteger() &&
@@ -205,9 +205,9 @@ QPDF::readLinearizationData() @@ -205,9 +205,9 @@ QPDF::readLinearizationData()
205 T.isInteger() && 205 T.isInteger() &&
206 (P.isInteger() || P.isNull()))) 206 (P.isInteger() || P.isNull())))
207 { 207 {
208 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 208 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
209 "linearization dictionary", 209 "linearization dictionary",
210 - this->file->getLastOffset(), 210 + this->m->file->getLastOffset(),
211 "some keys in linearization dictionary are of " 211 "some keys in linearization dictionary are of "
212 "the wrong type"); 212 "the wrong type");
213 } 213 }
@@ -216,9 +216,9 @@ QPDF::readLinearizationData() @@ -216,9 +216,9 @@ QPDF::readLinearizationData()
216 unsigned int n_H_items = H.getArrayNItems(); 216 unsigned int n_H_items = H.getArrayNItems();
217 if (! ((n_H_items == 2) || (n_H_items == 4))) 217 if (! ((n_H_items == 2) || (n_H_items == 4)))
218 { 218 {
219 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 219 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
220 "linearization dictionary", 220 "linearization dictionary",
221 - this->file->getLastOffset(), 221 + this->m->file->getLastOffset(),
222 "H has the wrong number of items"); 222 "H has the wrong number of items");
223 } 223 }
224 224
@@ -232,9 +232,9 @@ QPDF::readLinearizationData() @@ -232,9 +232,9 @@ QPDF::readLinearizationData()
232 } 232 }
233 else 233 else
234 { 234 {
235 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 235 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
236 "linearization dictionary", 236 "linearization dictionary",
237 - this->file->getLastOffset(), 237 + this->m->file->getLastOffset(),
238 "some H items are of the wrong type"); 238 "some H items are of the wrong type");
239 } 239 }
240 } 240 }
@@ -272,20 +272,20 @@ QPDF::readLinearizationData() @@ -272,20 +272,20 @@ QPDF::readLinearizationData()
272 // accurate and bail right now if it's not. 272 // accurate and bail right now if it's not.
273 if (N.getIntValue() != static_cast<long long>(getAllPages().size())) 273 if (N.getIntValue() != static_cast<long long>(getAllPages().size()))
274 { 274 {
275 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 275 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
276 "linearization hint table", 276 "linearization hint table",
277 - this->file->getLastOffset(), 277 + this->m->file->getLastOffset(),
278 "/N does not match number of pages"); 278 "/N does not match number of pages");
279 } 279 }
280 280
281 // file_size initialized by isLinearized() 281 // file_size initialized by isLinearized()
282 - this->linp.first_page_object = O.getIntValue();  
283 - this->linp.first_page_end = E.getIntValue();  
284 - this->linp.npages = N.getIntValue();  
285 - this->linp.xref_zero_offset = T.getIntValue();  
286 - this->linp.first_page = first_page;  
287 - this->linp.H_offset = H0_offset;  
288 - this->linp.H_length = H0_length; 282 + this->m->linp.first_page_object = O.getIntValue();
  283 + this->m->linp.first_page_end = E.getIntValue();
  284 + this->m->linp.npages = N.getIntValue();
  285 + this->m->linp.xref_zero_offset = T.getIntValue();
  286 + this->m->linp.first_page = first_page;
  287 + this->m->linp.H_offset = H0_offset;
  288 + this->m->linp.H_length = H0_length;
289 289
290 // Read hint streams 290 // Read hint streams
291 291
@@ -320,9 +320,9 @@ QPDF::readLinearizationData() @@ -320,9 +320,9 @@ QPDF::readLinearizationData()
320 int HSi = HS.getIntValue(); 320 int HSi = HS.getIntValue();
321 if ((HSi < 0) || (HSi >= h_size)) 321 if ((HSi < 0) || (HSi >= h_size))
322 { 322 {
323 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 323 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
324 "linearization hint table", 324 "linearization hint table",
325 - this->file->getLastOffset(), 325 + this->m->file->getLastOffset(),
326 "/S (shared object) offset is out of bounds"); 326 "/S (shared object) offset is out of bounds");
327 } 327 }
328 readHSharedObject(BitStream(h_buf + HSi, h_size - HSi)); 328 readHSharedObject(BitStream(h_buf + HSi, h_size - HSi));
@@ -332,13 +332,13 @@ QPDF::readLinearizationData() @@ -332,13 +332,13 @@ QPDF::readLinearizationData()
332 int HOi = HO.getIntValue(); 332 int HOi = HO.getIntValue();
333 if ((HOi < 0) || (HOi >= h_size)) 333 if ((HOi < 0) || (HOi >= h_size))
334 { 334 {
335 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 335 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
336 "linearization hint table", 336 "linearization hint table",
337 - this->file->getLastOffset(), 337 + this->m->file->getLastOffset(),
338 "/O (outline) offset is out of bounds"); 338 "/O (outline) offset is out of bounds");
339 } 339 }
340 readHGeneric(BitStream(h_buf + HOi, h_size - HOi), 340 readHGeneric(BitStream(h_buf + HOi, h_size - HOi),
341 - this->outline_hints); 341 + this->m->outline_hints);
342 } 342 }
343 } 343 }
344 344
@@ -349,14 +349,14 @@ QPDF::readHintStream(Pipeline&amp; pl, qpdf_offset_t offset, size_t length) @@ -349,14 +349,14 @@ QPDF::readHintStream(Pipeline&amp; pl, qpdf_offset_t offset, size_t length)
349 int gen; 349 int gen;
350 QPDFObjectHandle H = readObjectAtOffset( 350 QPDFObjectHandle H = readObjectAtOffset(
351 false, offset, "linearization hint stream", -1, 0, obj, gen); 351 false, offset, "linearization hint stream", -1, 0, obj, gen);
352 - ObjCache& oc = this->obj_cache[QPDFObjGen(obj, gen)]; 352 + ObjCache& oc = this->m->obj_cache[QPDFObjGen(obj, gen)];
353 qpdf_offset_t min_end_offset = oc.end_before_space; 353 qpdf_offset_t min_end_offset = oc.end_before_space;
354 qpdf_offset_t max_end_offset = oc.end_after_space; 354 qpdf_offset_t max_end_offset = oc.end_after_space;
355 if (! H.isStream()) 355 if (! H.isStream())
356 { 356 {
357 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 357 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
358 "linearization dictionary", 358 "linearization dictionary",
359 - this->file->getLastOffset(), 359 + this->m->file->getLastOffset(),
360 "hint table is not a stream"); 360 "hint table is not a stream");
361 } 361 }
362 362
@@ -373,7 +373,7 @@ QPDF::readHintStream(Pipeline&amp; pl, qpdf_offset_t offset, size_t length) @@ -373,7 +373,7 @@ QPDF::readHintStream(Pipeline&amp; pl, qpdf_offset_t offset, size_t length)
373 QTC::TC("qpdf", "QPDF hint table length indirect"); 373 QTC::TC("qpdf", "QPDF hint table length indirect");
374 // Force resolution 374 // Force resolution
375 (void) length_obj.getIntValue(); 375 (void) length_obj.getIntValue();
376 - ObjCache& oc = this->obj_cache[length_obj.getObjGen()]; 376 + ObjCache& oc = this->m->obj_cache[length_obj.getObjGen()];
377 min_end_offset = oc.end_before_space; 377 min_end_offset = oc.end_before_space;
378 max_end_offset = oc.end_after_space; 378 max_end_offset = oc.end_after_space;
379 } 379 }
@@ -385,12 +385,12 @@ QPDF::readHintStream(Pipeline&amp; pl, qpdf_offset_t offset, size_t length) @@ -385,12 +385,12 @@ QPDF::readHintStream(Pipeline&amp; pl, qpdf_offset_t offset, size_t length)
385 if ((computed_end < min_end_offset) || 385 if ((computed_end < min_end_offset) ||
386 (computed_end > max_end_offset)) 386 (computed_end > max_end_offset))
387 { 387 {
388 - *out_stream << "expected = " << computed_end  
389 - << "; actual = " << min_end_offset << ".."  
390 - << max_end_offset << std::endl;  
391 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), 388 + *this->m->out_stream << "expected = " << computed_end
  389 + << "; actual = " << min_end_offset << ".."
  390 + << max_end_offset << std::endl;
  391 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
392 "linearization dictionary", 392 "linearization dictionary",
393 - this->file->getLastOffset(), 393 + this->m->file->getLastOffset(),
394 "hint table length mismatch"); 394 "hint table length mismatch");
395 } 395 }
396 H.pipeStreamData(&pl, 0, qpdf_dl_specialized); 396 H.pipeStreamData(&pl, 0, qpdf_dl_specialized);
@@ -403,7 +403,7 @@ QPDF::readHPageOffset(BitStream h) @@ -403,7 +403,7 @@ QPDF::readHPageOffset(BitStream h)
403 // All comments referring to the PDF spec refer to the spec for 403 // All comments referring to the PDF spec refer to the spec for
404 // version 1.4. 404 // version 1.4.
405 405
406 - HPageOffset& t = this->page_offset_hints; 406 + HPageOffset& t = this->m->page_offset_hints;
407 407
408 t.min_nobjects = h.getBits(32); // 1 408 t.min_nobjects = h.getBits(32); // 1
409 t.first_page_offset = h.getBits(32); // 2 409 t.first_page_offset = h.getBits(32); // 2
@@ -421,7 +421,7 @@ QPDF::readHPageOffset(BitStream h) @@ -421,7 +421,7 @@ QPDF::readHPageOffset(BitStream h)
421 421
422 std::vector<HPageOffsetEntry>& entries = t.entries; 422 std::vector<HPageOffsetEntry>& entries = t.entries;
423 entries.clear(); 423 entries.clear();
424 - unsigned int nitems = this->linp.npages; 424 + unsigned int nitems = this->m->linp.npages;
425 load_vector_int(h, nitems, entries, 425 load_vector_int(h, nitems, entries,
426 t.nbits_delta_nobjects, 426 t.nbits_delta_nobjects,
427 &HPageOffsetEntry::delta_nobjects); 427 &HPageOffsetEntry::delta_nobjects);
@@ -450,7 +450,7 @@ QPDF::readHPageOffset(BitStream h) @@ -450,7 +450,7 @@ QPDF::readHPageOffset(BitStream h)
450 void 450 void
451 QPDF::readHSharedObject(BitStream h) 451 QPDF::readHSharedObject(BitStream h)
452 { 452 {
453 - HSharedObject& t = this->shared_object_hints; 453 + HSharedObject& t = this->m->shared_object_hints;
454 454
455 t.first_shared_obj = h.getBits(32); // 1 455 t.first_shared_obj = h.getBits(32); // 1
456 t.first_shared_offset = h.getBits(32); // 2 456 t.first_shared_offset = h.getBits(32); // 2
@@ -509,7 +509,7 @@ QPDF::checkLinearizationInternal() @@ -509,7 +509,7 @@ QPDF::checkLinearizationInternal()
509 509
510 // Check all values in linearization parameter dictionary 510 // Check all values in linearization parameter dictionary
511 511
512 - LinParameters& p = this->linp; 512 + LinParameters& p = this->m->linp;
513 513
514 // L: file size in bytes -- checked by isLinearized 514 // L: file size in bytes -- checked by isLinearized
515 515
@@ -533,7 +533,7 @@ QPDF::checkLinearizationInternal() @@ -533,7 +533,7 @@ QPDF::checkLinearizationInternal()
533 { 533 {
534 QPDFObjectHandle const& page = pages.at(i); 534 QPDFObjectHandle const& page = pages.at(i);
535 QPDFObjGen og(page.getObjGen()); 535 QPDFObjGen og(page.getObjGen());
536 - if (this->xref_table[og].getType() == 2) 536 + if (this->m->xref_table[og].getType() == 2)
537 { 537 {
538 errors.push_back("page dictionary for page " + 538 errors.push_back("page dictionary for page " +
539 QUtil::int_to_string(i) + " is compressed"); 539 QUtil::int_to_string(i) + " is compressed");
@@ -541,25 +541,25 @@ QPDF::checkLinearizationInternal() @@ -541,25 +541,25 @@ QPDF::checkLinearizationInternal()
541 } 541 }
542 542
543 // T: offset of whitespace character preceding xref entry for object 0 543 // T: offset of whitespace character preceding xref entry for object 0
544 - this->file->seek(p.xref_zero_offset, SEEK_SET); 544 + this->m->file->seek(p.xref_zero_offset, SEEK_SET);
545 while (1) 545 while (1)
546 { 546 {
547 char ch; 547 char ch;
548 - this->file->read(&ch, 1); 548 + this->m->file->read(&ch, 1);
549 if (! ((ch == ' ') || (ch == '\r') || (ch == '\n'))) 549 if (! ((ch == ' ') || (ch == '\r') || (ch == '\n')))
550 { 550 {
551 - this->file->seek(-1, SEEK_CUR); 551 + this->m->file->seek(-1, SEEK_CUR);
552 break; 552 break;
553 } 553 }
554 } 554 }
555 - if (this->file->tell() != this->first_xref_item_offset) 555 + if (this->m->file->tell() != this->m->first_xref_item_offset)
556 { 556 {
557 QTC::TC("qpdf", "QPDF err /T mismatch"); 557 QTC::TC("qpdf", "QPDF err /T mismatch");
558 errors.push_back("space before first xref item (/T) mismatch " 558 errors.push_back("space before first xref item (/T) mismatch "
559 "(computed = " + 559 "(computed = " +
560 - QUtil::int_to_string(this->first_xref_item_offset) + 560 + QUtil::int_to_string(this->m->first_xref_item_offset) +
561 "; file = " + 561 "; file = " +
562 - QUtil::int_to_string(this->file->tell())); 562 + QUtil::int_to_string(this->m->file->tell()));
563 } 563 }
564 564
565 // P: first page number -- Implementation note 124 says Acrobat 565 // P: first page number -- Implementation note 124 says Acrobat
@@ -570,7 +570,7 @@ QPDF::checkLinearizationInternal() @@ -570,7 +570,7 @@ QPDF::checkLinearizationInternal()
570 // at the end of the containing xref section if any object streams 570 // at the end of the containing xref section if any object streams
571 // are in use. 571 // are in use.
572 572
573 - if (this->uncompressed_after_compressed) 573 + if (this->m->uncompressed_after_compressed)
574 { 574 {
575 errors.push_back("linearized file contains an uncompressed object" 575 errors.push_back("linearized file contains an uncompressed object"
576 " after a compressed one in a cross-reference stream"); 576 " after a compressed one in a cross-reference stream");
@@ -584,8 +584,8 @@ QPDF::checkLinearizationInternal() @@ -584,8 +584,8 @@ QPDF::checkLinearizationInternal()
584 { // local scope 584 { // local scope
585 std::map<int, int> object_stream_data; 585 std::map<int, int> object_stream_data;
586 for (std::map<QPDFObjGen, QPDFXRefEntry>::const_iterator iter = 586 for (std::map<QPDFObjGen, QPDFXRefEntry>::const_iterator iter =
587 - this->xref_table.begin();  
588 - iter != this->xref_table.end(); ++iter) 587 + this->m->xref_table.begin();
  588 + iter != this->m->xref_table.end(); ++iter)
589 { 589 {
590 QPDFObjGen const& og = (*iter).first; 590 QPDFObjGen const& og = (*iter).first;
591 QPDFXRefEntry const& entry = (*iter).second; 591 QPDFXRefEntry const& entry = (*iter).second;
@@ -609,22 +609,22 @@ QPDF::checkLinearizationInternal() @@ -609,22 +609,22 @@ QPDF::checkLinearizationInternal()
609 // agree with pdlin. As of this writing, the test suite doesn't 609 // agree with pdlin. As of this writing, the test suite doesn't
610 // contain any files with threads. 610 // contain any files with threads.
611 611
612 - if (this->part6.empty()) 612 + if (this->m->part6.empty())
613 { 613 {
614 throw std::logic_error("linearization part 6 unexpectedly empty"); 614 throw std::logic_error("linearization part 6 unexpectedly empty");
615 } 615 }
616 qpdf_offset_t min_E = -1; 616 qpdf_offset_t min_E = -1;
617 qpdf_offset_t max_E = -1; 617 qpdf_offset_t max_E = -1;
618 - for (std::vector<QPDFObjectHandle>::iterator iter = this->part6.begin();  
619 - iter != this->part6.end(); ++iter) 618 + for (std::vector<QPDFObjectHandle>::iterator iter = this->m->part6.begin();
  619 + iter != this->m->part6.end(); ++iter)
620 { 620 {
621 QPDFObjGen og((*iter).getObjGen()); 621 QPDFObjGen og((*iter).getObjGen());
622 - if (this->obj_cache.count(og) == 0) 622 + if (this->m->obj_cache.count(og) == 0)
623 { 623 {
624 // All objects have to have been dereferenced to be classified. 624 // All objects have to have been dereferenced to be classified.
625 throw std::logic_error("linearization part6 object not in cache"); 625 throw std::logic_error("linearization part6 object not in cache");
626 } 626 }
627 - ObjCache const& oc = this->obj_cache[og]; 627 + ObjCache const& oc = this->m->obj_cache[og];
628 min_E = std::max(min_E, oc.end_before_space); 628 min_E = std::max(min_E, oc.end_before_space);
629 max_E = std::max(max_E, oc.end_after_space); 629 max_E = std::max(max_E, oc.end_after_space);
630 } 630 }
@@ -655,7 +655,7 @@ QPDF::checkLinearizationInternal() @@ -655,7 +655,7 @@ QPDF::checkLinearizationInternal()
655 for (std::list<std::string>::iterator iter = errors.begin(); 655 for (std::list<std::string>::iterator iter = errors.begin();
656 iter != errors.end(); ++iter) 656 iter != errors.end(); ++iter)
657 { 657 {
658 - *out_stream << "ERROR: " << (*iter) << std::endl; 658 + *this->m->out_stream << "ERROR: " << (*iter) << std::endl;
659 } 659 }
660 } 660 }
661 661
@@ -665,7 +665,7 @@ QPDF::checkLinearizationInternal() @@ -665,7 +665,7 @@ QPDF::checkLinearizationInternal()
665 for (std::list<std::string>::iterator iter = warnings.begin(); 665 for (std::list<std::string>::iterator iter = warnings.begin();
666 iter != warnings.end(); ++iter) 666 iter != warnings.end(); ++iter)
667 { 667 {
668 - *out_stream << "WARNING: " << (*iter) << std::endl; 668 + *this->m->out_stream << "WARNING: " << (*iter) << std::endl;
669 } 669 }
670 } 670 }
671 671
@@ -675,15 +675,15 @@ QPDF::checkLinearizationInternal() @@ -675,15 +675,15 @@ QPDF::checkLinearizationInternal()
675 qpdf_offset_t 675 qpdf_offset_t
676 QPDF::maxEnd(ObjUser const& ou) 676 QPDF::maxEnd(ObjUser const& ou)
677 { 677 {
678 - assert(this->obj_user_to_objects.count(ou) > 0);  
679 - std::set<QPDFObjGen> const& ogs = this->obj_user_to_objects[ou]; 678 + assert(this->m->obj_user_to_objects.count(ou) > 0);
  679 + std::set<QPDFObjGen> const& ogs = this->m->obj_user_to_objects[ou];
680 qpdf_offset_t end = 0; 680 qpdf_offset_t end = 0;
681 for (std::set<QPDFObjGen>::const_iterator iter = ogs.begin(); 681 for (std::set<QPDFObjGen>::const_iterator iter = ogs.begin();
682 iter != ogs.end(); ++iter) 682 iter != ogs.end(); ++iter)
683 { 683 {
684 QPDFObjGen const& og = *iter; 684 QPDFObjGen const& og = *iter;
685 - assert(this->obj_cache.count(og) > 0);  
686 - end = std::max(end, this->obj_cache[og].end_after_space); 685 + assert(this->m->obj_cache.count(og) > 0);
  686 + end = std::max(end, this->m->obj_cache[og].end_after_space);
687 } 687 }
688 return end; 688 return end;
689 } 689 }
@@ -691,7 +691,7 @@ QPDF::maxEnd(ObjUser const&amp; ou) @@ -691,7 +691,7 @@ QPDF::maxEnd(ObjUser const&amp; ou)
691 qpdf_offset_t 691 qpdf_offset_t
692 QPDF::getLinearizationOffset(QPDFObjGen const& og) 692 QPDF::getLinearizationOffset(QPDFObjGen const& og)
693 { 693 {
694 - QPDFXRefEntry entry = this->xref_table[og]; 694 + QPDFXRefEntry entry = this->m->xref_table[og];
695 qpdf_offset_t result = 0; 695 qpdf_offset_t result = 0;
696 switch (entry.getType()) 696 switch (entry.getType())
697 { 697 {
@@ -737,7 +737,7 @@ QPDF::lengthNextN(int first_object, int n, @@ -737,7 +737,7 @@ QPDF::lengthNextN(int first_object, int n,
737 for (int i = 0; i < n; ++i) 737 for (int i = 0; i < n; ++i)
738 { 738 {
739 QPDFObjGen og(first_object + i, 0); 739 QPDFObjGen og(first_object + i, 0);
740 - if (this->xref_table.count(og) == 0) 740 + if (this->m->xref_table.count(og) == 0)
741 { 741 {
742 errors.push_back( 742 errors.push_back(
743 "no xref table entry for " + 743 "no xref table entry for " +
@@ -745,8 +745,8 @@ QPDF::lengthNextN(int first_object, int n, @@ -745,8 +745,8 @@ QPDF::lengthNextN(int first_object, int n,
745 } 745 }
746 else 746 else
747 { 747 {
748 - assert(this->obj_cache.count(og) > 0);  
749 - length += this->obj_cache[og].end_after_space - 748 + assert(this->m->obj_cache.count(og) > 0);
  749 + length += this->m->obj_cache[og].end_after_space -
750 getLinearizationOffset(og); 750 getLinearizationOffset(og);
751 } 751 }
752 } 752 }
@@ -778,9 +778,9 @@ QPDF::checkHPageOffset(std::list&lt;std::string&gt;&amp; errors, @@ -778,9 +778,9 @@ QPDF::checkHPageOffset(std::list&lt;std::string&gt;&amp; errors,
778 778
779 unsigned int npages = pages.size(); 779 unsigned int npages = pages.size();
780 int table_offset = adjusted_offset( 780 int table_offset = adjusted_offset(
781 - this->page_offset_hints.first_page_offset); 781 + this->m->page_offset_hints.first_page_offset);
782 QPDFObjGen first_page_og(pages.at(0).getObjGen()); 782 QPDFObjGen first_page_og(pages.at(0).getObjGen());
783 - assert(this->xref_table.count(first_page_og) > 0); 783 + assert(this->m->xref_table.count(first_page_og) > 0);
784 int offset = getLinearizationOffset(first_page_og); 784 int offset = getLinearizationOffset(first_page_og);
785 if (table_offset != offset) 785 if (table_offset != offset)
786 { 786 {
@@ -791,13 +791,13 @@ QPDF::checkHPageOffset(std::list&lt;std::string&gt;&amp; errors, @@ -791,13 +791,13 @@ QPDF::checkHPageOffset(std::list&lt;std::string&gt;&amp; errors,
791 { 791 {
792 QPDFObjGen page_og(pages.at(pageno).getObjGen()); 792 QPDFObjGen page_og(pages.at(pageno).getObjGen());
793 int first_object = page_og.getObj(); 793 int first_object = page_og.getObj();
794 - assert(this->xref_table.count(page_og) > 0); 794 + assert(this->m->xref_table.count(page_og) > 0);
795 offset = getLinearizationOffset(page_og); 795 offset = getLinearizationOffset(page_og);
796 796
797 - HPageOffsetEntry& he = this->page_offset_hints.entries.at(pageno);  
798 - CHPageOffsetEntry& ce = this->c_page_offset_data.entries.at(pageno); 797 + HPageOffsetEntry& he = this->m->page_offset_hints.entries.at(pageno);
  798 + CHPageOffsetEntry& ce = this->m->c_page_offset_data.entries.at(pageno);
799 int h_nobjects = he.delta_nobjects + 799 int h_nobjects = he.delta_nobjects +
800 - this->page_offset_hints.min_nobjects; 800 + this->m->page_offset_hints.min_nobjects;
801 if (h_nobjects != ce.nobjects) 801 if (h_nobjects != ce.nobjects)
802 { 802 {
803 // This happens with pdlin when there are thumbnails. 803 // This happens with pdlin when there are thumbnails.
@@ -812,7 +812,7 @@ QPDF::checkHPageOffset(std::list&lt;std::string&gt;&amp; errors, @@ -812,7 +812,7 @@ QPDF::checkHPageOffset(std::list&lt;std::string&gt;&amp; errors,
812 // computed value if there is a discrepancy. 812 // computed value if there is a discrepancy.
813 int length = lengthNextN(first_object, h_nobjects, errors); 813 int length = lengthNextN(first_object, h_nobjects, errors);
814 int h_length = he.delta_page_length + 814 int h_length = he.delta_page_length +
815 - this->page_offset_hints.min_page_length; 815 + this->m->page_offset_hints.min_page_length;
816 if (length != h_length) 816 if (length != h_length)
817 { 817 {
818 // This condition almost certainly indicates a bad hint 818 // This condition almost certainly indicates a bad hint
@@ -853,12 +853,12 @@ QPDF::checkHPageOffset(std::list&lt;std::string&gt;&amp; errors, @@ -853,12 +853,12 @@ QPDF::checkHPageOffset(std::list&lt;std::string&gt;&amp; errors,
853 for (int i = 0; i < ce.nshared_objects; ++i) 853 for (int i = 0; i < ce.nshared_objects; ++i)
854 { 854 {
855 int idx = ce.shared_identifiers.at(i); 855 int idx = ce.shared_identifiers.at(i);
856 - if (idx >= this->c_shared_object_data.nshared_total) 856 + if (idx >= this->m->c_shared_object_data.nshared_total)
857 { 857 {
858 throw std::logic_error( 858 throw std::logic_error(
859 "index out of bounds for shared object hint table"); 859 "index out of bounds for shared object hint table");
860 } 860 }
861 - int obj = this->c_shared_object_data.entries.at(idx).object; 861 + int obj = this->m->c_shared_object_data.entries.at(idx).object;
862 computed_shared.insert(obj); 862 computed_shared.insert(obj);
863 } 863 }
864 864
@@ -916,7 +916,7 @@ QPDF::checkHSharedObject(std::list&lt;std::string&gt;&amp; errors, @@ -916,7 +916,7 @@ QPDF::checkHSharedObject(std::list&lt;std::string&gt;&amp; errors,
916 // these whenever there are no shared objects not referenced by 916 // these whenever there are no shared objects not referenced by
917 // the first page (i.e., nshared_total == nshared_first_page). 917 // the first page (i.e., nshared_total == nshared_first_page).
918 918
919 - HSharedObject& so = this->shared_object_hints; 919 + HSharedObject& so = this->m->shared_object_hints;
920 if (so.nshared_total < so.nshared_first_page) 920 if (so.nshared_total < so.nshared_first_page)
921 { 921 {
922 errors.push_back("shared object hint table: ntotal < nfirst_page"); 922 errors.push_back("shared object hint table: ntotal < nfirst_page");
@@ -932,7 +932,7 @@ QPDF::checkHSharedObject(std::list&lt;std::string&gt;&amp; errors, @@ -932,7 +932,7 @@ QPDF::checkHSharedObject(std::list&lt;std::string&gt;&amp; errors,
932 if (i == so.nshared_first_page) 932 if (i == so.nshared_first_page)
933 { 933 {
934 QTC::TC("qpdf", "QPDF lin check shared past first page"); 934 QTC::TC("qpdf", "QPDF lin check shared past first page");
935 - if (this->part8.empty()) 935 + if (this->m->part8.empty())
936 { 936 {
937 errors.push_back( 937 errors.push_back(
938 "part 8 is empty but nshared_total > " 938 "part 8 is empty but nshared_total > "
@@ -940,7 +940,7 @@ QPDF::checkHSharedObject(std::list&lt;std::string&gt;&amp; errors, @@ -940,7 +940,7 @@ QPDF::checkHSharedObject(std::list&lt;std::string&gt;&amp; errors,
940 } 940 }
941 else 941 else
942 { 942 {
943 - int obj = this->part8.at(0).getObjectID(); 943 + int obj = this->m->part8.at(0).getObjectID();
944 if (obj != so.first_shared_obj) 944 if (obj != so.first_shared_obj)
945 { 945 {
946 errors.push_back( 946 errors.push_back(
@@ -955,7 +955,7 @@ QPDF::checkHSharedObject(std::list&lt;std::string&gt;&amp; errors, @@ -955,7 +955,7 @@ QPDF::checkHSharedObject(std::list&lt;std::string&gt;&amp; errors,
955 cur_object = so.first_shared_obj; 955 cur_object = so.first_shared_obj;
956 956
957 QPDFObjGen og(cur_object, 0); 957 QPDFObjGen og(cur_object, 0);
958 - assert(this->xref_table.count(og) > 0); 958 + assert(this->m->xref_table.count(og) > 0);
959 int offset = getLinearizationOffset(og); 959 int offset = getLinearizationOffset(og);
960 int h_offset = adjusted_offset(so.first_shared_offset); 960 int h_offset = adjusted_offset(so.first_shared_offset);
961 if (offset != h_offset) 961 if (offset != h_offset)
@@ -996,15 +996,15 @@ QPDF::checkHOutlines(std::list&lt;std::string&gt;&amp; warnings) @@ -996,15 +996,15 @@ QPDF::checkHOutlines(std::list&lt;std::string&gt;&amp; warnings)
996 // wrong starting place). pdlin appears to generate correct 996 // wrong starting place). pdlin appears to generate correct
997 // values in those cases. 997 // values in those cases.
998 998
999 - if (this->c_outline_data.nobjects == this->outline_hints.nobjects) 999 + if (this->m->c_outline_data.nobjects == this->m->outline_hints.nobjects)
1000 { 1000 {
1001 - if (this->c_outline_data.nobjects == 0) 1001 + if (this->m->c_outline_data.nobjects == 0)
1002 { 1002 {
1003 return; 1003 return;
1004 } 1004 }
1005 1005
1006 - if (this->c_outline_data.first_object ==  
1007 - this->outline_hints.first_object) 1006 + if (this->m->c_outline_data.first_object ==
  1007 + this->m->outline_hints.first_object)
1008 { 1008 {
1009 // Check length and offset. Acrobat gets these wrong. 1009 // Check length and offset. Acrobat gets these wrong.
1010 QPDFObjectHandle outlines = getRoot().getKey("/Outlines"); 1010 QPDFObjectHandle outlines = getRoot().getKey("/Outlines");
@@ -1018,12 +1018,12 @@ QPDF::checkHOutlines(std::list&lt;std::string&gt;&amp; warnings) @@ -1018,12 +1018,12 @@ QPDF::checkHOutlines(std::list&lt;std::string&gt;&amp; warnings)
1018 return; 1018 return;
1019 } 1019 }
1020 QPDFObjGen og(outlines.getObjGen()); 1020 QPDFObjGen og(outlines.getObjGen());
1021 - assert(this->xref_table.count(og) > 0); 1021 + assert(this->m->xref_table.count(og) > 0);
1022 int offset = getLinearizationOffset(og); 1022 int offset = getLinearizationOffset(og);
1023 ObjUser ou(ObjUser::ou_root_key, "/Outlines"); 1023 ObjUser ou(ObjUser::ou_root_key, "/Outlines");
1024 int length = maxEnd(ou) - offset; 1024 int length = maxEnd(ou) - offset;
1025 int table_offset = 1025 int table_offset =
1026 - adjusted_offset(this->outline_hints.first_object_offset); 1026 + adjusted_offset(this->m->outline_hints.first_object_offset);
1027 if (offset != table_offset) 1027 if (offset != table_offset)
1028 { 1028 {
1029 warnings.push_back( 1029 warnings.push_back(
@@ -1031,7 +1031,7 @@ QPDF::checkHOutlines(std::list&lt;std::string&gt;&amp; warnings) @@ -1031,7 +1031,7 @@ QPDF::checkHOutlines(std::list&lt;std::string&gt;&amp; warnings)
1031 QUtil::int_to_string(table_offset) + 1031 QUtil::int_to_string(table_offset) +
1032 "; computed = " + QUtil::int_to_string(offset)); 1032 "; computed = " + QUtil::int_to_string(offset));
1033 } 1033 }
1034 - int table_length = this->outline_hints.group_length; 1034 + int table_length = this->m->outline_hints.group_length;
1035 if (length != table_length) 1035 if (length != table_length)
1036 { 1036 {
1037 warnings.push_back( 1037 warnings.push_back(
@@ -1063,41 +1063,42 @@ QPDF::showLinearizationData() @@ -1063,41 +1063,42 @@ QPDF::showLinearizationData()
1063 } 1063 }
1064 catch (QPDFExc& e) 1064 catch (QPDFExc& e)
1065 { 1065 {
1066 - *out_stream << e.what() << std::endl; 1066 + *this->m->out_stream << e.what() << std::endl;
1067 } 1067 }
1068 } 1068 }
1069 1069
1070 void 1070 void
1071 QPDF::dumpLinearizationDataInternal() 1071 QPDF::dumpLinearizationDataInternal()
1072 { 1072 {
1073 - *out_stream << this->file->getName() << ": linearization data:" << std::endl  
1074 - << std::endl;  
1075 -  
1076 - *out_stream  
1077 - << "file_size: " << this->linp.file_size << std::endl  
1078 - << "first_page_object: " << this->linp.first_page_object << std::endl  
1079 - << "first_page_end: " << this->linp.first_page_end << std::endl  
1080 - << "npages: " << this->linp.npages << std::endl  
1081 - << "xref_zero_offset: " << this->linp.xref_zero_offset << std::endl  
1082 - << "first_page: " << this->linp.first_page << std::endl  
1083 - << "H_offset: " << this->linp.H_offset << std::endl  
1084 - << "H_length: " << this->linp.H_length << std::endl 1073 + *this->m->out_stream
  1074 + << this->m->file->getName() << ": linearization data:" << std::endl
  1075 + << std::endl;
  1076 +
  1077 + *this->m->out_stream
  1078 + << "file_size: " << this->m->linp.file_size << std::endl
  1079 + << "first_page_object: " << this->m->linp.first_page_object << std::endl
  1080 + << "first_page_end: " << this->m->linp.first_page_end << std::endl
  1081 + << "npages: " << this->m->linp.npages << std::endl
  1082 + << "xref_zero_offset: " << this->m->linp.xref_zero_offset << std::endl
  1083 + << "first_page: " << this->m->linp.first_page << std::endl
  1084 + << "H_offset: " << this->m->linp.H_offset << std::endl
  1085 + << "H_length: " << this->m->linp.H_length << std::endl
1085 << std::endl; 1086 << std::endl;
1086 1087
1087 - *out_stream << "Page Offsets Hint Table" << std::endl  
1088 - << std::endl; 1088 + *this->m->out_stream << "Page Offsets Hint Table" << std::endl
  1089 + << std::endl;
1089 dumpHPageOffset(); 1090 dumpHPageOffset();
1090 - *out_stream << std::endl  
1091 - << "Shared Objects Hint Table" << std::endl  
1092 - << std::endl; 1091 + *this->m->out_stream << std::endl
  1092 + << "Shared Objects Hint Table" << std::endl
  1093 + << std::endl;
1093 dumpHSharedObject(); 1094 dumpHSharedObject();
1094 1095
1095 - if (this->outline_hints.nobjects > 0) 1096 + if (this->m->outline_hints.nobjects > 0)
1096 { 1097 {
1097 - *out_stream << std::endl  
1098 - << "Outlines Hint Table" << std::endl  
1099 - << std::endl;  
1100 - dumpHGeneric(this->outline_hints); 1098 + *this->m->out_stream << std::endl
  1099 + << "Outlines Hint Table" << std::endl
  1100 + << std::endl;
  1101 + dumpHGeneric(this->m->outline_hints);
1101 } 1102 }
1102 } 1103 }
1103 1104
@@ -1107,9 +1108,9 @@ QPDF::adjusted_offset(int offset) @@ -1107,9 +1108,9 @@ QPDF::adjusted_offset(int offset)
1107 // All offsets >= H_offset have to be increased by H_length 1108 // All offsets >= H_offset have to be increased by H_length
1108 // since all hint table location values disregard the hint table 1109 // since all hint table location values disregard the hint table
1109 // itself. 1110 // itself.
1110 - if (offset >= this->linp.H_offset) 1111 + if (offset >= this->m->linp.H_offset)
1111 { 1112 {
1112 - return offset + this->linp.H_length; 1113 + return offset + this->m->linp.H_length;
1113 } 1114 }
1114 return offset; 1115 return offset;
1115 } 1116 }
@@ -1118,8 +1119,8 @@ QPDF::adjusted_offset(int offset) @@ -1118,8 +1119,8 @@ QPDF::adjusted_offset(int offset)
1118 void 1119 void
1119 QPDF::dumpHPageOffset() 1120 QPDF::dumpHPageOffset()
1120 { 1121 {
1121 - HPageOffset& t = this->page_offset_hints;  
1122 - *out_stream 1122 + HPageOffset& t = this->m->page_offset_hints;
  1123 + *this->m->out_stream
1123 << "min_nobjects: " << t.min_nobjects 1124 << "min_nobjects: " << t.min_nobjects
1124 << std::endl 1125 << std::endl
1125 << "first_page_offset: " << adjusted_offset(t.first_page_offset) 1126 << "first_page_offset: " << adjusted_offset(t.first_page_offset)
@@ -1147,10 +1148,10 @@ QPDF::dumpHPageOffset() @@ -1147,10 +1148,10 @@ QPDF::dumpHPageOffset()
1147 << "shared_denominator: " << t.shared_denominator 1148 << "shared_denominator: " << t.shared_denominator
1148 << std::endl; 1149 << std::endl;
1149 1150
1150 - for (int i1 = 0; i1 < this->linp.npages; ++i1) 1151 + for (int i1 = 0; i1 < this->m->linp.npages; ++i1)
1151 { 1152 {
1152 HPageOffsetEntry& pe = t.entries.at(i1); 1153 HPageOffsetEntry& pe = t.entries.at(i1);
1153 - *out_stream 1154 + *this->m->out_stream
1154 << "Page " << i1 << ":" << std::endl 1155 << "Page " << i1 << ":" << std::endl
1155 << " nobjects: " << pe.delta_nobjects + t.min_nobjects 1156 << " nobjects: " << pe.delta_nobjects + t.min_nobjects
1156 << std::endl 1157 << std::endl
@@ -1164,10 +1165,10 @@ QPDF::dumpHPageOffset() @@ -1164,10 +1165,10 @@ QPDF::dumpHPageOffset()
1164 << " nshared_objects: " << pe.nshared_objects << std::endl; 1165 << " nshared_objects: " << pe.nshared_objects << std::endl;
1165 for (int i2 = 0; i2 < pe.nshared_objects; ++i2) 1166 for (int i2 = 0; i2 < pe.nshared_objects; ++i2)
1166 { 1167 {
1167 - *out_stream << " identifier " << i2 << ": "  
1168 - << pe.shared_identifiers.at(i2) << std::endl;  
1169 - *out_stream << " numerator " << i2 << ": "  
1170 - << pe.shared_numerators.at(i2) << std::endl; 1168 + *this->m->out_stream << " identifier " << i2 << ": "
  1169 + << pe.shared_identifiers.at(i2) << std::endl;
  1170 + *this->m->out_stream << " numerator " << i2 << ": "
  1171 + << pe.shared_numerators.at(i2) << std::endl;
1171 } 1172 }
1172 } 1173 }
1173 } 1174 }
@@ -1175,8 +1176,8 @@ QPDF::dumpHPageOffset() @@ -1175,8 +1176,8 @@ QPDF::dumpHPageOffset()
1175 void 1176 void
1176 QPDF::dumpHSharedObject() 1177 QPDF::dumpHSharedObject()
1177 { 1178 {
1178 - HSharedObject& t = this->shared_object_hints;  
1179 - *out_stream 1179 + HSharedObject& t = this->m->shared_object_hints;
  1180 + *this->m->out_stream
1180 << "first_shared_obj: " << t.first_shared_obj 1181 << "first_shared_obj: " << t.first_shared_obj
1181 << std::endl 1182 << std::endl
1182 << "first_shared_offset: " << adjusted_offset(t.first_shared_offset) 1183 << "first_shared_offset: " << adjusted_offset(t.first_shared_offset)
@@ -1195,19 +1196,20 @@ QPDF::dumpHSharedObject() @@ -1195,19 +1196,20 @@ QPDF::dumpHSharedObject()
1195 for (int i = 0; i < t.nshared_total; ++i) 1196 for (int i = 0; i < t.nshared_total; ++i)
1196 { 1197 {
1197 HSharedObjectEntry& se = t.entries.at(i); 1198 HSharedObjectEntry& se = t.entries.at(i);
1198 - *out_stream << "Shared Object " << i << ":" << std::endl;  
1199 - *out_stream << " group length: "  
1200 - << se.delta_group_length + t.min_group_length << std::endl; 1199 + *this->m->out_stream
  1200 + << "Shared Object " << i << ":" << std::endl
  1201 + << " group length: "
  1202 + << se.delta_group_length + t.min_group_length << std::endl;
1201 // PDF spec says signature present nobjects_minus_one are 1203 // PDF spec says signature present nobjects_minus_one are
1202 // always 0, so print them only if they have a non-zero value. 1204 // always 0, so print them only if they have a non-zero value.
1203 if (se.signature_present) 1205 if (se.signature_present)
1204 { 1206 {
1205 - *out_stream << " signature present" << std::endl; 1207 + *this->m->out_stream << " signature present" << std::endl;
1206 } 1208 }
1207 if (se.nobjects_minus_one != 0) 1209 if (se.nobjects_minus_one != 0)
1208 { 1210 {
1209 - *out_stream << " nobjects: "  
1210 - << se.nobjects_minus_one + 1 << std::endl; 1211 + *this->m->out_stream << " nobjects: "
  1212 + << se.nobjects_minus_one + 1 << std::endl;
1211 } 1213 }
1212 } 1214 }
1213 } 1215 }
@@ -1215,7 +1217,7 @@ QPDF::dumpHSharedObject() @@ -1215,7 +1217,7 @@ QPDF::dumpHSharedObject()
1215 void 1217 void
1216 QPDF::dumpHGeneric(HGeneric& t) 1218 QPDF::dumpHGeneric(HGeneric& t)
1217 { 1219 {
1218 - *out_stream 1220 + *this->m->out_stream
1219 << "first_object: " << t.first_object 1221 << "first_object: " << t.first_object
1220 << std::endl 1222 << std::endl
1221 << "first_object_offset: " << adjusted_offset(t.first_object_offset) 1223 << "first_object_offset: " << adjusted_offset(t.first_object_offset)
@@ -1242,7 +1244,7 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1242,7 +1244,7 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1242 // this function. Note that actual offsets and lengths are not 1244 // this function. Note that actual offsets and lengths are not
1243 // computed here, but anything related to object ordering is. 1245 // computed here, but anything related to object ordering is.
1244 1246
1245 - if (this->object_to_obj_users.empty()) 1247 + if (this->m->object_to_obj_users.empty())
1246 { 1248 {
1247 // Note that we can't call optimize here because we don't know 1249 // Note that we can't call optimize here because we don't know
1248 // whether it should be called with or without allow changes. 1250 // whether it should be called with or without allow changes.
@@ -1298,15 +1300,15 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1298,15 +1300,15 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1298 1300
1299 // * outlines: part 6 or 9 1301 // * outlines: part 6 or 9
1300 1302
1301 - this->part4.clear();  
1302 - this->part6.clear();  
1303 - this->part7.clear();  
1304 - this->part8.clear();  
1305 - this->part9.clear();  
1306 - this->c_linp = LinParameters();  
1307 - this->c_page_offset_data = CHPageOffset();  
1308 - this->c_shared_object_data = CHSharedObject();  
1309 - this->c_outline_data = HGeneric(); 1303 + this->m->part4.clear();
  1304 + this->m->part6.clear();
  1305 + this->m->part7.clear();
  1306 + this->m->part8.clear();
  1307 + this->m->part9.clear();
  1308 + this->m->c_linp = LinParameters();
  1309 + this->m->c_page_offset_data = CHPageOffset();
  1310 + this->m->c_shared_object_data = CHSharedObject();
  1311 + this->m->c_outline_data = HGeneric();
1310 1312
1311 QPDFObjectHandle root = getRoot(); 1313 QPDFObjectHandle root = getRoot();
1312 bool outlines_in_first_page = false; 1314 bool outlines_in_first_page = false;
@@ -1349,8 +1351,8 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1349,8 +1351,8 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1349 std::set<QPDFObjGen> lc_root; 1351 std::set<QPDFObjGen> lc_root;
1350 1352
1351 for (std::map<QPDFObjGen, std::set<ObjUser> >::iterator oiter = 1353 for (std::map<QPDFObjGen, std::set<ObjUser> >::iterator oiter =
1352 - this->object_to_obj_users.begin();  
1353 - oiter != this->object_to_obj_users.end(); ++oiter) 1354 + this->m->object_to_obj_users.begin();
  1355 + oiter != this->m->object_to_obj_users.end(); ++oiter)
1354 { 1356 {
1355 QPDFObjGen const& og = (*oiter).first; 1357 QPDFObjGen const& og = (*oiter).first;
1356 1358
@@ -1505,17 +1507,18 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1505,17 +1507,18 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1505 // npages is the size of the existing pages vector, which has been 1507 // npages is the size of the existing pages vector, which has been
1506 // created by traversing the pages tree, and as such is a 1508 // created by traversing the pages tree, and as such is a
1507 // reasonable size. 1509 // reasonable size.
1508 - this->c_linp.npages = npages;  
1509 - this->c_page_offset_data.entries = std::vector<CHPageOffsetEntry>(npages); 1510 + this->m->c_linp.npages = npages;
  1511 + this->m->c_page_offset_data.entries =
  1512 + std::vector<CHPageOffsetEntry>(npages);
1510 1513
1511 // Part 4: open document objects. We don't care about the order. 1514 // Part 4: open document objects. We don't care about the order.
1512 1515
1513 assert(lc_root.size() == 1); 1516 assert(lc_root.size() == 1);
1514 - this->part4.push_back(objGenToIndirect(*(lc_root.begin()))); 1517 + this->m->part4.push_back(objGenToIndirect(*(lc_root.begin())));
1515 for (std::set<QPDFObjGen>::iterator iter = lc_open_document.begin(); 1518 for (std::set<QPDFObjGen>::iterator iter = lc_open_document.begin();
1516 iter != lc_open_document.end(); ++iter) 1519 iter != lc_open_document.end(); ++iter)
1517 { 1520 {
1518 - this->part4.push_back(objGenToIndirect(*iter)); 1521 + this->m->part4.push_back(objGenToIndirect(*iter));
1519 } 1522 }
1520 1523
1521 // Part 6: first page objects. Note: implementation note 124 1524 // Part 6: first page objects. Note: implementation note 124
@@ -1533,8 +1536,8 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1533,8 +1536,8 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1533 "object not in lc_first_page_private"); 1536 "object not in lc_first_page_private");
1534 } 1537 }
1535 lc_first_page_private.erase(first_page_og); 1538 lc_first_page_private.erase(first_page_og);
1536 - this->c_linp.first_page_object = pages.at(0).getObjectID();  
1537 - this->part6.push_back(pages.at(0)); 1539 + this->m->c_linp.first_page_object = pages.at(0).getObjectID();
  1540 + this->m->part6.push_back(pages.at(0));
1538 1541
1539 // The PDF spec "recommends" an order for the rest of the objects, 1542 // The PDF spec "recommends" an order for the rest of the objects,
1540 // but we are going to disregard it except to the extent that it 1543 // but we are going to disregard it except to the extent that it
@@ -1544,19 +1547,19 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1544,19 +1547,19 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1544 for (std::set<QPDFObjGen>::iterator iter = lc_first_page_private.begin(); 1547 for (std::set<QPDFObjGen>::iterator iter = lc_first_page_private.begin();
1545 iter != lc_first_page_private.end(); ++iter) 1548 iter != lc_first_page_private.end(); ++iter)
1546 { 1549 {
1547 - this->part6.push_back(objGenToIndirect(*iter)); 1550 + this->m->part6.push_back(objGenToIndirect(*iter));
1548 } 1551 }
1549 1552
1550 for (std::set<QPDFObjGen>::iterator iter = lc_first_page_shared.begin(); 1553 for (std::set<QPDFObjGen>::iterator iter = lc_first_page_shared.begin();
1551 iter != lc_first_page_shared.end(); ++iter) 1554 iter != lc_first_page_shared.end(); ++iter)
1552 { 1555 {
1553 - this->part6.push_back(objGenToIndirect(*iter)); 1556 + this->m->part6.push_back(objGenToIndirect(*iter));
1554 } 1557 }
1555 1558
1556 // Place the outline dictionary if it goes in the first page section. 1559 // Place the outline dictionary if it goes in the first page section.
1557 if (outlines_in_first_page) 1560 if (outlines_in_first_page)
1558 { 1561 {
1559 - pushOutlinesToPart(this->part6, lc_outlines, object_stream_data); 1562 + pushOutlinesToPart(this->m->part6, lc_outlines, object_stream_data);
1560 } 1563 }
1561 1564
1562 // Fill in page offset hint table information for the first page. 1565 // Fill in page offset hint table information for the first page.
@@ -1565,7 +1568,7 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1565,7 +1568,7 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1565 // in garbage values for all the shared object identifiers on the 1568 // in garbage values for all the shared object identifiers on the
1566 // first page. 1569 // first page.
1567 1570
1568 - this->c_page_offset_data.entries.at(0).nobjects = this->part6.size(); 1571 + this->m->c_page_offset_data.entries.at(0).nobjects = this->m->part6.size();
1569 1572
1570 // Part 7: other pages' private objects 1573 // Part 7: other pages' private objects
1571 1574
@@ -1583,16 +1586,16 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1583,16 +1586,16 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1583 QUtil::int_to_string(i) + " not in lc_other_page_private"); 1586 QUtil::int_to_string(i) + " not in lc_other_page_private");
1584 } 1587 }
1585 lc_other_page_private.erase(page_og); 1588 lc_other_page_private.erase(page_og);
1586 - this->part7.push_back(pages.at(i)); 1589 + this->m->part7.push_back(pages.at(i));
1587 1590
1588 // Place all non-shared objects referenced by this page, 1591 // Place all non-shared objects referenced by this page,
1589 // updating the page object count for the hint table. 1592 // updating the page object count for the hint table.
1590 1593
1591 - this->c_page_offset_data.entries.at(i).nobjects = 1; 1594 + this->m->c_page_offset_data.entries.at(i).nobjects = 1;
1592 1595
1593 ObjUser ou(ObjUser::ou_page, i); 1596 ObjUser ou(ObjUser::ou_page, i);
1594 - assert(this->obj_user_to_objects.count(ou) > 0);  
1595 - std::set<QPDFObjGen> ogs = this->obj_user_to_objects[ou]; 1597 + assert(this->m->obj_user_to_objects.count(ou) > 0);
  1598 + std::set<QPDFObjGen> ogs = this->m->obj_user_to_objects[ou];
1596 for (std::set<QPDFObjGen>::iterator iter = ogs.begin(); 1599 for (std::set<QPDFObjGen>::iterator iter = ogs.begin();
1597 iter != ogs.end(); ++iter) 1600 iter != ogs.end(); ++iter)
1598 { 1601 {
@@ -1600,8 +1603,8 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1600,8 +1603,8 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1600 if (lc_other_page_private.count(og)) 1603 if (lc_other_page_private.count(og))
1601 { 1604 {
1602 lc_other_page_private.erase(og); 1605 lc_other_page_private.erase(og);
1603 - this->part7.push_back(objGenToIndirect(og));  
1604 - ++this->c_page_offset_data.entries.at(i).nobjects; 1606 + this->m->part7.push_back(objGenToIndirect(og));
  1607 + ++this->m->c_page_offset_data.entries.at(i).nobjects;
1605 } 1608 }
1606 } 1609 }
1607 } 1610 }
@@ -1620,7 +1623,7 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1620,7 +1623,7 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1620 for (std::set<QPDFObjGen>::iterator iter = lc_other_page_shared.begin(); 1623 for (std::set<QPDFObjGen>::iterator iter = lc_other_page_shared.begin();
1621 iter != lc_other_page_shared.end(); ++iter) 1624 iter != lc_other_page_shared.end(); ++iter)
1622 { 1625 {
1623 - this->part8.push_back(objGenToIndirect(*iter)); 1626 + this->m->part8.push_back(objGenToIndirect(*iter));
1624 } 1627 }
1625 1628
1626 // Part 9: other objects 1629 // Part 9: other objects
@@ -1634,7 +1637,7 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1634,7 +1637,7 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1634 1637
1635 // Place the pages tree. 1638 // Place the pages tree.
1636 std::set<QPDFObjGen> pages_ogs = 1639 std::set<QPDFObjGen> pages_ogs =
1637 - this->obj_user_to_objects[ObjUser(ObjUser::ou_root_key, "/Pages")]; 1640 + this->m->obj_user_to_objects[ObjUser(ObjUser::ou_root_key, "/Pages")];
1638 assert(! pages_ogs.empty()); 1641 assert(! pages_ogs.empty());
1639 for (std::set<QPDFObjGen>::iterator iter = pages_ogs.begin(); 1642 for (std::set<QPDFObjGen>::iterator iter = pages_ogs.begin();
1640 iter != pages_ogs.end(); ++iter) 1643 iter != pages_ogs.end(); ++iter)
@@ -1643,7 +1646,7 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1643,7 +1646,7 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1643 if (lc_other.count(og)) 1646 if (lc_other.count(og))
1644 { 1647 {
1645 lc_other.erase(og); 1648 lc_other.erase(og);
1646 - this->part9.push_back(objGenToIndirect(og)); 1649 + this->m->part9.push_back(objGenToIndirect(og));
1647 } 1650 }
1648 } 1651 }
1649 1652
@@ -1661,7 +1664,7 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1661,7 +1664,7 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1661 if (lc_thumbnail_private.count(thumb_og)) 1664 if (lc_thumbnail_private.count(thumb_og))
1662 { 1665 {
1663 lc_thumbnail_private.erase(thumb_og); 1666 lc_thumbnail_private.erase(thumb_og);
1664 - this->part9.push_back(thumb); 1667 + this->m->part9.push_back(thumb);
1665 } 1668 }
1666 else 1669 else
1667 { 1670 {
@@ -1673,7 +1676,7 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1673,7 +1676,7 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1673 // lc_thumbnail_private. 1676 // lc_thumbnail_private.
1674 } 1677 }
1675 std::set<QPDFObjGen>& ogs = 1678 std::set<QPDFObjGen>& ogs =
1676 - this->obj_user_to_objects[ObjUser(ObjUser::ou_thumb, i)]; 1679 + this->m->obj_user_to_objects[ObjUser(ObjUser::ou_thumb, i)];
1677 for (std::set<QPDFObjGen>::iterator iter = ogs.begin(); 1680 for (std::set<QPDFObjGen>::iterator iter = ogs.begin();
1678 iter != ogs.end(); ++iter) 1681 iter != ogs.end(); ++iter)
1679 { 1682 {
@@ -1681,7 +1684,7 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1681,7 +1684,7 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1681 if (lc_thumbnail_private.count(og)) 1684 if (lc_thumbnail_private.count(og))
1682 { 1685 {
1683 lc_thumbnail_private.erase(og); 1686 lc_thumbnail_private.erase(og);
1684 - this->part9.push_back(objGenToIndirect(og)); 1687 + this->m->part9.push_back(objGenToIndirect(og));
1685 } 1688 }
1686 } 1689 }
1687 } 1690 }
@@ -1698,28 +1701,28 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1698,28 +1701,28 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1698 for (std::set<QPDFObjGen>::iterator iter = lc_thumbnail_shared.begin(); 1701 for (std::set<QPDFObjGen>::iterator iter = lc_thumbnail_shared.begin();
1699 iter != lc_thumbnail_shared.end(); ++iter) 1702 iter != lc_thumbnail_shared.end(); ++iter)
1700 { 1703 {
1701 - this->part9.push_back(objGenToIndirect(*iter)); 1704 + this->m->part9.push_back(objGenToIndirect(*iter));
1702 } 1705 }
1703 1706
1704 // Place outlines unless in first page 1707 // Place outlines unless in first page
1705 if (! outlines_in_first_page) 1708 if (! outlines_in_first_page)
1706 { 1709 {
1707 - pushOutlinesToPart(this->part9, lc_outlines, object_stream_data); 1710 + pushOutlinesToPart(this->m->part9, lc_outlines, object_stream_data);
1708 } 1711 }
1709 1712
1710 // Place all remaining objects 1713 // Place all remaining objects
1711 for (std::set<QPDFObjGen>::iterator iter = lc_other.begin(); 1714 for (std::set<QPDFObjGen>::iterator iter = lc_other.begin();
1712 iter != lc_other.end(); ++iter) 1715 iter != lc_other.end(); ++iter)
1713 { 1716 {
1714 - this->part9.push_back(objGenToIndirect(*iter)); 1717 + this->m->part9.push_back(objGenToIndirect(*iter));
1715 } 1718 }
1716 1719
1717 // Make sure we got everything exactly once. 1720 // Make sure we got everything exactly once.
1718 1721
1719 unsigned int num_placed = 1722 unsigned int num_placed =
1720 - this->part4.size() + this->part6.size() + this->part7.size() +  
1721 - this->part8.size() + this->part9.size();  
1722 - unsigned int num_wanted = this->object_to_obj_users.size(); 1723 + this->m->part4.size() + this->m->part6.size() + this->m->part7.size() +
  1724 + this->m->part8.size() + this->m->part9.size();
  1725 + unsigned int num_wanted = this->m->object_to_obj_users.size();
1723 if (num_placed != num_wanted) 1726 if (num_placed != num_wanted)
1724 { 1727 {
1725 throw std::logic_error( 1728 throw std::logic_error(
@@ -1743,28 +1746,29 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1743,28 +1746,29 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1743 // can map from object number only without regards to generation. 1746 // can map from object number only without regards to generation.
1744 std::map<int, int> obj_to_index; 1747 std::map<int, int> obj_to_index;
1745 1748
1746 - this->c_shared_object_data.nshared_first_page = this->part6.size();  
1747 - this->c_shared_object_data.nshared_total =  
1748 - this->c_shared_object_data.nshared_first_page + this->part8.size(); 1749 + this->m->c_shared_object_data.nshared_first_page = this->m->part6.size();
  1750 + this->m->c_shared_object_data.nshared_total =
  1751 + this->m->c_shared_object_data.nshared_first_page +
  1752 + this->m->part8.size();
1749 1753
1750 std::vector<CHSharedObjectEntry>& shared = 1754 std::vector<CHSharedObjectEntry>& shared =
1751 - this->c_shared_object_data.entries;  
1752 - for (std::vector<QPDFObjectHandle>::iterator iter = this->part6.begin();  
1753 - iter != this->part6.end(); ++iter) 1755 + this->m->c_shared_object_data.entries;
  1756 + for (std::vector<QPDFObjectHandle>::iterator iter = this->m->part6.begin();
  1757 + iter != this->m->part6.end(); ++iter)
1754 { 1758 {
1755 QPDFObjectHandle& oh = *iter; 1759 QPDFObjectHandle& oh = *iter;
1756 int obj = oh.getObjectID(); 1760 int obj = oh.getObjectID();
1757 obj_to_index[obj] = shared.size(); 1761 obj_to_index[obj] = shared.size();
1758 shared.push_back(CHSharedObjectEntry(obj)); 1762 shared.push_back(CHSharedObjectEntry(obj));
1759 } 1763 }
1760 - QTC::TC("qpdf", "QPDF lin part 8 empty", this->part8.empty() ? 1 : 0);  
1761 - if (! this->part8.empty()) 1764 + QTC::TC("qpdf", "QPDF lin part 8 empty", this->m->part8.empty() ? 1 : 0);
  1765 + if (! this->m->part8.empty())
1762 { 1766 {
1763 - this->c_shared_object_data.first_shared_obj =  
1764 - this->part8.at(0).getObjectID(); 1767 + this->m->c_shared_object_data.first_shared_obj =
  1768 + this->m->part8.at(0).getObjectID();
1765 for (std::vector<QPDFObjectHandle>::iterator iter = 1769 for (std::vector<QPDFObjectHandle>::iterator iter =
1766 - this->part8.begin();  
1767 - iter != this->part8.end(); ++iter) 1770 + this->m->part8.begin();
  1771 + iter != this->m->part8.end(); ++iter)
1768 { 1772 {
1769 QPDFObjectHandle& oh = *iter; 1773 QPDFObjectHandle& oh = *iter;
1770 int obj = oh.getObjectID(); 1774 int obj = oh.getObjectID();
@@ -1772,8 +1776,8 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1772,8 +1776,8 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1772 shared.push_back(CHSharedObjectEntry(obj)); 1776 shared.push_back(CHSharedObjectEntry(obj));
1773 } 1777 }
1774 } 1778 }
1775 - if (static_cast<size_t>(this->c_shared_object_data.nshared_total) !=  
1776 - this->c_shared_object_data.entries.size()) 1779 + if (static_cast<size_t>(this->m->c_shared_object_data.nshared_total) !=
  1780 + this->m->c_shared_object_data.entries.size())
1777 { 1781 {
1778 throw std::logic_error( 1782 throw std::logic_error(
1779 "shared object hint table has wrong number of entries"); 1783 "shared object hint table has wrong number of entries");
@@ -1784,15 +1788,15 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -1784,15 +1788,15 @@ QPDF::calculateLinearizationData(std::map&lt;int, int&gt; const&amp; object_stream_data)
1784 1788
1785 for (unsigned int i = 1; i < npages; ++i) 1789 for (unsigned int i = 1; i < npages; ++i)
1786 { 1790 {
1787 - CHPageOffsetEntry& pe = this->c_page_offset_data.entries.at(i); 1791 + CHPageOffsetEntry& pe = this->m->c_page_offset_data.entries.at(i);
1788 ObjUser ou(ObjUser::ou_page, i); 1792 ObjUser ou(ObjUser::ou_page, i);
1789 - assert(this->obj_user_to_objects.count(ou) > 0);  
1790 - std::set<QPDFObjGen> const& ogs = this->obj_user_to_objects[ou]; 1793 + assert(this->m->obj_user_to_objects.count(ou) > 0);
  1794 + std::set<QPDFObjGen> const& ogs = this->m->obj_user_to_objects[ou];
1791 for (std::set<QPDFObjGen>::const_iterator iter = ogs.begin(); 1795 for (std::set<QPDFObjGen>::const_iterator iter = ogs.begin();
1792 iter != ogs.end(); ++iter) 1796 iter != ogs.end(); ++iter)
1793 { 1797 {
1794 QPDFObjGen const& og = *iter; 1798 QPDFObjGen const& og = *iter;
1795 - if ((this->object_to_obj_users[og].size() > 1) && 1799 + if ((this->m->object_to_obj_users[og].size() > 1) &&
1796 (obj_to_index.count(og.getObj()) > 0)) 1800 (obj_to_index.count(og.getObj()) > 0))
1797 { 1801 {
1798 int idx = obj_to_index[og.getObj()]; 1802 int idx = obj_to_index[og.getObj()];
@@ -1818,18 +1822,18 @@ QPDF::pushOutlinesToPart( @@ -1818,18 +1822,18 @@ QPDF::pushOutlinesToPart(
1818 outlines = getUncompressedObject(outlines, object_stream_data); 1822 outlines = getUncompressedObject(outlines, object_stream_data);
1819 QPDFObjGen outlines_og(outlines.getObjGen()); 1823 QPDFObjGen outlines_og(outlines.getObjGen());
1820 QTC::TC("qpdf", "QPDF lin outlines in part", 1824 QTC::TC("qpdf", "QPDF lin outlines in part",
1821 - ((&part == (&this->part6)) ? 0  
1822 - : (&part == (&this->part9)) ? 1 1825 + ((&part == (&this->m->part6)) ? 0
  1826 + : (&part == (&this->m->part9)) ? 1
1823 : 9999)); // can't happen 1827 : 9999)); // can't happen
1824 - this->c_outline_data.first_object = outlines_og.getObj();  
1825 - this->c_outline_data.nobjects = 1; 1828 + this->m->c_outline_data.first_object = outlines_og.getObj();
  1829 + this->m->c_outline_data.nobjects = 1;
1826 lc_outlines.erase(outlines_og); 1830 lc_outlines.erase(outlines_og);
1827 part.push_back(outlines); 1831 part.push_back(outlines);
1828 for (std::set<QPDFObjGen>::iterator iter = lc_outlines.begin(); 1832 for (std::set<QPDFObjGen>::iterator iter = lc_outlines.begin();
1829 iter != lc_outlines.end(); ++iter) 1833 iter != lc_outlines.end(); ++iter)
1830 { 1834 {
1831 part.push_back(objGenToIndirect(*iter)); 1835 part.push_back(objGenToIndirect(*iter));
1832 - ++this->c_outline_data.nobjects; 1836 + ++this->m->c_outline_data.nobjects;
1833 } 1837 }
1834 } 1838 }
1835 1839
@@ -1843,11 +1847,11 @@ QPDF::getLinearizedParts( @@ -1843,11 +1847,11 @@ QPDF::getLinearizedParts(
1843 std::vector<QPDFObjectHandle>& part9) 1847 std::vector<QPDFObjectHandle>& part9)
1844 { 1848 {
1845 calculateLinearizationData(object_stream_data); 1849 calculateLinearizationData(object_stream_data);
1846 - part4 = this->part4;  
1847 - part6 = this->part6;  
1848 - part7 = this->part7;  
1849 - part8 = this->part8;  
1850 - part9 = this->part9; 1850 + part4 = this->m->part4;
  1851 + part6 = this->m->part6;
  1852 + part7 = this->m->part7;
  1853 + part8 = this->m->part8;
  1854 + part9 = this->m->part9;
1851 } 1855 }
1852 1856
1853 static inline int nbits(int val) 1857 static inline int nbits(int val)
@@ -1889,7 +1893,7 @@ QPDF::calculateHPageOffset( @@ -1889,7 +1893,7 @@ QPDF::calculateHPageOffset(
1889 1893
1890 std::vector<QPDFObjectHandle> const& pages = getAllPages(); 1894 std::vector<QPDFObjectHandle> const& pages = getAllPages();
1891 unsigned int npages = pages.size(); 1895 unsigned int npages = pages.size();
1892 - CHPageOffset& cph = this->c_page_offset_data; 1896 + CHPageOffset& cph = this->m->c_page_offset_data;
1893 std::vector<CHPageOffsetEntry>& cphe = cph.entries; 1897 std::vector<CHPageOffsetEntry>& cphe = cph.entries;
1894 1898
1895 // Calculate minimum and maximum values for number of objects per 1899 // Calculate minimum and maximum values for number of objects per
@@ -1902,7 +1906,7 @@ QPDF::calculateHPageOffset( @@ -1902,7 +1906,7 @@ QPDF::calculateHPageOffset(
1902 int max_length = min_length; 1906 int max_length = min_length;
1903 int max_shared = cphe.at(0).nshared_objects; 1907 int max_shared = cphe.at(0).nshared_objects;
1904 1908
1905 - HPageOffset& ph = this->page_offset_hints; 1909 + HPageOffset& ph = this->m->page_offset_hints;
1906 std::vector<HPageOffsetEntry>& phe = ph.entries; 1910 std::vector<HPageOffsetEntry>& phe = ph.entries;
1907 // npages is the size of the existing pages array. 1911 // npages is the size of the existing pages array.
1908 phe = std::vector<HPageOffsetEntry>(npages); 1912 phe = std::vector<HPageOffsetEntry>(npages);
@@ -1940,7 +1944,7 @@ QPDF::calculateHPageOffset( @@ -1940,7 +1944,7 @@ QPDF::calculateHPageOffset(
1940 ph.nbits_delta_page_length = nbits(max_length - min_length); 1944 ph.nbits_delta_page_length = nbits(max_length - min_length);
1941 ph.nbits_nshared_objects = nbits(max_shared); 1945 ph.nbits_nshared_objects = nbits(max_shared);
1942 ph.nbits_shared_identifier = 1946 ph.nbits_shared_identifier =
1943 - nbits(this->c_shared_object_data.nshared_total); 1947 + nbits(this->m->c_shared_object_data.nshared_total);
1944 ph.shared_denominator = 4; // doesn't matter 1948 ph.shared_denominator = 4; // doesn't matter
1945 1949
1946 // It isn't clear how to compute content offset and content 1950 // It isn't clear how to compute content offset and content
@@ -1975,9 +1979,9 @@ QPDF::calculateHSharedObject( @@ -1975,9 +1979,9 @@ QPDF::calculateHSharedObject(
1975 std::map<int, qpdf_offset_t> const& lengths, 1979 std::map<int, qpdf_offset_t> const& lengths,
1976 std::map<int, int> const& obj_renumber) 1980 std::map<int, int> const& obj_renumber)
1977 { 1981 {
1978 - CHSharedObject& cso = this->c_shared_object_data; 1982 + CHSharedObject& cso = this->m->c_shared_object_data;
1979 std::vector<CHSharedObjectEntry>& csoe = cso.entries; 1983 std::vector<CHSharedObjectEntry>& csoe = cso.entries;
1980 - HSharedObject& so = this->shared_object_hints; 1984 + HSharedObject& so = this->m->shared_object_hints;
1981 std::vector<HSharedObjectEntry>& soe = so.entries; 1985 std::vector<HSharedObjectEntry>& soe = so.entries;
1982 soe.clear(); 1986 soe.clear();
1983 1987
@@ -2026,14 +2030,14 @@ QPDF::calculateHOutline( @@ -2026,14 +2030,14 @@ QPDF::calculateHOutline(
2026 std::map<int, qpdf_offset_t> const& lengths, 2030 std::map<int, qpdf_offset_t> const& lengths,
2027 std::map<int, int> const& obj_renumber) 2031 std::map<int, int> const& obj_renumber)
2028 { 2032 {
2029 - HGeneric& cho = this->c_outline_data; 2033 + HGeneric& cho = this->m->c_outline_data;
2030 2034
2031 if (cho.nobjects == 0) 2035 if (cho.nobjects == 0)
2032 { 2036 {
2033 return; 2037 return;
2034 } 2038 }
2035 2039
2036 - HGeneric& ho = this->outline_hints; 2040 + HGeneric& ho = this->m->outline_hints;
2037 2041
2038 ho.first_object = 2042 ho.first_object =
2039 (*(obj_renumber.find(cho.first_object))).second; 2043 (*(obj_renumber.find(cho.first_object))).second;
@@ -2083,7 +2087,7 @@ write_vector_vector(BitWriter&amp; w, @@ -2083,7 +2087,7 @@ write_vector_vector(BitWriter&amp; w,
2083 void 2087 void
2084 QPDF::writeHPageOffset(BitWriter& w) 2088 QPDF::writeHPageOffset(BitWriter& w)
2085 { 2089 {
2086 - HPageOffset& t = this->page_offset_hints; 2090 + HPageOffset& t = this->m->page_offset_hints;
2087 2091
2088 w.writeBits(t.min_nobjects, 32); // 1 2092 w.writeBits(t.min_nobjects, 32); // 1
2089 w.writeBits(t.first_page_offset, 32); // 2 2093 w.writeBits(t.first_page_offset, 32); // 2
@@ -2130,7 +2134,7 @@ QPDF::writeHPageOffset(BitWriter&amp; w) @@ -2130,7 +2134,7 @@ QPDF::writeHPageOffset(BitWriter&amp; w)
2130 void 2134 void
2131 QPDF::writeHSharedObject(BitWriter& w) 2135 QPDF::writeHSharedObject(BitWriter& w)
2132 { 2136 {
2133 - HSharedObject& t = this->shared_object_hints; 2137 + HSharedObject& t = this->m->shared_object_hints;
2134 2138
2135 w.writeBits(t.first_shared_obj, 32); // 1 2139 w.writeBits(t.first_shared_obj, 32); // 1
2136 w.writeBits(t.first_shared_offset, 32); // 2 2140 w.writeBits(t.first_shared_offset, 32); // 2
@@ -2193,10 +2197,10 @@ QPDF::generateHintStream(std::map&lt;int, QPDFXRefEntry&gt; const&amp; xref, @@ -2193,10 +2197,10 @@ QPDF::generateHintStream(std::map&lt;int, QPDFXRefEntry&gt; const&amp; xref,
2193 S = c.getCount(); 2197 S = c.getCount();
2194 writeHSharedObject(w); 2198 writeHSharedObject(w);
2195 O = 0; 2199 O = 0;
2196 - if (this->outline_hints.nobjects > 0) 2200 + if (this->m->outline_hints.nobjects > 0)
2197 { 2201 {
2198 O = c.getCount(); 2202 O = c.getCount();
2199 - writeHGeneric(w, this->outline_hints); 2203 + writeHGeneric(w, this->m->outline_hints);
2200 } 2204 }
2201 c.finish(); 2205 c.finish();
2202 2206
libqpdf/QPDF_optimization.cc
@@ -62,7 +62,7 @@ void @@ -62,7 +62,7 @@ void
62 QPDF::optimize(std::map<int, int> const& object_stream_data, 62 QPDF::optimize(std::map<int, int> const& object_stream_data,
63 bool allow_changes) 63 bool allow_changes)
64 { 64 {
65 - if (! this->obj_user_to_objects.empty()) 65 + if (! this->m->obj_user_to_objects.empty())
66 { 66 {
67 // already optimized 67 // already optimized
68 return; 68 return;
@@ -83,19 +83,19 @@ QPDF::optimize(std::map&lt;int, int&gt; const&amp; object_stream_data, @@ -83,19 +83,19 @@ QPDF::optimize(std::map&lt;int, int&gt; const&amp; object_stream_data,
83 } 83 }
84 84
85 // Traverse pages tree pushing all inherited resources down to the 85 // Traverse pages tree pushing all inherited resources down to the
86 - // page level. This also initializes this->all_pages. 86 + // page level. This also initializes this->m->all_pages.
87 pushInheritedAttributesToPage(allow_changes, false); 87 pushInheritedAttributesToPage(allow_changes, false);
88 88
89 // Traverse pages 89 // Traverse pages
90 - int n = this->all_pages.size(); 90 + int n = this->m->all_pages.size();
91 for (int pageno = 0; pageno < n; ++pageno) 91 for (int pageno = 0; pageno < n; ++pageno)
92 { 92 {
93 updateObjectMaps(ObjUser(ObjUser::ou_page, pageno), 93 updateObjectMaps(ObjUser(ObjUser::ou_page, pageno),
94 - this->all_pages.at(pageno)); 94 + this->m->all_pages.at(pageno));
95 } 95 }
96 96
97 // Traverse document-level items 97 // Traverse document-level items
98 - std::set<std::string> keys = this->trailer.getKeys(); 98 + std::set<std::string> keys = this->m->trailer.getKeys();
99 for (std::set<std::string>::iterator iter = keys.begin(); 99 for (std::set<std::string>::iterator iter = keys.begin();
100 iter != keys.end(); ++iter) 100 iter != keys.end(); ++iter)
101 { 101 {
@@ -107,7 +107,7 @@ QPDF::optimize(std::map&lt;int, int&gt; const&amp; object_stream_data, @@ -107,7 +107,7 @@ QPDF::optimize(std::map&lt;int, int&gt; const&amp; object_stream_data,
107 else 107 else
108 { 108 {
109 updateObjectMaps(ObjUser(ObjUser::ou_trailer_key, key), 109 updateObjectMaps(ObjUser(ObjUser::ou_trailer_key, key),
110 - this->trailer.getKey(key)); 110 + this->m->trailer.getKey(key));
111 } 111 }
112 } 112 }
113 113
@@ -129,8 +129,8 @@ QPDF::optimize(std::map&lt;int, int&gt; const&amp; object_stream_data, @@ -129,8 +129,8 @@ QPDF::optimize(std::map&lt;int, int&gt; const&amp; object_stream_data,
129 129
130 ObjUser root_ou = ObjUser(ObjUser::ou_root); 130 ObjUser root_ou = ObjUser(ObjUser::ou_root);
131 QPDFObjGen root_og = QPDFObjGen(root.getObjGen()); 131 QPDFObjGen root_og = QPDFObjGen(root.getObjGen());
132 - obj_user_to_objects[root_ou].insert(root_og);  
133 - object_to_obj_users[root_og].insert(root_ou); 132 + this->m->obj_user_to_objects[root_ou].insert(root_og);
  133 + this->m->object_to_obj_users[root_og].insert(root_ou);
134 134
135 filterCompressedObjects(object_stream_data); 135 filterCompressedObjects(object_stream_data);
136 } 136 }
@@ -151,7 +151,7 @@ QPDF::pushInheritedAttributesToPage(bool allow_changes, bool warn_skipped_keys) @@ -151,7 +151,7 @@ QPDF::pushInheritedAttributesToPage(bool allow_changes, bool warn_skipped_keys)
151 // The record of whether we've done this is cleared by 151 // The record of whether we've done this is cleared by
152 // updateAllPagesCache(). If we're warning for skipped keys, 152 // updateAllPagesCache(). If we're warning for skipped keys,
153 // re-traverse unconditionally. 153 // re-traverse unconditionally.
154 - if (this->pushed_inherited_attributes_to_pages && (! warn_skipped_keys)) 154 + if (this->m->pushed_inherited_attributes_to_pages && (! warn_skipped_keys))
155 { 155 {
156 return; 156 return;
157 } 157 }
@@ -159,12 +159,12 @@ QPDF::pushInheritedAttributesToPage(bool allow_changes, bool warn_skipped_keys) @@ -159,12 +159,12 @@ QPDF::pushInheritedAttributesToPage(bool allow_changes, bool warn_skipped_keys)
159 // key_ancestors is a mapping of page attribute keys to a stack of 159 // key_ancestors is a mapping of page attribute keys to a stack of
160 // Pages nodes that contain values for them. 160 // Pages nodes that contain values for them.
161 std::map<std::string, std::vector<QPDFObjectHandle> > key_ancestors; 161 std::map<std::string, std::vector<QPDFObjectHandle> > key_ancestors;
162 - this->all_pages.clear(); 162 + this->m->all_pages.clear();
163 pushInheritedAttributesToPageInternal( 163 pushInheritedAttributesToPageInternal(
164 - this->trailer.getKey("/Root").getKey("/Pages"),  
165 - key_ancestors, this->all_pages, allow_changes, warn_skipped_keys); 164 + this->m->trailer.getKey("/Root").getKey("/Pages"),
  165 + key_ancestors, this->m->all_pages, allow_changes, warn_skipped_keys);
166 assert(key_ancestors.empty()); 166 assert(key_ancestors.empty());
167 - this->pushed_inherited_attributes_to_pages = true; 167 + this->m->pushed_inherited_attributes_to_pages = true;
168 } 168 }
169 169
170 void 170 void
@@ -192,8 +192,8 @@ QPDF::pushInheritedAttributesToPageInternal2( @@ -192,8 +192,8 @@ QPDF::pushInheritedAttributesToPageInternal2(
192 if (visited.count(this_og) > 0) 192 if (visited.count(this_og) > 0)
193 { 193 {
194 throw QPDFExc( 194 throw QPDFExc(
195 - qpdf_e_pages, this->file->getName(),  
196 - this->last_object_description, 0, 195 + qpdf_e_pages, this->m->file->getName(),
  196 + this->m->last_object_description, 0,
197 "Loop detected in /Pages structure (inherited attributes)"); 197 "Loop detected in /Pages structure (inherited attributes)");
198 } 198 }
199 visited.insert(this_og); 199 visited.insert(this_og);
@@ -219,9 +219,9 @@ QPDF::pushInheritedAttributesToPageInternal2( @@ -219,9 +219,9 @@ QPDF::pushInheritedAttributesToPageInternal2(
219 { 219 {
220 if (! allow_changes) 220 if (! allow_changes)
221 { 221 {
222 - throw QPDFExc(qpdf_e_internal, this->file->getName(),  
223 - this->last_object_description,  
224 - this->file->getLastOffset(), 222 + throw QPDFExc(qpdf_e_internal, this->m->file->getName(),
  223 + this->m->last_object_description,
  224 + this->m->file->getLastOffset(),
225 "optimize detected an " 225 "optimize detected an "
226 "inheritable attribute when called " 226 "inheritable attribute when called "
227 "in no-change mode"); 227 "in no-change mode");
@@ -269,8 +269,8 @@ QPDF::pushInheritedAttributesToPageInternal2( @@ -269,8 +269,8 @@ QPDF::pushInheritedAttributesToPageInternal2(
269 setLastObjectDescription("Pages object", 269 setLastObjectDescription("Pages object",
270 cur_pages.getObjectID(), 270 cur_pages.getObjectID(),
271 cur_pages.getGeneration()); 271 cur_pages.getGeneration());
272 - warn(QPDFExc(qpdf_e_pages, this->file->getName(),  
273 - this->last_object_description, 0, 272 + warn(QPDFExc(qpdf_e_pages, this->m->file->getName(),
  273 + this->m->last_object_description, 0,
274 "Unknown key " + key + " in /Pages object" 274 "Unknown key " + key + " in /Pages object"
275 " is being discarded as a result of" 275 " is being discarded as a result of"
276 " flattening the /Pages tree")); 276 " flattening the /Pages tree"));
@@ -337,9 +337,9 @@ QPDF::pushInheritedAttributesToPageInternal2( @@ -337,9 +337,9 @@ QPDF::pushInheritedAttributesToPageInternal2(
337 } 337 }
338 else 338 else
339 { 339 {
340 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
341 - this->last_object_description,  
342 - this->file->getLastOffset(), 340 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  341 + this->m->last_object_description,
  342 + this->m->file->getLastOffset(),
343 "invalid Type " + type + " in page tree"); 343 "invalid Type " + type + " in page tree");
344 } 344 }
345 visited.erase(this_og); 345 visited.erase(this_og);
@@ -382,8 +382,8 @@ QPDF::updateObjectMapsInternal(ObjUser const&amp; ou, QPDFObjectHandle oh, @@ -382,8 +382,8 @@ QPDF::updateObjectMapsInternal(ObjUser const&amp; ou, QPDFObjectHandle oh,
382 QTC::TC("qpdf", "QPDF opt loop detected"); 382 QTC::TC("qpdf", "QPDF opt loop detected");
383 return; 383 return;
384 } 384 }
385 - this->obj_user_to_objects[ou].insert(og);  
386 - this->object_to_obj_users[og].insert(ou); 385 + this->m->obj_user_to_objects[ou].insert(og);
  386 + this->m->object_to_obj_users[og].insert(ou);
387 visited.insert(og); 387 visited.insert(og);
388 } 388 }
389 389
@@ -445,8 +445,8 @@ QPDF::filterCompressedObjects(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -445,8 +445,8 @@ QPDF::filterCompressedObjects(std::map&lt;int, int&gt; const&amp; object_stream_data)
445 std::map<QPDFObjGen, std::set<ObjUser> > t_object_to_obj_users; 445 std::map<QPDFObjGen, std::set<ObjUser> > t_object_to_obj_users;
446 446
447 for (std::map<ObjUser, std::set<QPDFObjGen> >::iterator i1 = 447 for (std::map<ObjUser, std::set<QPDFObjGen> >::iterator i1 =
448 - this->obj_user_to_objects.begin();  
449 - i1 != this->obj_user_to_objects.end(); ++i1) 448 + this->m->obj_user_to_objects.begin();
  449 + i1 != this->m->obj_user_to_objects.end(); ++i1)
450 { 450 {
451 ObjUser const& ou = (*i1).first; 451 ObjUser const& ou = (*i1).first;
452 std::set<QPDFObjGen> const& objects = (*i1).second; 452 std::set<QPDFObjGen> const& objects = (*i1).second;
@@ -468,8 +468,8 @@ QPDF::filterCompressedObjects(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -468,8 +468,8 @@ QPDF::filterCompressedObjects(std::map&lt;int, int&gt; const&amp; object_stream_data)
468 } 468 }
469 469
470 for (std::map<QPDFObjGen, std::set<ObjUser> >::iterator i1 = 470 for (std::map<QPDFObjGen, std::set<ObjUser> >::iterator i1 =
471 - this->object_to_obj_users.begin();  
472 - i1 != this->object_to_obj_users.end(); ++i1) 471 + this->m->object_to_obj_users.begin();
  472 + i1 != this->m->object_to_obj_users.end(); ++i1)
473 { 473 {
474 QPDFObjGen const& og = (*i1).first; 474 QPDFObjGen const& og = (*i1).first;
475 std::set<ObjUser> const& objusers = (*i1).second; 475 std::set<ObjUser> const& objusers = (*i1).second;
@@ -490,6 +490,6 @@ QPDF::filterCompressedObjects(std::map&lt;int, int&gt; const&amp; object_stream_data) @@ -490,6 +490,6 @@ QPDF::filterCompressedObjects(std::map&lt;int, int&gt; const&amp; object_stream_data)
490 } 490 }
491 } 491 }
492 492
493 - this->obj_user_to_objects = t_obj_user_to_objects;  
494 - this->object_to_obj_users = t_object_to_obj_users; 493 + this->m->obj_user_to_objects = t_obj_user_to_objects;
  494 + this->m->object_to_obj_users = t_object_to_obj_users;
495 } 495 }
libqpdf/QPDF_pages.cc
@@ -44,12 +44,12 @@ std::vector&lt;QPDFObjectHandle&gt; const&amp; @@ -44,12 +44,12 @@ std::vector&lt;QPDFObjectHandle&gt; const&amp;
44 QPDF::getAllPages() 44 QPDF::getAllPages()
45 { 45 {
46 // Note that pushInheritedAttributesToPage may also be used to 46 // Note that pushInheritedAttributesToPage may also be used to
47 - // initialize this->all_pages.  
48 - if (this->all_pages.empty()) 47 + // initialize this->m->all_pages.
  48 + if (this->m->all_pages.empty())
49 { 49 {
50 - getAllPagesInternal(getRoot().getKey("/Pages"), this->all_pages); 50 + getAllPagesInternal(getRoot().getKey("/Pages"), this->m->all_pages);
51 } 51 }
52 - return this->all_pages; 52 + return this->m->all_pages;
53 } 53 }
54 54
55 void 55 void
@@ -69,8 +69,8 @@ QPDF::getAllPagesInternal2(QPDFObjectHandle cur_pages, @@ -69,8 +69,8 @@ QPDF::getAllPagesInternal2(QPDFObjectHandle cur_pages,
69 if (visited.count(this_og) > 0) 69 if (visited.count(this_og) > 0)
70 { 70 {
71 throw QPDFExc( 71 throw QPDFExc(
72 - qpdf_e_pages, this->file->getName(),  
73 - this->last_object_description, 0, 72 + qpdf_e_pages, this->m->file->getName(),
  73 + this->m->last_object_description, 0,
74 "Loop detected in /Pages structure (getAllPages)"); 74 "Loop detected in /Pages structure (getAllPages)");
75 } 75 }
76 visited.insert(this_og); 76 visited.insert(this_og);
@@ -103,9 +103,9 @@ QPDF::getAllPagesInternal2(QPDFObjectHandle cur_pages, @@ -103,9 +103,9 @@ QPDF::getAllPagesInternal2(QPDFObjectHandle cur_pages,
103 } 103 }
104 else 104 else
105 { 105 {
106 - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),  
107 - this->last_object_description,  
108 - this->file->getLastOffset(), 106 + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
  107 + this->m->last_object_description,
  108 + this->m->file->getLastOffset(),
109 "invalid Type " + type + " in page tree"); 109 "invalid Type " + type + " in page tree");
110 } 110 }
111 visited.erase(this_og); 111 visited.erase(this_og);
@@ -119,9 +119,9 @@ QPDF::updateAllPagesCache() @@ -119,9 +119,9 @@ QPDF::updateAllPagesCache()
119 // it that they got from calls to getAllPages(). We can defer 119 // it that they got from calls to getAllPages(). We can defer
120 // recalculation of pageobj_to_pages_pos until needed. 120 // recalculation of pageobj_to_pages_pos until needed.
121 QTC::TC("qpdf", "QPDF updateAllPagesCache"); 121 QTC::TC("qpdf", "QPDF updateAllPagesCache");
122 - this->all_pages.clear();  
123 - this->pageobj_to_pages_pos.clear();  
124 - this->pushed_inherited_attributes_to_pages = false; 122 + this->m->all_pages.clear();
  123 + this->m->pageobj_to_pages_pos.clear();
  124 + this->m->pushed_inherited_attributes_to_pages = false;
125 getAllPages(); 125 getAllPages();
126 } 126 }
127 127
@@ -131,26 +131,26 @@ QPDF::flattenPagesTree() @@ -131,26 +131,26 @@ QPDF::flattenPagesTree()
131 // If not already done, flatten the /Pages structure and 131 // If not already done, flatten the /Pages structure and
132 // initialize pageobj_to_pages_pos. 132 // initialize pageobj_to_pages_pos.
133 133
134 - if (! this->pageobj_to_pages_pos.empty()) 134 + if (! this->m->pageobj_to_pages_pos.empty())
135 { 135 {
136 return; 136 return;
137 } 137 }
138 138
139 // Push inherited objects down to the /Page level. As a side 139 // Push inherited objects down to the /Page level. As a side
140 - // effect this->all_pages will also be generated. 140 + // effect this->m->all_pages will also be generated.
141 pushInheritedAttributesToPage(true, true); 141 pushInheritedAttributesToPage(true, true);
142 142
143 QPDFObjectHandle pages = getRoot().getKey("/Pages"); 143 QPDFObjectHandle pages = getRoot().getKey("/Pages");
144 144
145 - int const len = this->all_pages.size(); 145 + int const len = this->m->all_pages.size();
146 for (int pos = 0; pos < len; ++pos) 146 for (int pos = 0; pos < len; ++pos)
147 { 147 {
148 // populate pageobj_to_pages_pos and fix parent pointer 148 // populate pageobj_to_pages_pos and fix parent pointer
149 - insertPageobjToPage(this->all_pages.at(pos), pos, true);  
150 - this->all_pages.at(pos).replaceKey("/Parent", pages); 149 + insertPageobjToPage(this->m->all_pages.at(pos), pos, true);
  150 + this->m->all_pages.at(pos).replaceKey("/Parent", pages);
151 } 151 }
152 152
153 - pages.replaceKey("/Kids", QPDFObjectHandle::newArray(this->all_pages)); 153 + pages.replaceKey("/Kids", QPDFObjectHandle::newArray(this->m->all_pages));
154 // /Count has not changed 154 // /Count has not changed
155 if (pages.getKey("/Count").getIntValue() != len) 155 if (pages.getKey("/Count").getIntValue() != len)
156 { 156 {
@@ -165,21 +165,22 @@ QPDF::insertPageobjToPage(QPDFObjectHandle const&amp; obj, int pos, @@ -165,21 +165,22 @@ QPDF::insertPageobjToPage(QPDFObjectHandle const&amp; obj, int pos,
165 QPDFObjGen og(obj.getObjGen()); 165 QPDFObjGen og(obj.getObjGen());
166 if (check_duplicate) 166 if (check_duplicate)
167 { 167 {
168 - if (! this->pageobj_to_pages_pos.insert(std::make_pair(og, pos)).second) 168 + if (! this->m->pageobj_to_pages_pos.insert(
  169 + std::make_pair(og, pos)).second)
169 { 170 {
170 QTC::TC("qpdf", "QPDF duplicate page reference"); 171 QTC::TC("qpdf", "QPDF duplicate page reference");
171 setLastObjectDescription("page " + QUtil::int_to_string(pos) + 172 setLastObjectDescription("page " + QUtil::int_to_string(pos) +
172 " (numbered from zero)", 173 " (numbered from zero)",
173 og.getObj(), og.getGen()); 174 og.getObj(), og.getGen());
174 - throw QPDFExc(qpdf_e_pages, this->file->getName(),  
175 - this->last_object_description, 0, 175 + throw QPDFExc(qpdf_e_pages, this->m->file->getName(),
  176 + this->m->last_object_description, 0,
176 "duplicate page reference found;" 177 "duplicate page reference found;"
177 " this would cause loss of data"); 178 " this would cause loss of data");
178 } 179 }
179 } 180 }
180 else 181 else
181 { 182 {
182 - this->pageobj_to_pages_pos[og] = pos; 183 + this->m->pageobj_to_pages_pos[og] = pos;
183 } 184 }
184 } 185 }
185 186
@@ -195,13 +196,13 @@ QPDF::insertPage(QPDFObjectHandle newpage, int pos) @@ -195,13 +196,13 @@ QPDF::insertPage(QPDFObjectHandle newpage, int pos)
195 if (! newpage.isIndirect()) 196 if (! newpage.isIndirect())
196 { 197 {
197 QTC::TC("qpdf", "QPDF insert non-indirect page"); 198 QTC::TC("qpdf", "QPDF insert non-indirect page");
198 - newpage = this->makeIndirectObject(newpage); 199 + newpage = makeIndirectObject(newpage);
199 } 200 }
200 else if (newpage.getOwningQPDF() != this) 201 else if (newpage.getOwningQPDF() != this)
201 { 202 {
202 QTC::TC("qpdf", "QPDF insert foreign page"); 203 QTC::TC("qpdf", "QPDF insert foreign page");
203 newpage.getOwningQPDF()->pushInheritedAttributesToPage(); 204 newpage.getOwningQPDF()->pushInheritedAttributesToPage();
204 - newpage = this->copyForeignObject(newpage, true); 205 + newpage = copyForeignObject(newpage, true);
205 } 206 }
206 else 207 else
207 { 208 {
@@ -210,26 +211,26 @@ QPDF::insertPage(QPDFObjectHandle newpage, int pos) @@ -210,26 +211,26 @@ QPDF::insertPage(QPDFObjectHandle newpage, int pos)
210 211
211 QTC::TC("qpdf", "QPDF insert page", 212 QTC::TC("qpdf", "QPDF insert page",
212 (pos == 0) ? 0 : // insert at beginning 213 (pos == 0) ? 0 : // insert at beginning
213 - (pos == static_cast<int>(this->all_pages.size())) ? 1 : // at end 214 + (pos == static_cast<int>(this->m->all_pages.size())) ? 1 : // at end
214 2); // insert in middle 215 2); // insert in middle
215 216
216 QPDFObjectHandle pages = getRoot().getKey("/Pages"); 217 QPDFObjectHandle pages = getRoot().getKey("/Pages");
217 QPDFObjectHandle kids = pages.getKey("/Kids"); 218 QPDFObjectHandle kids = pages.getKey("/Kids");
218 assert ((pos >= 0) && 219 assert ((pos >= 0) &&
219 - (static_cast<size_t>(pos) <= this->all_pages.size())); 220 + (static_cast<size_t>(pos) <= this->m->all_pages.size()));
220 221
221 newpage.replaceKey("/Parent", pages); 222 newpage.replaceKey("/Parent", pages);
222 kids.insertItem(pos, newpage); 223 kids.insertItem(pos, newpage);
223 int npages = kids.getArrayNItems(); 224 int npages = kids.getArrayNItems();
224 pages.replaceKey("/Count", QPDFObjectHandle::newInteger(npages)); 225 pages.replaceKey("/Count", QPDFObjectHandle::newInteger(npages));
225 - this->all_pages.insert(this->all_pages.begin() + pos, newpage);  
226 - assert(this->all_pages.size() == static_cast<size_t>(npages)); 226 + this->m->all_pages.insert(this->m->all_pages.begin() + pos, newpage);
  227 + assert(this->m->all_pages.size() == static_cast<size_t>(npages));
227 for (int i = pos + 1; i < npages; ++i) 228 for (int i = pos + 1; i < npages; ++i)
228 { 229 {
229 - insertPageobjToPage(this->all_pages.at(i), i, false); 230 + insertPageobjToPage(this->m->all_pages.at(i), i, false);
230 } 231 }
231 insertPageobjToPage(newpage, pos, true); 232 insertPageobjToPage(newpage, pos, true);
232 - assert(this->pageobj_to_pages_pos.size() == static_cast<size_t>(npages)); 233 + assert(this->m->pageobj_to_pages_pos.size() == static_cast<size_t>(npages));
233 } 234 }
234 235
235 void 236 void
@@ -238,7 +239,8 @@ QPDF::removePage(QPDFObjectHandle page) @@ -238,7 +239,8 @@ QPDF::removePage(QPDFObjectHandle page)
238 int pos = findPage(page); // also ensures flat /Pages 239 int pos = findPage(page); // also ensures flat /Pages
239 QTC::TC("qpdf", "QPDF remove page", 240 QTC::TC("qpdf", "QPDF remove page",
240 (pos == 0) ? 0 : // remove at beginning 241 (pos == 0) ? 0 : // remove at beginning
241 - (pos == static_cast<int>(this->all_pages.size() - 1)) ? 1 : // end 242 + (pos == static_cast<int>(
  243 + this->m->all_pages.size() - 1)) ? 1 : // end
242 2); // remove in middle 244 2); // remove in middle
243 245
244 QPDFObjectHandle pages = getRoot().getKey("/Pages"); 246 QPDFObjectHandle pages = getRoot().getKey("/Pages");
@@ -247,13 +249,13 @@ QPDF::removePage(QPDFObjectHandle page) @@ -247,13 +249,13 @@ QPDF::removePage(QPDFObjectHandle page)
247 kids.eraseItem(pos); 249 kids.eraseItem(pos);
248 int npages = kids.getArrayNItems(); 250 int npages = kids.getArrayNItems();
249 pages.replaceKey("/Count", QPDFObjectHandle::newInteger(npages)); 251 pages.replaceKey("/Count", QPDFObjectHandle::newInteger(npages));
250 - this->all_pages.erase(this->all_pages.begin() + pos);  
251 - assert(this->all_pages.size() == static_cast<size_t>(npages));  
252 - this->pageobj_to_pages_pos.erase(page.getObjGen());  
253 - assert(this->pageobj_to_pages_pos.size() == static_cast<size_t>(npages)); 252 + this->m->all_pages.erase(this->m->all_pages.begin() + pos);
  253 + assert(this->m->all_pages.size() == static_cast<size_t>(npages));
  254 + this->m->pageobj_to_pages_pos.erase(page.getObjGen());
  255 + assert(this->m->pageobj_to_pages_pos.size() == static_cast<size_t>(npages));
254 for (int i = pos; i < npages; ++i) 256 for (int i = pos; i < npages; ++i)
255 { 257 {
256 - insertPageobjToPage(this->all_pages.at(i), i, false); 258 + insertPageobjToPage(this->m->all_pages.at(i), i, false);
257 } 259 }
258 } 260 }
259 261
@@ -295,12 +297,12 @@ QPDF::findPage(QPDFObjGen const&amp; og) @@ -295,12 +297,12 @@ QPDF::findPage(QPDFObjGen const&amp; og)
295 { 297 {
296 flattenPagesTree(); 298 flattenPagesTree();
297 std::map<QPDFObjGen, int>::iterator it = 299 std::map<QPDFObjGen, int>::iterator it =
298 - this->pageobj_to_pages_pos.find(og);  
299 - if (it == this->pageobj_to_pages_pos.end()) 300 + this->m->pageobj_to_pages_pos.find(og);
  301 + if (it == this->m->pageobj_to_pages_pos.end())
300 { 302 {
301 setLastObjectDescription("page object", og.getObj(), og.getGen()); 303 setLastObjectDescription("page object", og.getObj(), og.getGen());
302 - throw QPDFExc(qpdf_e_pages, this->file->getName(),  
303 - this->last_object_description, 0, 304 + throw QPDFExc(qpdf_e_pages, this->m->file->getName(),
  305 + this->m->last_object_description, 0,
304 "page object not referenced in /Pages tree"); 306 "page object not referenced in /Pages tree");
305 } 307 }
306 return (*it).second; 308 return (*it).second;