aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDFWriter.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2022-02-08 15:18:08 +0100
committerJay Berkenbilt <ejb@ql.org>2022-02-08 17:51:15 +0100
commitcb769c62e55599e9f980001830bc61d9fcaa64a9 (patch)
tree0bf980c385a61cbc8720cf990762ffc1200f9d6a /libqpdf/QPDFWriter.cc
parent716381f65a2b2dc72f8da2426ba71aeab02c507f (diff)
downloadqpdf-cb769c62e55599e9f980001830bc61d9fcaa64a9.tar.zst
WHITESPACE ONLY -- expand tabs in source code
This comment expands all tabs using an 8-character tab-width. You should ignore this commit when using git blame or use git blame -w. In the early days, I used to use tabs where possible for indentation, since emacs did this automatically. In recent years, I have switched to only using spaces, which means qpdf source code has been a mixture of spaces and tabs. I have avoided cleaning this up because of not wanting gratuitous whitespaces change to cloud the output of git blame, but I changed my mind after discussing with users who view qpdf source code in editors/IDEs that have other tab widths by default and in light of the fact that I am planning to start applying automatic code formatting soon.
Diffstat (limited to 'libqpdf/QPDFWriter.cc')
-rw-r--r--libqpdf/QPDFWriter.cc1966
1 files changed, 983 insertions, 983 deletions
diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc
index 7940034e..bb568623 100644
--- a/libqpdf/QPDFWriter.cc
+++ b/libqpdf/QPDFWriter.cc
@@ -78,7 +78,7 @@ QPDFWriter::Members::~Members()
{
if (file && close_file)
{
- fclose(file);
+ fclose(file);
}
delete output_buffer;
}
@@ -113,16 +113,16 @@ QPDFWriter::setOutputFilename(char const* filename)
bool close_file = false;
if (filename == 0)
{
- description = "standard output";
- QTC::TC("qpdf", "QPDFWriter write to stdout");
- f = stdout;
- QUtil::binary_stdout();
+ description = "standard output";
+ QTC::TC("qpdf", "QPDFWriter write to stdout");
+ f = stdout;
+ QUtil::binary_stdout();
}
else
{
- QTC::TC("qpdf", "QPDFWriter write to file");
- f = QUtil::safe_fopen(filename, "wb+");
- close_file = true;
+ QTC::TC("qpdf", "QPDFWriter write to file");
+ f = QUtil::safe_fopen(filename, "wb+");
+ close_file = true;
}
setOutputFile(description, f, close_file);
}
@@ -256,26 +256,26 @@ QPDFWriter::setMinimumPDFVersion(std::string const& version,
bool set_extension_level = false;
if (this->m->min_pdf_version.empty())
{
- set_version = true;
+ set_version = true;
set_extension_level = true;
}
else
{
- int old_major = 0;
- int old_minor = 0;
- int min_major = 0;
- int min_minor = 0;
- parseVersion(version, old_major, old_minor);
- parseVersion(this->m->min_pdf_version, min_major, min_minor);
+ int old_major = 0;
+ int old_minor = 0;
+ int min_major = 0;
+ int min_minor = 0;
+ parseVersion(version, old_major, old_minor);
+ parseVersion(this->m->min_pdf_version, min_major, min_minor);
int compare = compareVersions(
old_major, old_minor, min_major, min_minor);
- if (compare > 0)
- {
- QTC::TC("qpdf", "QPDFWriter increasing minimum version",
+ if (compare > 0)
+ {
+ QTC::TC("qpdf", "QPDFWriter increasing minimum version",
extension_level == 0 ? 0 : 1);
- set_version = true;
+ set_version = true;
set_extension_level = true;
- }
+ }
else if (compare == 0)
{
if (extension_level > this->m->min_extension_level)
@@ -283,12 +283,12 @@ QPDFWriter::setMinimumPDFVersion(std::string const& version,
QTC::TC("qpdf", "QPDFWriter increasing extension level");
set_extension_level = true;
}
- }
+ }
}
if (set_version)
{
- this->m->min_pdf_version = version;
+ this->m->min_pdf_version = version;
}
if (set_extension_level)
{
@@ -337,7 +337,7 @@ QPDFWriter::setStaticAesIV(bool val)
{
if (val)
{
- Pl_AES_PDF::useStaticIV();
+ Pl_AES_PDF::useStaticIV();
}
}
@@ -388,19 +388,19 @@ QPDFWriter::setR2EncryptionParameters(
std::set<int> clear;
if (! allow_print)
{
- clear.insert(3);
+ clear.insert(3);
}
if (! allow_modify)
{
- clear.insert(4);
+ clear.insert(4);
}
if (! allow_extract)
{
- clear.insert(5);
+ clear.insert(5);
}
if (! allow_annotate)
{
- clear.insert(6);
+ clear.insert(6);
}
setEncryptionParameters(user_password, owner_password, 1, 2, 5, clear);
@@ -414,8 +414,8 @@ QPDFWriter::setR3EncryptionParameters(
{
std::set<int> clear;
interpretR3EncryptionParameters(
- clear, user_password, owner_password,
- allow_accessibility, allow_extract,
+ clear, user_password, owner_password,
+ allow_accessibility, allow_extract,
true, true, true, true, print, modify);
setEncryptionParameters(user_password, owner_password, 2, 3, 16, clear);
}
@@ -430,8 +430,8 @@ QPDFWriter::setR3EncryptionParameters(
{
std::set<int> clear;
interpretR3EncryptionParameters(
- clear, user_password, owner_password,
- allow_accessibility, allow_extract,
+ clear, user_password, owner_password,
+ allow_accessibility, allow_extract,
allow_assemble, allow_annotate_and_form,
allow_form_filling, allow_modify_other,
print, qpdf_r3m_all);
@@ -447,8 +447,8 @@ QPDFWriter::setR4EncryptionParameters(
{
std::set<int> clear;
interpretR3EncryptionParameters(
- clear, user_password, owner_password,
- allow_accessibility, allow_extract,
+ clear, user_password, owner_password,
+ allow_accessibility, allow_extract,
true, true, true, true, print, modify);
this->m->encrypt_use_aes = use_aes;
this->m->encrypt_metadata = encrypt_metadata;
@@ -466,8 +466,8 @@ QPDFWriter::setR4EncryptionParameters(
{
std::set<int> clear;
interpretR3EncryptionParameters(
- clear, user_password, owner_password,
- allow_accessibility, allow_extract,
+ clear, user_password, owner_password,
+ allow_accessibility, allow_extract,
allow_assemble, allow_annotate_and_form,
allow_form_filling, allow_modify_other,
print, qpdf_r3m_all);
@@ -485,8 +485,8 @@ QPDFWriter::setR5EncryptionParameters(
{
std::set<int> clear;
interpretR3EncryptionParameters(
- clear, user_password, owner_password,
- allow_accessibility, allow_extract,
+ clear, user_password, owner_password,
+ allow_accessibility, allow_extract,
true, true, true, true, print, modify);
this->m->encrypt_use_aes = true;
this->m->encrypt_metadata = encrypt_metadata;
@@ -504,8 +504,8 @@ QPDFWriter::setR5EncryptionParameters(
{
std::set<int> clear;
interpretR3EncryptionParameters(
- clear, user_password, owner_password,
- allow_accessibility, allow_extract,
+ clear, user_password, owner_password,
+ allow_accessibility, allow_extract,
allow_assemble, allow_annotate_and_form,
allow_form_filling, allow_modify_other,
print, qpdf_r3m_all);
@@ -523,8 +523,8 @@ QPDFWriter::setR6EncryptionParameters(
{
std::set<int> clear;
interpretR3EncryptionParameters(
- clear, user_password, owner_password,
- allow_accessibility, allow_extract,
+ clear, user_password, owner_password,
+ allow_accessibility, allow_extract,
true, true, true, true, print, modify);
this->m->encrypt_use_aes = true;
this->m->encrypt_metadata = encrypt_metadata;
@@ -542,8 +542,8 @@ QPDFWriter::setR6EncryptionParameters(
{
std::set<int> clear;
interpretR3EncryptionParameters(
- clear, user_password, owner_password,
- allow_accessibility, allow_extract,
+ clear, user_password, owner_password,
+ allow_accessibility, allow_extract,
allow_assemble, allow_annotate_and_form,
allow_form_filling, allow_modify_other,
print, qpdf_r3m_all);
@@ -594,11 +594,11 @@ QPDFWriter::interpretR3EncryptionParameters(
if (! allow_accessibility)
{
// setEncryptionParameters sets this if R > 3
- clear.insert(10);
+ clear.insert(10);
}
if (! allow_extract)
{
- clear.insert(5);
+ clear.insert(5);
}
// Note: these switch statements all "fall through" (no break
@@ -606,15 +606,15 @@ QPDFWriter::interpretR3EncryptionParameters(
switch (print)
{
case qpdf_r3p_none:
- clear.insert(3); // any printing
+ clear.insert(3); // any printing
case qpdf_r3p_low:
- clear.insert(12); // high resolution printing
+ clear.insert(12); // high resolution printing
case qpdf_r3p_full:
- break;
+ break;
- // no default so gcc warns for missing cases
+ // no default so gcc warns for missing cases
}
// Modify options. The qpdf_r3_modify_e options control groups of
@@ -627,21 +627,21 @@ QPDFWriter::interpretR3EncryptionParameters(
switch (modify)
{
case qpdf_r3m_none:
- clear.insert(11); // document assembly
+ clear.insert(11); // document assembly
case qpdf_r3m_assembly:
- clear.insert(9); // filling in form fields
+ clear.insert(9); // filling in form fields
case qpdf_r3m_form:
- clear.insert(6); // modify annotations, fill in form fields
+ clear.insert(6); // modify annotations, fill in form fields
case qpdf_r3m_annotate:
- clear.insert(4); // other modifications
+ clear.insert(4); // other modifications
case qpdf_r3m_all:
- break;
+ break;
- // no default so gcc warns for missing cases
+ // no default so gcc warns for missing cases
}
// END NOT EXERCISED IN TEST SUITE
@@ -686,9 +686,9 @@ QPDFWriter::setEncryptionParameters(
int P = 0;
// Create the complement of P, then invert.
for (std::set<int>::iterator iter = bits_to_clear.begin();
- iter != bits_to_clear.end(); ++iter)
+ iter != bits_to_clear.end(); ++iter)
{
- P |= (1 << ((*iter) - 1));
+ P |= (1 << ((*iter) - 1));
}
P = ~P;
@@ -713,7 +713,7 @@ QPDFWriter::setEncryptionParameters(
encryption_key, O, U, OE, UE, Perms);
}
setEncryptionParametersInternal(
- V, R, key_len, P, O, U, OE, UE, Perms,
+ V, R, key_len, P, O, U, OE, UE, Perms,
this->m->id1, user_password, encryption_key);
}
@@ -727,19 +727,19 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf)
generateID();
this->m->id1 =
trailer.getKey("/ID").getArrayItem(0).getStringValue();
- QPDFObjectHandle encrypt = trailer.getKey("/Encrypt");
- int V = encrypt.getKey("/V").getIntValueAsInt();
- int key_len = 5;
- if (V > 1)
- {
- key_len = encrypt.getKey("/Length").getIntValueAsInt() / 8;
- }
- if (encrypt.hasKey("/EncryptMetadata") &&
- encrypt.getKey("/EncryptMetadata").isBool())
- {
- this->m->encrypt_metadata =
- encrypt.getKey("/EncryptMetadata").getBoolValue();
- }
+ QPDFObjectHandle encrypt = trailer.getKey("/Encrypt");
+ int V = encrypt.getKey("/V").getIntValueAsInt();
+ int key_len = 5;
+ if (V > 1)
+ {
+ key_len = encrypt.getKey("/Length").getIntValueAsInt() / 8;
+ }
+ if (encrypt.hasKey("/EncryptMetadata") &&
+ encrypt.getKey("/EncryptMetadata").isBool())
+ {
+ this->m->encrypt_metadata =
+ encrypt.getKey("/EncryptMetadata").getBoolValue();
+ }
if (V >= 4)
{
// When copying encryption parameters, use AES even if the
@@ -750,8 +750,8 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf)
// different values.
this->m->encrypt_use_aes = true;
}
- QTC::TC("qpdf", "QPDFWriter copy encrypt metadata",
- this->m->encrypt_metadata ? 0 : 1);
+ QTC::TC("qpdf", "QPDFWriter copy encrypt metadata",
+ this->m->encrypt_metadata ? 0 : 1);
QTC::TC("qpdf", "QPDFWriter copy use_aes",
this->m->encrypt_use_aes ? 0 : 1);
std::string OE;
@@ -761,24 +761,24 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf)
if (V >= 5)
{
QTC::TC("qpdf", "QPDFWriter copy V5");
- OE = encrypt.getKey("/OE").getStringValue();
+ OE = encrypt.getKey("/OE").getStringValue();
UE = encrypt.getKey("/UE").getStringValue();
- Perms = encrypt.getKey("/Perms").getStringValue();
+ Perms = encrypt.getKey("/Perms").getStringValue();
encryption_key = qpdf.getEncryptionKey();
}
- setEncryptionParametersInternal(
- V,
- encrypt.getKey("/R").getIntValueAsInt(),
- key_len,
- static_cast<int>(encrypt.getKey("/P").getIntValue()),
- encrypt.getKey("/O").getStringValue(),
- encrypt.getKey("/U").getStringValue(),
+ setEncryptionParametersInternal(
+ V,
+ encrypt.getKey("/R").getIntValueAsInt(),
+ key_len,
+ static_cast<int>(encrypt.getKey("/P").getIntValue()),
+ encrypt.getKey("/O").getStringValue(),
+ encrypt.getKey("/U").getStringValue(),
OE,
UE,
Perms,
- this->m->id1, // this->m->id1 == the other file's id1
- qpdf.getPaddedUserPassword(),
+ this->m->id1, // this->m->id1 == the other file's id1
+ qpdf.getPaddedUserPassword(),
encryption_key);
}
}
@@ -789,41 +789,41 @@ QPDFWriter::disableIncompatibleEncryption(int major, int minor,
{
if (! this->m->encrypted)
{
- return;
+ return;
}
bool disable = false;
if (compareVersions(major, minor, 1, 3) < 0)
{
- disable = true;
+ disable = true;
}
else
{
- int V = QUtil::string_to_int(
+ int V = QUtil::string_to_int(
this->m->encryption_dictionary["/V"].c_str());
- int R = QUtil::string_to_int(
+ int R = QUtil::string_to_int(
this->m->encryption_dictionary["/R"].c_str());
- if (compareVersions(major, minor, 1, 4) < 0)
- {
- if ((V > 1) || (R > 2))
- {
- disable = true;
- }
- }
- else if (compareVersions(major, minor, 1, 5) < 0)
- {
- if ((V > 2) || (R > 3))
- {
- disable = true;
- }
- }
- else if (compareVersions(major, minor, 1, 6) < 0)
- {
- if (this->m->encrypt_use_aes)
- {
- disable = true;
- }
- }
+ if (compareVersions(major, minor, 1, 4) < 0)
+ {
+ if ((V > 1) || (R > 2))
+ {
+ disable = true;
+ }
+ }
+ else if (compareVersions(major, minor, 1, 5) < 0)
+ {
+ if ((V > 2) || (R > 3))
+ {
+ disable = true;
+ }
+ }
+ else if (compareVersions(major, minor, 1, 6) < 0)
+ {
+ if (this->m->encrypt_use_aes)
+ {
+ disable = true;
+ }
+ }
else if ((compareVersions(major, minor, 1, 7) < 0) ||
((compareVersions(major, minor, 1, 7) == 0) &&
extension_level < 3))
@@ -836,24 +836,24 @@ QPDFWriter::disableIncompatibleEncryption(int major, int minor,
}
if (disable)
{
- QTC::TC("qpdf", "QPDFWriter forced version disabled encryption");
- this->m->encrypted = false;
+ QTC::TC("qpdf", "QPDFWriter forced version disabled encryption");
+ this->m->encrypted = false;
}
}
void
QPDFWriter::parseVersion(std::string const& version,
- int& major, int& minor) const
+ int& major, int& minor) const
{
major = QUtil::string_to_int(version.c_str());
minor = 0;
size_t p = version.find('.');
if ((p != std::string::npos) && (version.length() > p))
{
- minor = QUtil::string_to_int(version.substr(p + 1).c_str());
+ minor = QUtil::string_to_int(version.substr(p + 1).c_str());
}
std::string tmp = QUtil::int_to_string(major) + "." +
- QUtil::int_to_string(minor);
+ QUtil::int_to_string(minor);
if (tmp != version)
{
// The version number in the input is probably invalid. This
@@ -866,27 +866,27 @@ QPDFWriter::parseVersion(std::string const& version,
int
QPDFWriter::compareVersions(int major1, int minor1,
- int major2, int minor2) const
+ int major2, int minor2) const
{
if (major1 < major2)
{
- return -1;
+ return -1;
}
else if (major1 > major2)
{
- return 1;
+ return 1;
}
else if (minor1 < minor2)
{
- return -1;
+ return -1;
}
else if (minor1 > minor2)
{
- return 1;
+ return 1;
}
else
{
- return 0;
+ return 0;
}
}
@@ -938,29 +938,29 @@ QPDFWriter::setEncryptionParametersInternal(
if ((R >= 4) && (! this->m->encrypt_metadata))
{
- this->m->encryption_dictionary["/EncryptMetadata"] = "false";
+ this->m->encryption_dictionary["/EncryptMetadata"] = "false";
}
if ((V == 4) || (V == 5))
{
- // The spec says the value for the crypt filter key can be
- // anything, and xpdf seems to agree. However, Adobe Reader
- // won't open our files unless we use /StdCF.
- this->m->encryption_dictionary["/StmF"] = "/StdCF";
- this->m->encryption_dictionary["/StrF"] = "/StdCF";
- std::string method = (this->m->encrypt_use_aes
+ // The spec says the value for the crypt filter key can be
+ // anything, and xpdf seems to agree. However, Adobe Reader
+ // won't open our files unless we use /StdCF.
+ this->m->encryption_dictionary["/StmF"] = "/StdCF";
+ this->m->encryption_dictionary["/StrF"] = "/StdCF";
+ std::string method = (this->m->encrypt_use_aes
? ((V < 5) ? "/AESV2" : "/AESV3")
: "/V2");
// The PDF spec says the /Length key is optional, but the PDF
// previewer on some versions of MacOS won't open encrypted
// files without it.
- this->m->encryption_dictionary["/CF"] =
- "<< /StdCF << /AuthEvent /DocOpen /CFM " + method +
+ this->m->encryption_dictionary["/CF"] =
+ "<< /StdCF << /AuthEvent /DocOpen /CFM " + method +
" /Length " + std::string((V < 5) ? "16" : "32") + " >> >>";
}
this->m->encrypted = true;
QPDF::EncryptionData encryption_data(
- V, R, key_len, P, O, U, OE, UE, Perms, id1, this->m->encrypt_metadata);
+ V, R, key_len, P, O, U, OE, UE, Perms, id1, this->m->encrypt_metadata);
if (V < 5)
{
this->m->encryption_key = QPDF::compute_encryption_key(
@@ -976,7 +976,7 @@ void
QPDFWriter::setDataKey(int objid)
{
this->m->cur_data_key = QPDF::compute_data_key(
- this->m->encryption_key, objid, 0,
+ this->m->encryption_key, objid, 0,
this->m->encrypt_use_aes, this->m->encryption_V, this->m->encryption_R);
}
@@ -986,8 +986,8 @@ QPDFWriter::bytesNeeded(long long n)
unsigned int bytes = 0;
while (n)
{
- ++bytes;
- n >>= 8;
+ ++bytes;
+ n >>= 8;
}
return bytes;
}
@@ -1003,8 +1003,8 @@ QPDFWriter::writeBinary(unsigned long long val, unsigned int bytes)
unsigned char data[sizeof(unsigned long long)];
for (unsigned int i = 0; i < bytes; ++i)
{
- data[bytes - i - 1] = static_cast<unsigned char>(val & 0xff);
- val >>= 8;
+ data[bytes - i - 1] = static_cast<unsigned char>(val & 0xff);
+ val >>= 8;
}
this->m->pipeline->write(data, bytes);
}
@@ -1026,7 +1026,7 @@ QPDFWriter::writeStringQDF(std::string const& str)
{
if (this->m->qdf_mode)
{
- writeString(str);
+ writeString(str);
}
}
@@ -1035,7 +1035,7 @@ QPDFWriter::writeStringNoQDF(std::string const& str)
{
if (! this->m->qdf_mode)
{
- writeString(str);
+ writeString(str);
}
}
@@ -1044,7 +1044,7 @@ QPDFWriter::writePad(int nspaces)
{
for (int i = 0; i < nspaces; ++i)
{
- writeString(" ");
+ writeString(" ");
}
}
@@ -1087,7 +1087,7 @@ QPDFWriter::PipelinePopper::~PipelinePopper()
assert(qw->m->pipeline_stack.size() >= 2);
qw->m->pipeline->finish();
assert(dynamic_cast<Pl_Count*>(qw->m->pipeline_stack.back()) ==
- qw->m->pipeline);
+ qw->m->pipeline);
// It might be possible for this assertion to fail if
// writeLinearized exits by exception when deterministic ID, but I
// don't think so. As of this writing, this is the only case in
@@ -1099,18 +1099,18 @@ QPDFWriter::PipelinePopper::~PipelinePopper()
qw->m->pipeline_stack.pop_back();
while (dynamic_cast<Pl_Count*>(qw->m->pipeline_stack.back()) == 0)
{
- Pipeline* p = qw->m->pipeline_stack.back();
+ Pipeline* p = qw->m->pipeline_stack.back();
if (dynamic_cast<Pl_MD5*>(p) == qw->m->md5_pipeline)
{
qw->m->md5_pipeline = 0;
}
- qw->m->pipeline_stack.pop_back();
- Pl_Buffer* buf = dynamic_cast<Pl_Buffer*>(p);
- if (bp && buf)
- {
- *bp = buf->getBufferSharedPointer();
- }
- delete p;
+ qw->m->pipeline_stack.pop_back();
+ Pl_Buffer* buf = dynamic_cast<Pl_Buffer*>(p);
+ if (bp && buf)
+ {
+ *bp = buf->getBufferSharedPointer();
+ }
+ delete p;
}
qw->m->pipeline = dynamic_cast<Pl_Count*>(qw->m->pipeline_stack.back());
}
@@ -1119,12 +1119,12 @@ void
QPDFWriter::adjustAESStreamLength(size_t& length)
{
if (this->m->encrypted && (! this->m->cur_data_key.empty()) &&
- this->m->encrypt_use_aes)
+ this->m->encrypt_use_aes)
{
- // Stream length will be padded with 1 to 16 bytes to end up
- // as a multiple of 16. It will also be prepended by 16 bits
- // of random data.
- length += 32 - (length & 0xf);
+ // Stream length will be padded with 1 to 16 bytes to end up
+ // as a multiple of 16. It will also be prepended by 16 bits
+ // of random data.
+ length += 32 - (length & 0xf);
}
}
@@ -1133,21 +1133,21 @@ QPDFWriter::pushEncryptionFilter(PipelinePopper& pp)
{
if (this->m->encrypted && (! this->m->cur_data_key.empty()))
{
- Pipeline* p = 0;
- if (this->m->encrypt_use_aes)
- {
- p = new Pl_AES_PDF(
- "aes stream encryption", this->m->pipeline, true,
- QUtil::unsigned_char_pointer(this->m->cur_data_key),
+ Pipeline* p = 0;
+ if (this->m->encrypt_use_aes)
+ {
+ p = new Pl_AES_PDF(
+ "aes stream encryption", this->m->pipeline, true,
+ QUtil::unsigned_char_pointer(this->m->cur_data_key),
this->m->cur_data_key.length());
- }
- else
- {
- p = new Pl_RC4("rc4 stream encryption", this->m->pipeline,
- QUtil::unsigned_char_pointer(this->m->cur_data_key),
- QIntC::to_int(this->m->cur_data_key.length()));
- }
- pushPipeline(p);
+ }
+ else
+ {
+ p = new Pl_RC4("rc4 stream encryption", this->m->pipeline,
+ QUtil::unsigned_char_pointer(this->m->cur_data_key),
+ QIntC::to_int(this->m->cur_data_key.length()));
+ }
+ pushPipeline(p);
}
// Must call this unconditionally so we can call popPipelineStack
// to balance pushEncryptionFilter().
@@ -1196,7 +1196,7 @@ QPDFWriter::openObject(int objid)
{
if (objid == 0)
{
- objid = this->m->next_objid++;
+ objid = this->m->next_objid++;
}
this->m->xref[objid] = QPDFXRefEntry(1, this->m->pipeline->getCount(), 0);
writeString(QUtil::int_to_string(objid));
@@ -1223,17 +1223,17 @@ QPDFWriter::assignCompressedObjectNumbers(QPDFObjGen const& og)
(this->m->object_stream_to_objects.count(objid) == 0))
{
// This is not an object stream.
- return;
+ return;
}
// Reserve numbers for the objects that belong to this object
// stream.
for (std::set<QPDFObjGen>::iterator iter =
- this->m->object_stream_to_objects[objid].begin();
- iter != this->m->object_stream_to_objects[objid].end();
- ++iter)
+ this->m->object_stream_to_objects[objid].begin();
+ iter != this->m->object_stream_to_objects[objid].end();
+ ++iter)
{
- this->m->obj_renumber[*iter] = this->m->next_objid++;
+ this->m->obj_renumber[*iter] = this->m->next_objid++;
}
}
@@ -1264,45 +1264,45 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object)
return;
}
- QPDFObjGen og = object.getObjGen();
+ QPDFObjGen og = object.getObjGen();
- if (this->m->obj_renumber.count(og) == 0)
- {
- if (this->m->object_to_object_stream.count(og))
- {
- // This is in an object stream. Don't process it
- // here. Instead, enqueue the object stream. Object
- // streams always have generation 0.
- int stream_id = this->m->object_to_object_stream[og];
+ if (this->m->obj_renumber.count(og) == 0)
+ {
+ if (this->m->object_to_object_stream.count(og))
+ {
+ // This is in an object stream. Don't process it
+ // here. Instead, enqueue the object stream. Object
+ // streams always have generation 0.
+ int stream_id = this->m->object_to_object_stream[og];
// Detect loops by storing invalid object ID 0, which
// will get overwritten later.
this->m->obj_renumber[og] = 0;
- enqueueObject(this->m->pdf.getObjectByID(stream_id, 0));
- }
- else
- {
- this->m->object_queue.push_back(object);
- this->m->obj_renumber[og] = this->m->next_objid++;
-
- if ((og.getGen() == 0) &&
+ enqueueObject(this->m->pdf.getObjectByID(stream_id, 0));
+ }
+ else
+ {
+ this->m->object_queue.push_back(object);
+ this->m->obj_renumber[og] = this->m->next_objid++;
+
+ if ((og.getGen() == 0) &&
this->m->object_stream_to_objects.count(og.getObj()))
- {
- // For linearized files, uncompressed objects go
- // at end, and we take care of assigning numbers
- // to them elsewhere.
- if (! this->m->linearized)
- {
- assignCompressedObjectNumbers(og);
- }
- }
- else if ((! this->m->direct_stream_lengths) &&
+ {
+ // For linearized files, uncompressed objects go
+ // at end, and we take care of assigning numbers
+ // to them elsewhere.
+ if (! this->m->linearized)
+ {
+ assignCompressedObjectNumbers(og);
+ }
+ }
+ else if ((! this->m->direct_stream_lengths) &&
object.isStream())
- {
- // reserve next object ID for length
- ++this->m->next_objid;
- }
- }
- }
+ {
+ // reserve next object ID for length
+ ++this->m->next_objid;
+ }
+ }
+ }
else if (this->m->obj_renumber[og] == 0)
{
// This can happen if a specially constructed file
@@ -1312,30 +1312,30 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object)
}
else if (object.isArray())
{
- int n = object.getArrayNItems();
- for (int i = 0; i < n; ++i)
- {
- if (! this->m->linearized)
- {
- enqueueObject(object.getArrayItem(i));
- }
- }
+ int n = object.getArrayNItems();
+ for (int i = 0; i < n; ++i)
+ {
+ if (! this->m->linearized)
+ {
+ enqueueObject(object.getArrayItem(i));
+ }
+ }
}
else if (object.isDictionary())
{
- std::set<std::string> keys = object.getKeys();
- for (std::set<std::string>::iterator iter = keys.begin();
- iter != keys.end(); ++iter)
- {
- if (! this->m->linearized)
- {
- enqueueObject(object.getKey(*iter));
- }
- }
+ std::set<std::string> keys = object.getKeys();
+ for (std::set<std::string>::iterator iter = keys.begin();
+ iter != keys.end(); ++iter)
+ {
+ if (! this->m->linearized)
+ {
+ enqueueObject(object.getKey(*iter));
+ }
+ }
}
else
{
- // ignore
+ // ignore
}
}
@@ -1344,18 +1344,18 @@ QPDFWriter::unparseChild(QPDFObjectHandle child, int level, int flags)
{
if (! this->m->linearized)
{
- enqueueObject(child);
+ enqueueObject(child);
}
if (child.isIndirect())
{
- QPDFObjGen old_og = child.getObjGen();
- int new_id = this->m->obj_renumber[old_og];
- writeString(QUtil::int_to_string(new_id));
- writeString(" 0 R");
+ QPDFObjGen old_og = child.getObjGen();
+ int new_id = this->m->obj_renumber[old_og];
+ writeString(QUtil::int_to_string(new_id));
+ writeString(" 0 R");
}
else
{
- unparseObject(child, level, flags);
+ unparseObject(child, level, flags);
}
}
@@ -1370,49 +1370,49 @@ QPDFWriter::writeTrailer(trailer_e which, int size, bool xref_stream,
}
else
{
- writeString("trailer <<");
+ writeString("trailer <<");
}
writeStringQDF("\n");
if (which == t_lin_second)
{
- writeString(" /Size ");
- writeString(QUtil::int_to_string(size));
+ writeString(" /Size ");
+ writeString(QUtil::int_to_string(size));
}
else
{
- std::set<std::string> keys = trailer.getKeys();
- for (std::set<std::string>::iterator iter = keys.begin();
- iter != keys.end(); ++iter)
- {
- std::string const& key = *iter;
- writeStringQDF(" ");
- writeStringNoQDF(" ");
- writeString(QPDF_Name::normalizeName(key));
- writeString(" ");
- if (key == "/Size")
- {
- writeString(QUtil::int_to_string(size));
- if (which == t_lin_first)
- {
- writeString(" /Prev ");
- qpdf_offset_t pos = this->m->pipeline->getCount();
- writeString(QUtil::int_to_string(prev));
- int nspaces =
+ std::set<std::string> keys = trailer.getKeys();
+ for (std::set<std::string>::iterator iter = keys.begin();
+ iter != keys.end(); ++iter)
+ {
+ std::string const& key = *iter;
+ writeStringQDF(" ");
+ writeStringNoQDF(" ");
+ writeString(QPDF_Name::normalizeName(key));
+ writeString(" ");
+ if (key == "/Size")
+ {
+ writeString(QUtil::int_to_string(size));
+ if (which == t_lin_first)
+ {
+ writeString(" /Prev ");
+ qpdf_offset_t pos = this->m->pipeline->getCount();
+ writeString(QUtil::int_to_string(prev));
+ int nspaces =
QIntC::to_int(pos - this->m->pipeline->getCount() + 21);
- if (nspaces < 0)
+ if (nspaces < 0)
{
throw std::logic_error(
"QPDFWriter: no padding required in trailer");
}
- writePad(nspaces);
- }
- }
- else
- {
- unparseChild(trailer.getKey(key), 1, 0);
- }
- writeStringQDF("\n");
- }
+ writePad(nspaces);
+ }
+ }
+ else
+ {
+ unparseChild(trailer.getKey(key), 1, 0);
+ }
+ writeStringQDF("\n");
+ }
}
// Write ID
@@ -1420,7 +1420,7 @@ QPDFWriter::writeTrailer(trailer_e which, int size, bool xref_stream,
writeString(" /ID [");
if (linearization_pass == 1)
{
- std::string original_id1 = getOriginalID1();
+ std::string original_id1 = getOriginalID1();
if (original_id1.empty())
{
writeString("<00000000000000000000000000000000>");
@@ -1457,13 +1457,13 @@ QPDFWriter::writeTrailer(trailer_e which, int size, bool xref_stream,
if (which != t_lin_second)
{
- // Write reference to encryption dictionary
- if (this->m->encrypted)
- {
- writeString(" /Encrypt ");
- writeString(QUtil::int_to_string(this->m->encryption_dict_objid));
- writeString(" 0 R");
- }
+ // Write reference to encryption dictionary
+ if (this->m->encrypted)
+ {
+ writeString(" /Encrypt ");
+ writeString(QUtil::int_to_string(this->m->encryption_dict_objid));
+ writeString(" 0 R");
+ }
}
writeStringQDF("\n");
@@ -1569,7 +1569,7 @@ QPDFWriter::willFilterStream(QPDFObjectHandle stream,
void
QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
- int flags, size_t stream_length,
+ int flags, size_t stream_length,
bool compress)
{
QPDFObjGen old_og = object.getObjGen();
@@ -1578,30 +1578,30 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
std::string indent;
for (int i = 0; i < level; ++i)
{
- indent += " ";
+ indent += " ";
}
if (object.isArray())
{
- // Note: PDF spec 1.4 implementation note 121 states that
- // Acrobat requires a space after the [ in the /H key of the
- // linearization parameter dictionary. We'll do this
- // unconditionally for all arrays because it looks nicer and
- // doesn't make the files that much bigger.
- writeString("[");
- writeStringQDF("\n");
- int n = object.getArrayNItems();
- for (int i = 0; i < n; ++i)
- {
- writeStringQDF(indent);
- writeStringQDF(" ");
- writeStringNoQDF(" ");
- unparseChild(object.getArrayItem(i), level + 1, child_flags);
- writeStringQDF("\n");
- }
- writeStringQDF(indent);
- writeStringNoQDF(" ");
- writeString("]");
+ // Note: PDF spec 1.4 implementation note 121 states that
+ // Acrobat requires a space after the [ in the /H key of the
+ // linearization parameter dictionary. We'll do this
+ // unconditionally for all arrays because it looks nicer and
+ // doesn't make the files that much bigger.
+ writeString("[");
+ writeStringQDF("\n");
+ int n = object.getArrayNItems();
+ for (int i = 0; i < n; ++i)
+ {
+ writeStringQDF(indent);
+ writeStringQDF(" ");
+ writeStringNoQDF(" ");
+ unparseChild(object.getArrayItem(i), level + 1, child_flags);
+ writeStringQDF("\n");
+ }
+ writeStringQDF(indent);
+ writeStringNoQDF(" ");
+ writeString("]");
}
else if (object.isDictionary())
{
@@ -1742,7 +1742,7 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
object.removeKey("/DecodeParms");
}
- if (flags & f_filtered)
+ if (flags & f_filtered)
{
// We will supply our own filter and decode
// parameters.
@@ -1791,96 +1791,96 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
}
}
- writeString("<<");
- writeStringQDF("\n");
-
- std::set<std::string> keys = object.getKeys();
- for (std::set<std::string>::iterator iter = keys.begin();
- iter != keys.end(); ++iter)
- {
- std::string const& key = *iter;
-
- writeStringQDF(indent);
- writeStringQDF(" ");
- writeStringNoQDF(" ");
- writeString(QPDF_Name::normalizeName(key));
- writeString(" ");
- if (key == "/Contents" &&
- object.isDictionaryOfType("/Sig") &&
- object.hasKey("/ByteRange"))
- {
+ writeString("<<");
+ writeStringQDF("\n");
+
+ std::set<std::string> keys = object.getKeys();
+ for (std::set<std::string>::iterator iter = keys.begin();
+ iter != keys.end(); ++iter)
+ {
+ std::string const& key = *iter;
+
+ writeStringQDF(indent);
+ writeStringQDF(" ");
+ writeStringNoQDF(" ");
+ writeString(QPDF_Name::normalizeName(key));
+ writeString(" ");
+ if (key == "/Contents" &&
+ object.isDictionaryOfType("/Sig") &&
+ object.hasKey("/ByteRange"))
+ {
QTC::TC("qpdf", "QPDFWriter no encryption sig contents");
- unparseChild(object.getKey(key), level + 1,
- child_flags | f_hex_string | f_no_encryption);
- }
- else
- {
- unparseChild(object.getKey(key), level + 1, child_flags);
- }
- writeStringQDF("\n");
- }
-
- if (flags & f_stream)
- {
- writeStringQDF(indent);
- writeStringQDF(" ");
- writeString(" /Length ");
-
- if (this->m->direct_stream_lengths)
- {
- writeString(QUtil::uint_to_string(stream_length));
- }
- else
- {
- writeString(
- QUtil::int_to_string(this->m->cur_stream_length_id));
- writeString(" 0 R");
- }
- writeStringQDF("\n");
- if (compress && (flags & f_filtered))
- {
- writeStringQDF(indent);
- writeStringQDF(" ");
- writeString(" /Filter /FlateDecode");
- writeStringQDF("\n");
- }
- }
-
- writeStringQDF(indent);
- writeStringNoQDF(" ");
- writeString(">>");
+ unparseChild(object.getKey(key), level + 1,
+ child_flags | f_hex_string | f_no_encryption);
+ }
+ else
+ {
+ unparseChild(object.getKey(key), level + 1, child_flags);
+ }
+ writeStringQDF("\n");
+ }
+
+ if (flags & f_stream)
+ {
+ writeStringQDF(indent);
+ writeStringQDF(" ");
+ writeString(" /Length ");
+
+ if (this->m->direct_stream_lengths)
+ {
+ writeString(QUtil::uint_to_string(stream_length));
+ }
+ else
+ {
+ writeString(
+ QUtil::int_to_string(this->m->cur_stream_length_id));
+ writeString(" 0 R");
+ }
+ writeStringQDF("\n");
+ if (compress && (flags & f_filtered))
+ {
+ writeStringQDF(indent);
+ writeStringQDF(" ");
+ writeString(" /Filter /FlateDecode");
+ writeStringQDF("\n");
+ }
+ }
+
+ writeStringQDF(indent);
+ writeStringNoQDF(" ");
+ writeString(">>");
}
else if (object.isStream())
{
- // Write stream data to a buffer.
- int new_id = this->m->obj_renumber[old_og];
- if (! this->m->direct_stream_lengths)
- {
- this->m->cur_stream_length_id = new_id + 1;
- }
+ // Write stream data to a buffer.
+ int new_id = this->m->obj_renumber[old_og];
+ if (! this->m->direct_stream_lengths)
+ {
+ this->m->cur_stream_length_id = new_id + 1;
+ }
- flags |= f_stream;
- bool compress_stream = false;
+ flags |= f_stream;
+ bool compress_stream = false;
bool is_metadata = false;
PointerHolder<Buffer> stream_data;
if (willFilterStream(object, compress_stream,
is_metadata, &stream_data))
- {
- flags |= f_filtered;
- }
+ {
+ flags |= f_filtered;
+ }
QPDFObjectHandle stream_dict = object.getDict();
- this->m->cur_stream_length = stream_data->getSize();
- if (is_metadata && this->m->encrypted && (! this->m->encrypt_metadata))
- {
- // Don't encrypt stream data for the metadata stream
- this->m->cur_data_key.clear();
- }
- adjustAESStreamLength(this->m->cur_stream_length);
- unparseObject(stream_dict, 0, flags,
+ this->m->cur_stream_length = stream_data->getSize();
+ if (is_metadata && this->m->encrypted && (! this->m->encrypt_metadata))
+ {
+ // Don't encrypt stream data for the metadata stream
+ this->m->cur_data_key.clear();
+ }
+ adjustAESStreamLength(this->m->cur_stream_length);
+ unparseObject(stream_dict, 0, flags,
this->m->cur_stream_length, compress_stream);
- unsigned char last_char = '\0';
- writeString("\nstream\n");
+ unsigned char last_char = '\0';
+ writeString("\nstream\n");
{
PipelinePopper pp_enc(this);
pushEncryptionFilter(pp_enc);
@@ -1898,72 +1898,72 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
{
this->m->added_newline = false;
}
- writeString("endstream");
+ writeString("endstream");
}
else if (object.isString())
{
- std::string val;
- if (this->m->encrypted &&
- (! (flags & f_in_ostream)) &&
- (! (flags & f_no_encryption)) &&
- (! this->m->cur_data_key.empty()))
- {
- val = object.getStringValue();
- if (this->m->encrypt_use_aes)
- {
- Pl_Buffer bufpl("encrypted string");
- Pl_AES_PDF pl(
+ std::string val;
+ if (this->m->encrypted &&
+ (! (flags & f_in_ostream)) &&
+ (! (flags & f_no_encryption)) &&
+ (! this->m->cur_data_key.empty()))
+ {
+ val = object.getStringValue();
+ if (this->m->encrypt_use_aes)
+ {
+ Pl_Buffer bufpl("encrypted string");
+ Pl_AES_PDF pl(
"aes encrypt string", &bufpl, true,
QUtil::unsigned_char_pointer(this->m->cur_data_key),
this->m->cur_data_key.length());
- pl.write(QUtil::unsigned_char_pointer(val), val.length());
- pl.finish();
- auto buf = bufpl.getBufferSharedPointer();
- val = QPDF_String(
- std::string(reinterpret_cast<char*>(buf->getBuffer()),
- buf->getSize())).unparse(true);
- }
- else
- {
- auto tmp_ph = QUtil::make_unique_cstr(val);
+ pl.write(QUtil::unsigned_char_pointer(val), val.length());
+ pl.finish();
+ auto buf = bufpl.getBufferSharedPointer();
+ val = QPDF_String(
+ std::string(reinterpret_cast<char*>(buf->getBuffer()),
+ buf->getSize())).unparse(true);
+ }
+ else
+ {
+ auto tmp_ph = QUtil::make_unique_cstr(val);
char* tmp = tmp_ph.get();
- size_t vlen = val.length();
- RC4 rc4(QUtil::unsigned_char_pointer(this->m->cur_data_key),
- QIntC::to_int(this->m->cur_data_key.length()));
- rc4.process(QUtil::unsigned_char_pointer(tmp), vlen);
- val = QPDF_String(std::string(tmp, vlen)).unparse();
- }
- }
- else if (flags & f_hex_string)
- {
- val = QPDF_String(object.getStringValue()).unparse(true);
- }
- else
- {
- val = object.unparseResolved();
- }
- writeString(val);
+ size_t vlen = val.length();
+ RC4 rc4(QUtil::unsigned_char_pointer(this->m->cur_data_key),
+ QIntC::to_int(this->m->cur_data_key.length()));
+ rc4.process(QUtil::unsigned_char_pointer(tmp), vlen);
+ val = QPDF_String(std::string(tmp, vlen)).unparse();
+ }
+ }
+ else if (flags & f_hex_string)
+ {
+ val = QPDF_String(object.getStringValue()).unparse(true);
+ }
+ else
+ {
+ val = object.unparseResolved();
+ }
+ writeString(val);
}
else
{
- writeString(object.unparseResolved());
+ writeString(object.unparseResolved());
}
}
void
QPDFWriter::writeObjectStreamOffsets(std::vector<qpdf_offset_t>& offsets,
- int first_obj)
+ int first_obj)
{
for (size_t i = 0; i < offsets.size(); ++i)
{
- if (i != 0)
- {
- writeStringQDF("\n");
- writeStringNoQDF(" ");
- }
- writeString(QUtil::uint_to_string(i + QIntC::to_size(first_obj)));
- writeString(" ");
- writeString(QUtil::int_to_string(offsets.at(i)));
+ if (i != 0)
+ {
+ writeStringQDF("\n");
+ writeStringNoQDF(" ");
+ }
+ writeString(QUtil::uint_to_string(i + QIntC::to_size(first_obj)));
+ writeString(" ");
+ writeString(QUtil::int_to_string(offsets.at(i)));
}
writeString("\n");
}
@@ -1989,25 +1989,25 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
bool compressed = false;
for (int pass = 1; pass <= 2; ++pass)
{
- // stream_buffer will be initialized only for pass 2
+ // stream_buffer will be initialized only for pass 2
PipelinePopper pp_ostream(this, &stream_buffer);
- if (pass == 1)
- {
- pushDiscardFilter(pp_ostream);
- }
- else
- {
- // Adjust offsets to skip over comment before first object
-
- first = offsets.at(0);
- for (std::vector<qpdf_offset_t>::iterator iter = offsets.begin();
- iter != offsets.end(); ++iter)
- {
- *iter -= first;
- }
-
- // Take one pass at writing pairs of numbers so we can get
- // their size information
+ if (pass == 1)
+ {
+ pushDiscardFilter(pp_ostream);
+ }
+ else
+ {
+ // Adjust offsets to skip over comment before first object
+
+ first = offsets.at(0);
+ for (std::vector<qpdf_offset_t>::iterator iter = offsets.begin();
+ iter != offsets.end(); ++iter)
+ {
+ *iter -= first;
+ }
+
+ // Take one pass at writing pairs of numbers so we can get
+ // their size information
{
PipelinePopper pp_discard(this);
pushDiscardFilter(pp_discard);
@@ -2015,42 +2015,42 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
first += this->m->pipeline->getCount();
}
- // Set up a stream to write the stream data into a buffer.
- Pipeline* next = pushPipeline(new Pl_Buffer("object stream"));
+ // Set up a stream to write the stream data into a buffer.
+ Pipeline* next = pushPipeline(new Pl_Buffer("object stream"));
if ((this->m->compress_streams ||
(this->m->stream_decode_level == qpdf_dl_none)) &&
(! this->m->qdf_mode))
- {
- compressed = true;
- next = pushPipeline(
- new Pl_Flate("compress object stream", next,
- Pl_Flate::a_deflate));
- }
- activatePipelineStack(pp_ostream);
- writeObjectStreamOffsets(offsets, first_obj);
- }
-
- int count = 0;
- for (std::set<QPDFObjGen>::iterator iter =
- this->m->object_stream_to_objects[old_id].begin();
- iter != this->m->object_stream_to_objects[old_id].end();
- ++iter, ++count)
- {
- QPDFObjGen obj = *iter;
- int new_obj = this->m->obj_renumber[obj];
- if (first_obj == -1)
- {
- first_obj = new_obj;
- }
- if (this->m->qdf_mode)
- {
- writeString("%% Object stream: object " +
- QUtil::int_to_string(new_obj) + ", index " +
- QUtil::int_to_string(count));
- if (! this->m->suppress_original_object_ids)
- {
- writeString("; original object ID: " +
- QUtil::int_to_string(obj.getObj()));
+ {
+ compressed = true;
+ next = pushPipeline(
+ new Pl_Flate("compress object stream", next,
+ Pl_Flate::a_deflate));
+ }
+ activatePipelineStack(pp_ostream);
+ writeObjectStreamOffsets(offsets, first_obj);
+ }
+
+ int count = 0;
+ for (std::set<QPDFObjGen>::iterator iter =
+ this->m->object_stream_to_objects[old_id].begin();
+ iter != this->m->object_stream_to_objects[old_id].end();
+ ++iter, ++count)
+ {
+ QPDFObjGen obj = *iter;
+ int new_obj = this->m->obj_renumber[obj];
+ if (first_obj == -1)
+ {
+ first_obj = new_obj;
+ }
+ if (this->m->qdf_mode)
+ {
+ writeString("%% Object stream: object " +
+ QUtil::int_to_string(new_obj) + ", index " +
+ QUtil::int_to_string(count));
+ if (! this->m->suppress_original_object_ids)
+ {
+ writeString("; original object ID: " +
+ QUtil::int_to_string(obj.getObj()));
// For compatibility, only write the generation if
// non-zero. While object streams only allow
// objects with generation 0, if we are generating
@@ -2061,17 +2061,17 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
QTC::TC("qpdf", "QPDFWriter original obj non-zero gen");
writeString(" " + QUtil::int_to_string(obj.getGen()));
}
- }
- writeString("\n");
- }
- if (pass == 1)
- {
- offsets.push_back(this->m->pipeline->getCount());
+ }
+ writeString("\n");
+ }
+ if (pass == 1)
+ {
+ offsets.push_back(this->m->pipeline->getCount());
// To avoid double-counting objects being written in
// object streams for progress reporting, decrement in
// pass 1.
indicateProgress(true, false);
- }
+ }
QPDFObjectHandle obj_to_write =
this->m->pdf.getObjectByObjGen(obj);
if (obj_to_write.isStream())
@@ -2084,10 +2084,10 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
"stream found inside object stream; treating as null");
obj_to_write = QPDFObjectHandle::newNull();
}
- writeObject(obj_to_write, count);
+ writeObject(obj_to_write, count);
- this->m->xref[new_obj] = QPDFXRefEntry(2, new_id, count);
- }
+ this->m->xref[new_obj] = QPDFXRefEntry(2, new_id, count);
+ }
}
// Write the object
@@ -2103,30 +2103,30 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
writeStringQDF("\n ");
if (compressed)
{
- writeString(" /Filter /FlateDecode");
+ writeString(" /Filter /FlateDecode");
}
writeString(" /N " + QUtil::uint_to_string(offsets.size()));
writeStringQDF("\n ");
writeString(" /First " + QUtil::int_to_string(first));
if (! object.isNull())
{
- // If the original object has an /Extends key, preserve it.
- QPDFObjectHandle dict = object.getDict();
- QPDFObjectHandle extends = dict.getKey("/Extends");
- if (extends.isIndirect())
- {
- QTC::TC("qpdf", "QPDFWriter copy Extends");
- writeStringQDF("\n ");
- writeString(" /Extends ");
- unparseChild(extends, 1, f_in_ostream);
- }
+ // If the original object has an /Extends key, preserve it.
+ QPDFObjectHandle dict = object.getDict();
+ QPDFObjectHandle extends = dict.getKey("/Extends");
+ if (extends.isIndirect())
+ {
+ QTC::TC("qpdf", "QPDFWriter copy Extends");
+ writeStringQDF("\n ");
+ writeString(" /Extends ");
+ unparseChild(extends, 1, f_in_ostream);
+ }
}
writeStringQDF("\n");
writeStringNoQDF(" ");
writeString(">>\nstream\n");
if (this->m->encrypted)
{
- QTC::TC("qpdf", "QPDFWriter encrypt object stream");
+ QTC::TC("qpdf", "QPDFWriter encrypt object stream");
}
{
PipelinePopper pp_enc(this);
@@ -2149,65 +2149,65 @@ QPDFWriter::writeObject(QPDFObjectHandle object, int object_stream_index)
if ((object_stream_index == -1) &&
(old_og.getGen() == 0) &&
- (this->m->object_stream_to_objects.count(old_og.getObj())))
+ (this->m->object_stream_to_objects.count(old_og.getObj())))
{
- writeObjectStream(object);
- return;
+ writeObjectStream(object);
+ return;
}
indicateProgress(false, false);
int new_id = this->m->obj_renumber[old_og];
if (this->m->qdf_mode)
{
- if (this->m->page_object_to_seq.count(old_og))
- {
- writeString("%% Page ");
- writeString(
- QUtil::int_to_string(
- this->m->page_object_to_seq[old_og]));
- writeString("\n");
- }
- if (this->m->contents_to_page_seq.count(old_og))
- {
- writeString("%% Contents for page ");
- writeString(
- QUtil::int_to_string(
- this->m->contents_to_page_seq[old_og]));
- writeString("\n");
- }
+ if (this->m->page_object_to_seq.count(old_og))
+ {
+ writeString("%% Page ");
+ writeString(
+ QUtil::int_to_string(
+ this->m->page_object_to_seq[old_og]));
+ writeString("\n");
+ }
+ if (this->m->contents_to_page_seq.count(old_og))
+ {
+ writeString("%% Contents for page ");
+ writeString(
+ QUtil::int_to_string(
+ this->m->contents_to_page_seq[old_og]));
+ writeString("\n");
+ }
}
if (object_stream_index == -1)
{
- if (this->m->qdf_mode && (! this->m->suppress_original_object_ids))
- {
- writeString("%% Original object ID: " +
- QUtil::int_to_string(object.getObjectID()) + " " +
- QUtil::int_to_string(object.getGeneration()) + "\n");
- }
- openObject(new_id);
- setDataKey(new_id);
- unparseObject(object, 0, 0);
- this->m->cur_data_key.clear();
- closeObject(new_id);
+ if (this->m->qdf_mode && (! this->m->suppress_original_object_ids))
+ {
+ writeString("%% Original object ID: " +
+ QUtil::int_to_string(object.getObjectID()) + " " +
+ QUtil::int_to_string(object.getGeneration()) + "\n");
+ }
+ openObject(new_id);
+ setDataKey(new_id);
+ unparseObject(object, 0, 0);
+ this->m->cur_data_key.clear();
+ closeObject(new_id);
}
else
{
- unparseObject(object, 0, f_in_ostream);
- writeString("\n");
+ unparseObject(object, 0, f_in_ostream);
+ writeString("\n");
}
if ((! this->m->direct_stream_lengths) && object.isStream())
{
- if (this->m->qdf_mode)
- {
- if (this->m->added_newline)
- {
- writeString("%QDF: ignore_newline\n");
- }
- }
- openObject(new_id + 1);
- writeString(QUtil::uint_to_string(this->m->cur_stream_length));
- closeObject(new_id + 1);
+ if (this->m->qdf_mode)
+ {
+ if (this->m->added_newline)
+ {
+ writeString("%QDF: ignore_newline\n");
+ }
+ }
+ openObject(new_id + 1);
+ writeString(QUtil::uint_to_string(this->m->cur_stream_length));
+ closeObject(new_id + 1);
}
}
@@ -2233,7 +2233,7 @@ QPDFWriter::generateID()
if (! this->m->id2.empty())
{
- return;
+ return;
}
QPDFObjectHandle trailer = this->m->pdf.getTrailer();
@@ -2242,30 +2242,30 @@ QPDFWriter::generateID()
if (this->m->static_id)
{
- // For test suite use only...
- static unsigned char tmp[] = {0x31, 0x41, 0x59, 0x26,
+ // For test suite use only...
+ static unsigned char tmp[] = {0x31, 0x41, 0x59, 0x26,
0x53, 0x58, 0x97, 0x93,
0x23, 0x84, 0x62, 0x64,
0x33, 0x83, 0x27, 0x95,
0x00};
- result = reinterpret_cast<char*>(tmp);
+ result = reinterpret_cast<char*>(tmp);
}
else
{
- // The PDF specification has guidelines for creating IDs, but
- // it states clearly that the only thing that's really
- // important is that it is very likely to be unique. We can't
- // really follow the guidelines in the spec exactly because we
- // haven't written the file yet. This scheme should be fine
- // though. The deterministic ID case uses a digest of a
- // sufficient portion of the file's contents such no two
- // non-matching files would match in the subsets used for this
- // computation. Note that we explicitly omit the filename from
- // the digest calculation for deterministic ID so that the same
- // file converted with qpdf, in that case, would have the same
- // ID regardless of the output file's name.
-
- std::string seed;
+ // The PDF specification has guidelines for creating IDs, but
+ // it states clearly that the only thing that's really
+ // important is that it is very likely to be unique. We can't
+ // really follow the guidelines in the spec exactly because we
+ // haven't written the file yet. This scheme should be fine
+ // though. The deterministic ID case uses a digest of a
+ // sufficient portion of the file's contents such no two
+ // non-matching files would match in the subsets used for this
+ // computation. Note that we explicitly omit the filename from
+ // the digest calculation for deterministic ID so that the same
+ // file converted with qpdf, in that case, would have the same
+ // ID regardless of the output file's name.
+
+ std::string seed;
if (this->m->deterministic_id)
{
if (this->m->deterministic_id_data.empty())
@@ -2285,28 +2285,28 @@ QPDFWriter::generateID()
seed += this->m->filename;
seed += " ";
}
- seed += " QPDF ";
- if (trailer.hasKey("/Info"))
- {
+ seed += " QPDF ";
+ if (trailer.hasKey("/Info"))
+ {
QPDFObjectHandle info = trailer.getKey("/Info");
- std::set<std::string> keys = info.getKeys();
- for (std::set<std::string>::iterator iter = keys.begin();
- iter != keys.end(); ++iter)
- {
- QPDFObjectHandle obj = info.getKey(*iter);
- if (obj.isString())
- {
- seed += " ";
- seed += obj.getStringValue();
- }
- }
- }
-
- MD5 m;
- m.encodeString(seed.c_str());
- MD5::Digest digest;
- m.digest(digest);
- result = std::string(reinterpret_cast<char*>(digest),
+ std::set<std::string> keys = info.getKeys();
+ for (std::set<std::string>::iterator iter = keys.begin();
+ iter != keys.end(); ++iter)
+ {
+ QPDFObjectHandle obj = info.getKey(*iter);
+ if (obj.isString())
+ {
+ seed += " ";
+ seed += obj.getStringValue();
+ }
+ }
+ }
+
+ MD5 m;
+ m.encodeString(seed.c_str());
+ MD5::Digest digest;
+ m.digest(digest);
+ result = std::string(reinterpret_cast<char*>(digest),
sizeof(MD5::Digest));
}
@@ -2319,7 +2319,7 @@ QPDFWriter::generateID()
this->m->id1 = getOriginalID1();
if (this->m->id1.empty())
{
- this->m->id1 = this->m->id2;
+ this->m->id1 = this->m->id2;
}
}
@@ -2331,31 +2331,31 @@ QPDFWriter::initializeSpecialStreams()
std::vector<QPDFObjectHandle> pages = this->m->pdf.getAllPages();
int num = 0;
for (std::vector<QPDFObjectHandle>::iterator iter = pages.begin();
- iter != pages.end(); ++iter)
- {
- QPDFObjectHandle& page = *iter;
- this->m->page_object_to_seq[page.getObjGen()] = ++num;
- QPDFObjectHandle contents = page.getKey("/Contents");
- std::vector<QPDFObjGen> contents_objects;
- if (contents.isArray())
- {
- int n = contents.getArrayNItems();
- for (int i = 0; i < n; ++i)
- {
- contents_objects.push_back(
- contents.getArrayItem(i).getObjGen());
- }
- }
- else if (contents.isStream())
- {
- contents_objects.push_back(contents.getObjGen());
- }
-
- for (auto const& c: contents_objects)
- {
- this->m->contents_to_page_seq[c] = num;
- this->m->normalized_streams.insert(c);
- }
+ iter != pages.end(); ++iter)
+ {
+ QPDFObjectHandle& page = *iter;
+ this->m->page_object_to_seq[page.getObjGen()] = ++num;
+ QPDFObjectHandle contents = page.getKey("/Contents");
+ std::vector<QPDFObjGen> contents_objects;
+ if (contents.isArray())
+ {
+ int n = contents.getArrayNItems();
+ for (int i = 0; i < n; ++i)
+ {
+ contents_objects.push_back(
+ contents.getArrayItem(i).getObjGen());
+ }
+ }
+ else if (contents.isStream())
+ {
+ contents_objects.push_back(contents.getObjGen());
+ }
+
+ for (auto const& c: contents_objects)
+ {
+ this->m->contents_to_page_seq[c] = num;
+ this->m->normalized_streams.insert(c);
+ }
}
}
@@ -2424,31 +2424,31 @@ QPDFWriter::generateObjectStreams()
size_t n_per = eligible.size() / n_object_streams;
if (n_per * n_object_streams < eligible.size())
{
- ++n_per;
+ ++n_per;
}
unsigned int n = 0;
int cur_ostream = 0;
for (std::vector<QPDFObjGen>::const_iterator iter = eligible.begin();
- iter != eligible.end(); ++iter)
- {
- if ((n % n_per) == 0)
- {
- if (n > 0)
- {
- QTC::TC("qpdf", "QPDFWriter generate >1 ostream");
- }
- n = 0;
- }
- if (n == 0)
- {
- // Construct a new null object as the "original" object
- // stream. The rest of the code knows that this means
- // we're creating the object stream from scratch.
- cur_ostream = this->m->pdf.makeIndirectObject(
- QPDFObjectHandle::newNull()).getObjectID();
- }
- this->m->object_to_object_stream[*iter] = cur_ostream;
- ++n;
+ iter != eligible.end(); ++iter)
+ {
+ if ((n % n_per) == 0)
+ {
+ if (n > 0)
+ {
+ QTC::TC("qpdf", "QPDFWriter generate >1 ostream");
+ }
+ n = 0;
+ }
+ if (n == 0)
+ {
+ // Construct a new null object as the "original" object
+ // stream. The rest of the code knows that this means
+ // we're creating the object stream from scratch.
+ cur_ostream = this->m->pdf.makeIndirectObject(
+ QPDFObjectHandle::newNull()).getObjectID();
+ }
+ this->m->object_to_object_stream[*iter] = cur_ostream;
+ ++n;
}
}
@@ -2529,7 +2529,7 @@ QPDFWriter::doWriteSetup()
if (this->m->linearized)
{
- this->m->qdf_mode = false;
+ this->m->qdf_mode = false;
}
if (this->m->pclm)
@@ -2541,14 +2541,14 @@ QPDFWriter::doWriteSetup()
if (this->m->qdf_mode)
{
- if (! this->m->normalize_content_set)
- {
- this->m->normalize_content = true;
- }
- if (! this->m->compress_streams_set)
- {
- this->m->compress_streams = false;
- }
+ if (! this->m->normalize_content_set)
+ {
+ this->m->normalize_content = true;
+ }
+ if (! this->m->compress_streams_set)
+ {
+ this->m->compress_streams = false;
+ }
if (! this->m->stream_decode_level_set)
{
this->m->stream_decode_level = qpdf_dl_generalized;
@@ -2557,119 +2557,119 @@ QPDFWriter::doWriteSetup()
if (this->m->encrypted)
{
- // Encryption has been explicitly set
- this->m->preserve_encryption = false;
+ // Encryption has been explicitly set
+ this->m->preserve_encryption = false;
}
else if (this->m->normalize_content ||
- this->m->stream_decode_level ||
+ this->m->stream_decode_level ||
this->m->pclm ||
- this->m->qdf_mode)
+ this->m->qdf_mode)
{
- // Encryption makes looking at contents pretty useless. If
- // the user explicitly encrypted though, we still obey that.
- this->m->preserve_encryption = false;
+ // Encryption makes looking at contents pretty useless. If
+ // the user explicitly encrypted though, we still obey that.
+ this->m->preserve_encryption = false;
}
if (this->m->preserve_encryption)
{
- copyEncryptionParameters(this->m->pdf);
+ copyEncryptionParameters(this->m->pdf);
}
if (! this->m->forced_pdf_version.empty())
{
- int major = 0;
- int minor = 0;
- parseVersion(this->m->forced_pdf_version, major, minor);
- disableIncompatibleEncryption(major, minor,
+ int major = 0;
+ int minor = 0;
+ parseVersion(this->m->forced_pdf_version, major, minor);
+ disableIncompatibleEncryption(major, minor,
this->m->forced_extension_level);
- if (compareVersions(major, minor, 1, 5) < 0)
- {
- QTC::TC("qpdf", "QPDFWriter forcing object stream disable");
- this->m->object_stream_mode = qpdf_o_disable;
- }
+ if (compareVersions(major, minor, 1, 5) < 0)
+ {
+ QTC::TC("qpdf", "QPDFWriter forcing object stream disable");
+ this->m->object_stream_mode = qpdf_o_disable;
+ }
}
if (this->m->qdf_mode || this->m->normalize_content ||
this->m->stream_decode_level)
{
- initializeSpecialStreams();
+ initializeSpecialStreams();
}
if (this->m->qdf_mode)
{
- // Generate indirect stream lengths for qdf mode since fix-qdf
- // uses them for storing recomputed stream length data.
- // Certain streams such as object streams, xref streams, and
- // hint streams always get direct stream lengths.
- this->m->direct_stream_lengths = false;
+ // Generate indirect stream lengths for qdf mode since fix-qdf
+ // uses them for storing recomputed stream length data.
+ // Certain streams such as object streams, xref streams, and
+ // hint streams always get direct stream lengths.
+ this->m->direct_stream_lengths = false;
}
switch (this->m->object_stream_mode)
{
case qpdf_o_disable:
- // no action required
- break;
+ // no action required
+ break;
case qpdf_o_preserve:
- preserveObjectStreams();
- break;
+ preserveObjectStreams();
+ break;
case qpdf_o_generate:
- generateObjectStreams();
- break;
+ generateObjectStreams();
+ break;
- // no default so gcc will warn for missing case tag
+ // no default so gcc will warn for missing case tag
}
if (this->m->linearized)
{
- // Page dictionaries are not allowed to be compressed objects.
- std::vector<QPDFObjectHandle> pages = this->m->pdf.getAllPages();
- for (std::vector<QPDFObjectHandle>::iterator iter = pages.begin();
- iter != pages.end(); ++iter)
- {
- QPDFObjectHandle& page = *iter;
- QPDFObjGen og = page.getObjGen();
- if (this->m->object_to_object_stream.count(og))
- {
- QTC::TC("qpdf", "QPDFWriter uncompressing page dictionary");
- this->m->object_to_object_stream.erase(og);
- }
- }
+ // Page dictionaries are not allowed to be compressed objects.
+ std::vector<QPDFObjectHandle> pages = this->m->pdf.getAllPages();
+ for (std::vector<QPDFObjectHandle>::iterator iter = pages.begin();
+ iter != pages.end(); ++iter)
+ {
+ QPDFObjectHandle& page = *iter;
+ QPDFObjGen og = page.getObjGen();
+ if (this->m->object_to_object_stream.count(og))
+ {
+ QTC::TC("qpdf", "QPDFWriter uncompressing page dictionary");
+ this->m->object_to_object_stream.erase(og);
+ }
+ }
}
if (this->m->linearized || this->m->encrypted)
{
- // The document catalog is not allowed to be compressed in
- // linearized files either. It also appears that Adobe Reader
- // 8.0.0 has a bug that prevents it from being able to handle
- // encrypted files with compressed document catalogs, so we
- // disable them in that case as well.
- QPDFObjGen og = this->m->pdf.getRoot().getObjGen();
- if (this->m->object_to_object_stream.count(og))
- {
- QTC::TC("qpdf", "QPDFWriter uncompressing root");
- this->m->object_to_object_stream.erase(og);
- }
+ // The document catalog is not allowed to be compressed in
+ // linearized files either. It also appears that Adobe Reader
+ // 8.0.0 has a bug that prevents it from being able to handle
+ // encrypted files with compressed document catalogs, so we
+ // disable them in that case as well.
+ QPDFObjGen og = this->m->pdf.getRoot().getObjGen();
+ if (this->m->object_to_object_stream.count(og))
+ {
+ QTC::TC("qpdf", "QPDFWriter uncompressing root");
+ this->m->object_to_object_stream.erase(og);
+ }
}
// Generate reverse mapping from object stream to objects
for (std::map<QPDFObjGen, int>::iterator iter =
- this->m->object_to_object_stream.begin();
- iter != this->m->object_to_object_stream.end(); ++iter)
- {
- QPDFObjGen obj = (*iter).first;
- int stream = (*iter).second;
- this->m->object_stream_to_objects[stream].insert(obj);
- this->m->max_ostream_index =
- std::max(this->m->max_ostream_index,
- QIntC::to_int(
+ this->m->object_to_object_stream.begin();
+ iter != this->m->object_to_object_stream.end(); ++iter)
+ {
+ QPDFObjGen obj = (*iter).first;
+ int stream = (*iter).second;
+ this->m->object_stream_to_objects[stream].insert(obj);
+ this->m->max_ostream_index =
+ std::max(this->m->max_ostream_index,
+ QIntC::to_int(
this->m->object_stream_to_objects[stream].size()) - 1);
}
if (! this->m->object_stream_to_objects.empty())
{
- setMinimumPDFVersion("1.5");
+ setMinimumPDFVersion("1.5");
}
setMinimumPDFVersion(this->m->pdf.getPDFVersion(),
@@ -2678,8 +2678,8 @@ QPDFWriter::doWriteSetup()
this->m->final_extension_level = this->m->min_extension_level;
if (! this->m->forced_pdf_version.empty())
{
- QTC::TC("qpdf", "QPDFWriter using forced PDF version");
- this->m->final_pdf_version = this->m->forced_pdf_version;
+ QTC::TC("qpdf", "QPDFWriter using forced PDF version");
+ this->m->final_pdf_version = this->m->forced_pdf_version;
this->m->final_extension_level = this->m->forced_extension_level;
}
}
@@ -2699,23 +2699,23 @@ QPDFWriter::write()
if (this->m->linearized)
{
- writeLinearized();
+ writeLinearized();
}
else
{
- writeStandard();
+ writeStandard();
}
this->m->pipeline->finish();
if (this->m->close_file)
{
- fclose(this->m->file);
+ fclose(this->m->file);
}
this->m->file = 0;
if (this->m->buffer_pipeline)
{
- this->m->output_buffer = this->m->buffer_pipeline->getBuffer();
- this->m->buffer_pipeline = 0;
+ this->m->output_buffer = this->m->buffer_pipeline->getBuffer();
+ this->m->buffer_pipeline = 0;
}
indicateProgress(false, true);
}
@@ -2747,9 +2747,9 @@ void
QPDFWriter::enqueuePart(std::vector<QPDFObjectHandle>& part)
{
for (std::vector<QPDFObjectHandle>::iterator iter = part.begin();
- iter != part.end(); ++iter)
+ iter != part.end(); ++iter)
{
- enqueueObject(*iter);
+ enqueueObject(*iter);
}
}
@@ -2759,13 +2759,13 @@ QPDFWriter::writeEncryptionDictionary()
this->m->encryption_dict_objid = openObject(this->m->encryption_dict_objid);
writeString("<<");
for (std::map<std::string, std::string>::iterator iter =
- this->m->encryption_dictionary.begin();
- iter != this->m->encryption_dictionary.end(); ++iter)
+ this->m->encryption_dictionary.begin();
+ iter != this->m->encryption_dictionary.end(); ++iter)
{
- writeString(" ");
- writeString((*iter).first);
- writeString(" ");
- writeString((*iter).second);
+ writeString(" ");
+ writeString((*iter).first);
+ writeString(" ");
+ writeString((*iter).second);
}
writeString(" >>");
closeObject(this->m->encryption_dict_objid);
@@ -2823,8 +2823,8 @@ QPDFWriter::writeHintStream(int hint_id)
writeString(QUtil::int_to_string(S));
if (O)
{
- writeString(" /O ");
- writeString(QUtil::int_to_string(O));
+ writeString(" /O ");
+ writeString(QUtil::int_to_string(O));
}
writeString(" /Length ");
adjustAESStreamLength(hlen);
@@ -2833,7 +2833,7 @@ QPDFWriter::writeHintStream(int hint_id)
if (this->m->encrypted)
{
- QTC::TC("qpdf", "QPDFWriter encrypted hint stream");
+ QTC::TC("qpdf", "QPDFWriter encrypted hint stream");
}
unsigned char last_char = '\0';
{
@@ -2845,7 +2845,7 @@ QPDFWriter::writeHintStream(int hint_id)
if (last_char != '\n')
{
- writeString("\n");
+ writeString("\n");
}
writeString("endstream");
closeObject(hint_id);
@@ -2862,8 +2862,8 @@ QPDFWriter::writeXRefTable(trailer_e which, int first, int last, int size)
qpdf_offset_t
QPDFWriter::writeXRefTable(trailer_e which, int first, int last, int size,
- qpdf_offset_t prev, bool suppress_offsets,
- int hint_id, qpdf_offset_t hint_offset,
+ qpdf_offset_t prev, bool suppress_offsets,
+ int hint_id, qpdf_offset_t hint_offset,
qpdf_offset_t hint_length, int linearization_pass)
{
writeString("xref\n");
@@ -2874,26 +2874,26 @@ QPDFWriter::writeXRefTable(trailer_e which, int first, int last, int size,
writeString("\n");
for (int i = first; i <= last; ++i)
{
- if (i == 0)
- {
- writeString("0000000000 65535 f \n");
- }
- else
- {
- qpdf_offset_t offset = 0;
- if (! suppress_offsets)
- {
- offset = this->m->xref[i].getOffset();
- if ((hint_id != 0) &&
- (i != hint_id) &&
- (offset >= hint_offset))
- {
- offset += hint_length;
- }
- }
- writeString(QUtil::int_to_string(offset, 10));
- writeString(" 00000 n \n");
- }
+ if (i == 0)
+ {
+ writeString("0000000000 65535 f \n");
+ }
+ else
+ {
+ qpdf_offset_t offset = 0;
+ if (! suppress_offsets)
+ {
+ offset = this->m->xref[i].getOffset();
+ if ((hint_id != 0) &&
+ (i != hint_id) &&
+ (offset >= hint_offset))
+ {
+ offset += hint_length;
+ }
+ }
+ writeString(QUtil::int_to_string(offset, 10));
+ writeString(" 00000 n \n");
+ }
}
writeTrailer(which, size, false, prev, linearization_pass);
writeString("\n");
@@ -2902,22 +2902,22 @@ QPDFWriter::writeXRefTable(trailer_e which, int first, int last, int size,
qpdf_offset_t
QPDFWriter::writeXRefStream(int objid, int max_id, qpdf_offset_t max_offset,
- trailer_e which, int first, int last, int size)
+ trailer_e which, int first, int last, int size)
{
// There are too many extra arguments to replace overloaded
// function with defaults in the header file...too much risk of
// leaving something off.
return writeXRefStream(objid, max_id, max_offset,
- which, first, last, size, 0, 0, 0, 0, false, 0);
+ which, first, last, size, 0, 0, 0, 0, false, 0);
}
qpdf_offset_t
QPDFWriter::writeXRefStream(int xref_id, int max_id, qpdf_offset_t max_offset,
- trailer_e which, int first, int last, int size,
- qpdf_offset_t prev, int hint_id,
- qpdf_offset_t hint_offset,
+ trailer_e which, int first, int last, int size,
+ qpdf_offset_t prev, int hint_id,
+ qpdf_offset_t hint_offset,
qpdf_offset_t hint_length,
- bool skip_compression,
+ bool skip_compression,
int linearization_pass)
{
qpdf_offset_t xref_offset = this->m->pipeline->getCount();
@@ -2942,18 +2942,18 @@ QPDFWriter::writeXRefStream(int xref_id, int max_id, qpdf_offset_t max_offset,
(this->m->stream_decode_level == qpdf_dl_none)) &&
(! this->m->qdf_mode))
{
- compressed = true;
- if (! skip_compression)
- {
- // Write the stream dictionary for compression but don't
- // actually compress. This helps us with computation of
- // padding for pass 1 of linearization.
- p = pushPipeline(
- new Pl_Flate("compress xref", p, Pl_Flate::a_deflate));
- }
- p = pushPipeline(
- new Pl_PNGFilter(
- "pngify xref", p, Pl_PNGFilter::a_encode, esize));
+ compressed = true;
+ if (! skip_compression)
+ {
+ // Write the stream dictionary for compression but don't
+ // actually compress. This helps us with computation of
+ // padding for pass 1 of linearization.
+ p = pushPipeline(
+ new Pl_Flate("compress xref", p, Pl_Flate::a_deflate));
+ }
+ p = pushPipeline(
+ new Pl_PNGFilter(
+ "pngify xref", p, Pl_PNGFilter::a_encode, esize));
}
PointerHolder<Buffer> xref_data;
{
@@ -3006,21 +3006,21 @@ QPDFWriter::writeXRefStream(int xref_id, int max_id, qpdf_offset_t max_offset,
writeString(" /Length " + QUtil::uint_to_string(xref_data->getSize()));
if (compressed)
{
- writeStringQDF("\n ");
- writeString(" /Filter /FlateDecode");
- writeStringQDF("\n ");
- writeString(" /DecodeParms << /Columns " +
- QUtil::int_to_string(esize) + " /Predictor 12 >>");
+ writeStringQDF("\n ");
+ writeString(" /Filter /FlateDecode");
+ writeStringQDF("\n ");
+ writeString(" /DecodeParms << /Columns " +
+ QUtil::int_to_string(esize) + " /Predictor 12 >>");
}
writeStringQDF("\n ");
writeString(" /W [ 1 " +
- QUtil::int_to_string(f1_size) + " " +
- QUtil::int_to_string(f2_size) + " ]");
+ QUtil::int_to_string(f1_size) + " " +
+ QUtil::int_to_string(f2_size) + " ]");
if (! ((first == 0) && (last == size - 1)))
{
- writeString(" /Index [ " +
- QUtil::int_to_string(first) + " " +
- QUtil::int_to_string(last - first + 1) + " ]");
+ writeString(" /Index [ " +
+ QUtil::int_to_string(first) + " " +
+ QUtil::int_to_string(last - first + 1) + " ]");
}
writeTrailer(which, size, true, prev, linearization_pass);
writeString("\nstream\n");
@@ -3138,17 +3138,17 @@ QPDFWriter::writeLinearized()
bool need_xref_stream = (! this->m->object_to_object_stream.empty());
if (need_xref_stream)
{
- second_half_xref = this->m->next_objid++;
+ second_half_xref = this->m->next_objid++;
}
// Assign numbers to all compressed objects in the second half.
std::vector<QPDFObjectHandle>* vecs2[] = {&part7, &part8, &part9};
for (int i = 0; i < 3; ++i)
{
- for (std::vector<QPDFObjectHandle>::iterator iter = (*vecs2[i]).begin();
- iter != (*vecs2[i]).end(); ++iter)
- {
- assignCompressedObjectNumbers((*iter).getObjGen());
- }
+ for (std::vector<QPDFObjectHandle>::iterator iter = (*vecs2[i]).begin();
+ iter != (*vecs2[i]).end(); ++iter)
+ {
+ assignCompressedObjectNumbers((*iter).getObjGen());
+ }
}
int second_half_end = this->m->next_objid - 1;
int second_trailer_size = this->m->next_objid;
@@ -3159,14 +3159,14 @@ QPDFWriter::writeLinearized()
int first_half_xref = 0;
if (need_xref_stream)
{
- first_half_xref = this->m->next_objid++;
+ first_half_xref = this->m->next_objid++;
}
int part4_first_obj = this->m->next_objid;
this->m->next_objid += QIntC::to_int(part4.size());
int after_part4 = this->m->next_objid;
if (this->m->encrypted)
{
- this->m->encryption_dict_objid = this->m->next_objid++;
+ this->m->encryption_dict_objid = this->m->next_objid++;
}
int hint_id = this->m->next_objid++;
int part6_first_obj = this->m->next_objid;
@@ -3176,11 +3176,11 @@ QPDFWriter::writeLinearized()
std::vector<QPDFObjectHandle>* vecs1[] = {&part4, &part6};
for (int i = 0; i < 2; ++i)
{
- for (std::vector<QPDFObjectHandle>::iterator iter = (*vecs1[i]).begin();
- iter != (*vecs1[i]).end(); ++iter)
- {
- assignCompressedObjectNumbers((*iter).getObjGen());
- }
+ for (std::vector<QPDFObjectHandle>::iterator iter = (*vecs1[i]).begin();
+ iter != (*vecs1[i]).end(); ++iter)
+ {
+ assignCompressedObjectNumbers((*iter).getObjGen());
+ }
}
int first_half_end = this->m->next_objid - 1;
int first_trailer_size = this->m->next_objid;
@@ -3235,8 +3235,8 @@ QPDFWriter::writeLinearized()
auto pp_md5 = make_pointer_holder<PipelinePopper>(this);
for (int pass = 1; pass <= 2; ++pass)
{
- if (pass == 1)
- {
+ if (pass == 1)
+ {
if (! this->m->lin_pass1_filename.empty())
{
lin_pass1_file =
@@ -3254,107 +3254,107 @@ QPDFWriter::writeLinearized()
{
pushMD5Pipeline(*pp_md5);
}
- }
-
- // Part 1: header
-
- writeHeader();
-
- // Part 2: linearization parameter dictionary. Save enough
- // space to write real dictionary. 200 characters is enough
- // space if all numerical values in the parameter dictionary
- // that contain offsets are 20 digits long plus a few extra
- // characters for safety. The entire linearization parameter
- // dictionary must appear within the first 1024 characters of
- // the file.
-
- qpdf_offset_t pos = this->m->pipeline->getCount();
- openObject(lindict_id);
- writeString("<<");
- if (pass == 2)
- {
- std::vector<QPDFObjectHandle> const& pages =
+ }
+
+ // Part 1: header
+
+ writeHeader();
+
+ // Part 2: linearization parameter dictionary. Save enough
+ // space to write real dictionary. 200 characters is enough
+ // space if all numerical values in the parameter dictionary
+ // that contain offsets are 20 digits long plus a few extra
+ // characters for safety. The entire linearization parameter
+ // dictionary must appear within the first 1024 characters of
+ // the file.
+
+ qpdf_offset_t pos = this->m->pipeline->getCount();
+ openObject(lindict_id);
+ writeString("<<");
+ if (pass == 2)
+ {
+ std::vector<QPDFObjectHandle> const& pages =
this->m->pdf.getAllPages();
- int first_page_object =
+ int first_page_object =
this->m->obj_renumber[pages.at(0).getObjGen()];
- int npages = QIntC::to_int(pages.size());
-
- writeString(" /Linearized 1 /L ");
- writeString(QUtil::int_to_string(file_size + hint_length));
- // Implementation note 121 states that a space is
- // mandatory after this open bracket.
- writeString(" /H [ ");
- writeString(QUtil::int_to_string(
+ int npages = QIntC::to_int(pages.size());
+
+ writeString(" /Linearized 1 /L ");
+ writeString(QUtil::int_to_string(file_size + hint_length));
+ // Implementation note 121 states that a space is
+ // mandatory after this open bracket.
+ writeString(" /H [ ");
+ writeString(QUtil::int_to_string(
this->m->xref[hint_id].getOffset()));
- writeString(" ");
- writeString(QUtil::int_to_string(hint_length));
- writeString(" ] /O ");
- writeString(QUtil::int_to_string(first_page_object));
- writeString(" /E ");
- writeString(QUtil::int_to_string(part6_end_offset + hint_length));
- writeString(" /N ");
- writeString(QUtil::int_to_string(npages));
- writeString(" /T ");
- writeString(QUtil::int_to_string(space_before_zero + hint_length));
- }
- writeString(" >>");
- closeObject(lindict_id);
- static int const pad = 200;
- int spaces = QIntC::to_int(pos - this->m->pipeline->getCount() + pad);
- assert(spaces >= 0);
- writePad(spaces);
- writeString("\n");
+ writeString(" ");
+ writeString(QUtil::int_to_string(hint_length));
+ writeString(" ] /O ");
+ writeString(QUtil::int_to_string(first_page_object));
+ writeString(" /E ");
+ writeString(QUtil::int_to_string(part6_end_offset + hint_length));
+ writeString(" /N ");
+ writeString(QUtil::int_to_string(npages));
+ writeString(" /T ");
+ writeString(QUtil::int_to_string(space_before_zero + hint_length));
+ }
+ writeString(" >>");
+ closeObject(lindict_id);
+ static int const pad = 200;
+ int spaces = QIntC::to_int(pos - this->m->pipeline->getCount() + pad);
+ assert(spaces >= 0);
+ writePad(spaces);
+ writeString("\n");
// If the user supplied any additional header text, write it
// here after the linearization parameter dictionary.
writeString(this->m->extra_header_text);
- // Part 3: first page cross reference table and trailer.
-
- qpdf_offset_t first_xref_offset = this->m->pipeline->getCount();
- qpdf_offset_t hint_offset = 0;
- if (pass == 2)
- {
- hint_offset = this->m->xref[hint_id].getOffset();
- }
- if (need_xref_stream)
- {
- // Must pad here too.
- if (pass == 1)
- {
- // Set first_half_max_obj_offset to a value large
- // enough to force four bytes to be reserved for each
- // file offset. This would provide adequate space for
- // the xref stream as long as the last object in page
- // 1 starts with in the first 4 GB of the file, which
- // is extremely likely. In the second pass, we will
- // know the actual value for this, but it's okay if
- // it's smaller.
- first_half_max_obj_offset = 1 << 25;
- }
- pos = this->m->pipeline->getCount();
- writeXRefStream(first_half_xref, first_half_end,
- first_half_max_obj_offset,
- t_lin_first, first_half_start, first_half_end,
- first_trailer_size,
- hint_length + second_xref_offset,
- hint_id, hint_offset, hint_length,
- (pass == 1), pass);
- qpdf_offset_t endpos = this->m->pipeline->getCount();
- if (pass == 1)
- {
- // Pad so we have enough room for the real xref
- // stream.
- writePad(calculateXrefStreamPadding(endpos - pos));
- first_xref_end = this->m->pipeline->getCount();
- }
- else
- {
- // Pad so that the next object starts at the same
- // place as in pass 1.
- writePad(QIntC::to_int(first_xref_end - endpos));
-
- if (this->m->pipeline->getCount() != first_xref_end)
+ // Part 3: first page cross reference table and trailer.
+
+ qpdf_offset_t first_xref_offset = this->m->pipeline->getCount();
+ qpdf_offset_t hint_offset = 0;
+ if (pass == 2)
+ {
+ hint_offset = this->m->xref[hint_id].getOffset();
+ }
+ if (need_xref_stream)
+ {
+ // Must pad here too.
+ if (pass == 1)
+ {
+ // Set first_half_max_obj_offset to a value large
+ // enough to force four bytes to be reserved for each
+ // file offset. This would provide adequate space for
+ // the xref stream as long as the last object in page
+ // 1 starts with in the first 4 GB of the file, which
+ // is extremely likely. In the second pass, we will
+ // know the actual value for this, but it's okay if
+ // it's smaller.
+ first_half_max_obj_offset = 1 << 25;
+ }
+ pos = this->m->pipeline->getCount();
+ writeXRefStream(first_half_xref, first_half_end,
+ first_half_max_obj_offset,
+ t_lin_first, first_half_start, first_half_end,
+ first_trailer_size,
+ hint_length + second_xref_offset,
+ hint_id, hint_offset, hint_length,
+ (pass == 1), pass);
+ qpdf_offset_t endpos = this->m->pipeline->getCount();
+ if (pass == 1)
+ {
+ // Pad so we have enough room for the real xref
+ // stream.
+ writePad(calculateXrefStreamPadding(endpos - pos));
+ first_xref_end = this->m->pipeline->getCount();
+ }
+ else
+ {
+ // Pad so that the next object starts at the same
+ // place as in pass 1.
+ writePad(QIntC::to_int(first_xref_end - endpos));
+
+ if (this->m->pipeline->getCount() != first_xref_end)
{
throw std::logic_error(
"insufficient padding for first pass xref stream; "
@@ -3362,111 +3362,111 @@ QPDFWriter::writeLinearized()
QUtil::int_to_string(first_xref_end) +
"; endpos=" + QUtil::int_to_string(endpos));
}
- }
- writeString("\n");
- }
- else
- {
- writeXRefTable(t_lin_first, first_half_start, first_half_end,
- first_trailer_size, hint_length + second_xref_offset,
- (pass == 1), hint_id, hint_offset, hint_length,
+ }
+ writeString("\n");
+ }
+ else
+ {
+ writeXRefTable(t_lin_first, first_half_start, first_half_end,
+ first_trailer_size, hint_length + second_xref_offset,
+ (pass == 1), hint_id, hint_offset, hint_length,
pass);
- writeString("startxref\n0\n%%EOF\n");
- }
-
- // Parts 4 through 9
-
- for (std::list<QPDFObjectHandle>::iterator iter =
- this->m->object_queue.begin();
- iter != this->m->object_queue.end(); ++iter)
- {
- QPDFObjectHandle cur_object = (*iter);
- if (cur_object.getObjectID() == part6_end_marker)
- {
- first_half_max_obj_offset = this->m->pipeline->getCount();
- }
- writeObject(cur_object);
- if (cur_object.getObjectID() == part4_end_marker)
- {
- if (this->m->encrypted)
- {
- writeEncryptionDictionary();
- }
- if (pass == 1)
- {
- this->m->xref[hint_id] =
- QPDFXRefEntry(1, this->m->pipeline->getCount(), 0);
- }
- else
- {
- // Part 5: hint stream
- writeBuffer(hint_buffer);
- }
- }
- if (cur_object.getObjectID() == part6_end_marker)
- {
- part6_end_offset = this->m->pipeline->getCount();
- }
- }
-
- // Part 10: overflow hint stream -- not used
-
- // Part 11: main cross reference table and trailer
-
- second_xref_offset = this->m->pipeline->getCount();
- if (need_xref_stream)
- {
- pos = this->m->pipeline->getCount();
- space_before_zero =
- writeXRefStream(second_half_xref,
- second_half_end, second_xref_offset,
- t_lin_second, 0, second_half_end,
- second_trailer_size,
- 0, 0, 0, 0, (pass == 1), pass);
- qpdf_offset_t endpos = this->m->pipeline->getCount();
-
- if (pass == 1)
- {
- // Pad so we have enough room for the real xref
- // stream. See comments for previous xref stream on
- // how we calculate the padding.
- writePad(calculateXrefStreamPadding(endpos - pos));
- writeString("\n");
- second_xref_end = this->m->pipeline->getCount();
- }
- else
- {
- // Make the file size the same.
- writePad(
+ writeString("startxref\n0\n%%EOF\n");
+ }
+
+ // Parts 4 through 9
+
+ for (std::list<QPDFObjectHandle>::iterator iter =
+ this->m->object_queue.begin();
+ iter != this->m->object_queue.end(); ++iter)
+ {
+ QPDFObjectHandle cur_object = (*iter);
+ if (cur_object.getObjectID() == part6_end_marker)
+ {
+ first_half_max_obj_offset = this->m->pipeline->getCount();
+ }
+ writeObject(cur_object);
+ if (cur_object.getObjectID() == part4_end_marker)
+ {
+ if (this->m->encrypted)
+ {
+ writeEncryptionDictionary();
+ }
+ if (pass == 1)
+ {
+ this->m->xref[hint_id] =
+ QPDFXRefEntry(1, this->m->pipeline->getCount(), 0);
+ }
+ else
+ {
+ // Part 5: hint stream
+ writeBuffer(hint_buffer);
+ }
+ }
+ if (cur_object.getObjectID() == part6_end_marker)
+ {
+ part6_end_offset = this->m->pipeline->getCount();
+ }
+ }
+
+ // Part 10: overflow hint stream -- not used
+
+ // Part 11: main cross reference table and trailer
+
+ second_xref_offset = this->m->pipeline->getCount();
+ if (need_xref_stream)
+ {
+ pos = this->m->pipeline->getCount();
+ space_before_zero =
+ writeXRefStream(second_half_xref,
+ second_half_end, second_xref_offset,
+ t_lin_second, 0, second_half_end,
+ second_trailer_size,
+ 0, 0, 0, 0, (pass == 1), pass);
+ qpdf_offset_t endpos = this->m->pipeline->getCount();
+
+ if (pass == 1)
+ {
+ // Pad so we have enough room for the real xref
+ // stream. See comments for previous xref stream on
+ // how we calculate the padding.
+ writePad(calculateXrefStreamPadding(endpos - pos));
+ writeString("\n");
+ second_xref_end = this->m->pipeline->getCount();
+ }
+ else
+ {
+ // Make the file size the same.
+ writePad(
QIntC::to_int(second_xref_end + hint_length -
1 - this->m->pipeline->getCount()));
- writeString("\n");
+ writeString("\n");
- // If this assertion fails, maybe we didn't have
- // enough padding above.
- if (this->m->pipeline->getCount() !=
+ // If this assertion fails, maybe we didn't have
+ // enough padding above.
+ if (this->m->pipeline->getCount() !=
second_xref_end + hint_length)
{
throw std::logic_error(
"count mismatch after xref stream;"
" possible insufficient padding?");
}
- }
- }
- else
- {
- space_before_zero =
- writeXRefTable(t_lin_second, 0, second_half_end,
- second_trailer_size, 0, false, 0, 0, 0, pass);
- }
- writeString("startxref\n");
- writeString(QUtil::int_to_string(first_xref_offset));
- writeString("\n%%EOF\n");
+ }
+ }
+ else
+ {
+ space_before_zero =
+ writeXRefTable(t_lin_second, 0, second_half_end,
+ second_trailer_size, 0, false, 0, 0, 0, pass);
+ }
+ writeString("startxref\n");
+ writeString(QUtil::int_to_string(first_xref_offset));
+ writeString("\n%%EOF\n");
discardGeneration(this->m->obj_renumber, this->m->obj_renumber_no_gen);
- if (pass == 1)
- {
+ if (pass == 1)
+ {
if (this->m->deterministic_id)
{
QTC::TC("qpdf", "QPDFWriter linearized deterministic ID",
@@ -3476,25 +3476,25 @@ QPDFWriter::writeLinearized()
assert(this->m->md5_pipeline == 0);
}
- // Close first pass pipeline
- file_size = this->m->pipeline->getCount();
- pp_pass1 = 0;
+ // Close first pass pipeline
+ file_size = this->m->pipeline->getCount();
+ pp_pass1 = 0;
- // Save hint offset since it will be set to zero by
- // calling openObject.
- qpdf_offset_t hint_offset1 = this->m->xref[hint_id].getOffset();
+ // Save hint offset since it will be set to zero by
+ // calling openObject.
+ qpdf_offset_t hint_offset1 = this->m->xref[hint_id].getOffset();
- // Write hint stream to a buffer
+ // Write hint stream to a buffer
{
pushPipeline(new Pl_Buffer("hint buffer"));
PipelinePopper pp_hint(this, &hint_buffer);
activatePipelineStack(pp_hint);
writeHintStream(hint_id);
}
- hint_length = QIntC::to_offset(hint_buffer->getSize());
+ hint_length = QIntC::to_offset(hint_buffer->getSize());
- // Restore hint offset
- this->m->xref[hint_id] = QPDFXRefEntry(1, hint_offset1, 0);
+ // Restore hint offset
+ this->m->xref[hint_id] = QPDFXRefEntry(1, hint_offset1, 0);
if (lin_pass1_file)
{
// Write some debugging information
@@ -3509,7 +3509,7 @@ QPDFWriter::writeLinearized()
fclose(lin_pass1_file);
lin_pass1_file = 0;
}
- }
+ }
}
}
@@ -3537,9 +3537,9 @@ QPDFWriter::enqueueObjectsStandard()
// no-op.
std::set<std::string> keys = trailer.getKeys();
for (std::set<std::string>::iterator iter = keys.begin();
- iter != keys.end(); ++iter)
+ iter != keys.end(); ++iter)
{
- enqueueObject(trailer.getKey(*iter));
+ enqueueObject(trailer.getKey(*iter));
}
}
@@ -3646,31 +3646,31 @@ QPDFWriter::writeStandard()
// Now start walking queue, outputting each object.
while (this->m->object_queue.size())
{
- QPDFObjectHandle cur_object = this->m->object_queue.front();
- this->m->object_queue.pop_front();
- writeObject(cur_object);
+ QPDFObjectHandle cur_object = this->m->object_queue.front();
+ this->m->object_queue.pop_front();
+ writeObject(cur_object);
}
// Write out the encryption dictionary, if any
if (this->m->encrypted)
{
- writeEncryptionDictionary();
+ writeEncryptionDictionary();
}
// Now write out xref. next_objid is now the number of objects.
qpdf_offset_t xref_offset = this->m->pipeline->getCount();
if (this->m->object_stream_to_objects.empty())
{
- // Write regular cross-reference table
- writeXRefTable(t_normal, 0, this->m->next_objid - 1,
+ // Write regular cross-reference table
+ writeXRefTable(t_normal, 0, this->m->next_objid - 1,
this->m->next_objid);
}
else
{
- // Write cross-reference stream.
- int xref_id = this->m->next_objid++;
- writeXRefStream(xref_id, xref_id, xref_offset, t_normal,
- 0, this->m->next_objid - 1, this->m->next_objid);
+ // Write cross-reference stream.
+ int xref_id = this->m->next_objid++;
+ writeXRefStream(xref_id, xref_id, xref_offset, t_normal,
+ 0, this->m->next_objid - 1, this->m->next_objid);
}
writeString("startxref\n");
writeString(QUtil::int_to_string(xref_offset));
@@ -3678,7 +3678,7 @@ QPDFWriter::writeStandard()
if (this->m->deterministic_id)
{
- QTC::TC("qpdf", "QPDFWriter standard deterministic ID",
+ QTC::TC("qpdf", "QPDFWriter standard deterministic ID",
this->m->object_stream_to_objects.empty() ? 0 : 1);
pp_md5 = 0;
assert(this->m->md5_pipeline == 0);