summaryrefslogtreecommitdiffstats
path: root/libqpdf
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2017-08-22 03:33:44 +0200
committerJay Berkenbilt <ejb@ql.org>2017-08-22 03:35:11 +0200
commita8c93bd324d0362a26c1e6591eead5c52f865c0d (patch)
treeb3eda018bb384479c109640f442c94bc3d84ac0b /libqpdf
parent8288a4eb3a326acced6f07b0caf75f6ada53150d (diff)
downloadqpdf-a8c93bd324d0362a26c1e6591eead5c52f865c0d.tar.zst
Push QPDF member variables into a nested class
Pushing member variables into a nested class enables addition of new member variables without breaking binary compatibility.
Diffstat (limited to 'libqpdf')
-rw-r--r--libqpdf/QPDF.cc514
-rw-r--r--libqpdf/QPDF_encryption.cc176
-rw-r--r--libqpdf/QPDF_linearization.cc440
-rw-r--r--libqpdf/QPDF_optimization.cc62
-rw-r--r--libqpdf/QPDF_pages.cc82
5 files changed, 654 insertions, 620 deletions
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index 9c79fc3a..f6e62546 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -74,7 +74,7 @@ QPDF::QPDFVersion()
return QPDF::qpdf_version;
}
-QPDF::QPDF() :
+QPDF::Members::Members() :
encrypted(false),
encryption_initialized(false),
ignore_xref_streams(false),
@@ -98,6 +98,15 @@ QPDF::QPDF() :
{
}
+QPDF::Members::~Members()
+{
+}
+
+QPDF::QPDF() :
+ m(new Members())
+{
+}
+
QPDF::~QPDF()
{
// If two objects are mutually referential (through each object
@@ -114,10 +123,10 @@ QPDF::~QPDF()
// reference will reread the object from the file, which would
// have the effect of undoing any modifications that may have been
// made to any of the objects.
- this->xref_table.clear();
+ this->m->xref_table.clear();
for (std::map<QPDFObjGen, ObjCache>::iterator iter =
- this->obj_cache.begin();
- iter != obj_cache.end(); ++iter)
+ this->m->obj_cache.begin();
+ iter != this->m->obj_cache.end(); ++iter)
{
QPDFObject::ObjAccessor::releaseResolved(
(*iter).second.object.getPointer());
@@ -158,7 +167,7 @@ void
QPDF::processInputSource(PointerHolder<InputSource> source,
char const* password)
{
- this->file = source;
+ this->m->file = source;
parse(password);
}
@@ -171,41 +180,41 @@ QPDF::emptyPDF()
void
QPDF::setIgnoreXRefStreams(bool val)
{
- this->ignore_xref_streams = val;
+ this->m->ignore_xref_streams = val;
}
void
QPDF::setOutputStreams(std::ostream* out, std::ostream* err)
{
- this->out_stream = out ? out : &std::cout;
- this->err_stream = err ? err : &std::cerr;
+ this->m->out_stream = out ? out : &std::cout;
+ this->m->err_stream = err ? err : &std::cerr;
}
void
QPDF::setSuppressWarnings(bool val)
{
- this->suppress_warnings = val;
+ this->m->suppress_warnings = val;
}
void
QPDF::setAttemptRecovery(bool val)
{
- this->attempt_recovery = val;
+ this->m->attempt_recovery = val;
}
std::vector<QPDFExc>
QPDF::getWarnings()
{
- std::vector<QPDFExc> result = this->warnings;
- this->warnings.clear();
+ std::vector<QPDFExc> result = this->m->warnings;
+ this->m->warnings.clear();
return result;
}
bool
QPDF::findHeader()
{
- qpdf_offset_t global_offset = this->file->tell();
- std::string line = this->file->readLine(1024);
+ qpdf_offset_t global_offset = this->m->file->tell();
+ std::string line = this->m->file->readLine(1024);
char const* p = line.c_str();
if (strncmp(p, "%PDF-", 5) != 0)
{
@@ -239,7 +248,7 @@ QPDF::findHeader()
}
if (valid)
{
- this->pdf_version = version;
+ this->m->pdf_version = version;
if (global_offset != 0)
{
// Empirical evidence strongly suggests that when there is
@@ -247,7 +256,7 @@ QPDF::findHeader()
// offsets in the file are such that 0 points to the
// beginning of the header.
QTC::TC("qpdf", "QPDF global offset");
- this->file = new OffsetInputSource(this->file, global_offset);
+ this->m->file = new OffsetInputSource(this->m->file, global_offset);
}
}
return valid;
@@ -256,14 +265,14 @@ QPDF::findHeader()
bool
QPDF::findStartxref()
{
- QPDFTokenizer::Token t = readToken(this->file, true);
+ QPDFTokenizer::Token t = readToken(this->m->file, true);
if (t == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "startxref"))
{
- t = readToken(this->file, true);
+ t = readToken(this->m->file, true);
if (t.getType() == QPDFTokenizer::tt_integer)
{
// Position in front of offset token
- this->file->seek(this->file->getLastOffset(), SEEK_SET);
+ this->m->file->seek(this->m->file->getLastOffset(), SEEK_SET);
return true;
}
}
@@ -275,37 +284,37 @@ QPDF::parse(char const* password)
{
if (password)
{
- this->provided_password = password;
+ this->m->provided_password = password;
}
// Find the header anywhere in the first 1024 bytes of the file.
PatternFinder hf(*this, &QPDF::findHeader);
- if (! this->file->findFirst("%PDF-", 0, 1024, hf))
+ if (! this->m->file->findFirst("%PDF-", 0, 1024, hf))
{
QTC::TC("qpdf", "QPDF not a pdf file");
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"", 0, "can't find PDF header"));
// QPDFWriter writes files that usually require at least
// version 1.2 for /FlateDecode
- this->pdf_version = "1.2";
+ this->m->pdf_version = "1.2";
}
- if (atof(this->pdf_version.c_str()) < 1.2)
+ if (atof(this->m->pdf_version.c_str()) < 1.2)
{
- this->tokenizer.allowPoundAnywhereInName();
+ this->m->tokenizer.allowPoundAnywhereInName();
}
// PDF spec says %%EOF must be found within the last 1024 bytes of
// the file. We add an extra 30 characters to leave room for the
// startxref stuff.
- this->file->seek(0, SEEK_END);
- qpdf_offset_t end_offset = this->file->tell();
+ this->m->file->seek(0, SEEK_END);
+ qpdf_offset_t end_offset = this->m->file->tell();
qpdf_offset_t start_offset = (end_offset > 1054 ? end_offset - 1054 : 0);
PatternFinder sf(*this, &QPDF::findStartxref);
qpdf_offset_t xref_offset = 0;
- if (this->file->findLast("startxref", start_offset, 0, sf))
+ if (this->m->file->findLast("startxref", start_offset, 0, sf))
{
xref_offset = QUtil::string_to_ll(
- readToken(this->file).getValue().c_str());
+ readToken(this->m->file).getValue().c_str());
}
try
@@ -313,14 +322,14 @@ QPDF::parse(char const* password)
if (xref_offset == 0)
{
QTC::TC("qpdf", "QPDF can't find startxref");
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0,
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0,
"can't find startxref");
}
read_xref(xref_offset);
}
catch (QPDFExc& e)
{
- if (this->attempt_recovery)
+ if (this->m->attempt_recovery)
{
reconstruct_xref(e);
QTC::TC("qpdf", "QPDF reconstructed xref table");
@@ -338,28 +347,29 @@ QPDF::parse(char const* password)
void
QPDF::warn(QPDFExc const& e)
{
- this->warnings.push_back(e);
- if (! this->suppress_warnings)
+ this->m->warnings.push_back(e);
+ if (! this->m->suppress_warnings)
{
- *err_stream << "WARNING: "
- << this->warnings.back().what() << std::endl;
+ *this->m->err_stream
+ << "WARNING: "
+ << this->m->warnings.back().what() << std::endl;
}
}
void
QPDF::setTrailer(QPDFObjectHandle obj)
{
- if (this->trailer.isInitialized())
+ if (this->m->trailer.isInitialized())
{
return;
}
- this->trailer = obj;
+ this->m->trailer = obj;
}
void
QPDF::reconstruct_xref(QPDFExc& e)
{
- if (this->reconstructed_xref)
+ if (this->m->reconstructed_xref)
{
// Avoid xref reconstruction infinite loops. This is getting
// very hard to reproduce because qpdf is throwing many fewer
@@ -367,19 +377,19 @@ QPDF::reconstruct_xref(QPDFExc& e)
throw e;
}
- this->reconstructed_xref = true;
+ this->m->reconstructed_xref = true;
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0,
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0,
"file is damaged"));
warn(e);
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0,
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0,
"Attempting to reconstruct cross-reference table"));
// Delete all references to type 1 (uncompressed) objects
std::set<QPDFObjGen> to_delete;
for (std::map<QPDFObjGen, QPDFXRefEntry>::iterator iter =
- this->xref_table.begin();
- iter != this->xref_table.end(); ++iter)
+ this->m->xref_table.begin();
+ iter != this->m->xref_table.end(); ++iter)
{
if (((*iter).second).getType() == 1)
{
@@ -389,21 +399,22 @@ QPDF::reconstruct_xref(QPDFExc& e)
for (std::set<QPDFObjGen>::iterator iter = to_delete.begin();
iter != to_delete.end(); ++iter)
{
- this->xref_table.erase(*iter);
+ this->m->xref_table.erase(*iter);
}
- this->file->seek(0, SEEK_END);
- qpdf_offset_t eof = this->file->tell();
- this->file->seek(0, SEEK_SET);
+ this->m->file->seek(0, SEEK_END);
+ qpdf_offset_t eof = this->m->file->tell();
+ this->m->file->seek(0, SEEK_SET);
bool in_obj = false;
qpdf_offset_t line_start = 0;
- while (this->file->tell() < eof)
- {
- this->file->findAndSkipNextEOL();
- qpdf_offset_t next_line_start = this->file->tell();
- this->file->seek(line_start, SEEK_SET);
- QPDFTokenizer::Token t1 = readToken(this->file, true);
- qpdf_offset_t token_start = this->file->tell() - t1.getValue().length();
+ while (this->m->file->tell() < eof)
+ {
+ this->m->file->findAndSkipNextEOL();
+ qpdf_offset_t next_line_start = this->m->file->tell();
+ this->m->file->seek(line_start, SEEK_SET);
+ QPDFTokenizer::Token t1 = readToken(this->m->file, true);
+ qpdf_offset_t token_start =
+ this->m->file->tell() - t1.getValue().length();
if (token_start >= next_line_start)
{
// don't process yet
@@ -419,8 +430,8 @@ QPDF::reconstruct_xref(QPDFExc& e)
{
if (t1.getType() == QPDFTokenizer::tt_integer)
{
- QPDFTokenizer::Token t2 = readToken(this->file, true);
- QPDFTokenizer::Token t3 = readToken(this->file, true);
+ QPDFTokenizer::Token t2 = readToken(this->m->file, true);
+ QPDFTokenizer::Token t3 = readToken(this->m->file, true);
if ((t2.getType() == QPDFTokenizer::tt_integer) &&
(t3 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "obj")))
{
@@ -430,11 +441,12 @@ QPDF::reconstruct_xref(QPDFExc& e)
insertXrefEntry(obj, 1, token_start, gen, true);
}
}
- else if ((! this->trailer.isInitialized()) &&
- (t1 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "trailer")))
+ else if ((! this->m->trailer.isInitialized()) &&
+ (t1 == QPDFTokenizer::Token(
+ QPDFTokenizer::tt_word, "trailer")))
{
QPDFObjectHandle t =
- readObject(this->file, "trailer", 0, 0, false);
+ readObject(this->m->file, "trailer", 0, 0, false);
if (! t.isDictionary())
{
// Oh well. It was worth a try.
@@ -445,11 +457,11 @@ QPDF::reconstruct_xref(QPDFExc& e)
}
}
}
- this->file->seek(next_line_start, SEEK_SET);
+ this->m->file->seek(next_line_start, SEEK_SET);
line_start = next_line_start;
}
- if (! this->trailer.isInitialized())
+ if (! this->m->trailer.isInitialized())
{
// We could check the last encountered object to see if it was
// an xref stream. If so, we could try to get the trailer
@@ -457,7 +469,7 @@ QPDF::reconstruct_xref(QPDFExc& e)
// with bad startxref pointers even when they have object
// streams.
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0,
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0,
"unable to find trailer "
"dictionary while recovering damaged file");
}
@@ -479,8 +491,8 @@ QPDF::read_xref(qpdf_offset_t xref_offset)
{
char buf[7];
memset(buf, 0, sizeof(buf));
- this->file->seek(xref_offset, SEEK_SET);
- this->file->read(buf, sizeof(buf) - 1);
+ this->m->file->seek(xref_offset, SEEK_SET);
+ this->m->file->read(buf, sizeof(buf) - 1);
// The PDF spec says xref must be followed by a line
// terminator, but files exist in the wild where it is
// terminated by arbitrary whitespace.
@@ -506,25 +518,25 @@ QPDF::read_xref(qpdf_offset_t xref_offset)
}
}
- if (! this->trailer.isInitialized())
+ if (! this->m->trailer.isInitialized())
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0,
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0,
"unable to find trailer while reading xref");
}
- int size = this->trailer.getKey("/Size").getIntValue();
+ int size = this->m->trailer.getKey("/Size").getIntValue();
int max_obj = 0;
- if (! xref_table.empty())
+ if (! this->m->xref_table.empty())
{
- max_obj = (*(xref_table.rbegin())).first.getObj();
+ max_obj = (*(this->m->xref_table.rbegin())).first.getObj();
}
- if (! this->deleted_objects.empty())
+ if (! this->m->deleted_objects.empty())
{
- max_obj = std::max(max_obj, *(this->deleted_objects.rbegin()));
+ max_obj = std::max(max_obj, *(this->m->deleted_objects.rbegin()));
}
if (size != max_obj + 1)
{
QTC::TC("qpdf", "QPDF xref size mismatch");
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0,
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0,
std::string("reported number of objects (") +
QUtil::int_to_string(size) +
") inconsistent with actual number of objects (" +
@@ -533,7 +545,7 @@ QPDF::read_xref(qpdf_offset_t xref_offset)
// We no longer need the deleted_objects table, so go ahead and
// clear it out to make sure we never depend on its being set.
- this->deleted_objects.clear();
+ this->m->deleted_objects.clear();
}
bool
@@ -677,9 +689,9 @@ QPDF::parse_xrefEntry(std::string const& line,
if (invalid)
{
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"xref table",
- this->file->getLastOffset(),
+ this->m->file->getLastOffset(),
"accepting invalid xref table entry"));
}
@@ -694,13 +706,13 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
{
std::vector<QPDFObjGen> deleted_items;
- this->file->seek(xref_offset, SEEK_SET);
+ this->m->file->seek(xref_offset, SEEK_SET);
bool done = false;
while (! done)
{
char linebuf[51];
memset(linebuf, 0, sizeof(linebuf));
- this->file->read(linebuf, sizeof(linebuf) - 1);
+ this->m->file->read(linebuf, sizeof(linebuf) - 1);
std::string line = linebuf;
int obj = 0;
int num = 0;
@@ -708,19 +720,19 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
if (! parse_xrefFirst(line, obj, num, bytes))
{
QTC::TC("qpdf", "QPDF invalid xref");
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "xref table", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "xref table", this->m->file->getLastOffset(),
"xref syntax invalid");
}
- this->file->seek(this->file->getLastOffset() + bytes, SEEK_SET);
+ this->m->file->seek(this->m->file->getLastOffset() + bytes, SEEK_SET);
for (int i = obj; i < obj + num; ++i)
{
if (i == 0)
{
// This is needed by checkLinearization()
- this->first_xref_item_offset = this->file->tell();
+ this->m->first_xref_item_offset = this->m->file->tell();
}
- std::string xref_entry = this->file->readLine(30);
+ std::string xref_entry = this->m->file->readLine(30);
// For xref_table, these will always be small enough to be ints
qpdf_offset_t f1 = 0;
int f2 = 0;
@@ -729,8 +741,8 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
{
QTC::TC("qpdf", "QPDF invalid xref entry");
throw QPDFExc(
- qpdf_e_damaged_pdf, this->file->getName(),
- "xref table", this->file->getLastOffset(),
+ qpdf_e_damaged_pdf, this->m->file->getName(),
+ "xref table", this->m->file->getLastOffset(),
"invalid xref entry (obj=" +
QUtil::int_to_string(i) + ")");
}
@@ -745,45 +757,45 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
insertXrefEntry(i, 1, f1, f2);
}
}
- qpdf_offset_t pos = this->file->tell();
- QPDFTokenizer::Token t = readToken(this->file);
+ qpdf_offset_t pos = this->m->file->tell();
+ QPDFTokenizer::Token t = readToken(this->m->file);
if (t == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "trailer"))
{
done = true;
}
else
{
- this->file->seek(pos, SEEK_SET);
+ this->m->file->seek(pos, SEEK_SET);
}
}
// Set offset to previous xref table if any
QPDFObjectHandle cur_trailer =
- readObject(this->file, "trailer", 0, 0, false);
+ readObject(this->m->file, "trailer", 0, 0, false);
if (! cur_trailer.isDictionary())
{
QTC::TC("qpdf", "QPDF missing trailer");
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "", this->m->file->getLastOffset(),
"expected trailer dictionary");
}
- if (! this->trailer.isInitialized())
+ if (! this->m->trailer.isInitialized())
{
setTrailer(cur_trailer);
- if (! this->trailer.hasKey("/Size"))
+ if (! this->m->trailer.hasKey("/Size"))
{
QTC::TC("qpdf", "QPDF trailer lacks size");
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "trailer", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "trailer", this->m->file->getLastOffset(),
"trailer dictionary lacks /Size key");
}
- if (! this->trailer.getKey("/Size").isInteger())
+ if (! this->m->trailer.getKey("/Size").isInteger())
{
QTC::TC("qpdf", "QPDF trailer size not integer");
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "trailer", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "trailer", this->m->file->getLastOffset(),
"/Size key in trailer dictionary is not "
"an integer");
}
@@ -791,7 +803,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
if (cur_trailer.hasKey("/XRefStm"))
{
- if (this->ignore_xref_streams)
+ if (this->m->ignore_xref_streams)
{
QTC::TC("qpdf", "QPDF ignoring XRefStm in trailer");
}
@@ -807,7 +819,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
}
else
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"xref stream", xref_offset,
"invalid /XRefStm");
}
@@ -827,8 +839,8 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
if (! cur_trailer.getKey("/Prev").isInteger())
{
QTC::TC("qpdf", "QPDF trailer prev not integer");
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "trailer", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "trailer", this->m->file->getLastOffset(),
"/Prev key in trailer dictionary is not "
"an integer");
}
@@ -847,7 +859,7 @@ qpdf_offset_t
QPDF::read_xrefStream(qpdf_offset_t xref_offset)
{
bool found = false;
- if (! this->ignore_xref_streams)
+ if (! this->m->ignore_xref_streams)
{
int xobj;
int xgen;
@@ -875,7 +887,7 @@ QPDF::read_xrefStream(qpdf_offset_t xref_offset)
if (! found)
{
QTC::TC("qpdf", "QPDF can't find xref");
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"", xref_offset, "xref not found");
}
@@ -896,7 +908,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
dict.getKey("/Size").isInteger() &&
(Index_obj.isArray() || Index_obj.isNull())))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"xref stream", xref_offset,
"Cross-reference stream does not have"
" proper /W and /Index keys");
@@ -910,7 +922,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
W[i] = W_obj.getArrayItem(i).getIntValue();
if (W[i] > max_bytes)
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"xref stream", xref_offset,
"Cross-reference stream's /W contains"
" impossibly large values");
@@ -919,7 +931,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
}
if (entry_size == 0)
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"xref stream", xref_offset,
"Cross-reference stream's /W indicates"
" entry size of 0");
@@ -933,7 +945,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
int n_index = Index_obj.getArrayNItems();
if ((n_index % 2) || (n_index < 2))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"xref stream", xref_offset,
"Cross-reference stream's /Index has an"
" invalid number of values");
@@ -946,7 +958,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
}
else
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"xref stream", xref_offset,
"Cross-reference stream's /Index's item " +
QUtil::int_to_string(i) +
@@ -969,7 +981,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
{
if (indx.at(i) > max_num_entries - num_entries)
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"xref stream", xref_offset,
"Cross-reference stream claims to contain"
" too many entries: " +
@@ -989,7 +1001,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
if (expected_size != actual_size)
{
- QPDFExc x(qpdf_e_damaged_pdf, this->file->getName(),
+ QPDFExc x(qpdf_e_damaged_pdf, this->m->file->getName(),
"xref stream", xref_offset,
"Cross-reference stream data has the wrong size;"
" expected = " + QUtil::int_to_string(expected_size) +
@@ -1050,7 +1062,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
{
if (fields[0] != 2)
{
- this->uncompressed_after_compressed = true;
+ this->m->uncompressed_after_compressed = true;
}
}
else if (fields[0] == 2)
@@ -1060,13 +1072,13 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
if (obj == 0)
{
// This is needed by checkLinearization()
- this->first_xref_item_offset = xref_offset;
+ this->m->first_xref_item_offset = xref_offset;
}
insertXrefEntry(obj, static_cast<int>(fields[0]),
fields[1], static_cast<int>(fields[2]));
}
- if (! this->trailer.isInitialized())
+ if (! this->m->trailer.isInitialized())
{
setTrailer(dict);
}
@@ -1075,8 +1087,8 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
{
if (! dict.getKey("/Prev").isInteger())
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "xref stream", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "xref stream", this->m->file->getLastOffset(),
"/Prev key in xref stream dictionary is not "
"an integer");
}
@@ -1108,12 +1120,12 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite)
{ // private scope
int gen = (f0 == 2 ? 0 : f2);
QPDFObjGen og(obj, gen);
- if (this->xref_table.count(og))
+ if (this->m->xref_table.count(og))
{
if (overwrite)
{
QTC::TC("qpdf", "QPDF xref overwrite object");
- this->xref_table.erase(og);
+ this->m->xref_table.erase(og);
}
else
{
@@ -1121,7 +1133,7 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite)
return;
}
}
- if (this->deleted_objects.count(obj))
+ if (this->m->deleted_objects.count(obj))
{
QTC::TC("qpdf", "QPDF xref deleted object");
return;
@@ -1131,22 +1143,22 @@ QPDF::insertXrefEntry(int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite)
switch (f0)
{
case 0:
- this->deleted_objects.insert(obj);
+ this->m->deleted_objects.insert(obj);
break;
case 1:
// f2 is generation
QTC::TC("qpdf", "QPDF xref gen > 0", ((f2 > 0) ? 1 : 0));
- this->xref_table[QPDFObjGen(obj, f2)] = QPDFXRefEntry(f0, f1, f2);
+ this->m->xref_table[QPDFObjGen(obj, f2)] = QPDFXRefEntry(f0, f1, f2);
break;
case 2:
- this->xref_table[QPDFObjGen(obj, 0)] = QPDFXRefEntry(f0, f1, f2);
+ this->m->xref_table[QPDFObjGen(obj, 0)] = QPDFXRefEntry(f0, f1, f2);
break;
default:
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "xref stream", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "xref stream", this->m->file->getLastOffset(),
"unknown xref stream entry type " +
QUtil::int_to_string(f0));
break;
@@ -1157,21 +1169,24 @@ void
QPDF::showXRefTable()
{
for (std::map<QPDFObjGen, QPDFXRefEntry>::iterator iter =
- this->xref_table.begin();
- iter != this->xref_table.end(); ++iter)
+ this->m->xref_table.begin();
+ iter != this->m->xref_table.end(); ++iter)
{
QPDFObjGen const& og = (*iter).first;
QPDFXRefEntry const& entry = (*iter).second;
- *out_stream << og.getObj() << "/" << og.getGen() << ": ";
+ *this->m->out_stream << og.getObj() << "/" << og.getGen() << ": ";
switch (entry.getType())
{
case 1:
- *out_stream << "uncompressed; offset = " << entry.getOffset();
+ *this->m->out_stream
+ << "uncompressed; offset = " << entry.getOffset();
break;
case 2:
- *out_stream << "compressed; stream = " << entry.getObjStreamNumber()
- << ", index = " << entry.getObjStreamIndex();
+ *this->m->out_stream
+ << "compressed; stream = "
+ << entry.getObjStreamNumber()
+ << ", index = " << entry.getObjStreamIndex();
break;
default:
@@ -1179,7 +1194,7 @@ QPDF::showXRefTable()
" showing xref_table");
break;
}
- *out_stream << std::endl;
+ *this->m->out_stream << std::endl;
}
}
@@ -1188,8 +1203,8 @@ QPDF::getAllObjects()
{
std::vector<QPDFObjectHandle> result;
for (std::map<QPDFObjGen, QPDFXRefEntry>::iterator iter =
- this->xref_table.begin();
- iter != this->xref_table.end(); ++iter)
+ this->m->xref_table.begin();
+ iter != this->m->xref_table.end(); ++iter)
{
QPDFObjGen const& og = (*iter).first;
@@ -1203,18 +1218,18 @@ void
QPDF::setLastObjectDescription(std::string const& description,
int objid, int generation)
{
- this->last_object_description.clear();
+ this->m->last_object_description.clear();
if (! description.empty())
{
- this->last_object_description += description;
+ this->m->last_object_description += description;
if (objid > 0)
{
- this->last_object_description += ": ";
+ this->m->last_object_description += ": ";
}
}
if (objid > 0)
{
- this->last_object_description += "object " +
+ this->m->last_object_description += "object " +
QUtil::int_to_string(objid) + " " +
QUtil::int_to_string(generation);
}
@@ -1231,20 +1246,20 @@ QPDF::readObject(PointerHolder<InputSource> input,
bool empty = false;
PointerHolder<StringDecrypter> decrypter_ph;
StringDecrypter* decrypter = 0;
- if (this->encrypted && (! in_object_stream))
+ if (this->m->encrypted && (! in_object_stream))
{
decrypter_ph = new StringDecrypter(this, objid, generation);
decrypter = decrypter_ph.getPointer();
}
QPDFObjectHandle object = QPDFObjectHandle::parse(
- input, description, this->tokenizer, empty, decrypter, this);
+ input, description, this->m->tokenizer, empty, decrypter, this);
if (empty)
{
// Nothing in the PDF spec appears to allow empty objects, but
// they have been encountered in actual PDF files and Adobe
// Reader appears to ignore them.
warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(),
- this->last_object_description,
+ this->m->last_object_description,
input->getLastOffset(),
"empty object treated as null"));
}
@@ -1299,7 +1314,7 @@ QPDF::readObject(PointerHolder<InputSource> input,
warn(QPDFExc(
qpdf_e_damaged_pdf,
input->getName(),
- this->last_object_description,
+ this->m->last_object_description,
input->tell(),
"stream keyword followed"
" by carriage return only"));
@@ -1315,7 +1330,7 @@ QPDF::readObject(PointerHolder<InputSource> input,
input->unreadCh(ch);
}
warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(),
- this->last_object_description,
+ this->m->last_object_description,
input->tell(),
"stream keyword not followed"
" by proper line terminator"));
@@ -1337,7 +1352,7 @@ QPDF::readObject(PointerHolder<InputSource> input,
{
QTC::TC("qpdf", "QPDF stream without length");
throw QPDFExc(qpdf_e_damaged_pdf, input->getName(),
- this->last_object_description, offset,
+ this->m->last_object_description, offset,
"stream dictionary lacks /Length key");
}
@@ -1346,7 +1361,7 @@ QPDF::readObject(PointerHolder<InputSource> input,
{
QTC::TC("qpdf", "QPDF stream length not integer");
throw QPDFExc(qpdf_e_damaged_pdf, input->getName(),
- this->last_object_description, offset,
+ this->m->last_object_description, offset,
"/Length key in stream dictionary is not "
"an integer");
}
@@ -1359,14 +1374,14 @@ QPDF::readObject(PointerHolder<InputSource> input,
{
QTC::TC("qpdf", "QPDF missing endstream");
throw QPDFExc(qpdf_e_damaged_pdf, input->getName(),
- this->last_object_description,
+ this->m->last_object_description,
input->getLastOffset(),
"expected endstream");
}
}
catch (QPDFExc& e)
{
- if (this->attempt_recovery)
+ if (this->m->attempt_recovery)
{
warn(e);
length = recoverStreamLength(
@@ -1396,12 +1411,12 @@ bool
QPDF::findEndstream()
{
// Find endstream or endobj. Position the input at that token.
- QPDFTokenizer::Token t = readToken(this->file, true);
+ QPDFTokenizer::Token t = readToken(this->m->file, true);
if ((t.getType() == QPDFTokenizer::tt_word) &&
((t.getValue() == "endobj") ||
(t.getValue() == "endstream")));
{
- this->file->seek(this->file->getLastOffset(), SEEK_SET);
+ this->m->file->seek(this->m->file->getLastOffset(), SEEK_SET);
return true;
}
return false;
@@ -1415,19 +1430,19 @@ QPDF::recoverStreamLength(PointerHolder<InputSource> input,
// Try to reconstruct stream length by looking for
// endstream or endobj
warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(),
- this->last_object_description, stream_offset,
+ this->m->last_object_description, stream_offset,
"attempting to recover stream length"));
PatternFinder ef(*this, &QPDF::findEndstream);
size_t length = 0;
- if (this->file->findFirst("end", stream_offset, 0, ef))
+ if (this->m->file->findFirst("end", stream_offset, 0, ef))
{
- length = this->file->tell() - stream_offset;
+ length = this->m->file->tell() - stream_offset;
// Reread endstream but, if it was endobj, don't skip that.
- QPDFTokenizer::Token t = readToken(this->file);
+ QPDFTokenizer::Token t = readToken(this->m->file);
if (t.getValue() == "endobj")
{
- this->file->seek(this->file->getLastOffset(), SEEK_SET);
+ this->m->file->seek(this->m->file->getLastOffset(), SEEK_SET);
}
}
@@ -1438,8 +1453,8 @@ QPDF::recoverStreamLength(PointerHolder<InputSource> input,
// Make sure this is inside this object
for (std::map<QPDFObjGen, QPDFXRefEntry>::iterator iter =
- this->xref_table.begin();
- iter != this->xref_table.end(); ++iter)
+ this->m->xref_table.begin();
+ iter != this->m->xref_table.end(); ++iter)
{
QPDFObjGen const& og = (*iter).first;
QPDFXRefEntry const& entry = (*iter).second;
@@ -1472,13 +1487,14 @@ QPDF::recoverStreamLength(PointerHolder<InputSource> input,
if (length == 0)
{
warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(),
- this->last_object_description, stream_offset,
- "unable to recover stream data; treating stream as empty"));
+ this->m->last_object_description, stream_offset,
+ "unable to recover stream data;"
+ " treating stream as empty"));
}
else
{
warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(),
- this->last_object_description, stream_offset,
+ this->m->last_object_description, stream_offset,
"recovered stream length: " +
QUtil::int_to_string(length)));
}
@@ -1490,8 +1506,8 @@ QPDF::recoverStreamLength(PointerHolder<InputSource> input,
QPDFTokenizer::Token
QPDF::readToken(PointerHolder<InputSource> input, bool allow_bad)
{
- return this->tokenizer.readToken(
- input, this->last_object_description, allow_bad);
+ return this->m->tokenizer.readToken(
+ input, this->m->last_object_description, allow_bad);
}
QPDFObjectHandle
@@ -1500,7 +1516,7 @@ QPDF::readObjectAtOffset(bool try_recovery,
int exp_objid, int exp_generation,
int& objid, int& generation)
{
- if (! this->attempt_recovery)
+ if (! this->m->attempt_recovery)
{
try_recovery = false;
}
@@ -1514,17 +1530,17 @@ QPDF::readObjectAtOffset(bool try_recovery,
if (offset == 0)
{
QTC::TC("qpdf", "QPDF bogus 0 offset", 0);
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description, 0,
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description, 0,
"object has offset 0"));
return QPDFObjectHandle::newNull();
}
- this->file->seek(offset, SEEK_SET);
+ this->m->file->seek(offset, SEEK_SET);
- QPDFTokenizer::Token tobjid = readToken(this->file);
- QPDFTokenizer::Token tgen = readToken(this->file);
- QPDFTokenizer::Token tobj = readToken(this->file);
+ QPDFTokenizer::Token tobjid = readToken(this->m->file);
+ QPDFTokenizer::Token tgen = readToken(this->m->file);
+ QPDFTokenizer::Token tobj = readToken(this->m->file);
bool objidok = (tobjid.getType() == QPDFTokenizer::tt_integer);
int genok = (tgen.getType() == QPDFTokenizer::tt_integer);
@@ -1539,8 +1555,8 @@ QPDF::readObjectAtOffset(bool try_recovery,
if (! (objidok && genok && objok))
{
QTC::TC("qpdf", "QPDF expected n n obj");
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description, offset,
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description, offset,
"expected n n obj");
}
objid = atoi(tobjid.getValue().c_str());
@@ -1549,8 +1565,8 @@ QPDF::readObjectAtOffset(bool try_recovery,
if (objid == 0)
{
QTC::TC("qpdf", "QPDF object id 0");
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description, offset,
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description, offset,
"object with ID 0");
}
@@ -1558,8 +1574,8 @@ QPDF::readObjectAtOffset(bool try_recovery,
(! ((objid == exp_objid) && (generation == exp_generation))))
{
QTC::TC("qpdf", "QPDF err wrong objid/generation");
- QPDFExc e(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description, offset,
+ QPDFExc e(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description, offset,
std::string("expected ") +
QUtil::int_to_string(exp_objid) + " " +
QUtil::int_to_string(exp_generation) + " obj");
@@ -1583,10 +1599,10 @@ QPDF::readObjectAtOffset(bool try_recovery,
// Try again after reconstructing xref table
reconstruct_xref(e);
QPDFObjGen og(exp_objid, exp_generation);
- if (this->xref_table.count(og) &&
- (this->xref_table[og].getType() == 1))
+ if (this->m->xref_table.count(og) &&
+ (this->m->xref_table[og].getType() == 1))
{
- qpdf_offset_t new_offset = this->xref_table[og].getOffset();
+ qpdf_offset_t new_offset = this->m->xref_table[og].getOffset();
QPDFObjectHandle result = readObjectAtOffset(
false, new_offset, description,
exp_objid, exp_generation, objid, generation);
@@ -1597,7 +1613,7 @@ QPDF::readObjectAtOffset(bool try_recovery,
{
QTC::TC("qpdf", "QPDF object gone after xref reconstruction");
warn(QPDFExc(
- qpdf_e_damaged_pdf, this->file->getName(),
+ qpdf_e_damaged_pdf, this->m->file->getName(),
"", 0,
std::string(
"object " +
@@ -1616,19 +1632,20 @@ QPDF::readObjectAtOffset(bool try_recovery,
}
QPDFObjectHandle oh = readObject(
- this->file, description, objid, generation, false);
+ this->m->file, description, objid, generation, false);
- if (! (readToken(this->file) ==
+ if (! (readToken(this->m->file) ==
QPDFTokenizer::Token(QPDFTokenizer::tt_word, "endobj")))
{
QTC::TC("qpdf", "QPDF err expected endobj");
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description, this->file->getLastOffset(),
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description,
+ this->m->file->getLastOffset(),
"expected endobj"));
}
QPDFObjGen og(objid, generation);
- if (! this->obj_cache.count(og))
+ if (! this->m->obj_cache.count(og))
{
// Store the object in the cache here so it gets cached
// whether we first know the offset or whether we first know
@@ -1640,30 +1657,30 @@ QPDF::readObjectAtOffset(bool try_recovery,
// linearization hint tables. Offsets and lengths of objects
// may imply the end of an object to be anywhere between these
// values.
- qpdf_offset_t end_before_space = this->file->tell();
+ qpdf_offset_t end_before_space = this->m->file->tell();
// skip over spaces
while (true)
{
char ch;
- if (this->file->read(&ch, 1))
+ if (this->m->file->read(&ch, 1))
{
if (! isspace(static_cast<unsigned char>(ch)))
{
- this->file->seek(-1, SEEK_CUR);
+ this->m->file->seek(-1, SEEK_CUR);
break;
}
}
else
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description, offset,
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description, offset,
"EOF after endobj");
}
}
- qpdf_offset_t end_after_space = this->file->tell();
+ qpdf_offset_t end_after_space = this->m->file->tell();
- this->obj_cache[og] =
+ this->m->obj_cache[og] =
ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh),
end_before_space, end_after_space);
}
@@ -1678,14 +1695,14 @@ QPDF::resolve(int objid, int generation)
// to insert things into the object cache that don't actually
// exist in the file.
QPDFObjGen og(objid, generation);
- if (this->resolving.count(og))
+ if (this->m->resolving.count(og))
{
// This can happen if an object references itself directly or
// indirectly in some key that has to be resolved during
// object parsing, such as stream length.
QTC::TC("qpdf", "QPDF recursion loop in resolve");
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "", this->file->getLastOffset(),
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "", this->m->file->getLastOffset(),
"loop detected resolving object " +
QUtil::int_to_string(objid) + " " +
QUtil::int_to_string(generation)));
@@ -1693,15 +1710,15 @@ QPDF::resolve(int objid, int generation)
}
ResolveRecorder rr(this, og);
- if (! this->obj_cache.count(og))
+ if (! this->m->obj_cache.count(og))
{
- if (! this->xref_table.count(og))
+ if (! this->m->xref_table.count(og))
{
// PDF spec says unknown objects resolve to the null object.
return new QPDF_Null;
}
- QPDFXRefEntry const& entry = this->xref_table[og];
+ QPDFXRefEntry const& entry = this->m->xref_table[og];
bool success = false;
try
{
@@ -1724,7 +1741,8 @@ QPDF::resolve(int objid, int generation)
break;
default:
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0,
+ throw QPDFExc(qpdf_e_damaged_pdf,
+ this->m->file->getName(), "", 0,
"object " +
QUtil::int_to_string(objid) + "/" +
QUtil::int_to_string(generation) +
@@ -1738,7 +1756,7 @@ QPDF::resolve(int objid, int generation)
}
catch (std::exception& e)
{
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), "", 0,
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "", 0,
"object " +
QUtil::int_to_string(objid) + "/" +
QUtil::int_to_string(generation) +
@@ -1748,12 +1766,12 @@ QPDF::resolve(int objid, int generation)
{
QTC::TC("qpdf", "QPDF resolve failure to null");
QPDFObjectHandle oh = QPDFObjectHandle::newNull();
- this->obj_cache[og] =
+ this->m->obj_cache[og] =
ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1);
}
}
- return this->obj_cache[og].object;
+ return this->m->obj_cache[og].object;
}
void
@@ -1763,9 +1781,9 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
QPDFObjectHandle obj_stream = getObjectByID(obj_stream_number, 0);
if (! obj_stream.isStream())
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description,
- this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description,
+ this->m->file->getLastOffset(),
"supposed object stream " +
QUtil::int_to_string(obj_stream_number) +
" is not a stream");
@@ -1775,18 +1793,18 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
// object stream for the objects in the stream.
QPDFObjGen stream_og(obj_stream_number, 0);
qpdf_offset_t end_before_space =
- this->obj_cache[stream_og].end_before_space;
+ this->m->obj_cache[stream_og].end_before_space;
qpdf_offset_t end_after_space =
- this->obj_cache[stream_og].end_after_space;
+ this->m->obj_cache[stream_og].end_after_space;
QPDFObjectHandle dict = obj_stream.getDict();
if (! (dict.getKey("/Type").isName() &&
dict.getKey("/Type").getName() == "/ObjStm"))
{
QTC::TC("qpdf", "QPDF ERR object stream with wrong type");
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description,
- this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description,
+ this->m->file->getLastOffset(),
"supposed object stream " +
QUtil::int_to_string(obj_stream_number) +
" has wrong type");
@@ -1795,9 +1813,9 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
if (! (dict.getKey("/N").isInteger() &&
dict.getKey("/First").isInteger()))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description,
- this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description,
+ this->m->file->getLastOffset(),
"object stream " +
QUtil::int_to_string(obj_stream_number) +
" has incorrect keys");
@@ -1821,7 +1839,8 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
(toffset.getType() == QPDFTokenizer::tt_integer)))
{
throw QPDFExc(qpdf_e_damaged_pdf, input->getName(),
- this->last_object_description, input->getLastOffset(),
+ this->m->last_object_description,
+ input->getLastOffset(),
"expected integer in object stream header");
}
@@ -1840,14 +1859,14 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
{
int obj = (*iter).first;
QPDFObjGen og(obj, 0);
- QPDFXRefEntry const& entry = this->xref_table[og];
+ QPDFXRefEntry const& entry = this->m->xref_table[og];
if ((entry.getType() == 2) &&
(entry.getObjStreamNumber() == obj_stream_number))
{
int offset = (*iter).second;
input->seek(offset, SEEK_SET);
QPDFObjectHandle oh = readObject(input, "", obj, 0, true);
- this->obj_cache[og] =
+ this->m->obj_cache[og] =
ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh),
end_before_space, end_after_space);
}
@@ -1862,16 +1881,16 @@ QPDFObjectHandle
QPDF::makeIndirectObject(QPDFObjectHandle oh)
{
QPDFObjGen o1(0, 0);
- if (! this->obj_cache.empty())
+ if (! this->m->obj_cache.empty())
{
- o1 = (*(this->obj_cache.rbegin())).first;
+ o1 = (*(this->m->obj_cache.rbegin())).first;
}
- QPDFObjGen o2 = (*(this->xref_table.rbegin())).first;
+ QPDFObjGen o2 = (*(this->m->xref_table.rbegin())).first;
QTC::TC("qpdf", "QPDF indirect last obj from xref",
(o2.getObj() > o1.getObj()) ? 1 : 0);
int max_objid = std::max(o1.getObj(), o2.getObj());
QPDFObjGen next(max_objid + 1, 0);
- this->obj_cache[next] =
+ this->m->obj_cache[next] =
ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1);
return QPDFObjectHandle::Factory::newIndirect(
this, next.getObj(), next.getGen());
@@ -1910,7 +1929,7 @@ QPDF::replaceObject(int objid, int generation, QPDFObjectHandle oh)
// Replace the object in the object cache
QPDFObjGen og(objid, generation);
- this->obj_cache[og] =
+ this->m->obj_cache[og] =
ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1);
}
@@ -1946,7 +1965,7 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign, bool allow_page)
"QPDF::copyForeign called with object from this QPDF");
}
- ObjCopier& obj_copier = this->object_copiers[other];
+ ObjCopier& obj_copier = this->m->object_copiers[other];
if (! obj_copier.visiting.empty())
{
throw std::logic_error("obj_copier.visiting is not empty"
@@ -2016,7 +2035,8 @@ QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier,
QTC::TC("qpdf", "QPDF loop reserving objects");
return;
}
- if (obj_copier.object_map.find(foreign_og) != obj_copier.object_map.end())
+ if (obj_copier.object_map.find(foreign_og) !=
+ obj_copier.object_map.end())
{
QTC::TC("qpdf", "QPDF already reserved object");
return;
@@ -2139,15 +2159,16 @@ QPDF::replaceForeignIndirectObjects(
replaceForeignIndirectObjects(
old_dict.getKey(*iter), obj_copier, false));
}
- if (this->copied_stream_data_provider == 0)
+ if (this->m->copied_stream_data_provider == 0)
{
- this->copied_stream_data_provider = new CopiedStreamDataProvider();
- this->copied_streams = this->copied_stream_data_provider;
+ this->m->copied_stream_data_provider =
+ new CopiedStreamDataProvider();
+ this->m->copied_streams = this->m->copied_stream_data_provider;
}
QPDFObjGen local_og(result.getObjGen());
- this->copied_stream_data_provider->registerForeignStream(
+ this->m->copied_stream_data_provider->registerForeignStream(
local_og, foreign);
- result.replaceStreamData(this->copied_streams,
+ result.replaceStreamData(this->m->copied_streams,
dict.getKey("/Filter"),
dict.getKey("/DecodeParms"));
}
@@ -2181,21 +2202,21 @@ QPDF::swapObjects(int objid1, int generation1, int objid2, int generation2)
resolve(objid2, generation2);
QPDFObjGen og1(objid1, generation1);
QPDFObjGen og2(objid2, generation2);
- ObjCache t = this->obj_cache[og1];
- this->obj_cache[og1] = this->obj_cache[og2];
- this->obj_cache[og2] = t;
+ ObjCache t = this->m->obj_cache[og1];
+ this->m->obj_cache[og1] = this->m->obj_cache[og2];
+ this->m->obj_cache[og2] = t;
}
std::string
QPDF::getFilename() const
{
- return this->file->getName();
+ return this->m->file->getName();
}
std::string
QPDF::getPDFVersion() const
{
- return this->pdf_version;
+ return this->m->pdf_version;
}
int
@@ -2225,17 +2246,17 @@ QPDF::getExtensionLevel()
QPDFObjectHandle
QPDF::getTrailer()
{
- return this->trailer;
+ return this->m->trailer;
}
QPDFObjectHandle
QPDF::getRoot()
{
- QPDFObjectHandle root = this->trailer.getKey("/Root");
+ QPDFObjectHandle root = this->m->trailer.getKey("/Root");
if (! root.isDictionary())
{
- throw QPDFExc(qpdf_e_damaged_pdf, file->getName(),
- "", file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "", this->m->file->getLastOffset(),
"unable to find /Root dictionary");
}
return root;
@@ -2245,8 +2266,8 @@ void
QPDF::getObjectStreamData(std::map<int, int>& omap)
{
for (std::map<QPDFObjGen, QPDFXRefEntry>::iterator iter =
- this->xref_table.begin();
- iter != this->xref_table.end(); ++iter)
+ this->m->xref_table.begin();
+ iter != this->m->xref_table.end(); ++iter)
{
QPDFObjGen const& og = (*iter).first;
QPDFXRefEntry const& entry = (*iter).second;
@@ -2270,12 +2291,13 @@ QPDF::getCompressibleObjGens()
// orphaned items.
// Exclude encryption dictionary, if any
- QPDFObjectHandle encryption_dict = trailer.getKey("/Encrypt");
+ QPDFObjectHandle encryption_dict =
+ this->m->trailer.getKey("/Encrypt");
QPDFObjGen encryption_dict_og = encryption_dict.getObjGen();
std::set<QPDFObjGen> visited;
std::list<QPDFObjectHandle> queue;
- queue.push_front(this->trailer);
+ queue.push_front(this->m->trailer);
std::vector<QPDFObjGen> result;
while (! queue.empty())
{
@@ -2353,25 +2375,25 @@ QPDF::pipeStreamData(int objid, int generation,
{
bool success = false;
std::vector<PointerHolder<Pipeline> > to_delete;
- if (this->encrypted)
+ if (this->m->encrypted)
{
decryptStream(pipeline, objid, generation, stream_dict, to_delete);
}
try
{
- this->file->seek(offset, SEEK_SET);
+ this->m->file->seek(offset, SEEK_SET);
char buf[10240];
while (length > 0)
{
size_t to_read = (sizeof(buf) < length ? sizeof(buf) : length);
- size_t len = this->file->read(buf, to_read);
+ size_t len = this->m->file->read(buf, to_read);
if (len == 0)
{
throw QPDFExc(qpdf_e_damaged_pdf,
- this->file->getName(),
- this->last_object_description,
- this->file->getLastOffset(),
+ this->m->file->getName(),
+ this->m->last_object_description,
+ this->m->file->getLastOffset(),
"unexpected EOF reading stream data");
}
length -= len;
@@ -2392,8 +2414,8 @@ QPDF::pipeStreamData(int objid, int generation,
if (! suppress_warnings)
{
QTC::TC("qpdf", "QPDF decoding error warning");
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "", this->file->getLastOffset(),
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "", this->m->file->getLastOffset(),
"error decoding stream data for object " +
QUtil::int_to_string(objid) + " " +
QUtil::int_to_string(generation) + ": " + e.what()));
@@ -2442,7 +2464,7 @@ QPDF::findAttachmentStreams()
item.getKey("/EF").getKey("/F").isStream())
{
QPDFObjectHandle stream = item.getKey("/EF").getKey("/F");
- this->attachment_streams.insert(stream.getObjGen());
+ this->m->attachment_streams.insert(stream.getObjGen());
}
}
}
diff --git a/libqpdf/QPDF_encryption.cc b/libqpdf/QPDF_encryption.cc
index 6c0c97ef..81325591 100644
--- a/libqpdf/QPDF_encryption.cc
+++ b/libqpdf/QPDF_encryption.cc
@@ -760,9 +760,9 @@ QPDF::interpretCF(QPDFObjectHandle cf)
if (cf.isName())
{
std::string filter = cf.getName();
- if (this->crypt_filters.count(filter) != 0)
+ if (this->m->crypt_filters.count(filter) != 0)
{
- return this->crypt_filters[filter];
+ return this->m->crypt_filters[filter];
}
else if (filter == "/Identity")
{
@@ -783,29 +783,29 @@ QPDF::interpretCF(QPDFObjectHandle cf)
void
QPDF::initializeEncryption()
{
- if (this->encryption_initialized)
+ if (this->m->encryption_initialized)
{
return;
}
- this->encryption_initialized = true;
+ this->m->encryption_initialized = true;
// After we initialize encryption parameters, we must used stored
// key information and never look at /Encrypt again. Otherwise,
// things could go wrong if someone mutates the encryption
// dictionary.
- if (! this->trailer.hasKey("/Encrypt"))
+ if (! this->m->trailer.hasKey("/Encrypt"))
{
return;
}
- // Go ahead and set this->encryption here. That way, isEncrypted
+ // Go ahead and set this->m->encrypted here. That way, isEncrypted
// will return true even if there were errors reading the
// encryption dictionary.
- this->encrypted = true;
+ this->m->encrypted = true;
std::string id1;
- QPDFObjectHandle id_obj = this->trailer.getKey("/ID");
+ QPDFObjectHandle id_obj = this->m->trailer.getKey("/ID");
if ((id_obj.isArray() &&
(id_obj.getArrayNItems() == 2) &&
id_obj.getArrayItem(0).isString()))
@@ -817,31 +817,31 @@ QPDF::initializeEncryption()
// Treating a missing ID as the empty string enables qpdf to
// decrypt some invalid encrypted files with no /ID that
// poppler can read but Adobe Reader can't.
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "trailer", this->file->getLastOffset(),
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "trailer", this->m->file->getLastOffset(),
"invalid /ID in trailer dictionary"));
}
- QPDFObjectHandle encryption_dict = this->trailer.getKey("/Encrypt");
+ QPDFObjectHandle encryption_dict = this->m->trailer.getKey("/Encrypt");
if (! encryption_dict.isDictionary())
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description,
- this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description,
+ this->m->file->getLastOffset(),
"/Encrypt in trailer dictionary is not a dictionary");
}
if (! (encryption_dict.getKey("/Filter").isName() &&
(encryption_dict.getKey("/Filter").getName() == "/Standard")))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "encryption dictionary", this->m->file->getLastOffset(),
"unsupported encryption filter");
}
if (! encryption_dict.getKey("/SubFilter").isNull())
{
- warn(QPDFExc(qpdf_e_unsupported, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ warn(QPDFExc(qpdf_e_unsupported, this->m->file->getName(),
+ "encryption dictionary", this->m->file->getLastOffset(),
"file uses encryption SubFilters,"
" which qpdf does not support"));
}
@@ -852,8 +852,8 @@ QPDF::initializeEncryption()
encryption_dict.getKey("/U").isString() &&
encryption_dict.getKey("/P").isInteger()))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "encryption dictionary", this->m->file->getLastOffset(),
"some encryption dictionary parameters are missing "
"or the wrong type");
}
@@ -869,15 +869,15 @@ QPDF::initializeEncryption()
if (! (((R >= 2) && (R <= 6)) &&
((V == 1) || (V == 2) || (V == 4) || (V == 5))))
{
- throw QPDFExc(qpdf_e_unsupported, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_unsupported, this->m->file->getName(),
+ "encryption dictionary", this->m->file->getLastOffset(),
"Unsupported /R or /V in encryption dictionary; R = " +
QUtil::int_to_string(R) + " (max 6), V = " +
QUtil::int_to_string(V) + " (max 5)");
}
- this->encryption_V = V;
- this->encryption_R = R;
+ this->m->encryption_V = V;
+ this->m->encryption_R = R;
// OE, UE, and Perms are only present if V >= 5.
std::string OE;
@@ -890,8 +890,9 @@ QPDF::initializeEncryption()
pad_short_parameter(U, key_bytes);
if (! ((O.length() == key_bytes) && (U.length() == key_bytes)))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "encryption dictionary",
+ this->m->file->getLastOffset(),
"incorrect length for /O and/or /U in "
"encryption dictionary");
}
@@ -902,8 +903,9 @@ QPDF::initializeEncryption()
encryption_dict.getKey("/UE").isString() &&
encryption_dict.getKey("/Perms").isString()))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "encryption dictionary",
+ this->m->file->getLastOffset(),
"some V=5 encryption dictionary parameters are "
"missing or the wrong type");
}
@@ -922,8 +924,9 @@ QPDF::initializeEncryption()
(UE.length() < OUE_key_bytes_V5) ||
(Perms.length() < Perms_key_bytes_V5))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "encryption dictionary",
+ this->m->file->getLastOffset(),
"incorrect length for some of"
" /O, /U, /OE, /UE, or /Perms in"
" encryption dictionary");
@@ -936,16 +939,17 @@ QPDF::initializeEncryption()
Length = encryption_dict.getKey("/Length").getIntValue();
if ((Length % 8) || (Length < 40) || (Length > 256))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "encryption dictionary",
+ this->m->file->getLastOffset(),
"invalid /Length value in encryption dictionary");
}
}
- this->encrypt_metadata = true;
+ this->m->encrypt_metadata = true;
if ((V >= 4) && (encryption_dict.getKey("/EncryptMetadata").isBool()))
{
- this->encrypt_metadata =
+ this->m->encrypt_metadata =
encryption_dict.getKey("/EncryptMetadata").getBoolValue();
}
@@ -986,40 +990,40 @@ QPDF::initializeEncryption()
method = e_unknown;
}
}
- this->crypt_filters[filter] = method;
+ this->m->crypt_filters[filter] = method;
}
}
QPDFObjectHandle StmF = encryption_dict.getKey("/StmF");
QPDFObjectHandle StrF = encryption_dict.getKey("/StrF");
QPDFObjectHandle EFF = encryption_dict.getKey("/EFF");
- this->cf_stream = interpretCF(StmF);
- this->cf_string = interpretCF(StrF);
+ this->m->cf_stream = interpretCF(StmF);
+ this->m->cf_string = interpretCF(StrF);
if (EFF.isName())
{
- this->cf_file = interpretCF(EFF);
+ this->m->cf_file = interpretCF(EFF);
}
else
{
- this->cf_file = this->cf_stream;
+ this->m->cf_file = this->m->cf_stream;
}
}
EncryptionData data(V, R, Length / 8, P, O, U, OE, UE, Perms,
- id1, this->encrypt_metadata);
+ id1, this->m->encrypt_metadata);
if (check_owner_password(
- this->user_password, this->provided_password, data))
+ this->m->user_password, this->m->provided_password, data))
{
// password supplied was owner password; user_password has
// been initialized for V < 5
}
- else if (check_user_password(this->provided_password, data))
+ else if (check_user_password(this->m->provided_password, data))
{
- this->user_password = this->provided_password;
+ this->m->user_password = this->m->provided_password;
}
else
{
- throw QPDFExc(qpdf_e_password, this->file->getName(),
+ throw QPDFExc(qpdf_e_password, this->m->file->getName(),
"", 0, "invalid password");
}
@@ -1028,8 +1032,8 @@ QPDF::initializeEncryption()
// For V < 5, the user password is encrypted with the owner
// password, and the user password is always used for
// computing the encryption key.
- this->encryption_key = compute_encryption_key(
- this->user_password, data);
+ this->m->encryption_key = compute_encryption_key(
+ this->m->user_password, data);
}
else
{
@@ -1037,12 +1041,13 @@ QPDF::initializeEncryption()
// compute the encryption key, and neither password can be
// used to recover the other.
bool perms_valid;
- this->encryption_key = recover_encryption_key_with_password(
- this->provided_password, data, perms_valid);
+ this->m->encryption_key = recover_encryption_key_with_password(
+ this->m->provided_password, data, perms_valid);
if (! perms_valid)
{
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- "encryption dictionary", this->file->getLastOffset(),
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ "encryption dictionary",
+ this->m->file->getLastOffset(),
"/Perms field in encryption dictionary"
" doesn't match expected value"));
}
@@ -1052,23 +1057,24 @@ QPDF::initializeEncryption()
std::string
QPDF::getKeyForObject(int objid, int generation, bool use_aes)
{
- if (! this->encrypted)
+ if (! this->m->encrypted)
{
throw std::logic_error(
"request for encryption key in non-encrypted PDF");
}
- if (! ((objid == this->cached_key_objid) &&
- (generation == this->cached_key_generation)))
+ if (! ((objid == this->m->cached_key_objid) &&
+ (generation == this->m->cached_key_generation)))
{
- this->cached_object_encryption_key =
- compute_data_key(this->encryption_key, objid, generation,
- use_aes, this->encryption_V, this->encryption_R);
- this->cached_key_objid = objid;
- this->cached_key_generation = generation;
+ this->m->cached_object_encryption_key =
+ compute_data_key(this->m->encryption_key, objid, generation,
+ use_aes, this->m->encryption_V,
+ this->m->encryption_R);
+ this->m->cached_key_objid = objid;
+ this->m->cached_key_generation = generation;
}
- return this->cached_object_encryption_key;
+ return this->m->cached_object_encryption_key;
}
void
@@ -1079,9 +1085,9 @@ QPDF::decryptString(std::string& str, int objid, int generation)
return;
}
bool use_aes = false;
- if (this->encryption_V >= 4)
+ if (this->m->encryption_V >= 4)
{
- switch (this->cf_string)
+ switch (this->m->cf_string)
{
case e_none:
return;
@@ -1098,15 +1104,15 @@ QPDF::decryptString(std::string& str, int objid, int generation)
break;
default:
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description,
- this->file->getLastOffset(),
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description,
+ this->m->file->getLastOffset(),
"unknown encryption filter for strings"
" (check /StrF in /Encrypt dictionary);"
" strings may be decrypted improperly"));
// To avoid repeated warnings, reset cf_string. Assume
// we'd want to use AES if V == 4.
- this->cf_string = e_aes;
+ this->m->cf_string = e_aes;
break;
}
}
@@ -1145,9 +1151,9 @@ QPDF::decryptString(std::string& str, int objid, int generation)
}
catch (std::runtime_error& e)
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description,
- this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description,
+ this->m->file->getLastOffset(),
"error decrypting string for object " +
QUtil::int_to_string(objid) + " " +
QUtil::int_to_string(generation) + ": " + e.what());
@@ -1170,7 +1176,7 @@ QPDF::decryptStream(Pipeline*& pipeline, int objid, int generation,
return;
}
bool use_aes = false;
- if (this->encryption_V >= 4)
+ if (this->m->encryption_V >= 4)
{
encryption_method_e method = e_unknown;
std::string method_source = "/StmF from /Encrypt dictionary";
@@ -1221,21 +1227,21 @@ QPDF::decryptStream(Pipeline*& pipeline, int objid, int generation,
if (method == e_unknown)
{
- if ((! this->encrypt_metadata) && (type == "/Metadata"))
+ if ((! this->m->encrypt_metadata) && (type == "/Metadata"))
{
QTC::TC("qpdf", "QPDF_encryption cleartext metadata");
method = e_none;
}
else
{
- if (this->attachment_streams.count(
+ if (this->m->attachment_streams.count(
QPDFObjGen(objid, generation)) > 0)
{
- method = this->cf_file;
+ method = this->m->cf_file;
}
else
{
- method = this->cf_stream;
+ method = this->m->cf_stream;
}
}
}
@@ -1259,15 +1265,15 @@ QPDF::decryptStream(Pipeline*& pipeline, int objid, int generation,
default:
// filter local to this stream.
- warn(QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description,
- this->file->getLastOffset(),
+ warn(QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description,
+ this->m->file->getLastOffset(),
"unknown encryption filter for streams"
" (check " + method_source + ");"
" streams may be decrypted improperly"));
// To avoid repeated warnings, reset cf_stream. Assume
// we'd want to use AES if V == 4.
- this->cf_stream = e_aes;
+ this->m->cf_stream = e_aes;
break;
}
}
@@ -1331,13 +1337,13 @@ QPDF::compute_encryption_parameters_V5(
std::string const&
QPDF::getPaddedUserPassword() const
{
- return this->user_password;
+ return this->m->user_password;
}
std::string
QPDF::getTrimmedUserPassword() const
{
- std::string result = this->user_password;
+ std::string result = this->m->user_password;
trim_user_password(result);
return result;
}
@@ -1345,13 +1351,13 @@ QPDF::getTrimmedUserPassword() const
std::string
QPDF::getEncryptionKey() const
{
- return this->encryption_key;
+ return this->m->encryption_key;
}
bool
QPDF::isEncrypted() const
{
- return this->encrypted;
+ return this->m->encrypted;
}
bool
@@ -1368,7 +1374,7 @@ QPDF::isEncrypted(int& R, int& P, int& V,
encryption_method_e& string_method,
encryption_method_e& file_method)
{
- if (this->encrypted)
+ if (this->m->encrypted)
{
QPDFObjectHandle trailer = getTrailer();
QPDFObjectHandle encrypt = trailer.getKey("/Encrypt");
@@ -1378,9 +1384,9 @@ QPDF::isEncrypted(int& R, int& P, int& V,
P = Pkey.getIntValue();
R = Rkey.getIntValue();
V = Vkey.getIntValue();
- stream_method = this->cf_stream;
- string_method = this->cf_stream;
- file_method = this->cf_file;
+ stream_method = this->m->cf_stream;
+ string_method = this->m->cf_stream;
+ file_method = this->m->cf_file;
return true;
}
else
diff --git a/libqpdf/QPDF_linearization.cc b/libqpdf/QPDF_linearization.cc
index b05b1d4c..3d04ab90 100644
--- a/libqpdf/QPDF_linearization.cc
+++ b/libqpdf/QPDF_linearization.cc
@@ -72,7 +72,7 @@ QPDF::checkLinearization()
}
catch (QPDFExc& e)
{
- *out_stream << e.what() << std::endl;
+ *this->m->out_stream << e.what() << std::endl;
}
return result;
}
@@ -82,7 +82,7 @@ QPDF::isLinearized()
{
// If the first object in the file is a dictionary with a suitable
// /Linearized key and has an /L key that accurately indicates the
- // file size, initialize this->lindict and return true.
+ // file size, initialize this->m->lindict and return true.
// A linearized PDF spec's first object will be contained within
// the first 1024 bytes of the file and will be a dictionary with
@@ -95,10 +95,10 @@ QPDF::isLinearized()
static int const tbuf_size = 1025;
char* buf = new char[tbuf_size];
- this->file->seek(0, SEEK_SET);
+ this->m->file->seek(0, SEEK_SET);
PointerHolder<char> b(true, buf);
memset(buf, '\0', tbuf_size);
- this->file->read(buf, tbuf_size - 1);
+ this->m->file->read(buf, tbuf_size - 1);
int lindict_obj = -1;
char* p = buf;
@@ -115,16 +115,16 @@ QPDF::isLinearized()
}
// Seek to the digit. Then skip over digits for a potential
// next iteration.
- this->file->seek(p - buf, SEEK_SET);
+ this->m->file->seek(p - buf, SEEK_SET);
while (((p - buf) < tbuf_size) && QUtil::is_digit(*p))
{
++p;
}
- QPDFTokenizer::Token t1 = readToken(this->file, true);
- QPDFTokenizer::Token t2 = readToken(this->file, true);
- QPDFTokenizer::Token t3 = readToken(this->file, true);
- QPDFTokenizer::Token t4 = readToken(this->file, true);
+ QPDFTokenizer::Token t1 = readToken(this->m->file, true);
+ QPDFTokenizer::Token t2 = readToken(this->m->file, true);
+ QPDFTokenizer::Token t3 = readToken(this->m->file, true);
+ QPDFTokenizer::Token t4 = readToken(this->m->file, true);
if ((t1.getType() == QPDFTokenizer::tt_integer) &&
(t2.getType() == QPDFTokenizer::tt_integer) &&
(t3 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "obj")) &&
@@ -158,19 +158,19 @@ QPDF::isLinearized()
if (L.isInteger())
{
qpdf_offset_t Li = L.getIntValue();
- this->file->seek(0, SEEK_END);
- if (Li != this->file->tell())
+ this->m->file->seek(0, SEEK_END);
+ if (Li != this->m->file->tell())
{
QTC::TC("qpdf", "QPDF /L mismatch");
return false;
}
else
{
- this->linp.file_size = Li;
+ this->m->linp.file_size = Li;
}
}
- this->lindict = candidate;
+ this->m->lindict = candidate;
return true;
}
@@ -191,12 +191,12 @@ QPDF::readLinearizationData()
}
// /L is read and stored in linp by isLinearized()
- QPDFObjectHandle H = lindict.getKey("/H");
- QPDFObjectHandle O = lindict.getKey("/O");
- QPDFObjectHandle E = lindict.getKey("/E");
- QPDFObjectHandle N = lindict.getKey("/N");
- QPDFObjectHandle T = lindict.getKey("/T");
- QPDFObjectHandle P = lindict.getKey("/P");
+ QPDFObjectHandle H = this->m->lindict.getKey("/H");
+ QPDFObjectHandle O = this->m->lindict.getKey("/O");
+ QPDFObjectHandle E = this->m->lindict.getKey("/E");
+ QPDFObjectHandle N = this->m->lindict.getKey("/N");
+ QPDFObjectHandle T = this->m->lindict.getKey("/T");
+ QPDFObjectHandle P = this->m->lindict.getKey("/P");
if (! (H.isArray() &&
O.isInteger() &&
@@ -205,9 +205,9 @@ QPDF::readLinearizationData()
T.isInteger() &&
(P.isInteger() || P.isNull())))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"linearization dictionary",
- this->file->getLastOffset(),
+ this->m->file->getLastOffset(),
"some keys in linearization dictionary are of "
"the wrong type");
}
@@ -216,9 +216,9 @@ QPDF::readLinearizationData()
unsigned int n_H_items = H.getArrayNItems();
if (! ((n_H_items == 2) || (n_H_items == 4)))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"linearization dictionary",
- this->file->getLastOffset(),
+ this->m->file->getLastOffset(),
"H has the wrong number of items");
}
@@ -232,9 +232,9 @@ QPDF::readLinearizationData()
}
else
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"linearization dictionary",
- this->file->getLastOffset(),
+ this->m->file->getLastOffset(),
"some H items are of the wrong type");
}
}
@@ -272,20 +272,20 @@ QPDF::readLinearizationData()
// accurate and bail right now if it's not.
if (N.getIntValue() != static_cast<long long>(getAllPages().size()))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"linearization hint table",
- this->file->getLastOffset(),
+ this->m->file->getLastOffset(),
"/N does not match number of pages");
}
// file_size initialized by isLinearized()
- this->linp.first_page_object = O.getIntValue();
- this->linp.first_page_end = E.getIntValue();
- this->linp.npages = N.getIntValue();
- this->linp.xref_zero_offset = T.getIntValue();
- this->linp.first_page = first_page;
- this->linp.H_offset = H0_offset;
- this->linp.H_length = H0_length;
+ this->m->linp.first_page_object = O.getIntValue();
+ this->m->linp.first_page_end = E.getIntValue();
+ this->m->linp.npages = N.getIntValue();
+ this->m->linp.xref_zero_offset = T.getIntValue();
+ this->m->linp.first_page = first_page;
+ this->m->linp.H_offset = H0_offset;
+ this->m->linp.H_length = H0_length;
// Read hint streams
@@ -320,9 +320,9 @@ QPDF::readLinearizationData()
int HSi = HS.getIntValue();
if ((HSi < 0) || (HSi >= h_size))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"linearization hint table",
- this->file->getLastOffset(),
+ this->m->file->getLastOffset(),
"/S (shared object) offset is out of bounds");
}
readHSharedObject(BitStream(h_buf + HSi, h_size - HSi));
@@ -332,13 +332,13 @@ QPDF::readLinearizationData()
int HOi = HO.getIntValue();
if ((HOi < 0) || (HOi >= h_size))
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"linearization hint table",
- this->file->getLastOffset(),
+ this->m->file->getLastOffset(),
"/O (outline) offset is out of bounds");
}
readHGeneric(BitStream(h_buf + HOi, h_size - HOi),
- this->outline_hints);
+ this->m->outline_hints);
}
}
@@ -349,14 +349,14 @@ QPDF::readHintStream(Pipeline& pl, qpdf_offset_t offset, size_t length)
int gen;
QPDFObjectHandle H = readObjectAtOffset(
false, offset, "linearization hint stream", -1, 0, obj, gen);
- ObjCache& oc = this->obj_cache[QPDFObjGen(obj, gen)];
+ ObjCache& oc = this->m->obj_cache[QPDFObjGen(obj, gen)];
qpdf_offset_t min_end_offset = oc.end_before_space;
qpdf_offset_t max_end_offset = oc.end_after_space;
if (! H.isStream())
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"linearization dictionary",
- this->file->getLastOffset(),
+ this->m->file->getLastOffset(),
"hint table is not a stream");
}
@@ -373,7 +373,7 @@ QPDF::readHintStream(Pipeline& pl, qpdf_offset_t offset, size_t length)
QTC::TC("qpdf", "QPDF hint table length indirect");
// Force resolution
(void) length_obj.getIntValue();
- ObjCache& oc = this->obj_cache[length_obj.getObjGen()];
+ ObjCache& oc = this->m->obj_cache[length_obj.getObjGen()];
min_end_offset = oc.end_before_space;
max_end_offset = oc.end_after_space;
}
@@ -385,12 +385,12 @@ QPDF::readHintStream(Pipeline& pl, qpdf_offset_t offset, size_t length)
if ((computed_end < min_end_offset) ||
(computed_end > max_end_offset))
{
- *out_stream << "expected = " << computed_end
- << "; actual = " << min_end_offset << ".."
- << max_end_offset << std::endl;
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
+ *this->m->out_stream << "expected = " << computed_end
+ << "; actual = " << min_end_offset << ".."
+ << max_end_offset << std::endl;
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
"linearization dictionary",
- this->file->getLastOffset(),
+ this->m->file->getLastOffset(),
"hint table length mismatch");
}
H.pipeStreamData(&pl, 0, qpdf_dl_specialized);
@@ -403,7 +403,7 @@ QPDF::readHPageOffset(BitStream h)
// All comments referring to the PDF spec refer to the spec for
// version 1.4.
- HPageOffset& t = this->page_offset_hints;
+ HPageOffset& t = this->m->page_offset_hints;
t.min_nobjects = h.getBits(32); // 1
t.first_page_offset = h.getBits(32); // 2
@@ -421,7 +421,7 @@ QPDF::readHPageOffset(BitStream h)
std::vector<HPageOffsetEntry>& entries = t.entries;
entries.clear();
- unsigned int nitems = this->linp.npages;
+ unsigned int nitems = this->m->linp.npages;
load_vector_int(h, nitems, entries,
t.nbits_delta_nobjects,
&HPageOffsetEntry::delta_nobjects);
@@ -450,7 +450,7 @@ QPDF::readHPageOffset(BitStream h)
void
QPDF::readHSharedObject(BitStream h)
{
- HSharedObject& t = this->shared_object_hints;
+ HSharedObject& t = this->m->shared_object_hints;
t.first_shared_obj = h.getBits(32); // 1
t.first_shared_offset = h.getBits(32); // 2
@@ -509,7 +509,7 @@ QPDF::checkLinearizationInternal()
// Check all values in linearization parameter dictionary
- LinParameters& p = this->linp;
+ LinParameters& p = this->m->linp;
// L: file size in bytes -- checked by isLinearized
@@ -533,7 +533,7 @@ QPDF::checkLinearizationInternal()
{
QPDFObjectHandle const& page = pages.at(i);
QPDFObjGen og(page.getObjGen());
- if (this->xref_table[og].getType() == 2)
+ if (this->m->xref_table[og].getType() == 2)
{
errors.push_back("page dictionary for page " +
QUtil::int_to_string(i) + " is compressed");
@@ -541,25 +541,25 @@ QPDF::checkLinearizationInternal()
}
// T: offset of whitespace character preceding xref entry for object 0
- this->file->seek(p.xref_zero_offset, SEEK_SET);
+ this->m->file->seek(p.xref_zero_offset, SEEK_SET);
while (1)
{
char ch;
- this->file->read(&ch, 1);
+ this->m->file->read(&ch, 1);
if (! ((ch == ' ') || (ch == '\r') || (ch == '\n')))
{
- this->file->seek(-1, SEEK_CUR);
+ this->m->file->seek(-1, SEEK_CUR);
break;
}
}
- if (this->file->tell() != this->first_xref_item_offset)
+ if (this->m->file->tell() != this->m->first_xref_item_offset)
{
QTC::TC("qpdf", "QPDF err /T mismatch");
errors.push_back("space before first xref item (/T) mismatch "
"(computed = " +
- QUtil::int_to_string(this->first_xref_item_offset) +
+ QUtil::int_to_string(this->m->first_xref_item_offset) +
"; file = " +
- QUtil::int_to_string(this->file->tell()));
+ QUtil::int_to_string(this->m->file->tell()));
}
// P: first page number -- Implementation note 124 says Acrobat
@@ -570,7 +570,7 @@ QPDF::checkLinearizationInternal()
// at the end of the containing xref section if any object streams
// are in use.
- if (this->uncompressed_after_compressed)
+ if (this->m->uncompressed_after_compressed)
{
errors.push_back("linearized file contains an uncompressed object"
" after a compressed one in a cross-reference stream");
@@ -584,8 +584,8 @@ QPDF::checkLinearizationInternal()
{ // local scope
std::map<int, int> object_stream_data;
for (std::map<QPDFObjGen, QPDFXRefEntry>::const_iterator iter =
- this->xref_table.begin();
- iter != this->xref_table.end(); ++iter)
+ this->m->xref_table.begin();
+ iter != this->m->xref_table.end(); ++iter)
{
QPDFObjGen const& og = (*iter).first;
QPDFXRefEntry const& entry = (*iter).second;
@@ -609,22 +609,22 @@ QPDF::checkLinearizationInternal()
// agree with pdlin. As of this writing, the test suite doesn't
// contain any files with threads.
- if (this->part6.empty())
+ if (this->m->part6.empty())
{
throw std::logic_error("linearization part 6 unexpectedly empty");
}
qpdf_offset_t min_E = -1;
qpdf_offset_t max_E = -1;
- for (std::vector<QPDFObjectHandle>::iterator iter = this->part6.begin();
- iter != this->part6.end(); ++iter)
+ for (std::vector<QPDFObjectHandle>::iterator iter = this->m->part6.begin();
+ iter != this->m->part6.end(); ++iter)
{
QPDFObjGen og((*iter).getObjGen());
- if (this->obj_cache.count(og) == 0)
+ if (this->m->obj_cache.count(og) == 0)
{
// All objects have to have been dereferenced to be classified.
throw std::logic_error("linearization part6 object not in cache");
}
- ObjCache const& oc = this->obj_cache[og];
+ ObjCache const& oc = this->m->obj_cache[og];
min_E = std::max(min_E, oc.end_before_space);
max_E = std::max(max_E, oc.end_after_space);
}
@@ -655,7 +655,7 @@ QPDF::checkLinearizationInternal()
for (std::list<std::string>::iterator iter = errors.begin();
iter != errors.end(); ++iter)
{
- *out_stream << "ERROR: " << (*iter) << std::endl;
+ *this->m->out_stream << "ERROR: " << (*iter) << std::endl;
}
}
@@ -665,7 +665,7 @@ QPDF::checkLinearizationInternal()
for (std::list<std::string>::iterator iter = warnings.begin();
iter != warnings.end(); ++iter)
{
- *out_stream << "WARNING: " << (*iter) << std::endl;
+ *this->m->out_stream << "WARNING: " << (*iter) << std::endl;
}
}
@@ -675,15 +675,15 @@ QPDF::checkLinearizationInternal()
qpdf_offset_t
QPDF::maxEnd(ObjUser const& ou)
{
- assert(this->obj_user_to_objects.count(ou) > 0);
- std::set<QPDFObjGen> const& ogs = this->obj_user_to_objects[ou];
+ assert(this->m->obj_user_to_objects.count(ou) > 0);
+ std::set<QPDFObjGen> const& ogs = this->m->obj_user_to_objects[ou];
qpdf_offset_t end = 0;
for (std::set<QPDFObjGen>::const_iterator iter = ogs.begin();
iter != ogs.end(); ++iter)
{
QPDFObjGen const& og = *iter;
- assert(this->obj_cache.count(og) > 0);
- end = std::max(end, this->obj_cache[og].end_after_space);
+ assert(this->m->obj_cache.count(og) > 0);
+ end = std::max(end, this->m->obj_cache[og].end_after_space);
}
return end;
}
@@ -691,7 +691,7 @@ QPDF::maxEnd(ObjUser const& ou)
qpdf_offset_t
QPDF::getLinearizationOffset(QPDFObjGen const& og)
{
- QPDFXRefEntry entry = this->xref_table[og];
+ QPDFXRefEntry entry = this->m->xref_table[og];
qpdf_offset_t result = 0;
switch (entry.getType())
{
@@ -737,7 +737,7 @@ QPDF::lengthNextN(int first_object, int n,
for (int i = 0; i < n; ++i)
{
QPDFObjGen og(first_object + i, 0);
- if (this->xref_table.count(og) == 0)
+ if (this->m->xref_table.count(og) == 0)
{
errors.push_back(
"no xref table entry for " +
@@ -745,8 +745,8 @@ QPDF::lengthNextN(int first_object, int n,
}
else
{
- assert(this->obj_cache.count(og) > 0);
- length += this->obj_cache[og].end_after_space -
+ assert(this->m->obj_cache.count(og) > 0);
+ length += this->m->obj_cache[og].end_after_space -
getLinearizationOffset(og);
}
}
@@ -778,9 +778,9 @@ QPDF::checkHPageOffset(std::list<std::string>& errors,
unsigned int npages = pages.size();
int table_offset = adjusted_offset(
- this->page_offset_hints.first_page_offset);
+ this->m->page_offset_hints.first_page_offset);
QPDFObjGen first_page_og(pages.at(0).getObjGen());
- assert(this->xref_table.count(first_page_og) > 0);
+ assert(this->m->xref_table.count(first_page_og) > 0);
int offset = getLinearizationOffset(first_page_og);
if (table_offset != offset)
{
@@ -791,13 +791,13 @@ QPDF::checkHPageOffset(std::list<std::string>& errors,
{
QPDFObjGen page_og(pages.at(pageno).getObjGen());
int first_object = page_og.getObj();
- assert(this->xref_table.count(page_og) > 0);
+ assert(this->m->xref_table.count(page_og) > 0);
offset = getLinearizationOffset(page_og);
- HPageOffsetEntry& he = this->page_offset_hints.entries.at(pageno);
- CHPageOffsetEntry& ce = this->c_page_offset_data.entries.at(pageno);
+ HPageOffsetEntry& he = this->m->page_offset_hints.entries.at(pageno);
+ CHPageOffsetEntry& ce = this->m->c_page_offset_data.entries.at(pageno);
int h_nobjects = he.delta_nobjects +
- this->page_offset_hints.min_nobjects;
+ this->m->page_offset_hints.min_nobjects;
if (h_nobjects != ce.nobjects)
{
// This happens with pdlin when there are thumbnails.
@@ -812,7 +812,7 @@ QPDF::checkHPageOffset(std::list<std::string>& errors,
// computed value if there is a discrepancy.
int length = lengthNextN(first_object, h_nobjects, errors);
int h_length = he.delta_page_length +
- this->page_offset_hints.min_page_length;
+ this->m->page_offset_hints.min_page_length;
if (length != h_length)
{
// This condition almost certainly indicates a bad hint
@@ -853,12 +853,12 @@ QPDF::checkHPageOffset(std::list<std::string>& errors,
for (int i = 0; i < ce.nshared_objects; ++i)
{
int idx = ce.shared_identifiers.at(i);
- if (idx >= this->c_shared_object_data.nshared_total)
+ if (idx >= this->m->c_shared_object_data.nshared_total)
{
throw std::logic_error(
"index out of bounds for shared object hint table");
}
- int obj = this->c_shared_object_data.entries.at(idx).object;
+ int obj = this->m->c_shared_object_data.entries.at(idx).object;
computed_shared.insert(obj);
}
@@ -916,7 +916,7 @@ QPDF::checkHSharedObject(std::list<std::string>& errors,
// these whenever there are no shared objects not referenced by
// the first page (i.e., nshared_total == nshared_first_page).
- HSharedObject& so = this->shared_object_hints;
+ HSharedObject& so = this->m->shared_object_hints;
if (so.nshared_total < so.nshared_first_page)
{
errors.push_back("shared object hint table: ntotal < nfirst_page");
@@ -932,7 +932,7 @@ QPDF::checkHSharedObject(std::list<std::string>& errors,
if (i == so.nshared_first_page)
{
QTC::TC("qpdf", "QPDF lin check shared past first page");
- if (this->part8.empty())
+ if (this->m->part8.empty())
{
errors.push_back(
"part 8 is empty but nshared_total > "
@@ -940,7 +940,7 @@ QPDF::checkHSharedObject(std::list<std::string>& errors,
}
else
{
- int obj = this->part8.at(0).getObjectID();
+ int obj = this->m->part8.at(0).getObjectID();
if (obj != so.first_shared_obj)
{
errors.push_back(
@@ -955,7 +955,7 @@ QPDF::checkHSharedObject(std::list<std::string>& errors,
cur_object = so.first_shared_obj;
QPDFObjGen og(cur_object, 0);
- assert(this->xref_table.count(og) > 0);
+ assert(this->m->xref_table.count(og) > 0);
int offset = getLinearizationOffset(og);
int h_offset = adjusted_offset(so.first_shared_offset);
if (offset != h_offset)
@@ -996,15 +996,15 @@ QPDF::checkHOutlines(std::list<std::string>& warnings)
// wrong starting place). pdlin appears to generate correct
// values in those cases.
- if (this->c_outline_data.nobjects == this->outline_hints.nobjects)
+ if (this->m->c_outline_data.nobjects == this->m->outline_hints.nobjects)
{
- if (this->c_outline_data.nobjects == 0)
+ if (this->m->c_outline_data.nobjects == 0)
{
return;
}
- if (this->c_outline_data.first_object ==
- this->outline_hints.first_object)
+ if (this->m->c_outline_data.first_object ==
+ this->m->outline_hints.first_object)
{
// Check length and offset. Acrobat gets these wrong.
QPDFObjectHandle outlines = getRoot().getKey("/Outlines");
@@ -1018,12 +1018,12 @@ QPDF::checkHOutlines(std::list<std::string>& warnings)
return;
}
QPDFObjGen og(outlines.getObjGen());
- assert(this->xref_table.count(og) > 0);
+ assert(this->m->xref_table.count(og) > 0);
int offset = getLinearizationOffset(og);
ObjUser ou(ObjUser::ou_root_key, "/Outlines");
int length = maxEnd(ou) - offset;
int table_offset =
- adjusted_offset(this->outline_hints.first_object_offset);
+ adjusted_offset(this->m->outline_hints.first_object_offset);
if (offset != table_offset)
{
warnings.push_back(
@@ -1031,7 +1031,7 @@ QPDF::checkHOutlines(std::list<std::string>& warnings)
QUtil::int_to_string(table_offset) +
"; computed = " + QUtil::int_to_string(offset));
}
- int table_length = this->outline_hints.group_length;
+ int table_length = this->m->outline_hints.group_length;
if (length != table_length)
{
warnings.push_back(
@@ -1063,41 +1063,42 @@ QPDF::showLinearizationData()
}
catch (QPDFExc& e)
{
- *out_stream << e.what() << std::endl;
+ *this->m->out_stream << e.what() << std::endl;
}
}
void
QPDF::dumpLinearizationDataInternal()
{
- *out_stream << this->file->getName() << ": linearization data:" << std::endl
- << std::endl;
-
- *out_stream
- << "file_size: " << this->linp.file_size << std::endl
- << "first_page_object: " << this->linp.first_page_object << std::endl
- << "first_page_end: " << this->linp.first_page_end << std::endl
- << "npages: " << this->linp.npages << std::endl
- << "xref_zero_offset: " << this->linp.xref_zero_offset << std::endl
- << "first_page: " << this->linp.first_page << std::endl
- << "H_offset: " << this->linp.H_offset << std::endl
- << "H_length: " << this->linp.H_length << std::endl
+ *this->m->out_stream
+ << this->m->file->getName() << ": linearization data:" << std::endl
+ << std::endl;
+
+ *this->m->out_stream
+ << "file_size: " << this->m->linp.file_size << std::endl
+ << "first_page_object: " << this->m->linp.first_page_object << std::endl
+ << "first_page_end: " << this->m->linp.first_page_end << std::endl
+ << "npages: " << this->m->linp.npages << std::endl
+ << "xref_zero_offset: " << this->m->linp.xref_zero_offset << std::endl
+ << "first_page: " << this->m->linp.first_page << std::endl
+ << "H_offset: " << this->m->linp.H_offset << std::endl
+ << "H_length: " << this->m->linp.H_length << std::endl
<< std::endl;
- *out_stream << "Page Offsets Hint Table" << std::endl
- << std::endl;
+ *this->m->out_stream << "Page Offsets Hint Table" << std::endl
+ << std::endl;
dumpHPageOffset();
- *out_stream << std::endl
- << "Shared Objects Hint Table" << std::endl
- << std::endl;
+ *this->m->out_stream << std::endl
+ << "Shared Objects Hint Table" << std::endl
+ << std::endl;
dumpHSharedObject();
- if (this->outline_hints.nobjects > 0)
+ if (this->m->outline_hints.nobjects > 0)
{
- *out_stream << std::endl
- << "Outlines Hint Table" << std::endl
- << std::endl;
- dumpHGeneric(this->outline_hints);
+ *this->m->out_stream << std::endl
+ << "Outlines Hint Table" << std::endl
+ << std::endl;
+ dumpHGeneric(this->m->outline_hints);
}
}
@@ -1107,9 +1108,9 @@ QPDF::adjusted_offset(int offset)
// All offsets >= H_offset have to be increased by H_length
// since all hint table location values disregard the hint table
// itself.
- if (offset >= this->linp.H_offset)
+ if (offset >= this->m->linp.H_offset)
{
- return offset + this->linp.H_length;
+ return offset + this->m->linp.H_length;
}
return offset;
}
@@ -1118,8 +1119,8 @@ QPDF::adjusted_offset(int offset)
void
QPDF::dumpHPageOffset()
{
- HPageOffset& t = this->page_offset_hints;
- *out_stream
+ HPageOffset& t = this->m->page_offset_hints;
+ *this->m->out_stream
<< "min_nobjects: " << t.min_nobjects
<< std::endl
<< "first_page_offset: " << adjusted_offset(t.first_page_offset)
@@ -1147,10 +1148,10 @@ QPDF::dumpHPageOffset()
<< "shared_denominator: " << t.shared_denominator
<< std::endl;
- for (int i1 = 0; i1 < this->linp.npages; ++i1)
+ for (int i1 = 0; i1 < this->m->linp.npages; ++i1)
{
HPageOffsetEntry& pe = t.entries.at(i1);
- *out_stream
+ *this->m->out_stream
<< "Page " << i1 << ":" << std::endl
<< " nobjects: " << pe.delta_nobjects + t.min_nobjects
<< std::endl
@@ -1164,10 +1165,10 @@ QPDF::dumpHPageOffset()
<< " nshared_objects: " << pe.nshared_objects << std::endl;
for (int i2 = 0; i2 < pe.nshared_objects; ++i2)
{
- *out_stream << " identifier " << i2 << ": "
- << pe.shared_identifiers.at(i2) << std::endl;
- *out_stream << " numerator " << i2 << ": "
- << pe.shared_numerators.at(i2) << std::endl;
+ *this->m->out_stream << " identifier " << i2 << ": "
+ << pe.shared_identifiers.at(i2) << std::endl;
+ *this->m->out_stream << " numerator " << i2 << ": "
+ << pe.shared_numerators.at(i2) << std::endl;
}
}
}
@@ -1175,8 +1176,8 @@ QPDF::dumpHPageOffset()
void
QPDF::dumpHSharedObject()
{
- HSharedObject& t = this->shared_object_hints;
- *out_stream
+ HSharedObject& t = this->m->shared_object_hints;
+ *this->m->out_stream
<< "first_shared_obj: " << t.first_shared_obj
<< std::endl
<< "first_shared_offset: " << adjusted_offset(t.first_shared_offset)
@@ -1195,19 +1196,20 @@ QPDF::dumpHSharedObject()
for (int i = 0; i < t.nshared_total; ++i)
{
HSharedObjectEntry& se = t.entries.at(i);
- *out_stream << "Shared Object " << i << ":" << std::endl;
- *out_stream << " group length: "
- << se.delta_group_length + t.min_group_length << std::endl;
+ *this->m->out_stream
+ << "Shared Object " << i << ":" << std::endl
+ << " group length: "
+ << se.delta_group_length + t.min_group_length << std::endl;
// PDF spec says signature present nobjects_minus_one are
// always 0, so print them only if they have a non-zero value.
if (se.signature_present)
{
- *out_stream << " signature present" << std::endl;
+ *this->m->out_stream << " signature present" << std::endl;
}
if (se.nobjects_minus_one != 0)
{
- *out_stream << " nobjects: "
- << se.nobjects_minus_one + 1 << std::endl;
+ *this->m->out_stream << " nobjects: "
+ << se.nobjects_minus_one + 1 << std::endl;
}
}
}
@@ -1215,7 +1217,7 @@ QPDF::dumpHSharedObject()
void
QPDF::dumpHGeneric(HGeneric& t)
{
- *out_stream
+ *this->m->out_stream
<< "first_object: " << t.first_object
<< std::endl
<< "first_object_offset: " << adjusted_offset(t.first_object_offset)
@@ -1242,7 +1244,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// this function. Note that actual offsets and lengths are not
// computed here, but anything related to object ordering is.
- if (this->object_to_obj_users.empty())
+ if (this->m->object_to_obj_users.empty())
{
// Note that we can't call optimize here because we don't know
// whether it should be called with or without allow changes.
@@ -1298,15 +1300,15 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// * outlines: part 6 or 9
- this->part4.clear();
- this->part6.clear();
- this->part7.clear();
- this->part8.clear();
- this->part9.clear();
- this->c_linp = LinParameters();
- this->c_page_offset_data = CHPageOffset();
- this->c_shared_object_data = CHSharedObject();
- this->c_outline_data = HGeneric();
+ this->m->part4.clear();
+ this->m->part6.clear();
+ this->m->part7.clear();
+ this->m->part8.clear();
+ this->m->part9.clear();
+ this->m->c_linp = LinParameters();
+ this->m->c_page_offset_data = CHPageOffset();
+ this->m->c_shared_object_data = CHSharedObject();
+ this->m->c_outline_data = HGeneric();
QPDFObjectHandle root = getRoot();
bool outlines_in_first_page = false;
@@ -1349,8 +1351,8 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
std::set<QPDFObjGen> lc_root;
for (std::map<QPDFObjGen, std::set<ObjUser> >::iterator oiter =
- this->object_to_obj_users.begin();
- oiter != this->object_to_obj_users.end(); ++oiter)
+ this->m->object_to_obj_users.begin();
+ oiter != this->m->object_to_obj_users.end(); ++oiter)
{
QPDFObjGen const& og = (*oiter).first;
@@ -1505,17 +1507,18 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// npages is the size of the existing pages vector, which has been
// created by traversing the pages tree, and as such is a
// reasonable size.
- this->c_linp.npages = npages;
- this->c_page_offset_data.entries = std::vector<CHPageOffsetEntry>(npages);
+ this->m->c_linp.npages = npages;
+ this->m->c_page_offset_data.entries =
+ std::vector<CHPageOffsetEntry>(npages);
// Part 4: open document objects. We don't care about the order.
assert(lc_root.size() == 1);
- this->part4.push_back(objGenToIndirect(*(lc_root.begin())));
+ this->m->part4.push_back(objGenToIndirect(*(lc_root.begin())));
for (std::set<QPDFObjGen>::iterator iter = lc_open_document.begin();
iter != lc_open_document.end(); ++iter)
{
- this->part4.push_back(objGenToIndirect(*iter));
+ this->m->part4.push_back(objGenToIndirect(*iter));
}
// Part 6: first page objects. Note: implementation note 124
@@ -1533,8 +1536,8 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
"object not in lc_first_page_private");
}
lc_first_page_private.erase(first_page_og);
- this->c_linp.first_page_object = pages.at(0).getObjectID();
- this->part6.push_back(pages.at(0));
+ this->m->c_linp.first_page_object = pages.at(0).getObjectID();
+ this->m->part6.push_back(pages.at(0));
// The PDF spec "recommends" an order for the rest of the objects,
// but we are going to disregard it except to the extent that it
@@ -1544,19 +1547,19 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
for (std::set<QPDFObjGen>::iterator iter = lc_first_page_private.begin();
iter != lc_first_page_private.end(); ++iter)
{
- this->part6.push_back(objGenToIndirect(*iter));
+ this->m->part6.push_back(objGenToIndirect(*iter));
}
for (std::set<QPDFObjGen>::iterator iter = lc_first_page_shared.begin();
iter != lc_first_page_shared.end(); ++iter)
{
- this->part6.push_back(objGenToIndirect(*iter));
+ this->m->part6.push_back(objGenToIndirect(*iter));
}
// Place the outline dictionary if it goes in the first page section.
if (outlines_in_first_page)
{
- pushOutlinesToPart(this->part6, lc_outlines, object_stream_data);
+ pushOutlinesToPart(this->m->part6, lc_outlines, object_stream_data);
}
// Fill in page offset hint table information for the first page.
@@ -1565,7 +1568,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// in garbage values for all the shared object identifiers on the
// first page.
- this->c_page_offset_data.entries.at(0).nobjects = this->part6.size();
+ this->m->c_page_offset_data.entries.at(0).nobjects = this->m->part6.size();
// Part 7: other pages' private objects
@@ -1583,16 +1586,16 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
QUtil::int_to_string(i) + " not in lc_other_page_private");
}
lc_other_page_private.erase(page_og);
- this->part7.push_back(pages.at(i));
+ this->m->part7.push_back(pages.at(i));
// Place all non-shared objects referenced by this page,
// updating the page object count for the hint table.
- this->c_page_offset_data.entries.at(i).nobjects = 1;
+ this->m->c_page_offset_data.entries.at(i).nobjects = 1;
ObjUser ou(ObjUser::ou_page, i);
- assert(this->obj_user_to_objects.count(ou) > 0);
- std::set<QPDFObjGen> ogs = this->obj_user_to_objects[ou];
+ assert(this->m->obj_user_to_objects.count(ou) > 0);
+ std::set<QPDFObjGen> ogs = this->m->obj_user_to_objects[ou];
for (std::set<QPDFObjGen>::iterator iter = ogs.begin();
iter != ogs.end(); ++iter)
{
@@ -1600,8 +1603,8 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
if (lc_other_page_private.count(og))
{
lc_other_page_private.erase(og);
- this->part7.push_back(objGenToIndirect(og));
- ++this->c_page_offset_data.entries.at(i).nobjects;
+ this->m->part7.push_back(objGenToIndirect(og));
+ ++this->m->c_page_offset_data.entries.at(i).nobjects;
}
}
}
@@ -1620,7 +1623,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
for (std::set<QPDFObjGen>::iterator iter = lc_other_page_shared.begin();
iter != lc_other_page_shared.end(); ++iter)
{
- this->part8.push_back(objGenToIndirect(*iter));
+ this->m->part8.push_back(objGenToIndirect(*iter));
}
// Part 9: other objects
@@ -1634,7 +1637,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// Place the pages tree.
std::set<QPDFObjGen> pages_ogs =
- this->obj_user_to_objects[ObjUser(ObjUser::ou_root_key, "/Pages")];
+ this->m->obj_user_to_objects[ObjUser(ObjUser::ou_root_key, "/Pages")];
assert(! pages_ogs.empty());
for (std::set<QPDFObjGen>::iterator iter = pages_ogs.begin();
iter != pages_ogs.end(); ++iter)
@@ -1643,7 +1646,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
if (lc_other.count(og))
{
lc_other.erase(og);
- this->part9.push_back(objGenToIndirect(og));
+ this->m->part9.push_back(objGenToIndirect(og));
}
}
@@ -1661,7 +1664,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
if (lc_thumbnail_private.count(thumb_og))
{
lc_thumbnail_private.erase(thumb_og);
- this->part9.push_back(thumb);
+ this->m->part9.push_back(thumb);
}
else
{
@@ -1673,7 +1676,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// lc_thumbnail_private.
}
std::set<QPDFObjGen>& ogs =
- this->obj_user_to_objects[ObjUser(ObjUser::ou_thumb, i)];
+ this->m->obj_user_to_objects[ObjUser(ObjUser::ou_thumb, i)];
for (std::set<QPDFObjGen>::iterator iter = ogs.begin();
iter != ogs.end(); ++iter)
{
@@ -1681,7 +1684,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
if (lc_thumbnail_private.count(og))
{
lc_thumbnail_private.erase(og);
- this->part9.push_back(objGenToIndirect(og));
+ this->m->part9.push_back(objGenToIndirect(og));
}
}
}
@@ -1698,28 +1701,28 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
for (std::set<QPDFObjGen>::iterator iter = lc_thumbnail_shared.begin();
iter != lc_thumbnail_shared.end(); ++iter)
{
- this->part9.push_back(objGenToIndirect(*iter));
+ this->m->part9.push_back(objGenToIndirect(*iter));
}
// Place outlines unless in first page
if (! outlines_in_first_page)
{
- pushOutlinesToPart(this->part9, lc_outlines, object_stream_data);
+ pushOutlinesToPart(this->m->part9, lc_outlines, object_stream_data);
}
// Place all remaining objects
for (std::set<QPDFObjGen>::iterator iter = lc_other.begin();
iter != lc_other.end(); ++iter)
{
- this->part9.push_back(objGenToIndirect(*iter));
+ this->m->part9.push_back(objGenToIndirect(*iter));
}
// Make sure we got everything exactly once.
unsigned int num_placed =
- this->part4.size() + this->part6.size() + this->part7.size() +
- this->part8.size() + this->part9.size();
- unsigned int num_wanted = this->object_to_obj_users.size();
+ this->m->part4.size() + this->m->part6.size() + this->m->part7.size() +
+ this->m->part8.size() + this->m->part9.size();
+ unsigned int num_wanted = this->m->object_to_obj_users.size();
if (num_placed != num_wanted)
{
throw std::logic_error(
@@ -1743,28 +1746,29 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// can map from object number only without regards to generation.
std::map<int, int> obj_to_index;
- this->c_shared_object_data.nshared_first_page = this->part6.size();
- this->c_shared_object_data.nshared_total =
- this->c_shared_object_data.nshared_first_page + this->part8.size();
+ this->m->c_shared_object_data.nshared_first_page = this->m->part6.size();
+ this->m->c_shared_object_data.nshared_total =
+ this->m->c_shared_object_data.nshared_first_page +
+ this->m->part8.size();
std::vector<CHSharedObjectEntry>& shared =
- this->c_shared_object_data.entries;
- for (std::vector<QPDFObjectHandle>::iterator iter = this->part6.begin();
- iter != this->part6.end(); ++iter)
+ this->m->c_shared_object_data.entries;
+ for (std::vector<QPDFObjectHandle>::iterator iter = this->m->part6.begin();
+ iter != this->m->part6.end(); ++iter)
{
QPDFObjectHandle& oh = *iter;
int obj = oh.getObjectID();
obj_to_index[obj] = shared.size();
shared.push_back(CHSharedObjectEntry(obj));
}
- QTC::TC("qpdf", "QPDF lin part 8 empty", this->part8.empty() ? 1 : 0);
- if (! this->part8.empty())
+ QTC::TC("qpdf", "QPDF lin part 8 empty", this->m->part8.empty() ? 1 : 0);
+ if (! this->m->part8.empty())
{
- this->c_shared_object_data.first_shared_obj =
- this->part8.at(0).getObjectID();
+ this->m->c_shared_object_data.first_shared_obj =
+ this->m->part8.at(0).getObjectID();
for (std::vector<QPDFObjectHandle>::iterator iter =
- this->part8.begin();
- iter != this->part8.end(); ++iter)
+ this->m->part8.begin();
+ iter != this->m->part8.end(); ++iter)
{
QPDFObjectHandle& oh = *iter;
int obj = oh.getObjectID();
@@ -1772,8 +1776,8 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
shared.push_back(CHSharedObjectEntry(obj));
}
}
- if (static_cast<size_t>(this->c_shared_object_data.nshared_total) !=
- this->c_shared_object_data.entries.size())
+ if (static_cast<size_t>(this->m->c_shared_object_data.nshared_total) !=
+ this->m->c_shared_object_data.entries.size())
{
throw std::logic_error(
"shared object hint table has wrong number of entries");
@@ -1784,15 +1788,15 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
for (unsigned int i = 1; i < npages; ++i)
{
- CHPageOffsetEntry& pe = this->c_page_offset_data.entries.at(i);
+ CHPageOffsetEntry& pe = this->m->c_page_offset_data.entries.at(i);
ObjUser ou(ObjUser::ou_page, i);
- assert(this->obj_user_to_objects.count(ou) > 0);
- std::set<QPDFObjGen> const& ogs = this->obj_user_to_objects[ou];
+ assert(this->m->obj_user_to_objects.count(ou) > 0);
+ std::set<QPDFObjGen> const& ogs = this->m->obj_user_to_objects[ou];
for (std::set<QPDFObjGen>::const_iterator iter = ogs.begin();
iter != ogs.end(); ++iter)
{
QPDFObjGen const& og = *iter;
- if ((this->object_to_obj_users[og].size() > 1) &&
+ if ((this->m->object_to_obj_users[og].size() > 1) &&
(obj_to_index.count(og.getObj()) > 0))
{
int idx = obj_to_index[og.getObj()];
@@ -1818,18 +1822,18 @@ QPDF::pushOutlinesToPart(
outlines = getUncompressedObject(outlines, object_stream_data);
QPDFObjGen outlines_og(outlines.getObjGen());
QTC::TC("qpdf", "QPDF lin outlines in part",
- ((&part == (&this->part6)) ? 0
- : (&part == (&this->part9)) ? 1
+ ((&part == (&this->m->part6)) ? 0
+ : (&part == (&this->m->part9)) ? 1
: 9999)); // can't happen
- this->c_outline_data.first_object = outlines_og.getObj();
- this->c_outline_data.nobjects = 1;
+ this->m->c_outline_data.first_object = outlines_og.getObj();
+ this->m->c_outline_data.nobjects = 1;
lc_outlines.erase(outlines_og);
part.push_back(outlines);
for (std::set<QPDFObjGen>::iterator iter = lc_outlines.begin();
iter != lc_outlines.end(); ++iter)
{
part.push_back(objGenToIndirect(*iter));
- ++this->c_outline_data.nobjects;
+ ++this->m->c_outline_data.nobjects;
}
}
@@ -1843,11 +1847,11 @@ QPDF::getLinearizedParts(
std::vector<QPDFObjectHandle>& part9)
{
calculateLinearizationData(object_stream_data);
- part4 = this->part4;
- part6 = this->part6;
- part7 = this->part7;
- part8 = this->part8;
- part9 = this->part9;
+ part4 = this->m->part4;
+ part6 = this->m->part6;
+ part7 = this->m->part7;
+ part8 = this->m->part8;
+ part9 = this->m->part9;
}
static inline int nbits(int val)
@@ -1889,7 +1893,7 @@ QPDF::calculateHPageOffset(
std::vector<QPDFObjectHandle> const& pages = getAllPages();
unsigned int npages = pages.size();
- CHPageOffset& cph = this->c_page_offset_data;
+ CHPageOffset& cph = this->m->c_page_offset_data;
std::vector<CHPageOffsetEntry>& cphe = cph.entries;
// Calculate minimum and maximum values for number of objects per
@@ -1902,7 +1906,7 @@ QPDF::calculateHPageOffset(
int max_length = min_length;
int max_shared = cphe.at(0).nshared_objects;
- HPageOffset& ph = this->page_offset_hints;
+ HPageOffset& ph = this->m->page_offset_hints;
std::vector<HPageOffsetEntry>& phe = ph.entries;
// npages is the size of the existing pages array.
phe = std::vector<HPageOffsetEntry>(npages);
@@ -1940,7 +1944,7 @@ QPDF::calculateHPageOffset(
ph.nbits_delta_page_length = nbits(max_length - min_length);
ph.nbits_nshared_objects = nbits(max_shared);
ph.nbits_shared_identifier =
- nbits(this->c_shared_object_data.nshared_total);
+ nbits(this->m->c_shared_object_data.nshared_total);
ph.shared_denominator = 4; // doesn't matter
// It isn't clear how to compute content offset and content
@@ -1975,9 +1979,9 @@ QPDF::calculateHSharedObject(
std::map<int, qpdf_offset_t> const& lengths,
std::map<int, int> const& obj_renumber)
{
- CHSharedObject& cso = this->c_shared_object_data;
+ CHSharedObject& cso = this->m->c_shared_object_data;
std::vector<CHSharedObjectEntry>& csoe = cso.entries;
- HSharedObject& so = this->shared_object_hints;
+ HSharedObject& so = this->m->shared_object_hints;
std::vector<HSharedObjectEntry>& soe = so.entries;
soe.clear();
@@ -2026,14 +2030,14 @@ QPDF::calculateHOutline(
std::map<int, qpdf_offset_t> const& lengths,
std::map<int, int> const& obj_renumber)
{
- HGeneric& cho = this->c_outline_data;
+ HGeneric& cho = this->m->c_outline_data;
if (cho.nobjects == 0)
{
return;
}
- HGeneric& ho = this->outline_hints;
+ HGeneric& ho = this->m->outline_hints;
ho.first_object =
(*(obj_renumber.find(cho.first_object))).second;
@@ -2083,7 +2087,7 @@ write_vector_vector(BitWriter& w,
void
QPDF::writeHPageOffset(BitWriter& w)
{
- HPageOffset& t = this->page_offset_hints;
+ HPageOffset& t = this->m->page_offset_hints;
w.writeBits(t.min_nobjects, 32); // 1
w.writeBits(t.first_page_offset, 32); // 2
@@ -2130,7 +2134,7 @@ QPDF::writeHPageOffset(BitWriter& w)
void
QPDF::writeHSharedObject(BitWriter& w)
{
- HSharedObject& t = this->shared_object_hints;
+ HSharedObject& t = this->m->shared_object_hints;
w.writeBits(t.first_shared_obj, 32); // 1
w.writeBits(t.first_shared_offset, 32); // 2
@@ -2193,10 +2197,10 @@ QPDF::generateHintStream(std::map<int, QPDFXRefEntry> const& xref,
S = c.getCount();
writeHSharedObject(w);
O = 0;
- if (this->outline_hints.nobjects > 0)
+ if (this->m->outline_hints.nobjects > 0)
{
O = c.getCount();
- writeHGeneric(w, this->outline_hints);
+ writeHGeneric(w, this->m->outline_hints);
}
c.finish();
diff --git a/libqpdf/QPDF_optimization.cc b/libqpdf/QPDF_optimization.cc
index fad710d0..1e42865c 100644
--- a/libqpdf/QPDF_optimization.cc
+++ b/libqpdf/QPDF_optimization.cc
@@ -62,7 +62,7 @@ void
QPDF::optimize(std::map<int, int> const& object_stream_data,
bool allow_changes)
{
- if (! this->obj_user_to_objects.empty())
+ if (! this->m->obj_user_to_objects.empty())
{
// already optimized
return;
@@ -83,19 +83,19 @@ QPDF::optimize(std::map<int, int> const& object_stream_data,
}
// Traverse pages tree pushing all inherited resources down to the
- // page level. This also initializes this->all_pages.
+ // page level. This also initializes this->m->all_pages.
pushInheritedAttributesToPage(allow_changes, false);
// Traverse pages
- int n = this->all_pages.size();
+ int n = this->m->all_pages.size();
for (int pageno = 0; pageno < n; ++pageno)
{
updateObjectMaps(ObjUser(ObjUser::ou_page, pageno),
- this->all_pages.at(pageno));
+ this->m->all_pages.at(pageno));
}
// Traverse document-level items
- std::set<std::string> keys = this->trailer.getKeys();
+ std::set<std::string> keys = this->m->trailer.getKeys();
for (std::set<std::string>::iterator iter = keys.begin();
iter != keys.end(); ++iter)
{
@@ -107,7 +107,7 @@ QPDF::optimize(std::map<int, int> const& object_stream_data,
else
{
updateObjectMaps(ObjUser(ObjUser::ou_trailer_key, key),
- this->trailer.getKey(key));
+ this->m->trailer.getKey(key));
}
}
@@ -129,8 +129,8 @@ QPDF::optimize(std::map<int, int> const& object_stream_data,
ObjUser root_ou = ObjUser(ObjUser::ou_root);
QPDFObjGen root_og = QPDFObjGen(root.getObjGen());
- obj_user_to_objects[root_ou].insert(root_og);
- object_to_obj_users[root_og].insert(root_ou);
+ this->m->obj_user_to_objects[root_ou].insert(root_og);
+ this->m->object_to_obj_users[root_og].insert(root_ou);
filterCompressedObjects(object_stream_data);
}
@@ -151,7 +151,7 @@ QPDF::pushInheritedAttributesToPage(bool allow_changes, bool warn_skipped_keys)
// The record of whether we've done this is cleared by
// updateAllPagesCache(). If we're warning for skipped keys,
// re-traverse unconditionally.
- if (this->pushed_inherited_attributes_to_pages && (! warn_skipped_keys))
+ if (this->m->pushed_inherited_attributes_to_pages && (! warn_skipped_keys))
{
return;
}
@@ -159,12 +159,12 @@ QPDF::pushInheritedAttributesToPage(bool allow_changes, bool warn_skipped_keys)
// key_ancestors is a mapping of page attribute keys to a stack of
// Pages nodes that contain values for them.
std::map<std::string, std::vector<QPDFObjectHandle> > key_ancestors;
- this->all_pages.clear();
+ this->m->all_pages.clear();
pushInheritedAttributesToPageInternal(
- this->trailer.getKey("/Root").getKey("/Pages"),
- key_ancestors, this->all_pages, allow_changes, warn_skipped_keys);
+ this->m->trailer.getKey("/Root").getKey("/Pages"),
+ key_ancestors, this->m->all_pages, allow_changes, warn_skipped_keys);
assert(key_ancestors.empty());
- this->pushed_inherited_attributes_to_pages = true;
+ this->m->pushed_inherited_attributes_to_pages = true;
}
void
@@ -192,8 +192,8 @@ QPDF::pushInheritedAttributesToPageInternal2(
if (visited.count(this_og) > 0)
{
throw QPDFExc(
- qpdf_e_pages, this->file->getName(),
- this->last_object_description, 0,
+ qpdf_e_pages, this->m->file->getName(),
+ this->m->last_object_description, 0,
"Loop detected in /Pages structure (inherited attributes)");
}
visited.insert(this_og);
@@ -219,9 +219,9 @@ QPDF::pushInheritedAttributesToPageInternal2(
{
if (! allow_changes)
{
- throw QPDFExc(qpdf_e_internal, this->file->getName(),
- this->last_object_description,
- this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_internal, this->m->file->getName(),
+ this->m->last_object_description,
+ this->m->file->getLastOffset(),
"optimize detected an "
"inheritable attribute when called "
"in no-change mode");
@@ -269,8 +269,8 @@ QPDF::pushInheritedAttributesToPageInternal2(
setLastObjectDescription("Pages object",
cur_pages.getObjectID(),
cur_pages.getGeneration());
- warn(QPDFExc(qpdf_e_pages, this->file->getName(),
- this->last_object_description, 0,
+ warn(QPDFExc(qpdf_e_pages, this->m->file->getName(),
+ this->m->last_object_description, 0,
"Unknown key " + key + " in /Pages object"
" is being discarded as a result of"
" flattening the /Pages tree"));
@@ -337,9 +337,9 @@ QPDF::pushInheritedAttributesToPageInternal2(
}
else
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description,
- this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description,
+ this->m->file->getLastOffset(),
"invalid Type " + type + " in page tree");
}
visited.erase(this_og);
@@ -382,8 +382,8 @@ QPDF::updateObjectMapsInternal(ObjUser const& ou, QPDFObjectHandle oh,
QTC::TC("qpdf", "QPDF opt loop detected");
return;
}
- this->obj_user_to_objects[ou].insert(og);
- this->object_to_obj_users[og].insert(ou);
+ this->m->obj_user_to_objects[ou].insert(og);
+ this->m->object_to_obj_users[og].insert(ou);
visited.insert(og);
}
@@ -445,8 +445,8 @@ QPDF::filterCompressedObjects(std::map<int, int> const& object_stream_data)
std::map<QPDFObjGen, std::set<ObjUser> > t_object_to_obj_users;
for (std::map<ObjUser, std::set<QPDFObjGen> >::iterator i1 =
- this->obj_user_to_objects.begin();
- i1 != this->obj_user_to_objects.end(); ++i1)
+ this->m->obj_user_to_objects.begin();
+ i1 != this->m->obj_user_to_objects.end(); ++i1)
{
ObjUser const& ou = (*i1).first;
std::set<QPDFObjGen> const& objects = (*i1).second;
@@ -468,8 +468,8 @@ QPDF::filterCompressedObjects(std::map<int, int> const& object_stream_data)
}
for (std::map<QPDFObjGen, std::set<ObjUser> >::iterator i1 =
- this->object_to_obj_users.begin();
- i1 != this->object_to_obj_users.end(); ++i1)
+ this->m->object_to_obj_users.begin();
+ i1 != this->m->object_to_obj_users.end(); ++i1)
{
QPDFObjGen const& og = (*i1).first;
std::set<ObjUser> const& objusers = (*i1).second;
@@ -490,6 +490,6 @@ QPDF::filterCompressedObjects(std::map<int, int> const& object_stream_data)
}
}
- this->obj_user_to_objects = t_obj_user_to_objects;
- this->object_to_obj_users = t_object_to_obj_users;
+ this->m->obj_user_to_objects = t_obj_user_to_objects;
+ this->m->object_to_obj_users = t_object_to_obj_users;
}
diff --git a/libqpdf/QPDF_pages.cc b/libqpdf/QPDF_pages.cc
index f9b421c6..31307e4e 100644
--- a/libqpdf/QPDF_pages.cc
+++ b/libqpdf/QPDF_pages.cc
@@ -44,12 +44,12 @@ std::vector<QPDFObjectHandle> const&
QPDF::getAllPages()
{
// Note that pushInheritedAttributesToPage may also be used to
- // initialize this->all_pages.
- if (this->all_pages.empty())
+ // initialize this->m->all_pages.
+ if (this->m->all_pages.empty())
{
- getAllPagesInternal(getRoot().getKey("/Pages"), this->all_pages);
+ getAllPagesInternal(getRoot().getKey("/Pages"), this->m->all_pages);
}
- return this->all_pages;
+ return this->m->all_pages;
}
void
@@ -69,8 +69,8 @@ QPDF::getAllPagesInternal2(QPDFObjectHandle cur_pages,
if (visited.count(this_og) > 0)
{
throw QPDFExc(
- qpdf_e_pages, this->file->getName(),
- this->last_object_description, 0,
+ qpdf_e_pages, this->m->file->getName(),
+ this->m->last_object_description, 0,
"Loop detected in /Pages structure (getAllPages)");
}
visited.insert(this_og);
@@ -103,9 +103,9 @@ QPDF::getAllPagesInternal2(QPDFObjectHandle cur_pages,
}
else
{
- throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
- this->last_object_description,
- this->file->getLastOffset(),
+ throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
+ this->m->last_object_description,
+ this->m->file->getLastOffset(),
"invalid Type " + type + " in page tree");
}
visited.erase(this_og);
@@ -119,9 +119,9 @@ QPDF::updateAllPagesCache()
// it that they got from calls to getAllPages(). We can defer
// recalculation of pageobj_to_pages_pos until needed.
QTC::TC("qpdf", "QPDF updateAllPagesCache");
- this->all_pages.clear();
- this->pageobj_to_pages_pos.clear();
- this->pushed_inherited_attributes_to_pages = false;
+ this->m->all_pages.clear();
+ this->m->pageobj_to_pages_pos.clear();
+ this->m->pushed_inherited_attributes_to_pages = false;
getAllPages();
}
@@ -131,26 +131,26 @@ QPDF::flattenPagesTree()
// If not already done, flatten the /Pages structure and
// initialize pageobj_to_pages_pos.
- if (! this->pageobj_to_pages_pos.empty())
+ if (! this->m->pageobj_to_pages_pos.empty())
{
return;
}
// Push inherited objects down to the /Page level. As a side
- // effect this->all_pages will also be generated.
+ // effect this->m->all_pages will also be generated.
pushInheritedAttributesToPage(true, true);
QPDFObjectHandle pages = getRoot().getKey("/Pages");
- int const len = this->all_pages.size();
+ int const len = this->m->all_pages.size();
for (int pos = 0; pos < len; ++pos)
{
// populate pageobj_to_pages_pos and fix parent pointer
- insertPageobjToPage(this->all_pages.at(pos), pos, true);
- this->all_pages.at(pos).replaceKey("/Parent", pages);
+ insertPageobjToPage(this->m->all_pages.at(pos), pos, true);
+ this->m->all_pages.at(pos).replaceKey("/Parent", pages);
}
- pages.replaceKey("/Kids", QPDFObjectHandle::newArray(this->all_pages));
+ pages.replaceKey("/Kids", QPDFObjectHandle::newArray(this->m->all_pages));
// /Count has not changed
if (pages.getKey("/Count").getIntValue() != len)
{
@@ -165,21 +165,22 @@ QPDF::insertPageobjToPage(QPDFObjectHandle const& obj, int pos,
QPDFObjGen og(obj.getObjGen());
if (check_duplicate)
{
- if (! this->pageobj_to_pages_pos.insert(std::make_pair(og, pos)).second)
+ if (! this->m->pageobj_to_pages_pos.insert(
+ std::make_pair(og, pos)).second)
{
QTC::TC("qpdf", "QPDF duplicate page reference");
setLastObjectDescription("page " + QUtil::int_to_string(pos) +
" (numbered from zero)",
og.getObj(), og.getGen());
- throw QPDFExc(qpdf_e_pages, this->file->getName(),
- this->last_object_description, 0,
+ throw QPDFExc(qpdf_e_pages, this->m->file->getName(),
+ this->m->last_object_description, 0,
"duplicate page reference found;"
" this would cause loss of data");
}
}
else
{
- this->pageobj_to_pages_pos[og] = pos;
+ this->m->pageobj_to_pages_pos[og] = pos;
}
}
@@ -195,13 +196,13 @@ QPDF::insertPage(QPDFObjectHandle newpage, int pos)
if (! newpage.isIndirect())
{
QTC::TC("qpdf", "QPDF insert non-indirect page");
- newpage = this->makeIndirectObject(newpage);
+ newpage = makeIndirectObject(newpage);
}
else if (newpage.getOwningQPDF() != this)
{
QTC::TC("qpdf", "QPDF insert foreign page");
newpage.getOwningQPDF()->pushInheritedAttributesToPage();
- newpage = this->copyForeignObject(newpage, true);
+ newpage = copyForeignObject(newpage, true);
}
else
{
@@ -210,26 +211,26 @@ QPDF::insertPage(QPDFObjectHandle newpage, int pos)
QTC::TC("qpdf", "QPDF insert page",
(pos == 0) ? 0 : // insert at beginning
- (pos == static_cast<int>(this->all_pages.size())) ? 1 : // at end
+ (pos == static_cast<int>(this->m->all_pages.size())) ? 1 : // at end
2); // insert in middle
QPDFObjectHandle pages = getRoot().getKey("/Pages");
QPDFObjectHandle kids = pages.getKey("/Kids");
assert ((pos >= 0) &&
- (static_cast<size_t>(pos) <= this->all_pages.size()));
+ (static_cast<size_t>(pos) <= this->m->all_pages.size()));
newpage.replaceKey("/Parent", pages);
kids.insertItem(pos, newpage);
int npages = kids.getArrayNItems();
pages.replaceKey("/Count", QPDFObjectHandle::newInteger(npages));
- this->all_pages.insert(this->all_pages.begin() + pos, newpage);
- assert(this->all_pages.size() == static_cast<size_t>(npages));
+ this->m->all_pages.insert(this->m->all_pages.begin() + pos, newpage);
+ assert(this->m->all_pages.size() == static_cast<size_t>(npages));
for (int i = pos + 1; i < npages; ++i)
{
- insertPageobjToPage(this->all_pages.at(i), i, false);
+ insertPageobjToPage(this->m->all_pages.at(i), i, false);
}
insertPageobjToPage(newpage, pos, true);
- assert(this->pageobj_to_pages_pos.size() == static_cast<size_t>(npages));
+ assert(this->m->pageobj_to_pages_pos.size() == static_cast<size_t>(npages));
}
void
@@ -238,7 +239,8 @@ QPDF::removePage(QPDFObjectHandle page)
int pos = findPage(page); // also ensures flat /Pages
QTC::TC("qpdf", "QPDF remove page",
(pos == 0) ? 0 : // remove at beginning
- (pos == static_cast<int>(this->all_pages.size() - 1)) ? 1 : // end
+ (pos == static_cast<int>(
+ this->m->all_pages.size() - 1)) ? 1 : // end
2); // remove in middle
QPDFObjectHandle pages = getRoot().getKey("/Pages");
@@ -247,13 +249,13 @@ QPDF::removePage(QPDFObjectHandle page)
kids.eraseItem(pos);
int npages = kids.getArrayNItems();
pages.replaceKey("/Count", QPDFObjectHandle::newInteger(npages));
- this->all_pages.erase(this->all_pages.begin() + pos);
- assert(this->all_pages.size() == static_cast<size_t>(npages));
- this->pageobj_to_pages_pos.erase(page.getObjGen());
- assert(this->pageobj_to_pages_pos.size() == static_cast<size_t>(npages));
+ this->m->all_pages.erase(this->m->all_pages.begin() + pos);
+ assert(this->m->all_pages.size() == static_cast<size_t>(npages));
+ this->m->pageobj_to_pages_pos.erase(page.getObjGen());
+ assert(this->m->pageobj_to_pages_pos.size() == static_cast<size_t>(npages));
for (int i = pos; i < npages; ++i)
{
- insertPageobjToPage(this->all_pages.at(i), i, false);
+ insertPageobjToPage(this->m->all_pages.at(i), i, false);
}
}
@@ -295,12 +297,12 @@ QPDF::findPage(QPDFObjGen const& og)
{
flattenPagesTree();
std::map<QPDFObjGen, int>::iterator it =
- this->pageobj_to_pages_pos.find(og);
- if (it == this->pageobj_to_pages_pos.end())
+ this->m->pageobj_to_pages_pos.find(og);
+ if (it == this->m->pageobj_to_pages_pos.end())
{
setLastObjectDescription("page object", og.getObj(), og.getGen());
- throw QPDFExc(qpdf_e_pages, this->file->getName(),
- this->last_object_description, 0,
+ throw QPDFExc(qpdf_e_pages, this->m->file->getName(),
+ this->m->last_object_description, 0,
"page object not referenced in /Pages tree");
}
return (*it).second;