aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDF_linearization.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2022-04-02 23:14:10 +0200
committerJay Berkenbilt <ejb@ql.org>2022-04-04 14:10:40 +0200
commit12f1eb15ca3fed6310402847559a7c99d3c77847 (patch)
tree8935675b623c6f3b4914b8b44f7fa5f2816a9241 /libqpdf/QPDF_linearization.cc
parentf20fa61eb4c323eb1642c69c236b3d9a1f8b2cdb (diff)
downloadqpdf-12f1eb15ca3fed6310402847559a7c99d3c77847.tar.zst
Programmatically apply new formatting to code
Run this: for i in **/*.cc **/*.c **/*.h **/*.hh; do clang-format < $i >| $i.new && mv $i.new $i done
Diffstat (limited to 'libqpdf/QPDF_linearization.cc')
-rw-r--r--libqpdf/QPDF_linearization.cc1386
1 files changed, 625 insertions, 761 deletions
diff --git a/libqpdf/QPDF_linearization.cc b/libqpdf/QPDF_linearization.cc
index 443ae662..7c5fa4fa 100644
--- a/libqpdf/QPDF_linearization.cc
+++ b/libqpdf/QPDF_linearization.cc
@@ -2,40 +2,41 @@
#include <qpdf/QPDF.hh>
+#include <qpdf/BitStream.hh>
+#include <qpdf/BitWriter.hh>
+#include <qpdf/Pl_Buffer.hh>
+#include <qpdf/Pl_Count.hh>
+#include <qpdf/Pl_Flate.hh>
#include <qpdf/QPDFExc.hh>
#include <qpdf/QTC.hh>
#include <qpdf/QUtil.hh>
-#include <qpdf/Pl_Buffer.hh>
-#include <qpdf/Pl_Flate.hh>
-#include <qpdf/Pl_Count.hh>
-#include <qpdf/BitWriter.hh>
-#include <qpdf/BitStream.hh>
-#include <iostream>
#include <algorithm>
#include <assert.h>
+#include <iostream>
#include <math.h>
#include <string.h>
template <class T, class int_type>
static void
-load_vector_int(BitStream& bit_stream, int nitems, std::vector<T>& vec,
- int bits_wanted, int_type T::*field)
+load_vector_int(
+ BitStream& bit_stream,
+ int nitems,
+ std::vector<T>& vec,
+ int bits_wanted,
+ int_type T::*field)
{
bool append = vec.empty();
// nitems times, read bits_wanted from the given bit stream,
// storing results in the ith vector entry.
- for (size_t i = 0; i < QIntC::to_size(nitems); ++i)
- {
- if (append)
- {
+ for (size_t i = 0; i < QIntC::to_size(nitems); ++i) {
+ if (append) {
vec.push_back(T());
}
vec.at(i).*field = bit_stream.getBitsInt(QIntC::to_size(bits_wanted));
}
- if (QIntC::to_int(vec.size()) != nitems)
- {
+ if (QIntC::to_int(vec.size()) != nitems) {
throw std::logic_error("vector has wrong size in load_vector_int");
}
// The PDF spec says that each hint table starts at a byte
@@ -45,18 +46,20 @@ load_vector_int(BitStream& bit_stream, int nitems, std::vector<T>& vec,
template <class T>
static void
-load_vector_vector(BitStream& bit_stream,
- int nitems1, std::vector<T>& vec1, int T::*nitems2,
- int bits_wanted, std::vector<int> T::*vec2)
+load_vector_vector(
+ BitStream& bit_stream,
+ int nitems1,
+ std::vector<T>& vec1,
+ int T::*nitems2,
+ int bits_wanted,
+ std::vector<int> T::*vec2)
{
// nitems1 times, read nitems2 (from the ith element of vec1) items
// into the vec2 vector field of the ith item of vec1.
- for (size_t i1 = 0; i1 < QIntC::to_size(nitems1); ++i1)
- {
- for (int i2 = 0; i2 < vec1.at(i1).*nitems2; ++i2)
- {
- (vec1.at(i1).*vec2).push_back(
- bit_stream.getBitsInt(QIntC::to_size(bits_wanted)));
+ for (size_t i1 = 0; i1 < QIntC::to_size(nitems1); ++i1) {
+ for (int i2 = 0; i2 < vec1.at(i1).*nitems2; ++i2) {
+ (vec1.at(i1).*vec2)
+ .push_back(bit_stream.getBitsInt(QIntC::to_size(bits_wanted)));
}
}
bit_stream.skipToNextByte();
@@ -66,13 +69,10 @@ bool
QPDF::checkLinearization()
{
bool result = false;
- try
- {
+ try {
readLinearizationData();
result = checkLinearizationInternal();
- }
- catch (std::runtime_error& e)
- {
+ } catch (std::runtime_error& e) {
*this->m->err_stream
<< "WARNING: error encountered while checking linearization data: "
<< e.what() << std::endl;
@@ -105,22 +105,18 @@ QPDF::isLinearized()
int lindict_obj = -1;
char* p = buf;
- while (lindict_obj == -1)
- {
+ while (lindict_obj == -1) {
// Find a digit or end of buffer
- while (((p - buf) < tbuf_size) && (! QUtil::is_digit(*p)))
- {
+ while (((p - buf) < tbuf_size) && (!QUtil::is_digit(*p))) {
++p;
}
- if (p - buf == tbuf_size)
- {
+ if (p - buf == tbuf_size) {
break;
}
// Seek to the digit. Then skip over digits for a potential
// next iteration.
this->m->file->seek(p - buf, SEEK_SET);
- while (((p - buf) < tbuf_size) && QUtil::is_digit(*p))
- {
+ while (((p - buf) < tbuf_size) && QUtil::is_digit(*p)) {
++p;
}
@@ -131,44 +127,36 @@ QPDF::isLinearized()
if ((t1.getType() == QPDFTokenizer::tt_integer) &&
(t2.getType() == QPDFTokenizer::tt_integer) &&
(t3 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "obj")) &&
- (t4.getType() == QPDFTokenizer::tt_dict_open))
- {
+ (t4.getType() == QPDFTokenizer::tt_dict_open)) {
lindict_obj =
QIntC::to_int(QUtil::string_to_ll(t1.getValue().c_str()));
}
}
- if (lindict_obj <= 0)
- {
+ if (lindict_obj <= 0) {
return false;
}
- QPDFObjectHandle candidate = QPDFObjectHandle::Factory::newIndirect(
- this, lindict_obj, 0);
- if (! candidate.isDictionary())
- {
+ QPDFObjectHandle candidate =
+ QPDFObjectHandle::Factory::newIndirect(this, lindict_obj, 0);
+ if (!candidate.isDictionary()) {
return false;
}
QPDFObjectHandle linkey = candidate.getKey("/Linearized");
- if (! (linkey.isNumber() &&
- (QIntC::to_int(floor(linkey.getNumericValue())) == 1)))
- {
+ if (!(linkey.isNumber() &&
+ (QIntC::to_int(floor(linkey.getNumericValue())) == 1))) {
return false;
}
QPDFObjectHandle L = candidate.getKey("/L");
- if (L.isInteger())
- {
+ if (L.isInteger()) {
qpdf_offset_t Li = L.getIntValue();
this->m->file->seek(0, SEEK_END);
- if (Li != this->m->file->tell())
- {
+ if (Li != this->m->file->tell()) {
QTC::TC("qpdf", "QPDF /L mismatch");
return false;
- }
- else
- {
+ } else {
this->m->linp.file_size = Li;
}
}
@@ -187,8 +175,7 @@ QPDF::readLinearizationData()
// Hint table parsing code needs at least 32 bits in a long.
assert(sizeof(long) >= 4);
- if (! isLinearized())
- {
+ if (!isLinearized()) {
throw std::logic_error("called readLinearizationData for file"
" that is not linearized");
}
@@ -201,44 +188,40 @@ QPDF::readLinearizationData()
QPDFObjectHandle T = this->m->lindict.getKey("/T");
QPDFObjectHandle P = this->m->lindict.getKey("/P");
- if (! (H.isArray() &&
- O.isInteger() &&
- E.isInteger() &&
- N.isInteger() &&
- T.isInteger() &&
- (P.isInteger() || P.isNull())))
- {
- throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
- "linearization dictionary",
- this->m->file->getLastOffset(),
- "some keys in linearization dictionary are of "
- "the wrong type");
+ if (!(H.isArray() && O.isInteger() && E.isInteger() && N.isInteger() &&
+ T.isInteger() && (P.isInteger() || P.isNull()))) {
+ throw QPDFExc(
+ qpdf_e_damaged_pdf,
+ this->m->file->getName(),
+ "linearization dictionary",
+ this->m->file->getLastOffset(),
+ "some keys in linearization dictionary are of "
+ "the wrong type");
}
// Hint table array: offset length [ offset length ]
size_t n_H_items = toS(H.getArrayNItems());
- if (! ((n_H_items == 2) || (n_H_items == 4)))
- {
- throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
- "linearization dictionary",
- this->m->file->getLastOffset(),
- "H has the wrong number of items");
+ if (!((n_H_items == 2) || (n_H_items == 4))) {
+ throw QPDFExc(
+ qpdf_e_damaged_pdf,
+ this->m->file->getName(),
+ "linearization dictionary",
+ this->m->file->getLastOffset(),
+ "H has the wrong number of items");
}
std::vector<int> H_items;
- for (size_t i = 0; i < n_H_items; ++i)
- {
+ for (size_t i = 0; i < n_H_items; ++i) {
QPDFObjectHandle oh(H.getArrayItem(toI(i)));
- if (oh.isInteger())
- {
+ if (oh.isInteger()) {
H_items.push_back(oh.getIntValueAsInt());
- }
- else
- {
- throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
- "linearization dictionary",
- this->m->file->getLastOffset(),
- "some H items are of the wrong type");
+ } else {
+ throw QPDFExc(
+ qpdf_e_damaged_pdf,
+ this->m->file->getName(),
+ "linearization dictionary",
+ this->m->file->getLastOffset(),
+ "some H items are of the wrong type");
}
}
@@ -247,8 +230,7 @@ QPDF::readLinearizationData()
int H0_length = H_items.at(1);
int H1_offset = 0;
int H1_length = 0;
- if (H_items.size() == 4)
- {
+ if (H_items.size() == 4) {
// Acrobat doesn't read or write these (as PDF 1.4), so we
// don't have a way to generate a test case.
// QTC::TC("qpdf", "QPDF overflow hint table");
@@ -258,13 +240,10 @@ QPDF::readLinearizationData()
// P: first page number
int first_page = 0;
- if (P.isInteger())
- {
+ if (P.isInteger()) {
QTC::TC("qpdf", "QPDF P present in lindict");
first_page = P.getIntValueAsInt();
- }
- else
- {
+ } else {
QTC::TC("qpdf", "QPDF P absent in lindict");
}
@@ -273,12 +252,13 @@ QPDF::readLinearizationData()
// Various places in the code use linp.npages, which is
// initialized from N, to pre-allocate memory, so make sure it's
// 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->m->file->getName(),
- "linearization hint table",
- this->m->file->getLastOffset(),
- "/N does not match number of pages");
+ if (N.getIntValue() != static_cast<long long>(getAllPages().size())) {
+ throw QPDFExc(
+ qpdf_e_damaged_pdf,
+ this->m->file->getName(),
+ "linearization hint table",
+ this->m->file->getLastOffset(),
+ "/N does not match number of pages");
}
// file_size initialized by isLinearized()
@@ -294,9 +274,8 @@ QPDF::readLinearizationData()
Pl_Buffer pb("hint buffer");
QPDFObjectHandle H0 = readHintStream(pb, H0_offset, toS(H0_length));
- if (H1_offset)
- {
- (void) readHintStream(pb, H1_offset, toS(H1_length));
+ if (H1_offset) {
+ (void)readHintStream(pb, H1_offset, toS(H1_length));
}
// PDF 1.4 hint tables that we ignore:
@@ -321,27 +300,28 @@ QPDF::readLinearizationData()
readHPageOffset(BitStream(h_buf, h_size));
int HSi = HS.getIntValueAsInt();
- if ((HSi < 0) || (toS(HSi) >= h_size))
- {
- throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
- "linearization hint table",
- this->m->file->getLastOffset(),
- "/S (shared object) offset is out of bounds");
+ if ((HSi < 0) || (toS(HSi) >= h_size)) {
+ throw QPDFExc(
+ qpdf_e_damaged_pdf,
+ this->m->file->getName(),
+ "linearization hint table",
+ this->m->file->getLastOffset(),
+ "/S (shared object) offset is out of bounds");
}
readHSharedObject(BitStream(h_buf + HSi, h_size - toS(HSi)));
- if (HO.isInteger())
- {
+ if (HO.isInteger()) {
int HOi = HO.getIntValueAsInt();
- if ((HOi < 0) || (toS(HOi) >= h_size))
- {
- throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(),
- "linearization hint table",
- this->m->file->getLastOffset(),
- "/O (outline) offset is out of bounds");
+ if ((HOi < 0) || (toS(HOi) >= h_size)) {
+ throw QPDFExc(
+ qpdf_e_damaged_pdf,
+ this->m->file->getName(),
+ "linearization hint table",
+ this->m->file->getLastOffset(),
+ "/O (outline) offset is out of bounds");
}
- readHGeneric(BitStream(h_buf + HOi, h_size - toS(HOi)),
- this->m->outline_hints);
+ readHGeneric(
+ BitStream(h_buf + HOi, h_size - toS(HOi)), this->m->outline_hints);
}
}
@@ -355,12 +335,13 @@ QPDF::readHintStream(Pipeline& pl, qpdf_offset_t offset, size_t length)
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->m->file->getName(),
- "linearization dictionary",
- this->m->file->getLastOffset(),
- "hint table is not a stream");
+ if (!H.isStream()) {
+ throw QPDFExc(
+ qpdf_e_damaged_pdf,
+ this->m->file->getName(),
+ "linearization dictionary",
+ this->m->file->getLastOffset(),
+ "hint table is not a stream");
}
QPDFObjectHandle Hdict = H.getDict();
@@ -371,30 +352,27 @@ QPDF::readHintStream(Pipeline& pl, qpdf_offset_t offset, size_t length)
// linearization parameter dictionary must be direct. We have to
// get the file position of the end of length in this case.
QPDFObjectHandle length_obj = Hdict.getKey("/Length");
- if (length_obj.isIndirect())
- {
+ if (length_obj.isIndirect()) {
QTC::TC("qpdf", "QPDF hint table length indirect");
// Force resolution
- (void) length_obj.getIntValue();
+ (void)length_obj.getIntValue();
ObjCache& oc2 = this->m->obj_cache[length_obj.getObjGen()];
min_end_offset = oc2.end_before_space;
max_end_offset = oc2.end_after_space;
- }
- else
- {
+ } else {
QTC::TC("qpdf", "QPDF hint table length direct");
}
qpdf_offset_t computed_end = offset + toO(length);
- if ((computed_end < min_end_offset) ||
- (computed_end > max_end_offset))
- {
+ if ((computed_end < min_end_offset) || (computed_end > max_end_offset)) {
*this->m->err_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->m->file->getLastOffset(),
- "hint table length mismatch");
+ throw QPDFExc(
+ qpdf_e_damaged_pdf,
+ this->m->file->getName(),
+ "linearization dictionary",
+ this->m->file->getLastOffset(),
+ "hint table length mismatch");
}
H.pipeStreamData(&pl, 0, qpdf_dl_specialized);
return Hdict;
@@ -408,46 +386,67 @@ QPDF::readHPageOffset(BitStream h)
HPageOffset& t = this->m->page_offset_hints;
- t.min_nobjects = h.getBitsInt(32); // 1
- t.first_page_offset = h.getBitsInt(32); // 2
- t.nbits_delta_nobjects = h.getBitsInt(16); // 3
- t.min_page_length = h.getBitsInt(32); // 4
- t.nbits_delta_page_length = h.getBitsInt(16); // 5
- t.min_content_offset = h.getBitsInt(32); // 6
- t.nbits_delta_content_offset = h.getBitsInt(16); // 7
- t.min_content_length = h.getBitsInt(32); // 8
- t.nbits_delta_content_length = h.getBitsInt(16); // 9
- t.nbits_nshared_objects = h.getBitsInt(16); // 10
- t.nbits_shared_identifier = h.getBitsInt(16); // 11
- t.nbits_shared_numerator = h.getBitsInt(16); // 12
- t.shared_denominator = h.getBitsInt(16); // 13
+ t.min_nobjects = h.getBitsInt(32); // 1
+ t.first_page_offset = h.getBitsInt(32); // 2
+ t.nbits_delta_nobjects = h.getBitsInt(16); // 3
+ t.min_page_length = h.getBitsInt(32); // 4
+ t.nbits_delta_page_length = h.getBitsInt(16); // 5
+ t.min_content_offset = h.getBitsInt(32); // 6
+ t.nbits_delta_content_offset = h.getBitsInt(16); // 7
+ t.min_content_length = h.getBitsInt(32); // 8
+ t.nbits_delta_content_length = h.getBitsInt(16); // 9
+ t.nbits_nshared_objects = h.getBitsInt(16); // 10
+ t.nbits_shared_identifier = h.getBitsInt(16); // 11
+ t.nbits_shared_numerator = h.getBitsInt(16); // 12
+ t.shared_denominator = h.getBitsInt(16); // 13
std::vector<HPageOffsetEntry>& entries = t.entries;
entries.clear();
int nitems = this->m->linp.npages;
- load_vector_int(h, nitems, entries,
- t.nbits_delta_nobjects,
- &HPageOffsetEntry::delta_nobjects);
- load_vector_int(h, nitems, entries,
- t.nbits_delta_page_length,
- &HPageOffsetEntry::delta_page_length);
- load_vector_int(h, nitems, entries,
- t.nbits_nshared_objects,
- &HPageOffsetEntry::nshared_objects);
- load_vector_vector(h, nitems, entries,
- &HPageOffsetEntry::nshared_objects,
- t.nbits_shared_identifier,
- &HPageOffsetEntry::shared_identifiers);
- load_vector_vector(h, nitems, entries,
- &HPageOffsetEntry::nshared_objects,
- t.nbits_shared_numerator,
- &HPageOffsetEntry::shared_numerators);
- load_vector_int(h, nitems, entries,
- t.nbits_delta_content_offset,
- &HPageOffsetEntry::delta_content_offset);
- load_vector_int(h, nitems, entries,
- t.nbits_delta_content_length,
- &HPageOffsetEntry::delta_content_length);
+ load_vector_int(
+ h,
+ nitems,
+ entries,
+ t.nbits_delta_nobjects,
+ &HPageOffsetEntry::delta_nobjects);
+ load_vector_int(
+ h,
+ nitems,
+ entries,
+ t.nbits_delta_page_length,
+ &HPageOffsetEntry::delta_page_length);
+ load_vector_int(
+ h,
+ nitems,
+ entries,
+ t.nbits_nshared_objects,
+ &HPageOffsetEntry::nshared_objects);
+ load_vector_vector(
+ h,
+ nitems,
+ entries,
+ &HPageOffsetEntry::nshared_objects,
+ t.nbits_shared_identifier,
+ &HPageOffsetEntry::shared_identifiers);
+ load_vector_vector(
+ h,
+ nitems,
+ entries,
+ &HPageOffsetEntry::nshared_objects,
+ t.nbits_shared_numerator,
+ &HPageOffsetEntry::shared_numerators);
+ load_vector_int(
+ h,
+ nitems,
+ entries,
+ t.nbits_delta_content_offset,
+ &HPageOffsetEntry::delta_content_offset);
+ load_vector_int(
+ h,
+ nitems,
+ entries,
+ t.nbits_delta_content_length,
+ &HPageOffsetEntry::delta_content_length);
}
void
@@ -455,50 +454,55 @@ QPDF::readHSharedObject(BitStream h)
{
HSharedObject& t = this->m->shared_object_hints;
- t.first_shared_obj = h.getBitsInt(32); // 1
- t.first_shared_offset = h.getBitsInt(32); // 2
- t.nshared_first_page = h.getBitsInt(32); // 3
- t.nshared_total = h.getBitsInt(32); // 4
- t.nbits_nobjects = h.getBitsInt(16); // 5
- t.min_group_length = h.getBitsInt(32); // 6
- t.nbits_delta_group_length = h.getBitsInt(16); // 7
+ t.first_shared_obj = h.getBitsInt(32); // 1
+ t.first_shared_offset = h.getBitsInt(32); // 2
+ t.nshared_first_page = h.getBitsInt(32); // 3
+ t.nshared_total = h.getBitsInt(32); // 4
+ t.nbits_nobjects = h.getBitsInt(16); // 5
+ t.min_group_length = h.getBitsInt(32); // 6
+ t.nbits_delta_group_length = h.getBitsInt(16); // 7
- QTC::TC("qpdf", "QPDF lin nshared_total > nshared_first_page",
- (t.nshared_total > t.nshared_first_page) ? 1 : 0);
+ QTC::TC(
+ "qpdf",
+ "QPDF lin nshared_total > nshared_first_page",
+ (t.nshared_total > t.nshared_first_page) ? 1 : 0);
std::vector<HSharedObjectEntry>& entries = t.entries;
entries.clear();
int nitems = t.nshared_total;
- load_vector_int(h, nitems, entries,
- t.nbits_delta_group_length,
- &HSharedObjectEntry::delta_group_length);
- load_vector_int(h, nitems, entries,
- 1, &HSharedObjectEntry::signature_present);
- for (size_t i = 0; i < toS(nitems); ++i)
- {
- if (entries.at(i).signature_present)
- {
+ load_vector_int(
+ h,
+ nitems,
+ entries,
+ t.nbits_delta_group_length,
+ &HSharedObjectEntry::delta_group_length);
+ load_vector_int(
+ h, nitems, entries, 1, &HSharedObjectEntry::signature_present);
+ for (size_t i = 0; i < toS(nitems); ++i) {
+ if (entries.at(i).signature_present) {
// Skip 128-bit MD5 hash. These are not supported by
// acrobat, so they should probably never be there. We
// have no test case for this.
- for (int j = 0; j < 4; ++j)
- {
- (void) h.getBits(32);
+ for (int j = 0; j < 4; ++j) {
+ (void)h.getBits(32);
}
}
}
- load_vector_int(h, nitems, entries,
- t.nbits_nobjects,
- &HSharedObjectEntry::nobjects_minus_one);
+ load_vector_int(
+ h,
+ nitems,
+ entries,
+ t.nbits_nobjects,
+ &HSharedObjectEntry::nobjects_minus_one);
}
void
QPDF::readHGeneric(BitStream h, HGeneric& t)
{
- t.first_object = h.getBitsInt(32); // 1
- t.first_object_offset = h.getBitsInt(32); // 2
- t.nobjects = h.getBitsInt(32); // 3
- t.group_length = h.getBitsInt(32); // 4
+ t.first_object = h.getBitsInt(32); // 1
+ t.first_object_offset = h.getBitsInt(32); // 2
+ t.nobjects = h.getBitsInt(32); // 3
+ t.group_length = h.getBitsInt(32); // 4
}
bool
@@ -518,51 +522,45 @@ QPDF::checkLinearizationInternal()
// O: object number of first page
std::vector<QPDFObjectHandle> const& pages = getAllPages();
- if (p.first_page_object != pages.at(0).getObjectID())
- {
+ if (p.first_page_object != pages.at(0).getObjectID()) {
QTC::TC("qpdf", "QPDF err /O mismatch");
errors.push_back("first page object (/O) mismatch");
}
// N: number of pages
int npages = toI(pages.size());
- if (p.npages != npages)
- {
+ if (p.npages != npages) {
// Not tested in the test suite
errors.push_back("page count (/N) mismatch");
}
- for (size_t i = 0; i < toS(npages); ++i)
- {
+ for (size_t i = 0; i < toS(npages); ++i) {
QPDFObjectHandle const& page = pages.at(i);
QPDFObjGen og(page.getObjGen());
- if (this->m->xref_table[og].getType() == 2)
- {
- errors.push_back("page dictionary for page " +
- QUtil::uint_to_string(i) + " is compressed");
+ if (this->m->xref_table[og].getType() == 2) {
+ errors.push_back(
+ "page dictionary for page " + QUtil::uint_to_string(i) +
+ " is compressed");
}
}
// T: offset of whitespace character preceding xref entry for object 0
this->m->file->seek(p.xref_zero_offset, SEEK_SET);
- while (1)
- {
+ while (1) {
char ch;
this->m->file->read(&ch, 1);
- if (! ((ch == ' ') || (ch == '\r') || (ch == '\n')))
- {
+ if (!((ch == ' ') || (ch == '\r') || (ch == '\n'))) {
this->m->file->seek(-1, SEEK_CUR);
break;
}
}
- if (this->m->file->tell() != this->m->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->m->first_xref_item_offset) +
- "; file = " +
- QUtil::int_to_string(this->m->file->tell()));
+ errors.push_back(
+ "space before first xref item (/T) mismatch "
+ "(computed = " +
+ QUtil::int_to_string(this->m->first_xref_item_offset) +
+ "; file = " + QUtil::int_to_string(this->m->file->tell()));
}
// P: first page number -- Implementation note 124 says Acrobat
@@ -573,8 +571,7 @@ QPDF::checkLinearizationInternal()
// at the end of the containing xref section if any object streams
// are in use.
- if (this->m->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");
}
@@ -588,12 +585,11 @@ QPDF::checkLinearizationInternal()
std::map<int, int> object_stream_data;
for (std::map<QPDFObjGen, QPDFXRefEntry>::const_iterator iter =
this->m->xref_table.begin();
- iter != this->m->xref_table.end(); ++iter)
- {
+ iter != this->m->xref_table.end();
+ ++iter) {
QPDFObjGen const& og = (*iter).first;
QPDFXRefEntry const& entry = (*iter).second;
- if (entry.getType() == 2)
- {
+ if (entry.getType() == 2) {
object_stream_data[og.getObj()] = entry.getObjStreamNumber();
}
}
@@ -612,18 +608,16 @@ QPDF::checkLinearizationInternal()
// agree with pdlin. As of this writing, the test suite doesn't
// contain any files with threads.
- if (this->m->part6.empty())
- {
+ if (this->m->part6.empty()) {
stopOnError("linearization part 6 unexpectedly empty");
}
qpdf_offset_t min_E = -1;
qpdf_offset_t max_E = -1;
for (std::vector<QPDFObjectHandle>::iterator iter = this->m->part6.begin();
- iter != this->m->part6.end(); ++iter)
- {
+ iter != this->m->part6.end();
+ ++iter) {
QPDFObjGen og((*iter).getObjGen());
- if (this->m->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");
}
@@ -631,14 +625,12 @@ QPDF::checkLinearizationInternal()
min_E = std::max(min_E, oc.end_before_space);
max_E = std::max(max_E, oc.end_after_space);
}
- if ((p.first_page_end < min_E) || (p.first_page_end > max_E))
- {
+ if ((p.first_page_end < min_E) || (p.first_page_end > max_E)) {
QTC::TC("qpdf", "QPDF warn /E mismatch");
- warnings.push_back("end of first page section (/E) mismatch: /E = " +
- QUtil::int_to_string(p.first_page_end) +
- "; computed = " +
- QUtil::int_to_string(min_E) + ".." +
- QUtil::int_to_string(max_E));
+ warnings.push_back(
+ "end of first page section (/E) mismatch: /E = " +
+ QUtil::int_to_string(p.first_page_end) + "; computed = " +
+ QUtil::int_to_string(min_E) + ".." + QUtil::int_to_string(max_E));
}
// Check hint tables
@@ -657,22 +649,20 @@ QPDF::checkLinearizationInternal()
// them as errors. We'll hang onto the distinction in the code for
// now in case we ever have a chance to clean up the linearization
// code.
- if (! errors.empty())
- {
+ if (!errors.empty()) {
result = false;
for (std::list<std::string>::iterator iter = errors.begin();
- iter != errors.end(); ++iter)
- {
+ iter != errors.end();
+ ++iter) {
*this->m->err_stream << "WARNING: " << (*iter) << std::endl;
}
}
- if (! warnings.empty())
- {
+ if (!warnings.empty()) {
result = false;
for (std::list<std::string>::iterator iter = warnings.begin();
- iter != warnings.end(); ++iter)
- {
+ iter != warnings.end();
+ ++iter) {
*this->m->err_stream << "WARNING: " << (*iter) << std::endl;
}
}
@@ -683,18 +673,16 @@ QPDF::checkLinearizationInternal()
qpdf_offset_t
QPDF::maxEnd(ObjUser const& ou)
{
- if (this->m->obj_user_to_objects.count(ou) == 0)
- {
+ if (this->m->obj_user_to_objects.count(ou) == 0) {
stopOnError("no entry in object user table for requested object user");
}
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)
- {
+ iter != ogs.end();
+ ++iter) {
QPDFObjGen const& og = *iter;
- if (this->m->obj_cache.count(og) == 0)
- {
+ if (this->m->obj_cache.count(og) == 0) {
stopOnError("unknown object referenced in object user table");
}
end = std::max(end, this->m->obj_cache[og].end_after_space);
@@ -707,20 +695,19 @@ QPDF::getLinearizationOffset(QPDFObjGen const& og)
{
QPDFXRefEntry entry = this->m->xref_table[og];
qpdf_offset_t result = 0;
- switch (entry.getType())
- {
- case 1:
+ switch (entry.getType()) {
+ case 1:
result = entry.getOffset();
break;
- case 2:
+ case 2:
// For compressed objects, return the offset of the object
// stream that contains them.
- result = getLinearizationOffset(
- QPDFObjGen(entry.getObjStreamNumber(), 0));
+ result =
+ getLinearizationOffset(QPDFObjGen(entry.getObjStreamNumber(), 0));
break;
- default:
+ default:
stopOnError(
"getLinearizationOffset called for xref entry not of type 1 or 2");
break;
@@ -729,53 +716,46 @@ QPDF::getLinearizationOffset(QPDFObjGen const& og)
}
QPDFObjectHandle
-QPDF::getUncompressedObject(QPDFObjectHandle& obj,
- std::map<int, int> const& object_stream_data)
+QPDF::getUncompressedObject(
+ QPDFObjectHandle& obj, std::map<int, int> const& object_stream_data)
{
- if (obj.isNull() || (object_stream_data.count(obj.getObjectID()) == 0))
- {
+ if (obj.isNull() || (object_stream_data.count(obj.getObjectID()) == 0)) {
return obj;
- }
- else
- {
+ } else {
int repl = (*(object_stream_data.find(obj.getObjectID()))).second;
return objGenToIndirect(QPDFObjGen(repl, 0));
}
}
int
-QPDF::lengthNextN(int first_object, int n,
- std::list<std::string>& errors)
+QPDF::lengthNextN(int first_object, int n, std::list<std::string>& errors)
{
int length = 0;
- for (int i = 0; i < n; ++i)
- {
+ for (int i = 0; i < n; ++i) {
QPDFObjGen og(first_object + i, 0);
- if (this->m->xref_table.count(og) == 0)
- {
+ if (this->m->xref_table.count(og) == 0) {
errors.push_back(
"no xref table entry for " +
QUtil::int_to_string(first_object + i) + " 0");
- }
- else
- {
- if (this->m->obj_cache.count(og) == 0)
- {
+ } else {
+ if (this->m->obj_cache.count(og) == 0) {
stopOnError("found unknown object while"
" calculating length for linearization data");
}
- length += toI(this->m->obj_cache[og].end_after_space -
- getLinearizationOffset(og));
+ length +=
+ toI(this->m->obj_cache[og].end_after_space -
+ getLinearizationOffset(og));
}
}
return length;
}
void
-QPDF::checkHPageOffset(std::list<std::string>& errors,
- std::list<std::string>& warnings,
- std::vector<QPDFObjectHandle> const& pages,
- std::map<int, int>& shared_idx_to_obj)
+QPDF::checkHPageOffset(
+ std::list<std::string>& errors,
+ std::list<std::string>& warnings,
+ std::vector<QPDFObjectHandle> const& pages,
+ std::map<int, int>& shared_idx_to_obj)
{
// Implementation note 126 says Acrobat always sets
// delta_content_offset and delta_content_length in the page
@@ -795,25 +775,21 @@ QPDF::checkHPageOffset(std::list<std::string>& errors,
// even when they are private.
int npages = toI(pages.size());
- qpdf_offset_t table_offset = adjusted_offset(
- this->m->page_offset_hints.first_page_offset);
+ qpdf_offset_t table_offset =
+ adjusted_offset(this->m->page_offset_hints.first_page_offset);
QPDFObjGen first_page_og(pages.at(0).getObjGen());
- if (this->m->xref_table.count(first_page_og) == 0)
- {
+ if (this->m->xref_table.count(first_page_og) == 0) {
stopOnError("supposed first page object is not known");
}
qpdf_offset_t offset = getLinearizationOffset(first_page_og);
- if (table_offset != offset)
- {
+ if (table_offset != offset) {
warnings.push_back("first page object offset mismatch");
}
- for (int pageno = 0; pageno < npages; ++pageno)
- {
+ for (int pageno = 0; pageno < npages; ++pageno) {
QPDFObjGen page_og(pages.at(toS(pageno)).getObjGen());
int first_object = page_og.getObj();
- if (this->m->xref_table.count(page_og) == 0)
- {
+ if (this->m->xref_table.count(page_og) == 0) {
stopOnError("unknown object in page offset hint table");
}
offset = getLinearizationOffset(page_og);
@@ -822,33 +798,31 @@ QPDF::checkHPageOffset(std::list<std::string>& errors,
this->m->page_offset_hints.entries.at(toS(pageno));
CHPageOffsetEntry& ce =
this->m->c_page_offset_data.entries.at(toS(pageno));
- int h_nobjects = he.delta_nobjects +
- this->m->page_offset_hints.min_nobjects;
- if (h_nobjects != ce.nobjects)
- {
+ int h_nobjects =
+ he.delta_nobjects + this->m->page_offset_hints.min_nobjects;
+ if (h_nobjects != ce.nobjects) {
// This happens with pdlin when there are thumbnails.
warnings.push_back(
"object count mismatch for page " +
- QUtil::int_to_string(pageno) + ": hint table = " +
- QUtil::int_to_string(h_nobjects) + "; computed = " +
- QUtil::int_to_string(ce.nobjects));
+ QUtil::int_to_string(pageno) +
+ ": hint table = " + QUtil::int_to_string(h_nobjects) +
+ "; computed = " + QUtil::int_to_string(ce.nobjects));
}
// Use value for number of objects in hint table rather than
// computed value if there is a discrepancy.
int length = lengthNextN(first_object, h_nobjects, errors);
- int h_length = toI(he.delta_page_length +
- this->m->page_offset_hints.min_page_length);
- if (length != h_length)
- {
+ int h_length = toI(
+ he.delta_page_length + this->m->page_offset_hints.min_page_length);
+ if (length != h_length) {
// This condition almost certainly indicates a bad hint
// table or a bug in this code.
errors.push_back(
"page length mismatch for page " +
- QUtil::int_to_string(pageno) + ": hint table = " +
- QUtil::int_to_string(h_length) + "; computed length = " +
- QUtil::int_to_string(length) + " (offset = " +
- QUtil::int_to_string(offset) + ")");
+ QUtil::int_to_string(pageno) +
+ ": hint table = " + QUtil::int_to_string(h_length) +
+ "; computed length = " + QUtil::int_to_string(length) +
+ " (offset = " + QUtil::int_to_string(offset) + ")");
}
offset += h_length;
@@ -857,42 +831,34 @@ QPDF::checkHPageOffset(std::list<std::string>& errors,
std::set<int> hint_shared;
std::set<int> computed_shared;
- if ((pageno == 0) && (he.nshared_objects > 0))
- {
+ if ((pageno == 0) && (he.nshared_objects > 0)) {
// pdlin and Acrobat both do this even though the spec
// states clearly and unambiguously that they should not.
warnings.push_back("page 0 has shared identifier entries");
}
- for (size_t i = 0; i < toS(he.nshared_objects); ++i)
- {
+ for (size_t i = 0; i < toS(he.nshared_objects); ++i) {
int idx = he.shared_identifiers.at(i);
- if (shared_idx_to_obj.count(idx) == 0)
- {
- stopOnError(
- "unable to get object for item in"
- " shared objects hint table");
+ if (shared_idx_to_obj.count(idx) == 0) {
+ stopOnError("unable to get object for item in"
+ " shared objects hint table");
}
hint_shared.insert(shared_idx_to_obj[idx]);
}
- for (size_t i = 0; i < toS(ce.nshared_objects); ++i)
- {
+ for (size_t i = 0; i < toS(ce.nshared_objects); ++i) {
int idx = ce.shared_identifiers.at(i);
- if (idx >= this->m->c_shared_object_data.nshared_total)
- {
- stopOnError(
- "index out of bounds for shared object hint table");
+ if (idx >= this->m->c_shared_object_data.nshared_total) {
+ stopOnError("index out of bounds for shared object hint table");
}
int obj = this->m->c_shared_object_data.entries.at(toS(idx)).object;
computed_shared.insert(obj);
}
for (std::set<int>::iterator iter = hint_shared.begin();
- iter != hint_shared.end(); ++iter)
- {
- if (! computed_shared.count(*iter))
- {
+ iter != hint_shared.end();
+ ++iter) {
+ if (!computed_shared.count(*iter)) {
// pdlin puts thumbnails here even though it shouldn't
warnings.push_back(
"page " + QUtil::int_to_string(pageno) +
@@ -902,10 +868,9 @@ QPDF::checkHPageOffset(std::list<std::string>& errors,
}
for (std::set<int>::iterator iter = computed_shared.begin();
- iter != computed_shared.end(); ++iter)
- {
- if (! hint_shared.count(*iter))
- {
+ iter != computed_shared.end();
+ ++iter) {
+ if (!hint_shared.count(*iter)) {
// Acrobat does not put some things including at least
// built-in fonts and procsets here, at least in some
// cases.
@@ -919,10 +884,11 @@ QPDF::checkHPageOffset(std::list<std::string>& errors,
}
void
-QPDF::checkHSharedObject(std::list<std::string>& errors,
- std::list<std::string>& warnings,
- std::vector<QPDFObjectHandle> const& pages,
- std::map<int, int>& idx_to_obj)
+QPDF::checkHSharedObject(
+ std::list<std::string>& errors,
+ std::list<std::string>& warnings,
+ std::vector<QPDFObjectHandle> const& pages,
+ std::map<int, int>& idx_to_obj)
{
// Implementation note 125 says shared object groups always
// contain only one object. Implementation note 128 says that
@@ -943,57 +909,44 @@ QPDF::checkHSharedObject(std::list<std::string>& errors,
// the first page (i.e., nshared_total == nshared_first_page).
HSharedObject& so = this->m->shared_object_hints;
- if (so.nshared_total < so.nshared_first_page)
- {
+ if (so.nshared_total < so.nshared_first_page) {
errors.push_back("shared object hint table: ntotal < nfirst_page");
- }
- else
- {
+ } else {
// The first nshared_first_page objects are consecutive
// objects starting with the first page object. The rest are
// consecutive starting from the first_shared_obj object.
int cur_object = pages.at(0).getObjectID();
- for (int i = 0; i < so.nshared_total; ++i)
- {
- if (i == so.nshared_first_page)
- {
+ for (int i = 0; i < so.nshared_total; ++i) {
+ if (i == so.nshared_first_page) {
QTC::TC("qpdf", "QPDF lin check shared past first page");
- if (this->m->part8.empty())
- {
- errors.push_back(
- "part 8 is empty but nshared_total > "
- "nshared_first_page");
- }
- else
- {
+ if (this->m->part8.empty()) {
+ errors.push_back("part 8 is empty but nshared_total > "
+ "nshared_first_page");
+ } else {
int obj = this->m->part8.at(0).getObjectID();
- if (obj != so.first_shared_obj)
- {
+ if (obj != so.first_shared_obj) {
errors.push_back(
"first shared object number mismatch: "
"hint table = " +
QUtil::int_to_string(so.first_shared_obj) +
- "; computed = " +
- QUtil::int_to_string(obj));
+ "; computed = " + QUtil::int_to_string(obj));
}
}
cur_object = so.first_shared_obj;
QPDFObjGen og(cur_object, 0);
- if (this->m->xref_table.count(og) == 0)
- {
+ if (this->m->xref_table.count(og) == 0) {
stopOnError("unknown object in shared object hint table");
}
qpdf_offset_t offset = getLinearizationOffset(og);
qpdf_offset_t h_offset =
adjusted_offset(so.first_shared_offset);
- if (offset != h_offset)
- {
+ if (offset != h_offset) {
errors.push_back(
"first shared object offset mismatch: hint table = " +
- QUtil::int_to_string(h_offset) + "; computed = " +
- QUtil::int_to_string(offset));
+ QUtil::int_to_string(h_offset) +
+ "; computed = " + QUtil::int_to_string(offset));
}
}
@@ -1002,13 +955,12 @@ QPDF::checkHSharedObject(std::list<std::string>& errors,
int nobjects = se.nobjects_minus_one + 1;
int length = lengthNextN(cur_object, nobjects, errors);
int h_length = so.min_group_length + se.delta_group_length;
- if (length != h_length)
- {
+ if (length != h_length) {
errors.push_back(
"shared object " + QUtil::int_to_string(i) +
" length mismatch: hint table = " +
- QUtil::int_to_string(h_length) + "; computed = " +
- QUtil::int_to_string(length));
+ QUtil::int_to_string(h_length) +
+ "; computed = " + QUtil::int_to_string(length));
}
cur_object += nobjects;
}
@@ -1026,20 +978,16 @@ QPDF::checkHOutlines(std::list<std::string>& warnings)
// wrong starting place). pdlin appears to generate correct
// values in those cases.
- if (this->m->c_outline_data.nobjects == this->m->outline_hints.nobjects)
- {
- if (this->m->c_outline_data.nobjects == 0)
- {
+ if (this->m->c_outline_data.nobjects == this->m->outline_hints.nobjects) {
+ if (this->m->c_outline_data.nobjects == 0) {
return;
}
if (this->m->c_outline_data.first_object ==
- this->m->outline_hints.first_object)
- {
+ this->m->outline_hints.first_object) {
// Check length and offset. Acrobat gets these wrong.
QPDFObjectHandle outlines = getRoot().getKey("/Outlines");
- if (! outlines.isIndirect())
- {
+ if (!outlines.isIndirect()) {
// This case is not exercised in test suite since not
// permitted by the spec, but if this does occur, the
// code below would fail.
@@ -1048,8 +996,7 @@ QPDF::checkHOutlines(std::list<std::string>& warnings)
return;
}
QPDFObjGen og(outlines.getObjGen());
- if (this->m->xref_table.count(og) == 0)
- {
+ if (this->m->xref_table.count(og) == 0) {
stopOnError("unknown object in outlines hint table");
}
qpdf_offset_t offset = getLinearizationOffset(og);
@@ -1057,30 +1004,24 @@ QPDF::checkHOutlines(std::list<std::string>& warnings)
int length = toI(maxEnd(ou) - offset);
qpdf_offset_t table_offset =
adjusted_offset(this->m->outline_hints.first_object_offset);
- if (offset != table_offset)
- {
+ if (offset != table_offset) {
warnings.push_back(
"incorrect offset in outlines table: hint table = " +
QUtil::int_to_string(table_offset) +
"; computed = " + QUtil::int_to_string(offset));
}
int table_length = this->m->outline_hints.group_length;
- if (length != table_length)
- {
+ if (length != table_length) {
warnings.push_back(
"incorrect length in outlines table: hint table = " +
QUtil::int_to_string(table_length) +
"; computed = " + QUtil::int_to_string(length));
}
- }
- else
- {
+ } else {
warnings.push_back("incorrect first object number in outline "
"hints table.");
}
- }
- else
- {
+ } else {
warnings.push_back("incorrect object count in outline hint table");
}
}
@@ -1088,14 +1029,11 @@ QPDF::checkHOutlines(std::list<std::string>& warnings)
void
QPDF::showLinearizationData()
{
- try
- {
+ try {
readLinearizationData();
checkLinearizationInternal();
dumpLinearizationDataInternal();
- }
- catch (QPDFExc& e)
- {
+ } catch (QPDFExc& e) {
*this->m->err_stream << e.what() << std::endl;
}
}
@@ -1103,9 +1041,9 @@ QPDF::showLinearizationData()
void
QPDF::dumpLinearizationDataInternal()
{
- *this->m->out_stream
- << this->m->file->getName() << ": linearization data:" << std::endl
- << 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
@@ -1118,16 +1056,14 @@ QPDF::dumpLinearizationDataInternal()
<< "H_length: " << this->m->linp.H_length << std::endl
<< std::endl;
- *this->m->out_stream << "Page Offsets Hint Table" << std::endl
- << std::endl;
+ *this->m->out_stream << "Page Offsets Hint Table" << std::endl << std::endl;
dumpHPageOffset();
*this->m->out_stream << std::endl
<< "Shared Objects Hint Table" << std::endl
<< std::endl;
dumpHSharedObject();
- if (this->m->outline_hints.nobjects > 0)
- {
+ if (this->m->outline_hints.nobjects > 0) {
*this->m->out_stream << std::endl
<< "Outlines Hint Table" << std::endl
<< std::endl;
@@ -1141,53 +1077,39 @@ QPDF::adjusted_offset(qpdf_offset_t 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->m->linp.H_offset)
- {
+ if (offset >= this->m->linp.H_offset) {
return offset + this->m->linp.H_length;
}
return offset;
}
-
void
QPDF::dumpHPageOffset()
{
HPageOffset& t = this->m->page_offset_hints;
*this->m->out_stream
- << "min_nobjects: " << t.min_nobjects
- << std::endl
+ << "min_nobjects: " << t.min_nobjects << std::endl
<< "first_page_offset: " << adjusted_offset(t.first_page_offset)
<< std::endl
- << "nbits_delta_nobjects: " << t.nbits_delta_nobjects
- << std::endl
- << "min_page_length: " << t.min_page_length
- << std::endl
- << "nbits_delta_page_length: " << t.nbits_delta_page_length
- << std::endl
- << "min_content_offset: " << t.min_content_offset
- << std::endl
+ << "nbits_delta_nobjects: " << t.nbits_delta_nobjects << std::endl
+ << "min_page_length: " << t.min_page_length << std::endl
+ << "nbits_delta_page_length: " << t.nbits_delta_page_length << std::endl
+ << "min_content_offset: " << t.min_content_offset << std::endl
<< "nbits_delta_content_offset: " << t.nbits_delta_content_offset
<< std::endl
- << "min_content_length: " << t.min_content_length
- << std::endl
+ << "min_content_length: " << t.min_content_length << std::endl
<< "nbits_delta_content_length: " << t.nbits_delta_content_length
<< std::endl
- << "nbits_nshared_objects: " << t.nbits_nshared_objects
- << std::endl
- << "nbits_shared_identifier: " << t.nbits_shared_identifier
- << std::endl
- << "nbits_shared_numerator: " << t.nbits_shared_numerator
- << std::endl
- << "shared_denominator: " << t.shared_denominator
- << std::endl;
+ << "nbits_nshared_objects: " << t.nbits_nshared_objects << std::endl
+ << "nbits_shared_identifier: " << t.nbits_shared_identifier << std::endl
+ << "nbits_shared_numerator: " << t.nbits_shared_numerator << std::endl
+ << "shared_denominator: " << t.shared_denominator << std::endl;
- for (size_t i1 = 0; i1 < toS(this->m->linp.npages); ++i1)
- {
+ for (size_t i1 = 0; i1 < toS(this->m->linp.npages); ++i1) {
HPageOffsetEntry& pe = t.entries.at(i1);
*this->m->out_stream
<< "Page " << i1 << ":" << std::endl
- << " nobjects: " << pe.delta_nobjects + t.min_nobjects
- << std::endl
+ << " nobjects: " << pe.delta_nobjects + t.min_nobjects << std::endl
<< " length: " << pe.delta_page_length + t.min_page_length
<< std::endl
// content offset is relative to page, not file
@@ -1196,8 +1118,7 @@ QPDF::dumpHPageOffset()
<< " content_length: "
<< pe.delta_content_length + t.min_content_length << std::endl
<< " nshared_objects: " << pe.nshared_objects << std::endl;
- for (size_t i2 = 0; i2 < toS(pe.nshared_objects); ++i2)
- {
+ for (size_t i2 = 0; i2 < toS(pe.nshared_objects); ++i2) {
*this->m->out_stream << " identifier " << i2 << ": "
<< pe.shared_identifiers.at(i2) << std::endl;
*this->m->out_stream << " numerator " << i2 << ": "
@@ -1210,39 +1131,33 @@ void
QPDF::dumpHSharedObject()
{
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)
- << std::endl
- << "nshared_first_page: " << t.nshared_first_page
- << std::endl
- << "nshared_total: " << t.nshared_total
- << std::endl
- << "nbits_nobjects: " << t.nbits_nobjects
- << std::endl
- << "min_group_length: " << t.min_group_length
- << std::endl
- << "nbits_delta_group_length: " << t.nbits_delta_group_length
- << std::endl;
-
- for (size_t i = 0; i < toS(t.nshared_total); ++i)
- {
+ *this->m->out_stream << "first_shared_obj: " << t.first_shared_obj
+ << std::endl
+ << "first_shared_offset: "
+ << adjusted_offset(t.first_shared_offset) << std::endl
+ << "nshared_first_page: " << t.nshared_first_page
+ << std::endl
+ << "nshared_total: " << t.nshared_total << std::endl
+ << "nbits_nobjects: " << t.nbits_nobjects << std::endl
+ << "min_group_length: " << t.min_group_length
+ << std::endl
+ << "nbits_delta_group_length: "
+ << t.nbits_delta_group_length << std::endl;
+
+ for (size_t i = 0; i < toS(t.nshared_total); ++i) {
HSharedObjectEntry& se = t.entries.at(i);
*this->m->out_stream
<< "Shared Object " << i << ":" << std::endl
- << " group length: "
- << se.delta_group_length + t.min_group_length << 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)
- {
+ if (se.signature_present) {
*this->m->out_stream << " signature present" << std::endl;
}
- if (se.nobjects_minus_one != 0)
- {
- *this->m->out_stream << " nobjects: "
- << se.nobjects_minus_one + 1 << std::endl;
+ if (se.nobjects_minus_one != 0) {
+ *this->m->out_stream << " nobjects: " << se.nobjects_minus_one + 1
+ << std::endl;
}
}
}
@@ -1250,15 +1165,11 @@ QPDF::dumpHSharedObject()
void
QPDF::dumpHGeneric(HGeneric& t)
{
- *this->m->out_stream
- << "first_object: " << t.first_object
- << std::endl
- << "first_object_offset: " << adjusted_offset(t.first_object_offset)
- << std::endl
- << "nobjects: " << t.nobjects
- << std::endl
- << "group_length: " << t.group_length
- << std::endl;
+ *this->m->out_stream << "first_object: " << t.first_object << std::endl
+ << "first_object_offset: "
+ << adjusted_offset(t.first_object_offset) << std::endl
+ << "nobjects: " << t.nobjects << std::endl
+ << "group_length: " << t.group_length << std::endl;
}
QPDFObjectHandle
@@ -1277,8 +1188,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->m->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.
throw std::logic_error(
@@ -1346,23 +1256,20 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
QPDFObjectHandle root = getRoot();
bool outlines_in_first_page = false;
QPDFObjectHandle pagemode = root.getKey("/PageMode");
- QTC::TC("qpdf", "QPDF categorize pagemode present",
- pagemode.isName() ? 1 : 0);
- if (pagemode.isName())
- {
- if (pagemode.getName() == "/UseOutlines")
- {
- if (root.hasKey("/Outlines"))
- {
+ QTC::TC(
+ "qpdf", "QPDF categorize pagemode present", pagemode.isName() ? 1 : 0);
+ if (pagemode.isName()) {
+ if (pagemode.getName() == "/UseOutlines") {
+ if (root.hasKey("/Outlines")) {
outlines_in_first_page = true;
- }
- else
- {
+ } else {
QTC::TC("qpdf", "QPDF UseOutlines but no Outlines");
}
}
- QTC::TC("qpdf", "QPDF categorize pagemode outlines",
- outlines_in_first_page ? 1 : 0);
+ QTC::TC(
+ "qpdf",
+ "QPDF categorize pagemode outlines",
+ outlines_in_first_page ? 1 : 0);
}
std::set<std::string> open_document_keys;
@@ -1383,10 +1290,10 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
std::set<QPDFObjGen> lc_outlines;
std::set<QPDFObjGen> lc_root;
- for (std::map<QPDFObjGen, std::set<ObjUser> >::iterator oiter =
+ for (std::map<QPDFObjGen, std::set<ObjUser>>::iterator oiter =
this->m->object_to_obj_users.begin();
- oiter != this->m->object_to_obj_users.end(); ++oiter)
- {
+ oiter != this->m->object_to_obj_users.end();
+ ++oiter) {
QPDFObjGen const& og = (*oiter).first;
std::set<ObjUser>& ous = (*oiter).second;
@@ -1400,103 +1307,72 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
bool is_root = false;
for (std::set<ObjUser>::iterator uiter = ous.begin();
- uiter != ous.end(); ++uiter)
- {
+ uiter != ous.end();
+ ++uiter) {
ObjUser const& ou = *uiter;
- switch (ou.ou_type)
- {
- case ObjUser::ou_trailer_key:
- if (ou.key == "/Encrypt")
- {
+ switch (ou.ou_type) {
+ case ObjUser::ou_trailer_key:
+ if (ou.key == "/Encrypt") {
in_open_document = true;
- }
- else
- {
+ } else {
++others;
}
break;
- case ObjUser::ou_thumb:
+ case ObjUser::ou_thumb:
++thumbs;
break;
- case ObjUser::ou_root_key:
- if (open_document_keys.count(ou.key) > 0)
- {
+ case ObjUser::ou_root_key:
+ if (open_document_keys.count(ou.key) > 0) {
in_open_document = true;
- }
- else if (ou.key == "/Outlines")
- {
+ } else if (ou.key == "/Outlines") {
in_outlines = true;
- }
- else
- {
+ } else {
++others;
}
break;
- case ObjUser::ou_page:
- if (ou.pageno == 0)
- {
+ case ObjUser::ou_page:
+ if (ou.pageno == 0) {
in_first_page = true;
- }
- else
- {
+ } else {
++other_pages;
}
break;
- case ObjUser::ou_root:
+ case ObjUser::ou_root:
is_root = true;
break;
- case ObjUser::ou_bad:
- stopOnError(
- "INTERNAL ERROR: QPDF::calculateLinearizationData: "
- "invalid user type");
+ case ObjUser::ou_bad:
+ stopOnError("INTERNAL ERROR: QPDF::calculateLinearizationData: "
+ "invalid user type");
break;
}
}
- if (is_root)
- {
+ if (is_root) {
lc_root.insert(og);
- }
- else if (in_outlines)
- {
+ } else if (in_outlines) {
lc_outlines.insert(og);
- }
- else if (in_open_document)
- {
+ } else if (in_open_document) {
lc_open_document.insert(og);
- }
- else if ((in_first_page) &&
- (others == 0) && (other_pages == 0) && (thumbs == 0))
- {
+ } else if (
+ (in_first_page) && (others == 0) && (other_pages == 0) &&
+ (thumbs == 0)) {
lc_first_page_private.insert(og);
- }
- else if (in_first_page)
- {
+ } else if (in_first_page) {
lc_first_page_shared.insert(og);
- }
- else if ((other_pages == 1) && (others == 0) && (thumbs == 0))
- {
+ } else if ((other_pages == 1) && (others == 0) && (thumbs == 0)) {
lc_other_page_private.insert(og);
- }
- else if (other_pages > 1)
- {
+ } else if (other_pages > 1) {
lc_other_page_shared.insert(og);
- }
- else if ((thumbs == 1) && (others == 0))
- {
+ } else if ((thumbs == 1) && (others == 0)) {
lc_thumbnail_private.insert(og);
- }
- else if (thumbs > 1)
- {
+ } else if (thumbs > 1) {
lc_thumbnail_shared.insert(og);
- }
- else
- {
+ } else {
lc_other.insert(og);
}
}
@@ -1522,8 +1398,8 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// should be a no-op in a properly linearized file.
std::vector<QPDFObjectHandle> t = getAllPages();
for (std::vector<QPDFObjectHandle>::iterator iter = t.begin();
- iter != t.end(); ++iter)
- {
+ iter != t.end();
+ ++iter) {
pages.push_back(getUncompressedObject(*iter, object_stream_data));
}
}
@@ -1546,15 +1422,14 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// Part 4: open document objects. We don't care about the order.
- if (lc_root.size() != 1)
- {
+ if (lc_root.size() != 1) {
stopOnError("found other than one root while"
" calculating linearization data");
}
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)
- {
+ iter != lc_open_document.end();
+ ++iter) {
this->m->part4.push_back(objGenToIndirect(*iter));
}
@@ -1565,13 +1440,11 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// will do the same.
// First, place the actual first page object itself.
- if (pages.empty())
- {
+ if (pages.empty()) {
stopOnError("no pages found while calculating linearization data");
}
QPDFObjGen first_page_og(pages.at(0).getObjGen());
- if (! lc_first_page_private.count(first_page_og))
- {
+ if (!lc_first_page_private.count(first_page_og)) {
stopOnError(
"INTERNAL ERROR: QPDF::calculateLinearizationData: first page "
"object not in lc_first_page_private");
@@ -1586,20 +1459,19 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// hint tables.
for (std::set<QPDFObjGen>::iterator iter = lc_first_page_private.begin();
- iter != lc_first_page_private.end(); ++iter)
- {
+ iter != lc_first_page_private.end();
+ ++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)
- {
+ iter != lc_first_page_shared.end();
+ ++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)
- {
+ if (outlines_in_first_page) {
pushOutlinesToPart(this->m->part6, lc_outlines, object_stream_data);
}
@@ -1615,13 +1487,11 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// Part 7: other pages' private objects
// For each page in order:
- for (size_t i = 1; i < toS(npages); ++i)
- {
+ for (size_t i = 1; i < toS(npages); ++i) {
// Place this page's page object
QPDFObjGen page_og(pages.at(i).getObjGen());
- if (! lc_other_page_private.count(page_og))
- {
+ if (!lc_other_page_private.count(page_og)) {
stopOnError(
"INTERNAL ERROR: "
"QPDF::calculateLinearizationData: page object for page " +
@@ -1636,18 +1506,16 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
this->m->c_page_offset_data.entries.at(i).nobjects = 1;
ObjUser ou(ObjUser::ou_page, toI(i));
- if (this->m->obj_user_to_objects.count(ou) == 0)
- {
+ if (this->m->obj_user_to_objects.count(ou) == 0) {
stopOnError("found unreferenced page while"
" calculating linearization data");
}
std::set<QPDFObjGen> ogs = this->m->obj_user_to_objects[ou];
for (std::set<QPDFObjGen>::iterator iter = ogs.begin();
- iter != ogs.end(); ++iter)
- {
+ iter != ogs.end();
+ ++iter) {
QPDFObjGen const& og = (*iter);
- if (lc_other_page_private.count(og))
- {
+ if (lc_other_page_private.count(og)) {
lc_other_page_private.erase(og);
this->m->part7.push_back(objGenToIndirect(og));
++this->m->c_page_offset_data.entries.at(i).nobjects;
@@ -1655,8 +1523,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
}
}
// That should have covered all part7 objects.
- if (! lc_other_page_private.empty())
- {
+ if (!lc_other_page_private.empty()) {
stopOnError(
"INTERNAL ERROR:"
" QPDF::calculateLinearizationData: lc_other_page_private is "
@@ -1667,8 +1534,8 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// Order is unimportant.
for (std::set<QPDFObjGen>::iterator iter = lc_other_page_shared.begin();
- iter != lc_other_page_shared.end(); ++iter)
- {
+ iter != lc_other_page_shared.end();
+ ++iter) {
this->m->part8.push_back(objGenToIndirect(*iter));
}
@@ -1684,17 +1551,15 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// Place the pages tree.
std::set<QPDFObjGen> pages_ogs =
this->m->obj_user_to_objects[ObjUser(ObjUser::ou_root_key, "/Pages")];
- if (pages_ogs.empty())
- {
+ if (pages_ogs.empty()) {
stopOnError("found empty pages tree while"
" calculating linearization data");
}
for (std::set<QPDFObjGen>::iterator iter = pages_ogs.begin();
- iter != pages_ogs.end(); ++iter)
- {
+ iter != pages_ogs.end();
+ ++iter) {
QPDFObjGen const& og = *iter;
- if (lc_other.count(og))
- {
+ if (lc_other.count(og)) {
lc_other.erase(og);
this->m->part9.push_back(objGenToIndirect(og));
}
@@ -1703,21 +1568,16 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// Place private thumbnail images in page order. Slightly more
// information would be required if we were going to bother with
// thumbnail hint tables.
- for (size_t i = 0; i < toS(npages); ++i)
- {
+ for (size_t i = 0; i < toS(npages); ++i) {
QPDFObjectHandle thumb = pages.at(i).getKey("/Thumb");
thumb = getUncompressedObject(thumb, object_stream_data);
- if (! thumb.isNull())
- {
+ if (!thumb.isNull()) {
// Output the thumbnail itself
QPDFObjGen thumb_og(thumb.getObjGen());
- if (lc_thumbnail_private.count(thumb_og))
- {
+ if (lc_thumbnail_private.count(thumb_og)) {
lc_thumbnail_private.erase(thumb_og);
this->m->part9.push_back(thumb);
- }
- else
- {
+ } else {
// No internal error this time...there's nothing to
// stop this object from having been referred to
// somewhere else outside of a page's /Thumb, and if
@@ -1726,62 +1586,55 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
// lc_thumbnail_private.
}
std::set<QPDFObjGen>& ogs =
- this->m->obj_user_to_objects[
- ObjUser(ObjUser::ou_thumb, toI(i))];
+ this->m
+ ->obj_user_to_objects[ObjUser(ObjUser::ou_thumb, toI(i))];
for (std::set<QPDFObjGen>::iterator iter = ogs.begin();
- iter != ogs.end(); ++iter)
- {
+ iter != ogs.end();
+ ++iter) {
QPDFObjGen const& og = *iter;
- if (lc_thumbnail_private.count(og))
- {
+ if (lc_thumbnail_private.count(og)) {
lc_thumbnail_private.erase(og);
this->m->part9.push_back(objGenToIndirect(og));
}
}
}
}
- if (! lc_thumbnail_private.empty())
- {
- stopOnError(
- "INTERNAL ERROR: "
- "QPDF::calculateLinearizationData: lc_thumbnail_private "
- "not empty after placing thumbnails");
+ if (!lc_thumbnail_private.empty()) {
+ stopOnError("INTERNAL ERROR: "
+ "QPDF::calculateLinearizationData: lc_thumbnail_private "
+ "not empty after placing thumbnails");
}
// Place shared thumbnail objects
for (std::set<QPDFObjGen>::iterator iter = lc_thumbnail_shared.begin();
- iter != lc_thumbnail_shared.end(); ++iter)
- {
+ iter != lc_thumbnail_shared.end();
+ ++iter) {
this->m->part9.push_back(objGenToIndirect(*iter));
}
// Place outlines unless in first page
- if (! outlines_in_first_page)
- {
+ if (!outlines_in_first_page) {
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)
- {
+ iter != lc_other.end();
+ ++iter) {
this->m->part9.push_back(objGenToIndirect(*iter));
}
// Make sure we got everything exactly once.
- size_t num_placed =
- this->m->part4.size() + this->m->part6.size() + this->m->part7.size() +
- this->m->part8.size() + this->m->part9.size();
+ size_t num_placed = this->m->part4.size() + this->m->part6.size() +
+ this->m->part7.size() + this->m->part8.size() + this->m->part9.size();
size_t num_wanted = this->m->object_to_obj_users.size();
- if (num_placed != num_wanted)
- {
+ if (num_placed != num_wanted) {
stopOnError(
"INTERNAL ERROR: QPDF::calculateLinearizationData: wrong "
"number of objects placed (num_placed = " +
QUtil::uint_to_string(num_placed) +
- "; number of objects: " +
- QUtil::uint_to_string(num_wanted));
+ "; number of objects: " + QUtil::uint_to_string(num_wanted));
}
// Calculate shared object hint table information including
@@ -1806,22 +1659,21 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
std::vector<CHSharedObjectEntry>& shared =
this->m->c_shared_object_data.entries;
for (std::vector<QPDFObjectHandle>::iterator iter = this->m->part6.begin();
- iter != this->m->part6.end(); ++iter)
- {
+ iter != this->m->part6.end();
+ ++iter) {
QPDFObjectHandle& oh = *iter;
int obj = oh.getObjectID();
obj_to_index[obj] = toI(shared.size());
shared.push_back(CHSharedObjectEntry(obj));
}
QTC::TC("qpdf", "QPDF lin part 8 empty", this->m->part8.empty() ? 1 : 0);
- if (! this->m->part8.empty())
- {
+ if (!this->m->part8.empty()) {
this->m->c_shared_object_data.first_shared_obj =
this->m->part8.at(0).getObjectID();
for (std::vector<QPDFObjectHandle>::iterator iter =
this->m->part8.begin();
- iter != this->m->part8.end(); ++iter)
- {
+ iter != this->m->part8.end();
+ ++iter) {
QPDFObjectHandle& oh = *iter;
int obj = oh.getObjectID();
obj_to_index[obj] = toI(shared.size());
@@ -1829,32 +1681,27 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data)
}
}
if (static_cast<size_t>(this->m->c_shared_object_data.nshared_total) !=
- this->m->c_shared_object_data.entries.size())
- {
- stopOnError(
- "shared object hint table has wrong number of entries");
+ this->m->c_shared_object_data.entries.size()) {
+ stopOnError("shared object hint table has wrong number of entries");
}
// Now compute the list of shared objects for each page after the
// first page.
- for (size_t i = 1; i < toS(npages); ++i)
- {
+ for (size_t i = 1; i < toS(npages); ++i) {
CHPageOffsetEntry& pe = this->m->c_page_offset_data.entries.at(i);
ObjUser ou(ObjUser::ou_page, toI(i));
- if (this->m->obj_user_to_objects.count(ou) == 0)
- {
+ if (this->m->obj_user_to_objects.count(ou) == 0) {
stopOnError("found unreferenced page while"
" calculating linearization data");
}
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)
- {
+ iter != ogs.end();
+ ++iter) {
QPDFObjGen const& og = *iter;
if ((this->m->object_to_obj_users[og].size() > 1) &&
- (obj_to_index.count(og.getObj()) > 0))
- {
+ (obj_to_index.count(og.getObj()) > 0)) {
int idx = obj_to_index[og.getObj()];
++pe.nshared_objects;
pe.shared_identifiers.push_back(idx);
@@ -1871,23 +1718,24 @@ QPDF::pushOutlinesToPart(
{
QPDFObjectHandle root = getRoot();
QPDFObjectHandle outlines = root.getKey("/Outlines");
- if (outlines.isNull())
- {
+ if (outlines.isNull()) {
return;
}
outlines = getUncompressedObject(outlines, object_stream_data);
QPDFObjGen outlines_og(outlines.getObjGen());
- QTC::TC("qpdf", "QPDF lin outlines in part",
- ((&part == (&this->m->part6)) ? 0
+ QTC::TC(
+ "qpdf",
+ "QPDF lin outlines in part",
+ ((&part == (&this->m->part6)) ? 0
: (&part == (&this->m->part9)) ? 1
- : 9999)); // can't happen
+ : 9999)); // can't happen
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)
- {
+ iter != lc_outlines.end();
+ ++iter) {
part.push_back(objGenToIndirect(*iter));
++this->m->c_outline_data.nobjects;
}
@@ -1910,14 +1758,16 @@ QPDF::getLinearizedParts(
part9 = this->m->part9;
}
-static inline int nbits(int val)
+static inline int
+nbits(int val)
{
return (val == 0 ? 0 : (1 + nbits(val >> 1)));
}
int
QPDF::outputLengthNextN(
- int in_object, int n,
+ int in_object,
+ int n,
std::map<int, qpdf_offset_t> const& lengths,
std::map<int, int> const& obj_renumber)
{
@@ -1925,17 +1775,14 @@ QPDF::outputLengthNextN(
// the output file starting with whatever object in_object from
// the input file mapped to.
- if (obj_renumber.count(in_object) == 0)
- {
+ if (obj_renumber.count(in_object) == 0) {
stopOnError("found object that is not renumbered while"
" writing linearization data");
}
int first = (*(obj_renumber.find(in_object))).second;
int length = 0;
- for (int i = 0; i < n; ++i)
- {
- if (lengths.count(first + i) == 0)
- {
+ for (int i = 0; i < n; ++i) {
+ if (lengths.count(first + i) == 0) {
stopOnError("found item with unknown length"
" while writing linearization data");
}
@@ -1975,8 +1822,7 @@ QPDF::calculateHPageOffset(
// npages is the size of the existing pages array.
phe = std::vector<HPageOffsetEntry>(npages);
- for (unsigned int i = 0; i < npages; ++i)
- {
+ for (unsigned int i = 0; i < npages; ++i) {
// Calculate values for each page, assigning full values to
// the delta items. They will be adjusted later.
@@ -2009,7 +1855,7 @@ QPDF::calculateHPageOffset(
ph.nbits_nshared_objects = nbits(max_shared);
ph.nbits_shared_identifier =
nbits(this->m->c_shared_object_data.nshared_total);
- ph.shared_denominator = 4; // doesn't matter
+ ph.shared_denominator = 4; // doesn't matter
// It isn't clear how to compute content offset and content
// length. Since we are not interleaving page objects with the
@@ -2019,12 +1865,10 @@ QPDF::calculateHPageOffset(
ph.nbits_delta_content_length = ph.nbits_delta_page_length;
ph.min_content_length = ph.min_page_length;
- for (size_t i = 0; i < npages; ++i)
- {
+ for (size_t i = 0; i < npages; ++i) {
// Adjust delta entries
if ((phe.at(i).delta_nobjects < min_nobjects) ||
- (phe.at(i).delta_page_length < min_length))
- {
+ (phe.at(i).delta_page_length < min_length)) {
stopOnError("found too small delta nobjects or delta page length"
" while writing linearization data");
}
@@ -2032,8 +1876,7 @@ QPDF::calculateHPageOffset(
phe.at(i).delta_page_length -= min_length;
phe.at(i).delta_content_length = phe.at(i).delta_page_length;
- for (size_t j = 0; j < toS(cphe.at(i).nshared_objects); ++j)
- {
+ for (size_t j = 0; j < toS(cphe.at(i).nshared_objects); ++j) {
phe.at(i).shared_identifiers.push_back(
cphe.at(i).shared_identifiers.at(j));
phe.at(i).shared_numerators.push_back(0);
@@ -2053,29 +1896,26 @@ QPDF::calculateHSharedObject(
std::vector<HSharedObjectEntry>& soe = so.entries;
soe.clear();
- int min_length = outputLengthNextN(
- csoe.at(0).object, 1, lengths, obj_renumber);
+ int min_length =
+ outputLengthNextN(csoe.at(0).object, 1, lengths, obj_renumber);
int max_length = min_length;
- for (size_t i = 0; i < toS(cso.nshared_total); ++i)
- {
+ for (size_t i = 0; i < toS(cso.nshared_total); ++i) {
// Assign absolute numbers to deltas; adjust later
- int length = outputLengthNextN(
- csoe.at(i).object, 1, lengths, obj_renumber);
+ int length =
+ outputLengthNextN(csoe.at(i).object, 1, lengths, obj_renumber);
min_length = std::min(min_length, length);
max_length = std::max(max_length, length);
soe.push_back(HSharedObjectEntry());
soe.at(i).delta_group_length = length;
}
- if (soe.size() != QIntC::to_size(cso.nshared_total))
- {
+ if (soe.size() != QIntC::to_size(cso.nshared_total)) {
stopOnError("soe has wrong size after initialization");
}
so.nshared_total = cso.nshared_total;
so.nshared_first_page = cso.nshared_first_page;
- if (so.nshared_total > so.nshared_first_page)
- {
+ if (so.nshared_total > so.nshared_first_page) {
so.first_shared_obj =
(*(obj_renumber.find(cso.first_shared_obj))).second;
so.first_shared_offset =
@@ -2084,11 +1924,9 @@ QPDF::calculateHSharedObject(
so.min_group_length = min_length;
so.nbits_delta_group_length = nbits(max_length - min_length);
- for (size_t i = 0; i < toS(cso.nshared_total); ++i)
- {
+ for (size_t i = 0; i < toS(cso.nshared_total); ++i) {
// Adjust deltas
- if (soe.at(i).delta_group_length < min_length)
- {
+ if (soe.at(i).delta_group_length < min_length) {
stopOnError("found too small group length while"
" writing linearization data");
}
@@ -2104,34 +1942,30 @@ QPDF::calculateHOutline(
{
HGeneric& cho = this->m->c_outline_data;
- if (cho.nobjects == 0)
- {
+ if (cho.nobjects == 0) {
return;
}
HGeneric& ho = this->m->outline_hints;
- ho.first_object =
- (*(obj_renumber.find(cho.first_object))).second;
- ho.first_object_offset =
- (*(xref.find(ho.first_object))).second.getOffset();
+ ho.first_object = (*(obj_renumber.find(cho.first_object))).second;
+ ho.first_object_offset = (*(xref.find(ho.first_object))).second.getOffset();
ho.nobjects = cho.nobjects;
- ho.group_length = outputLengthNextN(
- cho.first_object, ho.nobjects, lengths, obj_renumber);
+ ho.group_length =
+ outputLengthNextN(cho.first_object, ho.nobjects, lengths, obj_renumber);
}
template <class T, class int_type>
static void
-write_vector_int(BitWriter& w, int nitems, std::vector<T>& vec,
- int bits, int_type T::*field)
+write_vector_int(
+ BitWriter& w, int nitems, std::vector<T>& vec, int bits, int_type T::*field)
{
// nitems times, write bits bits from the given field of the ith
// vector to the given bit writer.
- for (size_t i = 0; i < QIntC::to_size(nitems); ++i)
- {
- w.writeBits(QIntC::to_ulonglong(vec.at(i).*field),
- QIntC::to_size(bits));
+ for (size_t i = 0; i < QIntC::to_size(nitems); ++i) {
+ w.writeBits(
+ QIntC::to_ulonglong(vec.at(i).*field), QIntC::to_size(bits));
}
// The PDF spec says that each hint table starts at a byte
// boundary. Each "row" actually must start on a byte boundary.
@@ -2140,69 +1974,92 @@ write_vector_int(BitWriter& w, int nitems, std::vector<T>& vec,
template <class T>
static void
-write_vector_vector(BitWriter& w,
- int nitems1, std::vector<T>& vec1, int T::*nitems2,
- int bits, std::vector<int> T::*vec2)
+write_vector_vector(
+ BitWriter& w,
+ int nitems1,
+ std::vector<T>& vec1,
+ int T::*nitems2,
+ int bits,
+ std::vector<int> T::*vec2)
{
// nitems1 times, write nitems2 (from the ith element of vec1) items
// from the vec2 vector field of the ith item of vec1.
- for (size_t i1 = 0; i1 < QIntC::to_size(nitems1); ++i1)
- {
- for (size_t i2 = 0; i2 < QIntC::to_size(vec1.at(i1).*nitems2); ++i2)
- {
- w.writeBits(QIntC::to_ulonglong((vec1.at(i1).*vec2).at(i2)),
- QIntC::to_size(bits));
+ for (size_t i1 = 0; i1 < QIntC::to_size(nitems1); ++i1) {
+ for (size_t i2 = 0; i2 < QIntC::to_size(vec1.at(i1).*nitems2); ++i2) {
+ w.writeBits(
+ QIntC::to_ulonglong((vec1.at(i1).*vec2).at(i2)),
+ QIntC::to_size(bits));
}
}
w.flush();
}
-
void
QPDF::writeHPageOffset(BitWriter& w)
{
HPageOffset& t = this->m->page_offset_hints;
- w.writeBitsInt(t.min_nobjects, 32); // 1
- w.writeBitsInt(toI(t.first_page_offset), 32); // 2
- w.writeBitsInt(t.nbits_delta_nobjects, 16); // 3
- w.writeBitsInt(t.min_page_length, 32); // 4
- w.writeBitsInt(t.nbits_delta_page_length, 16); // 5
- w.writeBitsInt(t.min_content_offset, 32); // 6
- w.writeBitsInt(t.nbits_delta_content_offset, 16); // 7
- w.writeBitsInt(t.min_content_length, 32); // 8
- w.writeBitsInt(t.nbits_delta_content_length, 16); // 9
- w.writeBitsInt(t.nbits_nshared_objects, 16); // 10
- w.writeBitsInt(t.nbits_shared_identifier, 16); // 11
- w.writeBitsInt(t.nbits_shared_numerator, 16); // 12
- w.writeBitsInt(t.shared_denominator, 16); // 13
+ w.writeBitsInt(t.min_nobjects, 32); // 1
+ w.writeBitsInt(toI(t.first_page_offset), 32); // 2
+ w.writeBitsInt(t.nbits_delta_nobjects, 16); // 3
+ w.writeBitsInt(t.min_page_length, 32); // 4
+ w.writeBitsInt(t.nbits_delta_page_length, 16); // 5
+ w.writeBitsInt(t.min_content_offset, 32); // 6
+ w.writeBitsInt(t.nbits_delta_content_offset, 16); // 7
+ w.writeBitsInt(t.min_content_length, 32); // 8
+ w.writeBitsInt(t.nbits_delta_content_length, 16); // 9
+ w.writeBitsInt(t.nbits_nshared_objects, 16); // 10
+ w.writeBitsInt(t.nbits_shared_identifier, 16); // 11
+ w.writeBitsInt(t.nbits_shared_numerator, 16); // 12
+ w.writeBitsInt(t.shared_denominator, 16); // 13
int nitems = toI(getAllPages().size());
std::vector<HPageOffsetEntry>& entries = t.entries;
- write_vector_int(w, nitems, entries,
- t.nbits_delta_nobjects,
- &HPageOffsetEntry::delta_nobjects);
- write_vector_int(w, nitems, entries,
- t.nbits_delta_page_length,
- &HPageOffsetEntry::delta_page_length);
- write_vector_int(w, nitems, entries,
- t.nbits_nshared_objects,
- &HPageOffsetEntry::nshared_objects);
- write_vector_vector(w, nitems, entries,
- &HPageOffsetEntry::nshared_objects,
- t.nbits_shared_identifier,
- &HPageOffsetEntry::shared_identifiers);
- write_vector_vector(w, nitems, entries,
- &HPageOffsetEntry::nshared_objects,
- t.nbits_shared_numerator,
- &HPageOffsetEntry::shared_numerators);
- write_vector_int(w, nitems, entries,
- t.nbits_delta_content_offset,
- &HPageOffsetEntry::delta_content_offset);
- write_vector_int(w, nitems, entries,
- t.nbits_delta_content_length,
- &HPageOffsetEntry::delta_content_length);
+ write_vector_int(
+ w,
+ nitems,
+ entries,
+ t.nbits_delta_nobjects,
+ &HPageOffsetEntry::delta_nobjects);
+ write_vector_int(
+ w,
+ nitems,
+ entries,
+ t.nbits_delta_page_length,
+ &HPageOffsetEntry::delta_page_length);
+ write_vector_int(
+ w,
+ nitems,
+ entries,
+ t.nbits_nshared_objects,
+ &HPageOffsetEntry::nshared_objects);
+ write_vector_vector(
+ w,
+ nitems,
+ entries,
+ &HPageOffsetEntry::nshared_objects,
+ t.nbits_shared_identifier,
+ &HPageOffsetEntry::shared_identifiers);
+ write_vector_vector(
+ w,
+ nitems,
+ entries,
+ &HPageOffsetEntry::nshared_objects,
+ t.nbits_shared_numerator,
+ &HPageOffsetEntry::shared_numerators);
+ write_vector_int(
+ w,
+ nitems,
+ entries,
+ t.nbits_delta_content_offset,
+ &HPageOffsetEntry::delta_content_offset);
+ write_vector_int(
+ w,
+ nitems,
+ entries,
+ t.nbits_delta_content_length,
+ &HPageOffsetEntry::delta_content_length);
}
void
@@ -2210,54 +2067,62 @@ QPDF::writeHSharedObject(BitWriter& w)
{
HSharedObject& t = this->m->shared_object_hints;
- w.writeBitsInt(t.first_shared_obj, 32); // 1
- w.writeBitsInt(toI(t.first_shared_offset), 32); // 2
- w.writeBitsInt(t.nshared_first_page, 32); // 3
- w.writeBitsInt(t.nshared_total, 32); // 4
- w.writeBitsInt(t.nbits_nobjects, 16); // 5
- w.writeBitsInt(t.min_group_length, 32); // 6
- w.writeBitsInt(t.nbits_delta_group_length, 16); // 7
+ w.writeBitsInt(t.first_shared_obj, 32); // 1
+ w.writeBitsInt(toI(t.first_shared_offset), 32); // 2
+ w.writeBitsInt(t.nshared_first_page, 32); // 3
+ w.writeBitsInt(t.nshared_total, 32); // 4
+ w.writeBitsInt(t.nbits_nobjects, 16); // 5
+ w.writeBitsInt(t.min_group_length, 32); // 6
+ w.writeBitsInt(t.nbits_delta_group_length, 16); // 7
- QTC::TC("qpdf", "QPDF lin write nshared_total > nshared_first_page",
- (t.nshared_total > t.nshared_first_page) ? 1 : 0);
+ QTC::TC(
+ "qpdf",
+ "QPDF lin write nshared_total > nshared_first_page",
+ (t.nshared_total > t.nshared_first_page) ? 1 : 0);
int nitems = t.nshared_total;
std::vector<HSharedObjectEntry>& entries = t.entries;
- write_vector_int(w, nitems, entries,
- t.nbits_delta_group_length,
- &HSharedObjectEntry::delta_group_length);
- write_vector_int(w, nitems, entries,
- 1, &HSharedObjectEntry::signature_present);
- for (size_t i = 0; i < toS(nitems); ++i)
- {
+ write_vector_int(
+ w,
+ nitems,
+ entries,
+ t.nbits_delta_group_length,
+ &HSharedObjectEntry::delta_group_length);
+ write_vector_int(
+ w, nitems, entries, 1, &HSharedObjectEntry::signature_present);
+ for (size_t i = 0; i < toS(nitems); ++i) {
// If signature were present, we'd have to write a 128-bit hash.
- if (entries.at(i).signature_present != 0)
- {
+ if (entries.at(i).signature_present != 0) {
stopOnError("found unexpected signature present"
" while writing linearization data");
}
}
- write_vector_int(w, nitems, entries,
- t.nbits_nobjects,
- &HSharedObjectEntry::nobjects_minus_one);
+ write_vector_int(
+ w,
+ nitems,
+ entries,
+ t.nbits_nobjects,
+ &HSharedObjectEntry::nobjects_minus_one);
}
void
QPDF::writeHGeneric(BitWriter& w, HGeneric& t)
{
- w.writeBitsInt(t.first_object, 32); // 1
- w.writeBitsInt(toI(t.first_object_offset), 32); // 2
- w.writeBitsInt(t.nobjects, 32); // 3
- w.writeBitsInt(t.group_length, 32); // 4
+ w.writeBitsInt(t.first_object, 32); // 1
+ w.writeBitsInt(toI(t.first_object_offset), 32); // 2
+ w.writeBitsInt(t.nobjects, 32); // 3
+ w.writeBitsInt(t.group_length, 32); // 4
}
void
-QPDF::generateHintStream(std::map<int, QPDFXRefEntry> const& xref,
- std::map<int, qpdf_offset_t> const& lengths,
- std::map<int, int> const& obj_renumber,
- PointerHolder<Buffer>& hint_buffer,
- int& S, int& O)
+QPDF::generateHintStream(
+ std::map<int, QPDFXRefEntry> const& xref,
+ std::map<int, qpdf_offset_t> const& lengths,
+ std::map<int, int> const& obj_renumber,
+ PointerHolder<Buffer>& hint_buffer,
+ int& S,
+ int& O)
{
// Populate actual hint table values
calculateHPageOffset(xref, lengths, obj_renumber);
@@ -2275,8 +2140,7 @@ QPDF::generateHintStream(std::map<int, QPDFXRefEntry> const& xref,
S = toI(c.getCount());
writeHSharedObject(w);
O = 0;
- if (this->m->outline_hints.nobjects > 0)
- {
+ if (this->m->outline_hints.nobjects > 0) {
O = toI(c.getCount());
writeHGeneric(w, this->m->outline_hints);
}