Commit ce435222b2ae95645a1a0f79a8b1fca443ed3724

Authored by Jay Berkenbilt
1 parent a8c93bd3

Push QPDFWriter member variables into a nested class

include/qpdf/QPDFWriter.hh
... ... @@ -374,7 +374,6 @@ class QPDFWriter
374 374  
375 375 enum trailer_e { t_normal, t_lin_first, t_lin_second };
376 376  
377   - void init();
378 377 int bytesNeeded(unsigned long long n);
379 378 void writeBinary(unsigned long long val, unsigned int bytes);
380 379 void writeString(std::string const& str);
... ... @@ -483,71 +482,88 @@ class QPDFWriter
483 482 void discardGeneration(std::map<QPDFObjGen, int> const& in,
484 483 std::map<int, int>& out);
485 484  
486   - QPDF& pdf;
487   - char const* filename;
488   - FILE* file;
489   - bool close_file;
490   - Pl_Buffer* buffer_pipeline;
491   - Buffer* output_buffer;
492   - bool normalize_content_set;
493   - bool normalize_content;
494   - bool compress_streams;
495   - bool compress_streams_set;
496   - qpdf_stream_decode_level_e stream_decode_level;
497   - bool stream_decode_level_set;
498   - bool qdf_mode;
499   - bool preserve_unreferenced_objects;
500   - bool newline_before_endstream;
501   - bool static_id;
502   - bool suppress_original_object_ids;
503   - bool direct_stream_lengths;
504   - bool encrypted;
505   - bool preserve_encryption;
506   - bool linearized;
507   - bool pclm;
508   - qpdf_object_stream_e object_stream_mode;
509   - std::string encryption_key;
510   - bool encrypt_metadata;
511   - bool encrypt_use_aes;
512   - std::map<std::string, std::string> encryption_dictionary;
513   - int encryption_V;
514   - int encryption_R;
515   -
516   - std::string id1; // for /ID key of
517   - std::string id2; // trailer dictionary
518   - std::string final_pdf_version;
519   - int final_extension_level;
520   - std::string min_pdf_version;
521   - int min_extension_level;
522   - std::string forced_pdf_version;
523   - int forced_extension_level;
524   - std::string extra_header_text;
525   - int encryption_dict_objid;
526   - std::string cur_data_key;
527   - std::list<PointerHolder<Pipeline> > to_delete;
528   - Pl_Count* pipeline;
529   - std::list<QPDFObjectHandle> object_queue;
530   - std::map<QPDFObjGen, int> obj_renumber;
531   - std::map<int, QPDFXRefEntry> xref;
532   - std::map<int, qpdf_offset_t> lengths;
533   - int next_objid;
534   - int cur_stream_length_id;
535   - size_t cur_stream_length;
536   - bool added_newline;
537   - int max_ostream_index;
538   - std::set<QPDFObjGen> normalized_streams;
539   - std::map<QPDFObjGen, int> page_object_to_seq;
540   - std::map<QPDFObjGen, int> contents_to_page_seq;
541   - std::map<QPDFObjGen, int> object_to_object_stream;
542   - std::map<int, std::set<QPDFObjGen> > object_stream_to_objects;
543   - std::list<Pipeline*> pipeline_stack;
544   - bool deterministic_id;
545   - Pl_MD5* md5_pipeline;
546   - std::string deterministic_id_data;
547   -
548   - // For linearization only
549   - std::map<int, int> obj_renumber_no_gen;
550   - std::map<int, int> object_to_object_stream_no_gen;
  485 + class Members
  486 + {
  487 + friend class QPDFWriter;
  488 +
  489 + public:
  490 + ~Members();
  491 +
  492 + private:
  493 + Members(QPDF& pdf);
  494 + Members(Members const&);
  495 +
  496 + QPDF& pdf;
  497 + char const* filename;
  498 + FILE* file;
  499 + bool close_file;
  500 + Pl_Buffer* buffer_pipeline;
  501 + Buffer* output_buffer;
  502 + bool normalize_content_set;
  503 + bool normalize_content;
  504 + bool compress_streams;
  505 + bool compress_streams_set;
  506 + qpdf_stream_decode_level_e stream_decode_level;
  507 + bool stream_decode_level_set;
  508 + bool qdf_mode;
  509 + bool preserve_unreferenced_objects;
  510 + bool newline_before_endstream;
  511 + bool static_id;
  512 + bool suppress_original_object_ids;
  513 + bool direct_stream_lengths;
  514 + bool encrypted;
  515 + bool preserve_encryption;
  516 + bool linearized;
  517 + bool pclm;
  518 + qpdf_object_stream_e object_stream_mode;
  519 + std::string encryption_key;
  520 + bool encrypt_metadata;
  521 + bool encrypt_use_aes;
  522 + std::map<std::string, std::string> encryption_dictionary;
  523 + int encryption_V;
  524 + int encryption_R;
  525 +
  526 + std::string id1; // for /ID key of
  527 + std::string id2; // trailer dictionary
  528 + std::string final_pdf_version;
  529 + int final_extension_level;
  530 + std::string min_pdf_version;
  531 + int min_extension_level;
  532 + std::string forced_pdf_version;
  533 + int forced_extension_level;
  534 + std::string extra_header_text;
  535 + int encryption_dict_objid;
  536 + std::string cur_data_key;
  537 + std::list<PointerHolder<Pipeline> > to_delete;
  538 + Pl_Count* pipeline;
  539 + std::list<QPDFObjectHandle> object_queue;
  540 + std::map<QPDFObjGen, int> obj_renumber;
  541 + std::map<int, QPDFXRefEntry> xref;
  542 + std::map<int, qpdf_offset_t> lengths;
  543 + int next_objid;
  544 + int cur_stream_length_id;
  545 + size_t cur_stream_length;
  546 + bool added_newline;
  547 + int max_ostream_index;
  548 + std::set<QPDFObjGen> normalized_streams;
  549 + std::map<QPDFObjGen, int> page_object_to_seq;
  550 + std::map<QPDFObjGen, int> contents_to_page_seq;
  551 + std::map<QPDFObjGen, int> object_to_object_stream;
  552 + std::map<int, std::set<QPDFObjGen> > object_stream_to_objects;
  553 + std::list<Pipeline*> pipeline_stack;
  554 + bool deterministic_id;
  555 + Pl_MD5* md5_pipeline;
  556 + std::string deterministic_id_data;
  557 +
  558 + // For linearization only
  559 + std::map<int, int> obj_renumber_no_gen;
  560 + std::map<int, int> object_to_object_stream_no_gen;
  561 + };
  562 +
  563 + // Keep all member variables inside the Members object, which we
  564 + // dynamically allocate. This makes it possible to add new private
  565 + // members without breaking binary compatibility.
  566 + PointerHolder<Members> m;
551 567 };
552 568  
553 569 #endif // __QPDFWRITER_HH__
... ...
libqpdf/QPDFWriter.cc
... ... @@ -23,80 +23,81 @@
23 23 #include <algorithm>
24 24 #include <stdlib.h>
25 25  
  26 +QPDFWriter::Members::Members(QPDF& pdf) :
  27 + pdf(pdf),
  28 + filename(0),
  29 + file(0),
  30 + close_file(false),
  31 + buffer_pipeline(0),
  32 + output_buffer(0),
  33 + normalize_content_set(false),
  34 + normalize_content(false),
  35 + compress_streams(true),
  36 + compress_streams_set(false),
  37 + stream_decode_level(qpdf_dl_none),
  38 + stream_decode_level_set(false),
  39 + qdf_mode(false),
  40 + preserve_unreferenced_objects(false),
  41 + newline_before_endstream(false),
  42 + static_id(false),
  43 + suppress_original_object_ids(false),
  44 + direct_stream_lengths(true),
  45 + encrypted(false),
  46 + preserve_encryption(true),
  47 + linearized(false),
  48 + pclm(false),
  49 + object_stream_mode(qpdf_o_preserve),
  50 + encrypt_metadata(true),
  51 + encrypt_use_aes(false),
  52 + encryption_V(0),
  53 + encryption_R(0),
  54 + final_extension_level(0),
  55 + min_extension_level(0),
  56 + forced_extension_level(0),
  57 + encryption_dict_objid(0),
  58 + pipeline(0),
  59 + next_objid(1),
  60 + cur_stream_length_id(0),
  61 + cur_stream_length(0),
  62 + added_newline(false),
  63 + max_ostream_index(0),
  64 + deterministic_id(false),
  65 + md5_pipeline(0)
  66 +{
  67 +}
  68 +
  69 +QPDFWriter::Members::~Members()
  70 +{
  71 + if (file && close_file)
  72 + {
  73 + fclose(file);
  74 + }
  75 + if (output_buffer)
  76 + {
  77 + delete output_buffer;
  78 + }
  79 +}
  80 +
26 81 QPDFWriter::QPDFWriter(QPDF& pdf) :
27   - pdf(pdf)
  82 + m(new Members(pdf))
28 83 {
29   - init();
30 84 }
31 85  
32 86 QPDFWriter::QPDFWriter(QPDF& pdf, char const* filename) :
33   - pdf(pdf)
  87 + m(new Members(pdf))
34 88 {
35   - init();
36 89 setOutputFilename(filename);
37 90 }
38 91  
39 92 QPDFWriter::QPDFWriter(QPDF& pdf, char const* description,
40 93 FILE *file, bool close_file) :
41   - pdf(pdf)
  94 + m(new Members(pdf))
42 95 {
43   - init();
44 96 setOutputFile(description, file, close_file);
45 97 }
46 98  
47   -void
48   -QPDFWriter::init()
49   -{
50   - filename = 0;
51   - file = 0;
52   - close_file = false;
53   - buffer_pipeline = 0;
54   - output_buffer = 0;
55   - normalize_content_set = false;
56   - normalize_content = false;
57   - compress_streams = true;
58   - compress_streams_set = false;
59   - stream_decode_level = qpdf_dl_none;
60   - stream_decode_level_set = false;
61   - qdf_mode = false;
62   - preserve_unreferenced_objects = false;
63   - newline_before_endstream = false;
64   - static_id = false;
65   - suppress_original_object_ids = false;
66   - direct_stream_lengths = true;
67   - encrypted = false;
68   - preserve_encryption = true;
69   - linearized = false;
70   - pclm = false;
71   - object_stream_mode = qpdf_o_preserve;
72   - encrypt_metadata = true;
73   - encrypt_use_aes = false;
74   - min_extension_level = 0;
75   - final_extension_level = 0;
76   - forced_extension_level = 0;
77   - encryption_V = 0;
78   - encryption_R = 0;
79   - encryption_dict_objid = 0;
80   - pipeline = 0;
81   - next_objid = 1;
82   - cur_stream_length_id = 0;
83   - cur_stream_length = 0;
84   - added_newline = false;
85   - max_ostream_index = 0;
86   - deterministic_id = false;
87   - md5_pipeline = 0;
88   -}
89   -
90 99 QPDFWriter::~QPDFWriter()
91 100 {
92   - if (file && close_file)
93   - {
94   - fclose(file);
95   - }
96   - if (output_buffer)
97   - {
98   - delete output_buffer;
99   - }
100 101 }
101 102  
102 103 void
... ... @@ -104,6 +105,7 @@ QPDFWriter::setOutputFilename(char const* filename)
104 105 {
105 106 char const* description = filename;
106 107 FILE* f = 0;
  108 + bool close_file = false;
107 109 if (filename == 0)
108 110 {
109 111 description = "standard output";
... ... @@ -123,42 +125,42 @@ QPDFWriter::setOutputFilename(char const* filename)
123 125 void
124 126 QPDFWriter::setOutputFile(char const* description, FILE* file, bool close_file)
125 127 {
126   - this->filename = description;
127   - this->file = file;
128   - this->close_file = close_file;
  128 + this->m->filename = description;
  129 + this->m->file = file;
  130 + this->m->close_file = close_file;
129 131 Pipeline* p = new Pl_StdioFile("qpdf output", file);
130   - to_delete.push_back(p);
  132 + this->m->to_delete.push_back(p);
131 133 initializePipelineStack(p);
132 134 }
133 135  
134 136 void
135 137 QPDFWriter::setOutputMemory()
136 138 {
137   - this->filename = "memory buffer";
138   - this->buffer_pipeline = new Pl_Buffer("qpdf output");
139   - to_delete.push_back(this->buffer_pipeline);
140   - initializePipelineStack(this->buffer_pipeline);
  139 + this->m->filename = "memory buffer";
  140 + this->m->buffer_pipeline = new Pl_Buffer("qpdf output");
  141 + this->m->to_delete.push_back(this->m->buffer_pipeline);
  142 + initializePipelineStack(this->m->buffer_pipeline);
141 143 }
142 144  
143 145 Buffer*
144 146 QPDFWriter::getBuffer()
145 147 {
146   - Buffer* result = this->output_buffer;
147   - this->output_buffer = 0;
  148 + Buffer* result = this->m->output_buffer;
  149 + this->m->output_buffer = 0;
148 150 return result;
149 151 }
150 152  
151 153 void
152 154 QPDFWriter::setOutputPipeline(Pipeline* p)
153 155 {
154   - this->filename = "custom pipeline";
  156 + this->m->filename = "custom pipeline";
155 157 initializePipelineStack(p);
156 158 }
157 159  
158 160 void
159 161 QPDFWriter::setObjectStreamMode(qpdf_object_stream_e mode)
160 162 {
161   - this->object_stream_mode = mode;
  163 + this->m->object_stream_mode = mode;
162 164 }
163 165  
164 166 void
... ... @@ -167,64 +169,64 @@ QPDFWriter::setStreamDataMode(qpdf_stream_data_e mode)
167 169 switch (mode)
168 170 {
169 171 case qpdf_s_uncompress:
170   - this->stream_decode_level =
171   - std::max(qpdf_dl_generalized, this->stream_decode_level);
172   - this->compress_streams = false;
  172 + this->m->stream_decode_level =
  173 + std::max(qpdf_dl_generalized, this->m->stream_decode_level);
  174 + this->m->compress_streams = false;
173 175 break;
174 176  
175 177 case qpdf_s_preserve:
176   - this->stream_decode_level = qpdf_dl_none;
177   - this->compress_streams = false;
  178 + this->m->stream_decode_level = qpdf_dl_none;
  179 + this->m->compress_streams = false;
178 180 break;
179 181  
180 182 case qpdf_s_compress:
181   - this->stream_decode_level =
182   - std::max(qpdf_dl_generalized, this->stream_decode_level);
183   - this->compress_streams = true;
  183 + this->m->stream_decode_level =
  184 + std::max(qpdf_dl_generalized, this->m->stream_decode_level);
  185 + this->m->compress_streams = true;
184 186 break;
185 187 }
186   - this->stream_decode_level_set = true;
187   - this->compress_streams_set = true;
  188 + this->m->stream_decode_level_set = true;
  189 + this->m->compress_streams_set = true;
188 190 }
189 191  
190 192  
191 193 void
192 194 QPDFWriter::setCompressStreams(bool val)
193 195 {
194   - this->compress_streams = val;
195   - this->compress_streams_set = true;
  196 + this->m->compress_streams = val;
  197 + this->m->compress_streams_set = true;
196 198 }
197 199  
198 200 void
199 201 QPDFWriter::setDecodeLevel(qpdf_stream_decode_level_e val)
200 202 {
201   - this->stream_decode_level = val;
202   - this->stream_decode_level_set = true;
  203 + this->m->stream_decode_level = val;
  204 + this->m->stream_decode_level_set = true;
203 205 }
204 206  
205 207 void
206 208 QPDFWriter::setContentNormalization(bool val)
207 209 {
208   - this->normalize_content_set = true;
209   - this->normalize_content = val;
  210 + this->m->normalize_content_set = true;
  211 + this->m->normalize_content = val;
210 212 }
211 213  
212 214 void
213 215 QPDFWriter::setQDFMode(bool val)
214 216 {
215   - this->qdf_mode = val;
  217 + this->m->qdf_mode = val;
216 218 }
217 219  
218 220 void
219 221 QPDFWriter::setPreserveUnreferencedObjects(bool val)
220 222 {
221   - this->preserve_unreferenced_objects = val;
  223 + this->m->preserve_unreferenced_objects = val;
222 224 }
223 225  
224 226 void
225 227 QPDFWriter::setNewlineBeforeEndstream(bool val)
226 228 {
227   - this->newline_before_endstream = val;
  229 + this->m->newline_before_endstream = val;
228 230 }
229 231  
230 232 void
... ... @@ -239,7 +241,7 @@ QPDFWriter::setMinimumPDFVersion(std::string const&amp; version,
239 241 {
240 242 bool set_version = false;
241 243 bool set_extension_level = false;
242   - if (this->min_pdf_version.empty())
  244 + if (this->m->min_pdf_version.empty())
243 245 {
244 246 set_version = true;
245 247 set_extension_level = true;
... ... @@ -251,7 +253,7 @@ QPDFWriter::setMinimumPDFVersion(std::string const&amp; version,
251 253 int min_major = 0;
252 254 int min_minor = 0;
253 255 parseVersion(version, old_major, old_minor);
254   - parseVersion(this->min_pdf_version, min_major, min_minor);
  256 + parseVersion(this->m->min_pdf_version, min_major, min_minor);
255 257 int compare = compareVersions(
256 258 old_major, old_minor, min_major, min_minor);
257 259 if (compare > 0)
... ... @@ -263,7 +265,7 @@ QPDFWriter::setMinimumPDFVersion(std::string const&amp; version,
263 265 }
264 266 else if (compare == 0)
265 267 {
266   - if (extension_level > this->min_extension_level)
  268 + if (extension_level > this->m->min_extension_level)
267 269 {
268 270 QTC::TC("qpdf", "QPDFWriter increasing extension level");
269 271 set_extension_level = true;
... ... @@ -273,11 +275,11 @@ QPDFWriter::setMinimumPDFVersion(std::string const&amp; version,
273 275  
274 276 if (set_version)
275 277 {
276   - this->min_pdf_version = version;
  278 + this->m->min_pdf_version = version;
277 279 }
278 280 if (set_extension_level)
279 281 {
280   - this->min_extension_level = extension_level;
  282 + this->m->min_extension_level = extension_level;
281 283 }
282 284 }
283 285  
... ... @@ -291,19 +293,19 @@ void
291 293 QPDFWriter::forcePDFVersion(std::string const& version,
292 294 int extension_level)
293 295 {
294   - this->forced_pdf_version = version;
295   - this->forced_extension_level = extension_level;
  296 + this->m->forced_pdf_version = version;
  297 + this->m->forced_extension_level = extension_level;
296 298 }
297 299  
298 300 void
299 301 QPDFWriter::setExtraHeaderText(std::string const& text)
300 302 {
301   - this->extra_header_text = text;
302   - if ((this->extra_header_text.length() > 0) &&
303   - (*(this->extra_header_text.rbegin()) != '\n'))
  303 + this->m->extra_header_text = text;
  304 + if ((this->m->extra_header_text.length() > 0) &&
  305 + (*(this->m->extra_header_text.rbegin()) != '\n'))
304 306 {
305 307 QTC::TC("qpdf", "QPDFWriter extra header text add newline");
306   - this->extra_header_text += "\n";
  308 + this->m->extra_header_text += "\n";
307 309 }
308 310 else
309 311 {
... ... @@ -314,13 +316,13 @@ QPDFWriter::setExtraHeaderText(std::string const&amp; text)
314 316 void
315 317 QPDFWriter::setStaticID(bool val)
316 318 {
317   - this->static_id = val;
  319 + this->m->static_id = val;
318 320 }
319 321  
320 322 void
321 323 QPDFWriter::setDeterministicID(bool val)
322 324 {
323   - this->deterministic_id = val;
  325 + this->m->deterministic_id = val;
324 326 }
325 327  
326 328 void
... ... @@ -335,32 +337,32 @@ QPDFWriter::setStaticAesIV(bool val)
335 337 void
336 338 QPDFWriter::setSuppressOriginalObjectIDs(bool val)
337 339 {
338   - this->suppress_original_object_ids = val;
  340 + this->m->suppress_original_object_ids = val;
339 341 }
340 342  
341 343 void
342 344 QPDFWriter::setPreserveEncryption(bool val)
343 345 {
344   - this->preserve_encryption = val;
  346 + this->m->preserve_encryption = val;
345 347 }
346 348  
347 349 void
348 350 QPDFWriter::setLinearization(bool val)
349 351 {
350   - this->linearized = val;
  352 + this->m->linearized = val;
351 353 if (val)
352 354 {
353   - this->pclm = false;
  355 + this->m->pclm = false;
354 356 }
355 357 }
356 358  
357 359 void
358 360 QPDFWriter::setPCLm(bool val)
359 361 {
360   - this->pclm = val;
  362 + this->m->pclm = val;
361 363 if (val)
362 364 {
363   - this->linearized = false;
  365 + this->m->linearized = false;
364 366 }
365 367 }
366 368  
... ... @@ -415,8 +417,8 @@ QPDFWriter::setR4EncryptionParameters(
415 417 interpretR3EncryptionParameters(
416 418 clear, user_password, owner_password,
417 419 allow_accessibility, allow_extract, print, modify);
418   - this->encrypt_use_aes = use_aes;
419   - this->encrypt_metadata = encrypt_metadata;
  420 + this->m->encrypt_use_aes = use_aes;
  421 + this->m->encrypt_metadata = encrypt_metadata;
420 422 setEncryptionParameters(user_password, owner_password, 4, 4, 16, clear);
421 423 }
422 424  
... ... @@ -431,8 +433,8 @@ QPDFWriter::setR5EncryptionParameters(
431 433 interpretR3EncryptionParameters(
432 434 clear, user_password, owner_password,
433 435 allow_accessibility, allow_extract, print, modify);
434   - this->encrypt_use_aes = true;
435   - this->encrypt_metadata = encrypt_metadata;
  436 + this->m->encrypt_use_aes = true;
  437 + this->m->encrypt_metadata = encrypt_metadata;
436 438 setEncryptionParameters(user_password, owner_password, 5, 5, 32, clear);
437 439 }
438 440  
... ... @@ -447,8 +449,8 @@ QPDFWriter::setR6EncryptionParameters(
447 449 interpretR3EncryptionParameters(
448 450 clear, user_password, owner_password,
449 451 allow_accessibility, allow_extract, print, modify);
450   - this->encrypt_use_aes = true;
451   - this->encrypt_metadata = encrypt_metadata;
  452 + this->m->encrypt_use_aes = true;
  453 + this->m->encrypt_metadata = encrypt_metadata;
452 454 setEncryptionParameters(user_password, owner_password, 5, 6, 32, clear);
453 455 }
454 456  
... ... @@ -563,29 +565,29 @@ QPDFWriter::setEncryptionParameters(
563 565 {
564 566 QPDF::compute_encryption_O_U(
565 567 user_password, owner_password, V, R, key_len, P,
566   - this->encrypt_metadata, this->id1, O, U);
  568 + this->m->encrypt_metadata, this->m->id1, O, U);
567 569 }
568 570 else
569 571 {
570 572 QPDF::compute_encryption_parameters_V5(
571 573 user_password, owner_password, V, R, key_len, P,
572   - this->encrypt_metadata, this->id1,
  574 + this->m->encrypt_metadata, this->m->id1,
573 575 encryption_key, O, U, OE, UE, Perms);
574 576 }
575 577 setEncryptionParametersInternal(
576 578 V, R, key_len, P, O, U, OE, UE, Perms,
577   - this->id1, user_password, encryption_key);
  579 + this->m->id1, user_password, encryption_key);
578 580 }
579 581  
580 582 void
581 583 QPDFWriter::copyEncryptionParameters(QPDF& qpdf)
582 584 {
583   - this->preserve_encryption = false;
  585 + this->m->preserve_encryption = false;
584 586 QPDFObjectHandle trailer = qpdf.getTrailer();
585 587 if (trailer.hasKey("/Encrypt"))
586 588 {
587 589 generateID();
588   - this->id1 =
  590 + this->m->id1 =
589 591 trailer.getKey("/ID").getArrayItem(0).getStringValue();
590 592 QPDFObjectHandle encrypt = trailer.getKey("/Encrypt");
591 593 int V = encrypt.getKey("/V").getIntValue();
... ... @@ -597,7 +599,7 @@ QPDFWriter::copyEncryptionParameters(QPDF&amp; qpdf)
597 599 if (encrypt.hasKey("/EncryptMetadata") &&
598 600 encrypt.getKey("/EncryptMetadata").isBool())
599 601 {
600   - this->encrypt_metadata =
  602 + this->m->encrypt_metadata =
601 603 encrypt.getKey("/EncryptMetadata").getBoolValue();
602 604 }
603 605 if (V >= 4)
... ... @@ -608,12 +610,12 @@ QPDFWriter::copyEncryptionParameters(QPDF&amp; qpdf)
608 610 // figuring out whether AES is used or not is complicated
609 611 // with /StmF, /StrF, and /EFF all potentially having
610 612 // different values.
611   - this->encrypt_use_aes = true;
  613 + this->m->encrypt_use_aes = true;
612 614 }
613 615 QTC::TC("qpdf", "QPDFWriter copy encrypt metadata",
614   - this->encrypt_metadata ? 0 : 1);
  616 + this->m->encrypt_metadata ? 0 : 1);
615 617 QTC::TC("qpdf", "QPDFWriter copy use_aes",
616   - this->encrypt_use_aes ? 0 : 1);
  618 + this->m->encrypt_use_aes ? 0 : 1);
617 619 std::string OE;
618 620 std::string UE;
619 621 std::string Perms;
... ... @@ -637,7 +639,7 @@ QPDFWriter::copyEncryptionParameters(QPDF&amp; qpdf)
637 639 OE,
638 640 UE,
639 641 Perms,
640   - this->id1, // this->id1 == the other file's id1
  642 + this->m->id1, // this->m->id1 == the other file's id1
641 643 qpdf.getPaddedUserPassword(),
642 644 encryption_key);
643 645 }
... ... @@ -647,7 +649,7 @@ void
647 649 QPDFWriter::disableIncompatibleEncryption(int major, int minor,
648 650 int extension_level)
649 651 {
650   - if (! this->encrypted)
  652 + if (! this->m->encrypted)
651 653 {
652 654 return;
653 655 }
... ... @@ -659,8 +661,8 @@ QPDFWriter::disableIncompatibleEncryption(int major, int minor,
659 661 }
660 662 else
661 663 {
662   - int V = atoi(encryption_dictionary["/V"].c_str());
663   - int R = atoi(encryption_dictionary["/R"].c_str());
  664 + int V = atoi(this->m->encryption_dictionary["/V"].c_str());
  665 + int R = atoi(this->m->encryption_dictionary["/R"].c_str());
664 666 if (compareVersions(major, minor, 1, 4) < 0)
665 667 {
666 668 if ((V > 1) || (R > 2))
... ... @@ -677,7 +679,7 @@ QPDFWriter::disableIncompatibleEncryption(int major, int minor,
677 679 }
678 680 else if (compareVersions(major, minor, 1, 6) < 0)
679 681 {
680   - if (this->encrypt_use_aes)
  682 + if (this->m->encrypt_use_aes)
681 683 {
682 684 disable = true;
683 685 }
... ... @@ -695,7 +697,7 @@ QPDFWriter::disableIncompatibleEncryption(int major, int minor,
695 697 if (disable)
696 698 {
697 699 QTC::TC("qpdf", "QPDFWriter forced version disabled encryption");
698   - this->encrypted = false;
  700 + this->m->encrypted = false;
699 701 }
700 702 }
701 703  
... ... @@ -754,20 +756,22 @@ QPDFWriter::setEncryptionParametersInternal(
754 756 std::string const& id1, std::string const& user_password,
755 757 std::string const& encryption_key)
756 758 {
757   - this->encryption_V = V;
758   - this->encryption_R = R;
759   - encryption_dictionary["/Filter"] = "/Standard";
760   - encryption_dictionary["/V"] = QUtil::int_to_string(V);
761   - encryption_dictionary["/Length"] = QUtil::int_to_string(key_len * 8);
762   - encryption_dictionary["/R"] = QUtil::int_to_string(R);
763   - encryption_dictionary["/P"] = QUtil::int_to_string(P);
764   - encryption_dictionary["/O"] = QPDF_String(O).unparse(true);
765   - encryption_dictionary["/U"] = QPDF_String(U).unparse(true);
  759 + this->m->encryption_V = V;
  760 + this->m->encryption_R = R;
  761 + this->m->encryption_dictionary["/Filter"] = "/Standard";
  762 + this->m->encryption_dictionary["/V"] = QUtil::int_to_string(V);
  763 + this->m->encryption_dictionary["/Length"] =
  764 + QUtil::int_to_string(key_len * 8);
  765 + this->m->encryption_dictionary["/R"] = QUtil::int_to_string(R);
  766 + this->m->encryption_dictionary["/P"] = QUtil::int_to_string(P);
  767 + this->m->encryption_dictionary["/O"] = QPDF_String(O).unparse(true);
  768 + this->m->encryption_dictionary["/U"] = QPDF_String(U).unparse(true);
766 769 if (V >= 5)
767 770 {
768   - encryption_dictionary["/OE"] = QPDF_String(OE).unparse(true);
769   - encryption_dictionary["/UE"] = QPDF_String(UE).unparse(true);
770   - encryption_dictionary["/Perms"] = QPDF_String(Perms).unparse(true);
  771 + this->m->encryption_dictionary["/OE"] = QPDF_String(OE).unparse(true);
  772 + this->m->encryption_dictionary["/UE"] = QPDF_String(UE).unparse(true);
  773 + this->m->encryption_dictionary["/Perms"] =
  774 + QPDF_String(Perms).unparse(true);
771 775 }
772 776 if (R >= 6)
773 777 {
... ... @@ -779,7 +783,7 @@ QPDFWriter::setEncryptionParametersInternal(
779 783 }
780 784 else if (R == 4)
781 785 {
782   - setMinimumPDFVersion(this->encrypt_use_aes ? "1.6" : "1.5");
  786 + setMinimumPDFVersion(this->m->encrypt_use_aes ? "1.6" : "1.5");
783 787 }
784 788 else if (R == 3)
785 789 {
... ... @@ -790,48 +794,48 @@ QPDFWriter::setEncryptionParametersInternal(
790 794 setMinimumPDFVersion("1.3");
791 795 }
792 796  
793   - if ((R >= 4) && (! encrypt_metadata))
  797 + if ((R >= 4) && (! this->m->encrypt_metadata))
794 798 {
795   - encryption_dictionary["/EncryptMetadata"] = "false";
  799 + this->m->encryption_dictionary["/EncryptMetadata"] = "false";
796 800 }
797 801 if ((V == 4) || (V == 5))
798 802 {
799 803 // The spec says the value for the crypt filter key can be
800 804 // anything, and xpdf seems to agree. However, Adobe Reader
801 805 // won't open our files unless we use /StdCF.
802   - encryption_dictionary["/StmF"] = "/StdCF";
803   - encryption_dictionary["/StrF"] = "/StdCF";
804   - std::string method = (this->encrypt_use_aes
  806 + this->m->encryption_dictionary["/StmF"] = "/StdCF";
  807 + this->m->encryption_dictionary["/StrF"] = "/StdCF";
  808 + std::string method = (this->m->encrypt_use_aes
805 809 ? ((V < 5) ? "/AESV2" : "/AESV3")
806 810 : "/V2");
807 811 // The PDF spec says the /Length key is optional, but the PDF
808 812 // previewer on some versions of MacOS won't open encrypted
809 813 // files without it.
810   - encryption_dictionary["/CF"] =
  814 + this->m->encryption_dictionary["/CF"] =
811 815 "<< /StdCF << /AuthEvent /DocOpen /CFM " + method +
812 816 " /Length " + std::string((V < 5) ? "16" : "32") + " >> >>";
813 817 }
814 818  
815   - this->encrypted = true;
  819 + this->m->encrypted = true;
816 820 QPDF::EncryptionData encryption_data(
817   - V, R, key_len, P, O, U, OE, UE, Perms, id1, this->encrypt_metadata);
  821 + V, R, key_len, P, O, U, OE, UE, Perms, id1, this->m->encrypt_metadata);
818 822 if (V < 5)
819 823 {
820   - this->encryption_key = QPDF::compute_encryption_key(
  824 + this->m->encryption_key = QPDF::compute_encryption_key(
821 825 user_password, encryption_data);
822 826 }
823 827 else
824 828 {
825   - this->encryption_key = encryption_key;
  829 + this->m->encryption_key = encryption_key;
826 830 }
827 831 }
828 832  
829 833 void
830 834 QPDFWriter::setDataKey(int objid)
831 835 {
832   - this->cur_data_key = QPDF::compute_data_key(
833   - this->encryption_key, objid, 0,
834   - this->encrypt_use_aes, this->encryption_V, this->encryption_R);
  836 + this->m->cur_data_key = QPDF::compute_data_key(
  837 + this->m->encryption_key, objid, 0,
  838 + this->m->encrypt_use_aes, this->m->encryption_V, this->m->encryption_R);
835 839 }
836 840  
837 841 int
... ... @@ -860,25 +864,25 @@ QPDFWriter::writeBinary(unsigned long long val, unsigned int bytes)
860 864 data[bytes - i - 1] = static_cast<unsigned char>(val & 0xff);
861 865 val >>= 8;
862 866 }
863   - this->pipeline->write(data, bytes);
  867 + this->m->pipeline->write(data, bytes);
864 868 }
865 869  
866 870 void
867 871 QPDFWriter::writeString(std::string const& str)
868 872 {
869   - this->pipeline->write(QUtil::unsigned_char_pointer(str), str.length());
  873 + this->m->pipeline->write(QUtil::unsigned_char_pointer(str), str.length());
870 874 }
871 875  
872 876 void
873 877 QPDFWriter::writeBuffer(PointerHolder<Buffer>& b)
874 878 {
875   - this->pipeline->write(b->getBuffer(), b->getSize());
  879 + this->m->pipeline->write(b->getBuffer(), b->getSize());
876 880 }
877 881  
878 882 void
879 883 QPDFWriter::writeStringQDF(std::string const& str)
880 884 {
881   - if (this->qdf_mode)
  885 + if (this->m->qdf_mode)
882 886 {
883 887 writeString(str);
884 888 }
... ... @@ -887,7 +891,7 @@ QPDFWriter::writeStringQDF(std::string const&amp; str)
887 891 void
888 892 QPDFWriter::writeStringNoQDF(std::string const& str)
889 893 {
890   - if (! this->qdf_mode)
  894 + if (! this->m->qdf_mode)
891 895 {
892 896 writeString(str);
893 897 }
... ... @@ -906,43 +910,43 @@ Pipeline*
906 910 QPDFWriter::pushPipeline(Pipeline* p)
907 911 {
908 912 assert(dynamic_cast<Pl_Count*>(p) == 0);
909   - this->pipeline_stack.push_back(p);
  913 + this->m->pipeline_stack.push_back(p);
910 914 return p;
911 915 }
912 916  
913 917 void
914 918 QPDFWriter::initializePipelineStack(Pipeline *p)
915 919 {
916   - this->pipeline = new Pl_Count("qpdf count", p);
917   - to_delete.push_back(this->pipeline);
918   - this->pipeline_stack.push_back(this->pipeline);
  920 + this->m->pipeline = new Pl_Count("qpdf count", p);
  921 + this->m->to_delete.push_back(this->m->pipeline);
  922 + this->m->pipeline_stack.push_back(this->m->pipeline);
919 923 }
920 924  
921 925 void
922 926 QPDFWriter::activatePipelineStack()
923 927 {
924   - Pl_Count* c = new Pl_Count("count", this->pipeline_stack.back());
925   - this->pipeline_stack.push_back(c);
926   - this->pipeline = c;
  928 + Pl_Count* c = new Pl_Count("count", this->m->pipeline_stack.back());
  929 + this->m->pipeline_stack.push_back(c);
  930 + this->m->pipeline = c;
927 931 }
928 932  
929 933 void
930 934 QPDFWriter::popPipelineStack(PointerHolder<Buffer>* bp)
931 935 {
932   - assert(this->pipeline_stack.size() >= 2);
933   - this->pipeline->finish();
934   - assert(dynamic_cast<Pl_Count*>(this->pipeline_stack.back()) ==
935   - this->pipeline);
936   - delete this->pipeline_stack.back();
937   - this->pipeline_stack.pop_back();
938   - while (dynamic_cast<Pl_Count*>(this->pipeline_stack.back()) == 0)
  936 + assert(this->m->pipeline_stack.size() >= 2);
  937 + this->m->pipeline->finish();
  938 + assert(dynamic_cast<Pl_Count*>(this->m->pipeline_stack.back()) ==
  939 + this->m->pipeline);
  940 + delete this->m->pipeline_stack.back();
  941 + this->m->pipeline_stack.pop_back();
  942 + while (dynamic_cast<Pl_Count*>(this->m->pipeline_stack.back()) == 0)
939 943 {
940   - Pipeline* p = this->pipeline_stack.back();
941   - if (dynamic_cast<Pl_MD5*>(p) == this->md5_pipeline)
  944 + Pipeline* p = this->m->pipeline_stack.back();
  945 + if (dynamic_cast<Pl_MD5*>(p) == this->m->md5_pipeline)
942 946 {
943   - this->md5_pipeline = 0;
  947 + this->m->md5_pipeline = 0;
944 948 }
945   - this->pipeline_stack.pop_back();
  949 + this->m->pipeline_stack.pop_back();
946 950 Pl_Buffer* buf = dynamic_cast<Pl_Buffer*>(p);
947 951 if (bp && buf)
948 952 {
... ... @@ -950,14 +954,14 @@ QPDFWriter::popPipelineStack(PointerHolder&lt;Buffer&gt;* bp)
950 954 }
951 955 delete p;
952 956 }
953   - this->pipeline = dynamic_cast<Pl_Count*>(this->pipeline_stack.back());
  957 + this->m->pipeline = dynamic_cast<Pl_Count*>(this->m->pipeline_stack.back());
954 958 }
955 959  
956 960 void
957 961 QPDFWriter::adjustAESStreamLength(size_t& length)
958 962 {
959   - if (this->encrypted && (! this->cur_data_key.empty()) &&
960   - this->encrypt_use_aes)
  963 + if (this->m->encrypted && (! this->m->cur_data_key.empty()) &&
  964 + this->m->encrypt_use_aes)
961 965 {
962 966 // Stream length will be padded with 1 to 16 bytes to end up
963 967 // as a multiple of 16. It will also be prepended by 16 bits
... ... @@ -969,21 +973,21 @@ QPDFWriter::adjustAESStreamLength(size_t&amp; length)
969 973 void
970 974 QPDFWriter::pushEncryptionFilter()
971 975 {
972   - if (this->encrypted && (! this->cur_data_key.empty()))
  976 + if (this->m->encrypted && (! this->m->cur_data_key.empty()))
973 977 {
974 978 Pipeline* p = 0;
975   - if (this->encrypt_use_aes)
  979 + if (this->m->encrypt_use_aes)
976 980 {
977 981 p = new Pl_AES_PDF(
978   - "aes stream encryption", this->pipeline, true,
979   - QUtil::unsigned_char_pointer(this->cur_data_key),
980   - this->cur_data_key.length());
  982 + "aes stream encryption", this->m->pipeline, true,
  983 + QUtil::unsigned_char_pointer(this->m->cur_data_key),
  984 + this->m->cur_data_key.length());
981 985 }
982 986 else
983 987 {
984   - p = new Pl_RC4("rc4 stream encryption", this->pipeline,
985   - QUtil::unsigned_char_pointer(this->cur_data_key),
986   - this->cur_data_key.length());
  988 + p = new Pl_RC4("rc4 stream encryption", this->m->pipeline,
  989 + QUtil::unsigned_char_pointer(this->m->cur_data_key),
  990 + this->m->cur_data_key.length());
987 991 }
988 992 pushPipeline(p);
989 993 }
... ... @@ -1002,31 +1006,31 @@ QPDFWriter::pushDiscardFilter()
1002 1006 void
1003 1007 QPDFWriter::pushMD5Pipeline()
1004 1008 {
1005   - if (! this->id2.empty())
  1009 + if (! this->m->id2.empty())
1006 1010 {
1007 1011 // Can't happen in the code
1008 1012 throw std::logic_error(
1009 1013 "Deterministic ID computation enabled after ID"
1010 1014 " generation has already occurred.");
1011 1015 }
1012   - assert(this->deterministic_id);
1013   - assert(this->md5_pipeline == 0);
1014   - assert(this->pipeline->getCount() == 0);
1015   - this->md5_pipeline = new Pl_MD5("qpdf md5", this->pipeline);
1016   - this->md5_pipeline->persistAcrossFinish(true);
1017   - // Special case code in popPipelineStack clears this->md5_pipeline
  1016 + assert(this->m->deterministic_id);
  1017 + assert(this->m->md5_pipeline == 0);
  1018 + assert(this->m->pipeline->getCount() == 0);
  1019 + this->m->md5_pipeline = new Pl_MD5("qpdf md5", this->m->pipeline);
  1020 + this->m->md5_pipeline->persistAcrossFinish(true);
  1021 + // Special case code in popPipelineStack clears this->m->md5_pipeline
1018 1022 // upon deletion.
1019   - pushPipeline(this->md5_pipeline);
  1023 + pushPipeline(this->m->md5_pipeline);
1020 1024 activatePipelineStack();
1021 1025 }
1022 1026  
1023 1027 void
1024 1028 QPDFWriter::computeDeterministicIDData()
1025 1029 {
1026   - assert(this->md5_pipeline != 0);
1027   - assert(this->deterministic_id_data.empty());
1028   - this->deterministic_id_data = this->md5_pipeline->getHexDigest();
1029   - this->md5_pipeline->enable(false);
  1030 + assert(this->m->md5_pipeline != 0);
  1031 + assert(this->m->deterministic_id_data.empty());
  1032 + this->m->deterministic_id_data = this->m->md5_pipeline->getHexDigest();
  1033 + this->m->md5_pipeline->enable(false);
1030 1034 }
1031 1035  
1032 1036 int
... ... @@ -1034,9 +1038,9 @@ QPDFWriter::openObject(int objid)
1034 1038 {
1035 1039 if (objid == 0)
1036 1040 {
1037   - objid = this->next_objid++;
  1041 + objid = this->m->next_objid++;
1038 1042 }
1039   - this->xref[objid] = QPDFXRefEntry(1, pipeline->getCount(), 0);
  1043 + this->m->xref[objid] = QPDFXRefEntry(1, this->m->pipeline->getCount(), 0);
1040 1044 writeString(QUtil::int_to_string(objid));
1041 1045 writeString(" 0 obj\n");
1042 1046 return objid;
... ... @@ -1049,7 +1053,8 @@ QPDFWriter::closeObject(int objid)
1049 1053 // repair.
1050 1054 writeString("\nendobj\n");
1051 1055 writeStringQDF("\n");
1052   - this->lengths[objid] = pipeline->getCount() - this->xref[objid].getOffset();
  1056 + this->m->lengths[objid] = this->m->pipeline->getCount() -
  1057 + this->m->xref[objid].getOffset();
1053 1058 }
1054 1059  
1055 1060 void
... ... @@ -1057,7 +1062,7 @@ QPDFWriter::assignCompressedObjectNumbers(QPDFObjGen const&amp; og)
1057 1062 {
1058 1063 int objid = og.getObj();
1059 1064 if ((og.getGen() != 0) ||
1060   - (this->object_stream_to_objects.count(objid) == 0))
  1065 + (this->m->object_stream_to_objects.count(objid) == 0))
1061 1066 {
1062 1067 // This is not an object stream.
1063 1068 return;
... ... @@ -1066,11 +1071,11 @@ QPDFWriter::assignCompressedObjectNumbers(QPDFObjGen const&amp; og)
1066 1071 // Reserve numbers for the objects that belong to this object
1067 1072 // stream.
1068 1073 for (std::set<QPDFObjGen>::iterator iter =
1069   - this->object_stream_to_objects[objid].begin();
1070   - iter != this->object_stream_to_objects[objid].end();
  1074 + this->m->object_stream_to_objects[objid].begin();
  1075 + iter != this->m->object_stream_to_objects[objid].end();
1071 1076 ++iter)
1072 1077 {
1073   - obj_renumber[*iter] = next_objid++;
  1078 + this->m->obj_renumber[*iter] = this->m->next_objid++;
1074 1079 }
1075 1080 }
1076 1081  
... ... @@ -1079,7 +1084,7 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object)
1079 1084 {
1080 1085 if (object.isIndirect())
1081 1086 {
1082   - if (object.getOwningQPDF() != &(this->pdf))
  1087 + if (object.getOwningQPDF() != &(this->m->pdf))
1083 1088 {
1084 1089 QTC::TC("qpdf", "QPDFWriter foreign object");
1085 1090 throw std::logic_error(
... ... @@ -1090,43 +1095,44 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object)
1090 1095  
1091 1096 QPDFObjGen og = object.getObjGen();
1092 1097  
1093   - if (obj_renumber.count(og) == 0)
  1098 + if (this->m->obj_renumber.count(og) == 0)
1094 1099 {
1095   - if (this->object_to_object_stream.count(og))
  1100 + if (this->m->object_to_object_stream.count(og))
1096 1101 {
1097 1102 // This is in an object stream. Don't process it
1098 1103 // here. Instead, enqueue the object stream. Object
1099 1104 // streams always have generation 0.
1100   - int stream_id = this->object_to_object_stream[og];
  1105 + int stream_id = this->m->object_to_object_stream[og];
1101 1106 // Detect loops by storing invalid object ID 0, which
1102 1107 // will get overwritten later.
1103   - obj_renumber[og] = 0;
1104   - enqueueObject(this->pdf.getObjectByID(stream_id, 0));
  1108 + this->m->obj_renumber[og] = 0;
  1109 + enqueueObject(this->m->pdf.getObjectByID(stream_id, 0));
1105 1110 }
1106 1111 else
1107 1112 {
1108   - object_queue.push_back(object);
1109   - obj_renumber[og] = next_objid++;
  1113 + this->m->object_queue.push_back(object);
  1114 + this->m->obj_renumber[og] = this->m->next_objid++;
1110 1115  
1111 1116 if ((og.getGen() == 0) &&
1112   - this->object_stream_to_objects.count(og.getObj()))
  1117 + this->m->object_stream_to_objects.count(og.getObj()))
1113 1118 {
1114 1119 // For linearized files, uncompressed objects go
1115 1120 // at end, and we take care of assigning numbers
1116 1121 // to them elsewhere.
1117   - if (! this->linearized)
  1122 + if (! this->m->linearized)
1118 1123 {
1119 1124 assignCompressedObjectNumbers(og);
1120 1125 }
1121 1126 }
1122   - else if ((! this->direct_stream_lengths) && object.isStream())
  1127 + else if ((! this->m->direct_stream_lengths) &&
  1128 + object.isStream())
1123 1129 {
1124 1130 // reserve next object ID for length
1125   - ++next_objid;
  1131 + ++this->m->next_objid;
1126 1132 }
1127 1133 }
1128 1134 }
1129   - else if (obj_renumber[og] == 0)
  1135 + else if (this->m->obj_renumber[og] == 0)
1130 1136 {
1131 1137 // This can happen if a specially constructed file
1132 1138 // indicates that an object stream is inside itself.
... ... @@ -1138,7 +1144,7 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object)
1138 1144 int n = object.getArrayNItems();
1139 1145 for (int i = 0; i < n; ++i)
1140 1146 {
1141   - if (! this->linearized)
  1147 + if (! this->m->linearized)
1142 1148 {
1143 1149 enqueueObject(object.getArrayItem(i));
1144 1150 }
... ... @@ -1150,7 +1156,7 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object)
1150 1156 for (std::set<std::string>::iterator iter = keys.begin();
1151 1157 iter != keys.end(); ++iter)
1152 1158 {
1153   - if (! this->linearized)
  1159 + if (! this->m->linearized)
1154 1160 {
1155 1161 enqueueObject(object.getKey(*iter));
1156 1162 }
... ... @@ -1165,14 +1171,14 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object)
1165 1171 void
1166 1172 QPDFWriter::unparseChild(QPDFObjectHandle child, int level, int flags)
1167 1173 {
1168   - if (! this->linearized)
  1174 + if (! this->m->linearized)
1169 1175 {
1170 1176 enqueueObject(child);
1171 1177 }
1172 1178 if (child.isIndirect())
1173 1179 {
1174 1180 QPDFObjGen old_og = child.getObjGen();
1175   - int new_id = obj_renumber[old_og];
  1181 + int new_id = this->m->obj_renumber[old_og];
1176 1182 writeString(QUtil::int_to_string(new_id));
1177 1183 writeString(" 0 R");
1178 1184 }
... ... @@ -1214,9 +1220,9 @@ QPDFWriter::writeTrailer(trailer_e which, int size, bool xref_stream,
1214 1220 if (which == t_lin_first)
1215 1221 {
1216 1222 writeString(" /Prev ");
1217   - qpdf_offset_t pos = this->pipeline->getCount();
  1223 + qpdf_offset_t pos = this->m->pipeline->getCount();
1218 1224 writeString(QUtil::int_to_string(prev));
1219   - int nspaces = pos - this->pipeline->getCount() + 21;
  1225 + int nspaces = pos - this->m->pipeline->getCount() + 21;
1220 1226 if (nspaces < 0)
1221 1227 {
1222 1228 throw std::logic_error(
... ... @@ -1243,23 +1249,23 @@ QPDFWriter::writeTrailer(trailer_e which, int size, bool xref_stream,
1243 1249 }
1244 1250 else
1245 1251 {
1246   - if ((linearization_pass == 0) && (this->deterministic_id))
  1252 + if ((linearization_pass == 0) && (this->m->deterministic_id))
1247 1253 {
1248 1254 computeDeterministicIDData();
1249 1255 }
1250 1256 generateID();
1251   - writeString(QPDF_String(this->id1).unparse(true));
1252   - writeString(QPDF_String(this->id2).unparse(true));
  1257 + writeString(QPDF_String(this->m->id1).unparse(true));
  1258 + writeString(QPDF_String(this->m->id2).unparse(true));
1253 1259 }
1254 1260 writeString("]");
1255 1261  
1256 1262 if (which != t_lin_second)
1257 1263 {
1258 1264 // Write reference to encryption dictionary
1259   - if (this->encrypted)
  1265 + if (this->m->encrypted)
1260 1266 {
1261 1267 writeString(" /Encrypt ");
1262   - writeString(QUtil::int_to_string(this->encryption_dict_objid));
  1268 + writeString(QUtil::int_to_string(this->m->encryption_dict_objid));
1263 1269 writeString(" 0 R");
1264 1270 }
1265 1271 }
... ... @@ -1348,7 +1354,7 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
1348 1354 bool have_extensions_adbe = false;
1349 1355  
1350 1356 QPDFObjectHandle extensions;
1351   - if (old_og == pdf.getRoot().getObjGen())
  1357 + if (old_og == this->m->pdf.getRoot().getObjGen())
1352 1358 {
1353 1359 is_root = true;
1354 1360 if (object.hasKey("/Extensions") &&
... ... @@ -1372,7 +1378,7 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
1372 1378 }
1373 1379 }
1374 1380  
1375   - bool need_extensions_adbe = (this->final_extension_level > 0);
  1381 + bool need_extensions_adbe = (this->m->final_extension_level > 0);
1376 1382  
1377 1383 if (is_root)
1378 1384 {
... ... @@ -1383,7 +1389,7 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
1383 1389 // We need Extensions and don't have it. Create
1384 1390 // it here.
1385 1391 QTC::TC("qpdf", "QPDFWriter create Extensions",
1386   - this->qdf_mode ? 0 : 1);
  1392 + this->m->qdf_mode ? 0 : 1);
1387 1393 extensions = QPDFObjectHandle::newDictionary();
1388 1394 object.replaceKey("/Extensions", extensions);
1389 1395 }
... ... @@ -1408,11 +1414,11 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
1408 1414 adbe.hasKey("/BaseVersion") &&
1409 1415 adbe.getKey("/BaseVersion").isName() &&
1410 1416 (adbe.getKey("/BaseVersion").getName() ==
1411   - "/" + this->final_pdf_version) &&
  1417 + "/" + this->m->final_pdf_version) &&
1412 1418 adbe.hasKey("/ExtensionLevel") &&
1413 1419 adbe.getKey("/ExtensionLevel").isInteger() &&
1414 1420 (adbe.getKey("/ExtensionLevel").getIntValue() ==
1415   - this->final_extension_level))
  1421 + this->m->final_extension_level))
1416 1422 {
1417 1423 QTC::TC("qpdf", "QPDFWriter preserve ADBE");
1418 1424 }
... ... @@ -1423,9 +1429,10 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
1423 1429 extensions.replaceKey(
1424 1430 "/ADBE",
1425 1431 QPDFObjectHandle::parse(
1426   - "<< /BaseVersion /" + this->final_pdf_version +
  1432 + "<< /BaseVersion /" + this->m->final_pdf_version +
1427 1433 " /ExtensionLevel " +
1428   - QUtil::int_to_string(this->final_extension_level) +
  1434 + QUtil::int_to_string(
  1435 + this->m->final_extension_level) +
1429 1436 " >>"));
1430 1437 }
1431 1438 else
... ... @@ -1516,14 +1523,14 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
1516 1523 writeStringQDF(" ");
1517 1524 writeString(" /Length ");
1518 1525  
1519   - if (this->direct_stream_lengths)
  1526 + if (this->m->direct_stream_lengths)
1520 1527 {
1521 1528 writeString(QUtil::int_to_string(stream_length));
1522 1529 }
1523 1530 else
1524 1531 {
1525 1532 writeString(
1526   - QUtil::int_to_string(this->cur_stream_length_id));
  1533 + QUtil::int_to_string(this->m->cur_stream_length_id));
1527 1534 writeString(" 0 R");
1528 1535 }
1529 1536 writeStringQDF("\n");
... ... @@ -1543,10 +1550,10 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
1543 1550 else if (object.isStream())
1544 1551 {
1545 1552 // Write stream data to a buffer.
1546   - int new_id = obj_renumber[old_og];
1547   - if (! this->direct_stream_lengths)
  1553 + int new_id = this->m->obj_renumber[old_og];
  1554 + if (! this->m->direct_stream_lengths)
1548 1555 {
1549   - this->cur_stream_length_id = new_id + 1;
  1556 + this->m->cur_stream_length_id = new_id + 1;
1550 1557 }
1551 1558 QPDFObjectHandle stream_dict = object.getDict();
1552 1559  
... ... @@ -1556,8 +1563,9 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
1556 1563 {
1557 1564 is_metadata = true;
1558 1565 }
1559   - bool filter = (this->compress_streams || this->stream_decode_level);
1560   - if (this->compress_streams)
  1566 + bool filter = (this->m->compress_streams ||
  1567 + this->m->stream_decode_level);
  1568 + if (this->m->compress_streams)
1561 1569 {
1562 1570 // Don't filter if the stream is already compressed with
1563 1571 // FlateDecode. We don't want to make it worse by getting
... ... @@ -1578,19 +1586,20 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
1578 1586 bool compress = false;
1579 1587 bool uncompress = false;
1580 1588 if (is_metadata &&
1581   - ((! this->encrypted) || (this->encrypt_metadata == false)))
  1589 + ((! this->m->encrypted) || (this->m->encrypt_metadata == false)))
1582 1590 {
1583 1591 QTC::TC("qpdf", "QPDFWriter not compressing metadata");
1584 1592 filter = true;
1585 1593 compress = false;
1586 1594 uncompress = true;
1587 1595 }
1588   - else if (this->normalize_content && normalized_streams.count(old_og))
  1596 + else if (this->m->normalize_content &&
  1597 + this->m->normalized_streams.count(old_og))
1589 1598 {
1590 1599 normalize = true;
1591 1600 filter = true;
1592 1601 }
1593   - else if (filter && this->compress_streams)
  1602 + else if (filter && this->m->compress_streams)
1594 1603 {
1595 1604 compress = true;
1596 1605 QTC::TC("qpdf", "QPDFWriter compressing uncompressed stream");
... ... @@ -1607,11 +1616,11 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
1607 1616  
1608 1617 filtered =
1609 1618 object.pipeStreamData(
1610   - this->pipeline,
  1619 + this->m->pipeline,
1611 1620 (((filter && normalize) ? qpdf_ef_normalize : 0) |
1612 1621 ((filter && compress) ? qpdf_ef_compress : 0)),
1613 1622 (filter
1614   - ? (uncompress ? qpdf_dl_all : this->stream_decode_level)
  1623 + ? (uncompress ? qpdf_dl_all : this->m->stream_decode_level)
1615 1624 : qpdf_dl_none));
1616 1625 popPipelineStack(&stream_data);
1617 1626 if (filter && (! filtered))
... ... @@ -1633,47 +1642,48 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
1633 1642 compress = false;
1634 1643 }
1635 1644  
1636   - this->cur_stream_length = stream_data->getSize();
1637   - if (is_metadata && this->encrypted && (! this->encrypt_metadata))
  1645 + this->m->cur_stream_length = stream_data->getSize();
  1646 + if (is_metadata && this->m->encrypted && (! this->m->encrypt_metadata))
1638 1647 {
1639 1648 // Don't encrypt stream data for the metadata stream
1640   - this->cur_data_key.clear();
  1649 + this->m->cur_data_key.clear();
1641 1650 }
1642   - adjustAESStreamLength(this->cur_stream_length);
1643   - unparseObject(stream_dict, 0, flags, this->cur_stream_length, compress);
  1651 + adjustAESStreamLength(this->m->cur_stream_length);
  1652 + unparseObject(stream_dict, 0, flags,
  1653 + this->m->cur_stream_length, compress);
1644 1654 writeString("\nstream\n");
1645 1655 pushEncryptionFilter();
1646 1656 writeBuffer(stream_data);
1647   - char last_char = this->pipeline->getLastChar();
  1657 + char last_char = this->m->pipeline->getLastChar();
1648 1658 popPipelineStack();
1649 1659  
1650   - if (this->newline_before_endstream ||
1651   - (this->qdf_mode && (last_char != '\n')))
  1660 + if (this->m->newline_before_endstream ||
  1661 + (this->m->qdf_mode && (last_char != '\n')))
1652 1662 {
1653 1663 writeString("\n");
1654   - this->added_newline = true;
  1664 + this->m->added_newline = true;
1655 1665 }
1656 1666 else
1657 1667 {
1658   - this->added_newline = false;
  1668 + this->m->added_newline = false;
1659 1669 }
1660 1670 writeString("endstream");
1661 1671 }
1662 1672 else if (object.isString())
1663 1673 {
1664 1674 std::string val;
1665   - if (this->encrypted &&
  1675 + if (this->m->encrypted &&
1666 1676 (! (flags & f_in_ostream)) &&
1667   - (! this->cur_data_key.empty()))
  1677 + (! this->m->cur_data_key.empty()))
1668 1678 {
1669 1679 val = object.getStringValue();
1670   - if (this->encrypt_use_aes)
  1680 + if (this->m->encrypt_use_aes)
1671 1681 {
1672 1682 Pl_Buffer bufpl("encrypted string");
1673 1683 Pl_AES_PDF pl(
1674 1684 "aes encrypt string", &bufpl, true,
1675   - QUtil::unsigned_char_pointer(this->cur_data_key),
1676   - this->cur_data_key.length());
  1685 + QUtil::unsigned_char_pointer(this->m->cur_data_key),
  1686 + this->m->cur_data_key.length());
1677 1687 pl.write(QUtil::unsigned_char_pointer(val), val.length());
1678 1688 pl.finish();
1679 1689 Buffer* buf = bufpl.getBuffer();
... ... @@ -1686,8 +1696,8 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
1686 1696 {
1687 1697 char* tmp = QUtil::copy_string(val);
1688 1698 size_t vlen = val.length();
1689   - RC4 rc4(QUtil::unsigned_char_pointer(this->cur_data_key),
1690   - this->cur_data_key.length());
  1699 + RC4 rc4(QUtil::unsigned_char_pointer(this->m->cur_data_key),
  1700 + this->m->cur_data_key.length());
1691 1701 rc4.process(QUtil::unsigned_char_pointer(tmp), vlen);
1692 1702 val = QPDF_String(std::string(tmp, vlen)).unparse();
1693 1703 delete [] tmp;
... ... @@ -1732,7 +1742,7 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
1732 1742 QPDFObjGen old_og = object.getObjGen();
1733 1743 assert(old_og.getGen() == 0);
1734 1744 int old_id = old_og.getObj();
1735   - int new_id = obj_renumber[old_og];
  1745 + int new_id = this->m->obj_renumber[old_og];
1736 1746  
1737 1747 std::vector<qpdf_offset_t> offsets;
1738 1748 qpdf_offset_t first = 0;
... ... @@ -1763,12 +1773,12 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
1763 1773 // their size information
1764 1774 pushDiscardFilter();
1765 1775 writeObjectStreamOffsets(offsets, first_obj);
1766   - first += this->pipeline->getCount();
  1776 + first += this->m->pipeline->getCount();
1767 1777 popPipelineStack();
1768 1778  
1769 1779 // Set up a stream to write the stream data into a buffer.
1770 1780 Pipeline* next = pushPipeline(new Pl_Buffer("object stream"));
1771   - if (! (this->stream_decode_level || this->qdf_mode))
  1781 + if (! (this->m->stream_decode_level || this->m->qdf_mode))
1772 1782 {
1773 1783 compressed = true;
1774 1784 next = pushPipeline(
... ... @@ -1781,22 +1791,22 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
1781 1791  
1782 1792 int count = 0;
1783 1793 for (std::set<QPDFObjGen>::iterator iter =
1784   - this->object_stream_to_objects[old_id].begin();
1785   - iter != this->object_stream_to_objects[old_id].end();
  1794 + this->m->object_stream_to_objects[old_id].begin();
  1795 + iter != this->m->object_stream_to_objects[old_id].end();
1786 1796 ++iter, ++count)
1787 1797 {
1788 1798 QPDFObjGen obj = *iter;
1789   - int new_obj = this->obj_renumber[obj];
  1799 + int new_obj = this->m->obj_renumber[obj];
1790 1800 if (first_obj == -1)
1791 1801 {
1792 1802 first_obj = new_obj;
1793 1803 }
1794   - if (this->qdf_mode)
  1804 + if (this->m->qdf_mode)
1795 1805 {
1796 1806 writeString("%% Object stream: object " +
1797 1807 QUtil::int_to_string(new_obj) + ", index " +
1798 1808 QUtil::int_to_string(count));
1799   - if (! this->suppress_original_object_ids)
  1809 + if (! this->m->suppress_original_object_ids)
1800 1810 {
1801 1811 writeString("; original object ID: " +
1802 1812 QUtil::int_to_string(obj.getObj()));
... ... @@ -1815,11 +1825,11 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
1815 1825 }
1816 1826 if (pass == 1)
1817 1827 {
1818   - offsets.push_back(this->pipeline->getCount());
  1828 + offsets.push_back(this->m->pipeline->getCount());
1819 1829 }
1820   - writeObject(this->pdf.getObjectByObjGen(obj), count);
  1830 + writeObject(this->m->pdf.getObjectByObjGen(obj), count);
1821 1831  
1822   - this->xref[new_obj] = QPDFXRefEntry(2, new_id, count);
  1832 + this->m->xref[new_obj] = QPDFXRefEntry(2, new_id, count);
1823 1833 }
1824 1834  
1825 1835 // stream_buffer will be initialized only for pass 2
... ... @@ -1860,7 +1870,7 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
1860 1870 writeStringQDF("\n");
1861 1871 writeStringNoQDF(" ");
1862 1872 writeString(">>\nstream\n");
1863   - if (this->encrypted)
  1873 + if (this->m->encrypted)
1864 1874 {
1865 1875 QTC::TC("qpdf", "QPDFWriter encrypt object stream");
1866 1876 }
... ... @@ -1868,7 +1878,7 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
1868 1878 writeBuffer(stream_buffer);
1869 1879 popPipelineStack();
1870 1880 writeString("endstream");
1871   - this->cur_data_key.clear();
  1881 + this->m->cur_data_key.clear();
1872 1882 closeObject(new_id);
1873 1883 }
1874 1884  
... ... @@ -1879,35 +1889,35 @@ QPDFWriter::writeObject(QPDFObjectHandle object, int object_stream_index)
1879 1889  
1880 1890 if ((object_stream_index == -1) &&
1881 1891 (old_og.getGen() == 0) &&
1882   - (this->object_stream_to_objects.count(old_og.getObj())))
  1892 + (this->m->object_stream_to_objects.count(old_og.getObj())))
1883 1893 {
1884 1894 writeObjectStream(object);
1885 1895 return;
1886 1896 }
1887 1897  
1888   - int new_id = obj_renumber[old_og];
1889   - if (this->qdf_mode)
  1898 + int new_id = this->m->obj_renumber[old_og];
  1899 + if (this->m->qdf_mode)
1890 1900 {
1891   - if (this->page_object_to_seq.count(old_og))
  1901 + if (this->m->page_object_to_seq.count(old_og))
1892 1902 {
1893 1903 writeString("%% Page ");
1894 1904 writeString(
1895 1905 QUtil::int_to_string(
1896   - this->page_object_to_seq[old_og]));
  1906 + this->m->page_object_to_seq[old_og]));
1897 1907 writeString("\n");
1898 1908 }
1899   - if (this->contents_to_page_seq.count(old_og))
  1909 + if (this->m->contents_to_page_seq.count(old_og))
1900 1910 {
1901 1911 writeString("%% Contents for page ");
1902 1912 writeString(
1903 1913 QUtil::int_to_string(
1904   - this->contents_to_page_seq[old_og]));
  1914 + this->m->contents_to_page_seq[old_og]));
1905 1915 writeString("\n");
1906 1916 }
1907 1917 }
1908 1918 if (object_stream_index == -1)
1909 1919 {
1910   - if (this->qdf_mode && (! this->suppress_original_object_ids))
  1920 + if (this->m->qdf_mode && (! this->m->suppress_original_object_ids))
1911 1921 {
1912 1922 writeString("%% Original object ID: " +
1913 1923 QUtil::int_to_string(object.getObjectID()) + " " +
... ... @@ -1916,7 +1926,7 @@ QPDFWriter::writeObject(QPDFObjectHandle object, int object_stream_index)
1916 1926 openObject(new_id);
1917 1927 setDataKey(new_id);
1918 1928 unparseObject(object, 0, 0);
1919   - this->cur_data_key.clear();
  1929 + this->m->cur_data_key.clear();
1920 1930 closeObject(new_id);
1921 1931 }
1922 1932 else
... ... @@ -1925,17 +1935,17 @@ QPDFWriter::writeObject(QPDFObjectHandle object, int object_stream_index)
1925 1935 writeString("\n");
1926 1936 }
1927 1937  
1928   - if ((! this->direct_stream_lengths) && object.isStream())
  1938 + if ((! this->m->direct_stream_lengths) && object.isStream())
1929 1939 {
1930   - if (this->qdf_mode)
  1940 + if (this->m->qdf_mode)
1931 1941 {
1932   - if (this->added_newline)
  1942 + if (this->m->added_newline)
1933 1943 {
1934 1944 writeString("%QDF: ignore_newline\n");
1935 1945 }
1936 1946 }
1937 1947 openObject(new_id + 1);
1938   - writeString(QUtil::int_to_string(this->cur_stream_length));
  1948 + writeString(QUtil::int_to_string(this->m->cur_stream_length));
1939 1949 closeObject(new_id + 1);
1940 1950 }
1941 1951 }
... ... @@ -1946,16 +1956,16 @@ QPDFWriter::generateID()
1946 1956 // Generate the ID lazily so that we can handle the user's
1947 1957 // preference to use static or deterministic ID generation.
1948 1958  
1949   - if (! this->id2.empty())
  1959 + if (! this->m->id2.empty())
1950 1960 {
1951 1961 return;
1952 1962 }
1953 1963  
1954   - QPDFObjectHandle trailer = pdf.getTrailer();
  1964 + QPDFObjectHandle trailer = this->m->pdf.getTrailer();
1955 1965  
1956 1966 std::string result;
1957 1967  
1958   - if (this->static_id)
  1968 + if (this->m->static_id)
1959 1969 {
1960 1970 // For test suite use only...
1961 1971 static unsigned char tmp[] = {0x31, 0x41, 0x59, 0x26,
... ... @@ -1981,9 +1991,9 @@ QPDFWriter::generateID()
1981 1991 // ID regardless of the output file's name.
1982 1992  
1983 1993 std::string seed;
1984   - if (this->deterministic_id)
  1994 + if (this->m->deterministic_id)
1985 1995 {
1986   - if (this->deterministic_id_data.empty())
  1996 + if (this->m->deterministic_id_data.empty())
1987 1997 {
1988 1998 QTC::TC("qpdf", "QPDFWriter deterministic with no data");
1989 1999 throw std::logic_error(
... ... @@ -1992,12 +2002,12 @@ QPDFWriter::generateID()
1992 2002 " deterministic ID and file encryption are requested"
1993 2003 " together.");
1994 2004 }
1995   - seed += this->deterministic_id_data;
  2005 + seed += this->m->deterministic_id_data;
1996 2006 }
1997 2007 else
1998 2008 {
1999 2009 seed += QUtil::int_to_string(QUtil::get_current_time());
2000   - seed += this->filename;
  2010 + seed += this->m->filename;
2001 2011 seed += " ";
2002 2012 }
2003 2013 seed += " QPDF ";
... ... @@ -2029,15 +2039,15 @@ QPDFWriter::generateID()
2029 2039 // word and generate a new second word. Otherwise, we'll use the
2030 2040 // generated ID for both.
2031 2041  
2032   - this->id2 = result;
  2042 + this->m->id2 = result;
2033 2043 if (trailer.hasKey("/ID"))
2034 2044 {
2035 2045 // Note: keep /ID from old file even if --static-id was given.
2036   - this->id1 = trailer.getKey("/ID").getArrayItem(0).getStringValue();
  2046 + this->m->id1 = trailer.getKey("/ID").getArrayItem(0).getStringValue();
2037 2047 }
2038 2048 else
2039 2049 {
2040   - this->id1 = this->id2;
  2050 + this->m->id1 = this->m->id2;
2041 2051 }
2042 2052 }
2043 2053  
... ... @@ -2046,13 +2056,13 @@ QPDFWriter::initializeSpecialStreams()
2046 2056 {
2047 2057 // Mark all page content streams in case we are filtering or
2048 2058 // normalizing.
2049   - std::vector<QPDFObjectHandle> pages = pdf.getAllPages();
  2059 + std::vector<QPDFObjectHandle> pages = this->m->pdf.getAllPages();
2050 2060 int num = 0;
2051 2061 for (std::vector<QPDFObjectHandle>::iterator iter = pages.begin();
2052 2062 iter != pages.end(); ++iter)
2053 2063 {
2054 2064 QPDFObjectHandle& page = *iter;
2055   - this->page_object_to_seq[page.getObjGen()] = ++num;
  2065 + this->m->page_object_to_seq[page.getObjGen()] = ++num;
2056 2066 QPDFObjectHandle contents = page.getKey("/Contents");
2057 2067 std::vector<QPDFObjGen> contents_objects;
2058 2068 if (contents.isArray())
... ... @@ -2072,8 +2082,8 @@ QPDFWriter::initializeSpecialStreams()
2072 2082 for (std::vector<QPDFObjGen>::iterator iter = contents_objects.begin();
2073 2083 iter != contents_objects.end(); ++iter)
2074 2084 {
2075   - this->contents_to_page_seq[*iter] = num;
2076   - this->normalized_streams.insert(*iter);
  2085 + this->m->contents_to_page_seq[*iter] = num;
  2086 + this->m->normalized_streams.insert(*iter);
2077 2087 }
2078 2088 }
2079 2089 }
... ... @@ -2088,11 +2098,11 @@ QPDFWriter::preserveObjectStreams()
2088 2098 // must have generation 0 because the PDF spec does not provide
2089 2099 // any way to do otherwise.
2090 2100 std::map<int, int> omap;
2091   - QPDF::Writer::getObjectStreamData(this->pdf, omap);
  2101 + QPDF::Writer::getObjectStreamData(this->m->pdf, omap);
2092 2102 for (std::map<int, int>::iterator iter = omap.begin();
2093 2103 iter != omap.end(); ++iter)
2094 2104 {
2095   - this->object_to_object_stream[QPDFObjGen((*iter).first, 0)] =
  2105 + this->m->object_to_object_stream[QPDFObjGen((*iter).first, 0)] =
2096 2106 (*iter).second;
2097 2107 }
2098 2108 }
... ... @@ -2111,7 +2121,7 @@ QPDFWriter::generateObjectStreams()
2111 2121 // This code doesn't do anything with /Extends.
2112 2122  
2113 2123 std::vector<QPDFObjGen> const& eligible =
2114   - QPDF::Writer::getCompressibleObjGens(this->pdf);
  2124 + QPDF::Writer::getCompressibleObjGens(this->m->pdf);
2115 2125 unsigned int n_object_streams = (eligible.size() + 99) / 100;
2116 2126 if (n_object_streams == 0)
2117 2127 {
... ... @@ -2140,10 +2150,10 @@ QPDFWriter::generateObjectStreams()
2140 2150 // Construct a new null object as the "original" object
2141 2151 // stream. The rest of the code knows that this means
2142 2152 // we're creating the object stream from scratch.
2143   - cur_ostream = this->pdf.makeIndirectObject(
  2153 + cur_ostream = this->m->pdf.makeIndirectObject(
2144 2154 QPDFObjectHandle::newNull()).getObjectID();
2145 2155 }
2146   - this->object_to_object_stream[*iter] = cur_ostream;
  2156 + this->m->object_to_object_stream[*iter] = cur_ostream;
2147 2157 ++n;
2148 2158 }
2149 2159 }
... ... @@ -2154,7 +2164,7 @@ QPDFWriter::getTrimmedTrailer()
2154 2164 // Remove keys from the trailer that necessarily have to be
2155 2165 // replaced when writing the file.
2156 2166  
2157   - QPDFObjectHandle trailer = pdf.getTrailer().shallowCopy();
  2167 + QPDFObjectHandle trailer = this->m->pdf.getTrailer().shallowCopy();
2158 2168  
2159 2169 // Remove encryption keys
2160 2170 trailer.removeKey("/ID");
... ... @@ -2231,9 +2241,9 @@ QPDFWriter::prepareFileForWrite()
2231 2241 dict = node.getDict();
2232 2242 // See whether we are able to filter this stream.
2233 2243 filterable = node.pipeStreamData(
2234   - 0, 0, this->stream_decode_level, true);
  2244 + 0, 0, this->m->stream_decode_level, true);
2235 2245 }
2236   - else if (pdf.getRoot().getObjectID() == node.getObjectID())
  2246 + else if (this->m->pdf.getRoot().getObjectID() == node.getObjectID())
2237 2247 {
2238 2248 is_root = true;
2239 2249 }
... ... @@ -2300,84 +2310,84 @@ QPDFWriter::write()
2300 2310 {
2301 2311 // Do preliminary setup
2302 2312  
2303   - if (this->linearized)
  2313 + if (this->m->linearized)
2304 2314 {
2305   - this->qdf_mode = false;
  2315 + this->m->qdf_mode = false;
2306 2316 }
2307 2317  
2308   - if (this->pclm)
  2318 + if (this->m->pclm)
2309 2319 {
2310   - this->stream_decode_level = qpdf_dl_none;
2311   - this->compress_streams = false;
2312   - this->encrypted = false;
  2320 + this->m->stream_decode_level = qpdf_dl_none;
  2321 + this->m->compress_streams = false;
  2322 + this->m->encrypted = false;
2313 2323 }
2314 2324  
2315   - if (this->qdf_mode)
  2325 + if (this->m->qdf_mode)
2316 2326 {
2317   - if (! this->normalize_content_set)
  2327 + if (! this->m->normalize_content_set)
2318 2328 {
2319   - this->normalize_content = true;
  2329 + this->m->normalize_content = true;
2320 2330 }
2321   - if (! this->compress_streams_set)
  2331 + if (! this->m->compress_streams_set)
2322 2332 {
2323   - this->compress_streams = false;
  2333 + this->m->compress_streams = false;
2324 2334 }
2325   - if (! this->stream_decode_level_set)
  2335 + if (! this->m->stream_decode_level_set)
2326 2336 {
2327   - this->stream_decode_level = qpdf_dl_generalized;
  2337 + this->m->stream_decode_level = qpdf_dl_generalized;
2328 2338 }
2329 2339 }
2330 2340  
2331   - if (this->encrypted)
  2341 + if (this->m->encrypted)
2332 2342 {
2333 2343 // Encryption has been explicitly set
2334   - this->preserve_encryption = false;
  2344 + this->m->preserve_encryption = false;
2335 2345 }
2336   - else if (this->normalize_content ||
2337   - this->stream_decode_level ||
2338   - this->pclm ||
2339   - this->qdf_mode)
  2346 + else if (this->m->normalize_content ||
  2347 + this->m->stream_decode_level ||
  2348 + this->m->pclm ||
  2349 + this->m->qdf_mode)
2340 2350 {
2341 2351 // Encryption makes looking at contents pretty useless. If
2342 2352 // the user explicitly encrypted though, we still obey that.
2343   - this->preserve_encryption = false;
  2353 + this->m->preserve_encryption = false;
2344 2354 }
2345 2355  
2346   - if (preserve_encryption)
  2356 + if (this->m->preserve_encryption)
2347 2357 {
2348   - copyEncryptionParameters(this->pdf);
  2358 + copyEncryptionParameters(this->m->pdf);
2349 2359 }
2350 2360  
2351   - if (! this->forced_pdf_version.empty())
  2361 + if (! this->m->forced_pdf_version.empty())
2352 2362 {
2353 2363 int major = 0;
2354 2364 int minor = 0;
2355   - parseVersion(this->forced_pdf_version, major, minor);
  2365 + parseVersion(this->m->forced_pdf_version, major, minor);
2356 2366 disableIncompatibleEncryption(major, minor,
2357   - this->forced_extension_level);
  2367 + this->m->forced_extension_level);
2358 2368 if (compareVersions(major, minor, 1, 5) < 0)
2359 2369 {
2360 2370 QTC::TC("qpdf", "QPDFWriter forcing object stream disable");
2361   - this->object_stream_mode = qpdf_o_disable;
  2371 + this->m->object_stream_mode = qpdf_o_disable;
2362 2372 }
2363 2373 }
2364 2374  
2365   - if (this->qdf_mode || this->normalize_content ||
2366   - this->stream_decode_level)
  2375 + if (this->m->qdf_mode || this->m->normalize_content ||
  2376 + this->m->stream_decode_level)
2367 2377 {
2368 2378 initializeSpecialStreams();
2369 2379 }
2370 2380  
2371   - if (this->qdf_mode)
  2381 + if (this->m->qdf_mode)
2372 2382 {
2373 2383 // Generate indirect stream lengths for qdf mode since fix-qdf
2374 2384 // uses them for storing recomputed stream length data.
2375 2385 // Certain streams such as object streams, xref streams, and
2376 2386 // hint streams always get direct stream lengths.
2377   - this->direct_stream_lengths = false;
  2387 + this->m->direct_stream_lengths = false;
2378 2388 }
2379 2389  
2380   - switch (this->object_stream_mode)
  2390 + switch (this->m->object_stream_mode)
2381 2391 {
2382 2392 case qpdf_o_disable:
2383 2393 // no action required
... ... @@ -2394,60 +2404,60 @@ QPDFWriter::write()
2394 2404 // no default so gcc will warn for missing case tag
2395 2405 }
2396 2406  
2397   - if (this->linearized)
  2407 + if (this->m->linearized)
2398 2408 {
2399 2409 // Page dictionaries are not allowed to be compressed objects.
2400   - std::vector<QPDFObjectHandle> pages = pdf.getAllPages();
  2410 + std::vector<QPDFObjectHandle> pages = this->m->pdf.getAllPages();
2401 2411 for (std::vector<QPDFObjectHandle>::iterator iter = pages.begin();
2402 2412 iter != pages.end(); ++iter)
2403 2413 {
2404 2414 QPDFObjectHandle& page = *iter;
2405 2415 QPDFObjGen og = page.getObjGen();
2406   - if (this->object_to_object_stream.count(og))
  2416 + if (this->m->object_to_object_stream.count(og))
2407 2417 {
2408 2418 QTC::TC("qpdf", "QPDFWriter uncompressing page dictionary");
2409   - this->object_to_object_stream.erase(og);
  2419 + this->m->object_to_object_stream.erase(og);
2410 2420 }
2411 2421 }
2412 2422 }
2413 2423  
2414   - if (this->linearized || this->encrypted)
  2424 + if (this->m->linearized || this->m->encrypted)
2415 2425 {
2416 2426 // The document catalog is not allowed to be compressed in
2417 2427 // linearized files either. It also appears that Adobe Reader
2418 2428 // 8.0.0 has a bug that prevents it from being able to handle
2419 2429 // encrypted files with compressed document catalogs, so we
2420 2430 // disable them in that case as well.
2421   - QPDFObjGen og = pdf.getRoot().getObjGen();
2422   - if (this->object_to_object_stream.count(og))
  2431 + QPDFObjGen og = this->m->pdf.getRoot().getObjGen();
  2432 + if (this->m->object_to_object_stream.count(og))
2423 2433 {
2424 2434 QTC::TC("qpdf", "QPDFWriter uncompressing root");
2425   - this->object_to_object_stream.erase(og);
  2435 + this->m->object_to_object_stream.erase(og);
2426 2436 }
2427 2437 }
2428 2438  
2429 2439 // Generate reverse mapping from object stream to objects
2430 2440 for (std::map<QPDFObjGen, int>::iterator iter =
2431   - this->object_to_object_stream.begin();
2432   - iter != this->object_to_object_stream.end(); ++iter)
  2441 + this->m->object_to_object_stream.begin();
  2442 + iter != this->m->object_to_object_stream.end(); ++iter)
2433 2443 {
2434 2444 QPDFObjGen obj = (*iter).first;
2435 2445 int stream = (*iter).second;
2436   - this->object_stream_to_objects[stream].insert(obj);
2437   - this->max_ostream_index =
2438   - std::max(this->max_ostream_index,
  2446 + this->m->object_stream_to_objects[stream].insert(obj);
  2447 + this->m->max_ostream_index =
  2448 + std::max(this->m->max_ostream_index,
2439 2449 static_cast<int>(
2440   - this->object_stream_to_objects[stream].size()) - 1);
  2450 + this->m->object_stream_to_objects[stream].size()) - 1);
2441 2451 }
2442 2452  
2443   - if (! this->object_stream_to_objects.empty())
  2453 + if (! this->m->object_stream_to_objects.empty())
2444 2454 {
2445 2455 setMinimumPDFVersion("1.5");
2446 2456 }
2447 2457  
2448 2458 prepareFileForWrite();
2449 2459  
2450   - if (this->linearized)
  2460 + if (this->m->linearized)
2451 2461 {
2452 2462 writeLinearized();
2453 2463 }
... ... @@ -2456,16 +2466,16 @@ QPDFWriter::write()
2456 2466 writeStandard();
2457 2467 }
2458 2468  
2459   - this->pipeline->finish();
2460   - if (this->close_file)
  2469 + this->m->pipeline->finish();
  2470 + if (this->m->close_file)
2461 2471 {
2462   - fclose(this->file);
  2472 + fclose(this->m->file);
2463 2473 }
2464   - this->file = 0;
2465   - if (this->buffer_pipeline)
  2474 + this->m->file = 0;
  2475 + if (this->m->buffer_pipeline)
2466 2476 {
2467   - this->output_buffer = this->buffer_pipeline->getBuffer();
2468   - this->buffer_pipeline = 0;
  2477 + this->m->output_buffer = this->m->buffer_pipeline->getBuffer();
  2478 + this->m->buffer_pipeline = 0;
2469 2479 }
2470 2480 }
2471 2481  
... ... @@ -2482,11 +2492,11 @@ QPDFWriter::enqueuePart(std::vector&lt;QPDFObjectHandle&gt;&amp; part)
2482 2492 void
2483 2493 QPDFWriter::writeEncryptionDictionary()
2484 2494 {
2485   - this->encryption_dict_objid = openObject(this->encryption_dict_objid);
  2495 + this->m->encryption_dict_objid = openObject(this->m->encryption_dict_objid);
2486 2496 writeString("<<");
2487 2497 for (std::map<std::string, std::string>::iterator iter =
2488   - this->encryption_dictionary.begin();
2489   - iter != this->encryption_dictionary.end(); ++iter)
  2498 + this->m->encryption_dictionary.begin();
  2499 + iter != this->m->encryption_dictionary.end(); ++iter)
2490 2500 {
2491 2501 writeString(" ");
2492 2502 writeString((*iter).first);
... ... @@ -2494,25 +2504,26 @@ QPDFWriter::writeEncryptionDictionary()
2494 2504 writeString((*iter).second);
2495 2505 }
2496 2506 writeString(" >>");
2497   - closeObject(this->encryption_dict_objid);
  2507 + closeObject(this->m->encryption_dict_objid);
2498 2508 }
2499 2509  
2500 2510 void
2501 2511 QPDFWriter::writeHeader()
2502 2512 {
2503   - setMinimumPDFVersion(pdf.getPDFVersion(), pdf.getExtensionLevel());
2504   - this->final_pdf_version = this->min_pdf_version;
2505   - this->final_extension_level = this->min_extension_level;
2506   - if (! this->forced_pdf_version.empty())
  2513 + setMinimumPDFVersion(this->m->pdf.getPDFVersion(),
  2514 + this->m->pdf.getExtensionLevel());
  2515 + this->m->final_pdf_version = this->m->min_pdf_version;
  2516 + this->m->final_extension_level = this->m->min_extension_level;
  2517 + if (! this->m->forced_pdf_version.empty())
2507 2518 {
2508 2519 QTC::TC("qpdf", "QPDFWriter using forced PDF version");
2509   - this->final_pdf_version = this->forced_pdf_version;
2510   - this->final_extension_level = this->forced_extension_level;
  2520 + this->m->final_pdf_version = this->m->forced_pdf_version;
  2521 + this->m->final_extension_level = this->m->forced_extension_level;
2511 2522 }
2512 2523  
2513 2524 writeString("%PDF-");
2514   - writeString(this->final_pdf_version);
2515   - if (this->pclm)
  2525 + writeString(this->m->final_pdf_version);
  2526 + if (this->m->pclm)
2516 2527 {
2517 2528 // PCLm version
2518 2529 writeString("\n%PCLm 1.0\n");
... ... @@ -2539,7 +2550,8 @@ QPDFWriter::writeHintStream(int hint_id)
2539 2550 int S = 0;
2540 2551 int O = 0;
2541 2552 QPDF::Writer::generateHintStream(
2542   - this->pdf, this->xref, this->lengths, this->obj_renumber_no_gen,
  2553 + this->m->pdf, this->m->xref, this->m->lengths,
  2554 + this->m->obj_renumber_no_gen,
2543 2555 hint_buffer, S, O);
2544 2556  
2545 2557 openObject(hint_id);
... ... @@ -2559,13 +2571,13 @@ QPDFWriter::writeHintStream(int hint_id)
2559 2571 writeString(QUtil::int_to_string(hlen));
2560 2572 writeString(" >>\nstream\n");
2561 2573  
2562   - if (this->encrypted)
  2574 + if (this->m->encrypted)
2563 2575 {
2564 2576 QTC::TC("qpdf", "QPDFWriter encrypted hint stream");
2565 2577 }
2566 2578 pushEncryptionFilter();
2567 2579 writeBuffer(hint_buffer);
2568   - char last_char = this->pipeline->getLastChar();
  2580 + char last_char = this->m->pipeline->getLastChar();
2569 2581 popPipelineStack();
2570 2582  
2571 2583 if (last_char != '\n')
... ... @@ -2592,7 +2604,7 @@ QPDFWriter::writeXRefTable(trailer_e which, int first, int last, int size,
2592 2604 writeString(QUtil::int_to_string(first));
2593 2605 writeString(" ");
2594 2606 writeString(QUtil::int_to_string(last - first + 1));
2595   - qpdf_offset_t space_before_zero = this->pipeline->getCount();
  2607 + qpdf_offset_t space_before_zero = this->m->pipeline->getCount();
2596 2608 writeString("\n");
2597 2609 for (int i = first; i <= last; ++i)
2598 2610 {
... ... @@ -2605,7 +2617,7 @@ QPDFWriter::writeXRefTable(trailer_e which, int first, int last, int size,
2605 2617 qpdf_offset_t offset = 0;
2606 2618 if (! suppress_offsets)
2607 2619 {
2608   - offset = this->xref[i].getOffset();
  2620 + offset = this->m->xref[i].getOffset();
2609 2621 if ((hint_id != 0) &&
2610 2622 (i != hint_id) &&
2611 2623 (offset >= hint_offset))
... ... @@ -2639,7 +2651,7 @@ QPDFWriter::writeXRefStream(int xref_id, int max_id, qpdf_offset_t max_offset,
2639 2651 bool skip_compression,
2640 2652 int linearization_pass)
2641 2653 {
2642   - qpdf_offset_t xref_offset = this->pipeline->getCount();
  2654 + qpdf_offset_t xref_offset = this->m->pipeline->getCount();
2643 2655 qpdf_offset_t space_before_zero = xref_offset - 1;
2644 2656  
2645 2657 // field 1 contains offsets and object stream identifiers
... ... @@ -2647,17 +2659,17 @@ QPDFWriter::writeXRefStream(int xref_id, int max_id, qpdf_offset_t max_offset,
2647 2659 bytesNeeded(max_id));
2648 2660  
2649 2661 // field 2 contains object stream indices
2650   - int f2_size = bytesNeeded(this->max_ostream_index);
  2662 + int f2_size = bytesNeeded(this->m->max_ostream_index);
2651 2663  
2652 2664 unsigned int esize = 1 + f1_size + f2_size;
2653 2665  
2654 2666 // Must store in xref table in advance of writing the actual data
2655 2667 // rather than waiting for openObject to do it.
2656   - this->xref[xref_id] = QPDFXRefEntry(1, pipeline->getCount(), 0);
  2668 + this->m->xref[xref_id] = QPDFXRefEntry(1, this->m->pipeline->getCount(), 0);
2657 2669  
2658 2670 Pipeline* p = pushPipeline(new Pl_Buffer("xref stream"));
2659 2671 bool compressed = false;
2660   - if (! (this->stream_decode_level || this->qdf_mode))
  2672 + if (! (this->m->stream_decode_level || this->m->qdf_mode))
2661 2673 {
2662 2674 compressed = true;
2663 2675 if (! skip_compression)
... ... @@ -2675,7 +2687,7 @@ QPDFWriter::writeXRefStream(int xref_id, int max_id, qpdf_offset_t max_offset,
2675 2687 activatePipelineStack();
2676 2688 for (int i = first; i <= last; ++i)
2677 2689 {
2678   - QPDFXRefEntry& e = this->xref[i];
  2690 + QPDFXRefEntry& e = this->m->xref[i];
2679 2691 switch (e.getType())
2680 2692 {
2681 2693 case 0:
... ... @@ -2799,11 +2811,11 @@ QPDFWriter::writeLinearized()
2799 2811 {
2800 2812 // Optimize file and enqueue objects in order
2801 2813  
2802   - discardGeneration(this->object_to_object_stream,
2803   - this->object_to_object_stream_no_gen);
  2814 + discardGeneration(this->m->object_to_object_stream,
  2815 + this->m->object_to_object_stream_no_gen);
2804 2816  
2805   - bool need_xref_stream = (! this->object_to_object_stream.empty());
2806   - pdf.optimize(this->object_to_object_stream_no_gen);
  2817 + bool need_xref_stream = (! this->m->object_to_object_stream.empty());
  2818 + this->m->pdf.optimize(this->m->object_to_object_stream_no_gen);
2807 2819  
2808 2820 std::vector<QPDFObjectHandle> part4;
2809 2821 std::vector<QPDFObjectHandle> part6;
... ... @@ -2811,7 +2823,7 @@ QPDFWriter::writeLinearized()
2811 2823 std::vector<QPDFObjectHandle> part8;
2812 2824 std::vector<QPDFObjectHandle> part9;
2813 2825 QPDF::Writer::getLinearizedParts(
2814   - this->pdf, this->object_to_object_stream_no_gen,
  2826 + this->m->pdf, this->m->object_to_object_stream_no_gen,
2815 2827 part4, part6, part7, part8, part9);
2816 2828  
2817 2829 // Object number sequence:
... ... @@ -2834,11 +2846,11 @@ QPDFWriter::writeLinearized()
2834 2846 int second_half_uncompressed = part7.size() + part8.size() + part9.size();
2835 2847 int second_half_first_obj = 1;
2836 2848 int after_second_half = 1 + second_half_uncompressed;
2837   - this->next_objid = after_second_half;
  2849 + this->m->next_objid = after_second_half;
2838 2850 int second_half_xref = 0;
2839 2851 if (need_xref_stream)
2840 2852 {
2841   - second_half_xref = this->next_objid++;
  2853 + second_half_xref = this->m->next_objid++;
2842 2854 }
2843 2855 // Assign numbers to all compressed objects in the second half.
2844 2856 std::vector<QPDFObjectHandle>* vecs2[] = {&part7, &part8, &part9};
... ... @@ -2850,28 +2862,28 @@ QPDFWriter::writeLinearized()
2850 2862 assignCompressedObjectNumbers((*iter).getObjGen());
2851 2863 }
2852 2864 }
2853   - int second_half_end = this->next_objid - 1;
2854   - int second_trailer_size = this->next_objid;
  2865 + int second_half_end = this->m->next_objid - 1;
  2866 + int second_trailer_size = this->m->next_objid;
2855 2867  
2856 2868 // First half objects
2857   - int first_half_start = this->next_objid;
2858   - int lindict_id = this->next_objid++;
  2869 + int first_half_start = this->m->next_objid;
  2870 + int lindict_id = this->m->next_objid++;
2859 2871 int first_half_xref = 0;
2860 2872 if (need_xref_stream)
2861 2873 {
2862   - first_half_xref = this->next_objid++;
  2874 + first_half_xref = this->m->next_objid++;
2863 2875 }
2864   - int part4_first_obj = this->next_objid;
2865   - this->next_objid += part4.size();
2866   - int after_part4 = this->next_objid;
2867   - if (this->encrypted)
  2876 + int part4_first_obj = this->m->next_objid;
  2877 + this->m->next_objid += part4.size();
  2878 + int after_part4 = this->m->next_objid;
  2879 + if (this->m->encrypted)
2868 2880 {
2869   - this->encryption_dict_objid = this->next_objid++;
  2881 + this->m->encryption_dict_objid = this->m->next_objid++;
2870 2882 }
2871   - int hint_id = this->next_objid++;
2872   - int part6_first_obj = this->next_objid;
2873   - this->next_objid += part6.size();
2874   - int after_part6 = this->next_objid;
  2883 + int hint_id = this->m->next_objid++;
  2884 + int part6_first_obj = this->m->next_objid;
  2885 + this->m->next_objid += part6.size();
  2886 + int after_part6 = this->m->next_objid;
2875 2887 // Assign numbers to all compressed objects in the first half
2876 2888 std::vector<QPDFObjectHandle>* vecs1[] = {&part4, &part6};
2877 2889 for (int i = 0; i < 2; ++i)
... ... @@ -2882,8 +2894,8 @@ QPDFWriter::writeLinearized()
2882 2894 assignCompressedObjectNumbers((*iter).getObjGen());
2883 2895 }
2884 2896 }
2885   - int first_half_end = this->next_objid - 1;
2886   - int first_trailer_size = this->next_objid;
  2897 + int first_half_end = this->m->next_objid - 1;
  2898 + int first_trailer_size = this->m->next_objid;
2887 2899  
2888 2900 int part4_end_marker = part4.back().getObjectID();
2889 2901 int part6_end_marker = part6.back().getObjectID();
... ... @@ -2895,17 +2907,17 @@ QPDFWriter::writeLinearized()
2895 2907 qpdf_offset_t first_xref_end = 0;
2896 2908 qpdf_offset_t second_xref_end = 0;
2897 2909  
2898   - this->next_objid = part4_first_obj;
  2910 + this->m->next_objid = part4_first_obj;
2899 2911 enqueuePart(part4);
2900   - assert(this->next_objid == after_part4);
2901   - this->next_objid = part6_first_obj;
  2912 + assert(this->m->next_objid == after_part4);
  2913 + this->m->next_objid = part6_first_obj;
2902 2914 enqueuePart(part6);
2903   - assert(this->next_objid == after_part6);
2904   - this->next_objid = second_half_first_obj;
  2915 + assert(this->m->next_objid == after_part6);
  2916 + this->m->next_objid = second_half_first_obj;
2905 2917 enqueuePart(part7);
2906 2918 enqueuePart(part8);
2907 2919 enqueuePart(part9);
2908   - assert(this->next_objid == after_second_half);
  2920 + assert(this->m->next_objid == after_second_half);
2909 2921  
2910 2922 qpdf_offset_t hint_length = 0;
2911 2923 PointerHolder<Buffer> hint_buffer;
... ... @@ -2917,7 +2929,7 @@ QPDFWriter::writeLinearized()
2917 2929 if (pass == 1)
2918 2930 {
2919 2931 pushDiscardFilter();
2920   - if (this->deterministic_id)
  2932 + if (this->m->deterministic_id)
2921 2933 {
2922 2934 pushMD5Pipeline();
2923 2935 }
... ... @@ -2935,13 +2947,15 @@ QPDFWriter::writeLinearized()
2935 2947 // dictionary must appear within the first 1024 characters of
2936 2948 // the file.
2937 2949  
2938   - qpdf_offset_t pos = this->pipeline->getCount();
  2950 + qpdf_offset_t pos = this->m->pipeline->getCount();
2939 2951 openObject(lindict_id);
2940 2952 writeString("<<");
2941 2953 if (pass == 2)
2942 2954 {
2943   - std::vector<QPDFObjectHandle> const& pages = pdf.getAllPages();
2944   - int first_page_object = obj_renumber[pages.at(0).getObjGen()];
  2955 + std::vector<QPDFObjectHandle> const& pages =
  2956 + this->m->pdf.getAllPages();
  2957 + int first_page_object =
  2958 + this->m->obj_renumber[pages.at(0).getObjGen()];
2945 2959 int npages = pages.size();
2946 2960  
2947 2961 writeString(" /Linearized 1 /L ");
... ... @@ -2949,7 +2963,8 @@ QPDFWriter::writeLinearized()
2949 2963 // Implementation note 121 states that a space is
2950 2964 // mandatory after this open bracket.
2951 2965 writeString(" /H [ ");
2952   - writeString(QUtil::int_to_string(this->xref[hint_id].getOffset()));
  2966 + writeString(QUtil::int_to_string(
  2967 + this->m->xref[hint_id].getOffset()));
2953 2968 writeString(" ");
2954 2969 writeString(QUtil::int_to_string(hint_length));
2955 2970 writeString(" ] /O ");
... ... @@ -2964,22 +2979,22 @@ QPDFWriter::writeLinearized()
2964 2979 writeString(" >>");
2965 2980 closeObject(lindict_id);
2966 2981 static int const pad = 200;
2967   - int spaces = (pos - this->pipeline->getCount() + pad);
  2982 + int spaces = (pos - this->m->pipeline->getCount() + pad);
2968 2983 assert(spaces >= 0);
2969 2984 writePad(spaces);
2970 2985 writeString("\n");
2971 2986  
2972 2987 // If the user supplied any additional header text, write it
2973 2988 // here after the linearization parameter dictionary.
2974   - writeString(this->extra_header_text);
  2989 + writeString(this->m->extra_header_text);
2975 2990  
2976 2991 // Part 3: first page cross reference table and trailer.
2977 2992  
2978   - qpdf_offset_t first_xref_offset = this->pipeline->getCount();
  2993 + qpdf_offset_t first_xref_offset = this->m->pipeline->getCount();
2979 2994 qpdf_offset_t hint_offset = 0;
2980 2995 if (pass == 2)
2981 2996 {
2982   - hint_offset = this->xref[hint_id].getOffset();
  2997 + hint_offset = this->m->xref[hint_id].getOffset();
2983 2998 }
2984 2999 if (need_xref_stream)
2985 3000 {
... ... @@ -2996,7 +3011,7 @@ QPDFWriter::writeLinearized()
2996 3011 // it's smaller.
2997 3012 first_half_max_obj_offset = 1 << 25;
2998 3013 }
2999   - pos = this->pipeline->getCount();
  3014 + pos = this->m->pipeline->getCount();
3000 3015 writeXRefStream(first_half_xref, first_half_end,
3001 3016 first_half_max_obj_offset,
3002 3017 t_lin_first, first_half_start, first_half_end,
... ... @@ -3004,13 +3019,13 @@ QPDFWriter::writeLinearized()
3004 3019 hint_length + second_xref_offset,
3005 3020 hint_id, hint_offset, hint_length,
3006 3021 (pass == 1), pass);
3007   - qpdf_offset_t endpos = this->pipeline->getCount();
  3022 + qpdf_offset_t endpos = this->m->pipeline->getCount();
3008 3023 if (pass == 1)
3009 3024 {
3010 3025 // Pad so we have enough room for the real xref
3011 3026 // stream.
3012 3027 writePad(calculateXrefStreamPadding(endpos - pos));
3013   - first_xref_end = this->pipeline->getCount();
  3028 + first_xref_end = this->m->pipeline->getCount();
3014 3029 }
3015 3030 else
3016 3031 {
... ... @@ -3018,7 +3033,7 @@ QPDFWriter::writeLinearized()
3018 3033 // place as in pass 1.
3019 3034 writePad(first_xref_end - endpos);
3020 3035  
3021   - if (this->pipeline->getCount() != first_xref_end)
  3036 + if (this->m->pipeline->getCount() != first_xref_end)
3022 3037 {
3023 3038 throw std::logic_error(
3024 3039 "insufficient padding for first pass xref stream");
... ... @@ -3038,25 +3053,25 @@ QPDFWriter::writeLinearized()
3038 3053 // Parts 4 through 9
3039 3054  
3040 3055 for (std::list<QPDFObjectHandle>::iterator iter =
3041   - this->object_queue.begin();
3042   - iter != this->object_queue.end(); ++iter)
  3056 + this->m->object_queue.begin();
  3057 + iter != this->m->object_queue.end(); ++iter)
3043 3058 {
3044 3059 QPDFObjectHandle cur_object = (*iter);
3045 3060 if (cur_object.getObjectID() == part6_end_marker)
3046 3061 {
3047   - first_half_max_obj_offset = this->pipeline->getCount();
  3062 + first_half_max_obj_offset = this->m->pipeline->getCount();
3048 3063 }
3049 3064 writeObject(cur_object);
3050 3065 if (cur_object.getObjectID() == part4_end_marker)
3051 3066 {
3052   - if (this->encrypted)
  3067 + if (this->m->encrypted)
3053 3068 {
3054 3069 writeEncryptionDictionary();
3055 3070 }
3056 3071 if (pass == 1)
3057 3072 {
3058   - this->xref[hint_id] =
3059   - QPDFXRefEntry(1, this->pipeline->getCount(), 0);
  3073 + this->m->xref[hint_id] =
  3074 + QPDFXRefEntry(1, this->m->pipeline->getCount(), 0);
3060 3075 }
3061 3076 else
3062 3077 {
... ... @@ -3066,7 +3081,7 @@ QPDFWriter::writeLinearized()
3066 3081 }
3067 3082 if (cur_object.getObjectID() == part6_end_marker)
3068 3083 {
3069   - part6_end_offset = this->pipeline->getCount();
  3084 + part6_end_offset = this->m->pipeline->getCount();
3070 3085 }
3071 3086 }
3072 3087  
... ... @@ -3074,17 +3089,17 @@ QPDFWriter::writeLinearized()
3074 3089  
3075 3090 // Part 11: main cross reference table and trailer
3076 3091  
3077   - second_xref_offset = this->pipeline->getCount();
  3092 + second_xref_offset = this->m->pipeline->getCount();
3078 3093 if (need_xref_stream)
3079 3094 {
3080   - pos = this->pipeline->getCount();
  3095 + pos = this->m->pipeline->getCount();
3081 3096 space_before_zero =
3082 3097 writeXRefStream(second_half_xref,
3083 3098 second_half_end, second_xref_offset,
3084 3099 t_lin_second, 0, second_half_end,
3085 3100 second_trailer_size,
3086 3101 0, 0, 0, 0, (pass == 1), pass);
3087   - qpdf_offset_t endpos = this->pipeline->getCount();
  3102 + qpdf_offset_t endpos = this->m->pipeline->getCount();
3088 3103  
3089 3104 if (pass == 1)
3090 3105 {
... ... @@ -3093,18 +3108,18 @@ QPDFWriter::writeLinearized()
3093 3108 // how we calculate the padding.
3094 3109 writePad(calculateXrefStreamPadding(endpos - pos));
3095 3110 writeString("\n");
3096   - second_xref_end = this->pipeline->getCount();
  3111 + second_xref_end = this->m->pipeline->getCount();
3097 3112 }
3098 3113 else
3099 3114 {
3100 3115 // Make the file size the same.
3101   - qpdf_offset_t pos = this->pipeline->getCount();
  3116 + qpdf_offset_t pos = this->m->pipeline->getCount();
3102 3117 writePad(second_xref_end + hint_length - 1 - pos);
3103 3118 writeString("\n");
3104 3119  
3105 3120 // If this assertion fails, maybe we didn't have
3106 3121 // enough padding above.
3107   - if (this->pipeline->getCount() !=
  3122 + if (this->m->pipeline->getCount() !=
3108 3123 second_xref_end + hint_length)
3109 3124 {
3110 3125 throw std::logic_error(
... ... @@ -3123,26 +3138,26 @@ QPDFWriter::writeLinearized()
3123 3138 writeString(QUtil::int_to_string(first_xref_offset));
3124 3139 writeString("\n%%EOF\n");
3125 3140  
3126   - discardGeneration(this->obj_renumber, this->obj_renumber_no_gen);
  3141 + discardGeneration(this->m->obj_renumber, this->m->obj_renumber_no_gen);
3127 3142  
3128 3143 if (pass == 1)
3129 3144 {
3130   - if (this->deterministic_id)
  3145 + if (this->m->deterministic_id)
3131 3146 {
3132 3147 QTC::TC("qpdf", "QPDFWriter linearized deterministic ID",
3133 3148 need_xref_stream ? 0 : 1);
3134 3149 computeDeterministicIDData();
3135 3150 popPipelineStack();
3136   - assert(this->md5_pipeline == 0);
  3151 + assert(this->m->md5_pipeline == 0);
3137 3152 }
3138 3153  
3139 3154 // Close first pass pipeline
3140   - file_size = this->pipeline->getCount();
  3155 + file_size = this->m->pipeline->getCount();
3141 3156 popPipelineStack();
3142 3157  
3143 3158 // Save hint offset since it will be set to zero by
3144 3159 // calling openObject.
3145   - qpdf_offset_t hint_offset = this->xref[hint_id].getOffset();
  3160 + qpdf_offset_t hint_offset = this->m->xref[hint_id].getOffset();
3146 3161  
3147 3162 // Write hint stream to a buffer
3148 3163 pushPipeline(new Pl_Buffer("hint buffer"));
... ... @@ -3152,7 +3167,7 @@ QPDFWriter::writeLinearized()
3152 3167 hint_length = hint_buffer->getSize();
3153 3168  
3154 3169 // Restore hint offset
3155   - this->xref[hint_id] = QPDFXRefEntry(1, hint_offset, 0);
  3170 + this->m->xref[hint_id] = QPDFXRefEntry(1, hint_offset, 0);
3156 3171 }
3157 3172 }
3158 3173 }
... ... @@ -3160,10 +3175,10 @@ QPDFWriter::writeLinearized()
3160 3175 void
3161 3176 QPDFWriter::enqueueObjectsStandard()
3162 3177 {
3163   - if (this->preserve_unreferenced_objects)
  3178 + if (this->m->preserve_unreferenced_objects)
3164 3179 {
3165 3180 QTC::TC("qpdf", "QPDFWriter preserve unreferenced standard");
3166   - std::vector<QPDFObjectHandle> all = this->pdf.getAllObjects();
  3181 + std::vector<QPDFObjectHandle> all = this->m->pdf.getAllObjects();
3167 3182 for (std::vector<QPDFObjectHandle>::iterator iter = all.begin();
3168 3183 iter != all.end(); ++iter)
3169 3184 {
... ... @@ -3196,7 +3211,7 @@ QPDFWriter::enqueueObjectsPCLm()
3196 3211 std::string image_transform_content = "q /image Do Q\n";
3197 3212  
3198 3213 // enqueue all pages first
3199   - std::vector<QPDFObjectHandle> all = this->pdf.getAllPages();
  3214 + std::vector<QPDFObjectHandle> all = this->m->pdf.getAllPages();
3200 3215 for (std::vector<QPDFObjectHandle>::iterator iter = all.begin();
3201 3216 iter != all.end(); ++iter)
3202 3217 {
... ... @@ -3215,7 +3230,7 @@ QPDFWriter::enqueueObjectsPCLm()
3215 3230 {
3216 3231 enqueueObject(strips.getKey(*image));
3217 3232 enqueueObject(QPDFObjectHandle::newStream(
3218   - &pdf, image_transform_content));
  3233 + &this->m->pdf, image_transform_content));
3219 3234 }
3220 3235 }
3221 3236  
... ... @@ -3227,7 +3242,7 @@ QPDFWriter::enqueueObjectsPCLm()
3227 3242 void
3228 3243 QPDFWriter::writeStandard()
3229 3244 {
3230   - if (this->deterministic_id)
  3245 + if (this->m->deterministic_id)
3231 3246 {
3232 3247 pushMD5Pipeline();
3233 3248 }
... ... @@ -3235,9 +3250,9 @@ QPDFWriter::writeStandard()
3235 3250 // Start writing
3236 3251  
3237 3252 writeHeader();
3238   - writeString(this->extra_header_text);
  3253 + writeString(this->m->extra_header_text);
3239 3254  
3240   - if (this->pclm)
  3255 + if (this->m->pclm)
3241 3256 {
3242 3257 enqueueObjectsPCLm();
3243 3258 }
... ... @@ -3249,42 +3264,43 @@ QPDFWriter::writeStandard()
3249 3264 // Now start walking queue, outputing each object. There shouldn't
3250 3265 // really be any here, but this will catch anything that somehow
3251 3266 // got missed.
3252   - while (this->object_queue.size())
  3267 + while (this->m->object_queue.size())
3253 3268 {
3254   - QPDFObjectHandle cur_object = this->object_queue.front();
3255   - this->object_queue.pop_front();
  3269 + QPDFObjectHandle cur_object = this->m->object_queue.front();
  3270 + this->m->object_queue.pop_front();
3256 3271 writeObject(cur_object);
3257 3272 }
3258 3273  
3259 3274 // Write out the encryption dictionary, if any
3260   - if (this->encrypted)
  3275 + if (this->m->encrypted)
3261 3276 {
3262 3277 writeEncryptionDictionary();
3263 3278 }
3264 3279  
3265 3280 // Now write out xref. next_objid is now the number of objects.
3266   - qpdf_offset_t xref_offset = this->pipeline->getCount();
3267   - if (this->object_stream_to_objects.empty())
  3281 + qpdf_offset_t xref_offset = this->m->pipeline->getCount();
  3282 + if (this->m->object_stream_to_objects.empty())
3268 3283 {
3269 3284 // Write regular cross-reference table
3270   - writeXRefTable(t_normal, 0, this->next_objid - 1, this->next_objid);
  3285 + writeXRefTable(t_normal, 0, this->m->next_objid - 1,
  3286 + this->m->next_objid);
3271 3287 }
3272 3288 else
3273 3289 {
3274 3290 // Write cross-reference stream.
3275   - int xref_id = this->next_objid++;
  3291 + int xref_id = this->m->next_objid++;
3276 3292 writeXRefStream(xref_id, xref_id, xref_offset, t_normal,
3277   - 0, this->next_objid - 1, this->next_objid);
  3293 + 0, this->m->next_objid - 1, this->m->next_objid);
3278 3294 }
3279 3295 writeString("startxref\n");
3280 3296 writeString(QUtil::int_to_string(xref_offset));
3281 3297 writeString("\n%%EOF\n");
3282 3298  
3283   - if (this->deterministic_id)
  3299 + if (this->m->deterministic_id)
3284 3300 {
3285 3301 QTC::TC("qpdf", "QPDFWriter standard deterministic ID",
3286   - this->object_stream_to_objects.empty() ? 0 : 1);
  3302 + this->m->object_stream_to_objects.empty() ? 0 : 1);
3287 3303 popPipelineStack();
3288   - assert(this->md5_pipeline == 0);
  3304 + assert(this->m->md5_pipeline == 0);
3289 3305 }
3290 3306 }
... ...