diff options
author | Jay Berkenbilt <ejb@ql.org> | 2022-02-08 15:18:08 +0100 |
---|---|---|
committer | Jay Berkenbilt <ejb@ql.org> | 2022-02-08 17:51:15 +0100 |
commit | cb769c62e55599e9f980001830bc61d9fcaa64a9 (patch) | |
tree | 0bf980c385a61cbc8720cf990762ffc1200f9d6a /libqpdf/QPDF_linearization.cc | |
parent | 716381f65a2b2dc72f8da2426ba71aeab02c507f (diff) | |
download | qpdf-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/QPDF_linearization.cc')
-rw-r--r-- | libqpdf/QPDF_linearization.cc | 1746 |
1 files changed, 873 insertions, 873 deletions
diff --git a/libqpdf/QPDF_linearization.cc b/libqpdf/QPDF_linearization.cc index a107ced7..443ae662 100644 --- a/libqpdf/QPDF_linearization.cc +++ b/libqpdf/QPDF_linearization.cc @@ -20,7 +20,7 @@ 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) + int bits_wanted, int_type T::*field) { bool append = vec.empty(); // nitems times, read bits_wanted from the given bit stream, @@ -32,7 +32,7 @@ load_vector_int(BitStream& bit_stream, int nitems, std::vector<T>& vec, { vec.push_back(T()); } - vec.at(i).*field = bit_stream.getBitsInt(QIntC::to_size(bits_wanted)); + vec.at(i).*field = bit_stream.getBitsInt(QIntC::to_size(bits_wanted)); } if (QIntC::to_int(vec.size()) != nitems) { @@ -46,18 +46,18 @@ 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) + 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( + 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(); } @@ -68,12 +68,12 @@ QPDF::checkLinearization() bool result = false; try { - readLinearizationData(); - result = checkLinearizationInternal(); + readLinearizationData(); + result = checkLinearizationInternal(); } catch (std::runtime_error& e) { - *this->m->err_stream + *this->m->err_stream << "WARNING: error encountered while checking linearization data: " << e.what() << std::endl; } @@ -133,44 +133,44 @@ QPDF::isLinearized() (t3 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "obj")) && (t4.getType() == QPDFTokenizer::tt_dict_open)) { - lindict_obj = + lindict_obj = QIntC::to_int(QUtil::string_to_ll(t1.getValue().c_str())); - } + } } if (lindict_obj <= 0) { - return false; + return false; } QPDFObjectHandle candidate = QPDFObjectHandle::Factory::newIndirect( - this, lindict_obj, 0); + this, lindict_obj, 0); if (! candidate.isDictionary()) { - return false; + return false; } QPDFObjectHandle linkey = candidate.getKey("/Linearized"); if (! (linkey.isNumber() && (QIntC::to_int(floor(linkey.getNumericValue())) == 1))) { - return false; + return false; } QPDFObjectHandle L = candidate.getKey("/L"); if (L.isInteger()) { - qpdf_offset_t Li = L.getIntValue(); - this->m->file->seek(0, SEEK_END); - if (Li != this->m->file->tell()) - { - QTC::TC("qpdf", "QPDF /L mismatch"); - return false; - } - else - { - this->m->linp.file_size = Li; - } + qpdf_offset_t Li = L.getIntValue(); + this->m->file->seek(0, SEEK_END); + if (Li != this->m->file->tell()) + { + QTC::TC("qpdf", "QPDF /L mismatch"); + return false; + } + else + { + this->m->linp.file_size = Li; + } } this->m->lindict = candidate; @@ -189,8 +189,8 @@ QPDF::readLinearizationData() if (! isLinearized()) { - throw std::logic_error("called readLinearizationData for file" - " that is not linearized"); + throw std::logic_error("called readLinearizationData for file" + " that is not linearized"); } // /L is read and stored in linp by isLinearized() @@ -202,44 +202,44 @@ QPDF::readLinearizationData() QPDFObjectHandle P = this->m->lindict.getKey("/P"); if (! (H.isArray() && - O.isInteger() && - E.isInteger() && - N.isInteger() && - T.isInteger() && - (P.isInteger() || P.isNull()))) + 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"); + 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"); + 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) { - QPDFObjectHandle oh(H.getArrayItem(toI(i))); - 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"); - } + QPDFObjectHandle oh(H.getArrayItem(toI(i))); + 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"); + } } // H: hint table offset/length for primary and overflow hint tables @@ -249,23 +249,23 @@ QPDF::readLinearizationData() int H1_length = 0; 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"); - H1_offset = H_items.at(2); - H1_length = H_items.at(3); + // 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"); + H1_offset = H_items.at(2); + H1_length = H_items.at(3); } // P: first page number int first_page = 0; if (P.isInteger()) { - QTC::TC("qpdf", "QPDF P present in lindict"); - first_page = P.getIntValueAsInt(); + QTC::TC("qpdf", "QPDF P present in lindict"); + first_page = P.getIntValueAsInt(); } else { - QTC::TC("qpdf", "QPDF P absent in lindict"); + QTC::TC("qpdf", "QPDF P absent in lindict"); } // Store linearization parameter data @@ -296,7 +296,7 @@ QPDF::readLinearizationData() QPDFObjectHandle H0 = readHintStream(pb, H0_offset, toS(H0_length)); if (H1_offset) { - (void) readHintStream(pb, H1_offset, toS(H1_length)); + (void) readHintStream(pb, H1_offset, toS(H1_length)); } // PDF 1.4 hint tables that we ignore: @@ -332,7 +332,7 @@ QPDF::readLinearizationData() if (HO.isInteger()) { - int HOi = HO.getIntValueAsInt(); + int HOi = HO.getIntValueAsInt(); if ((HOi < 0) || (toS(HOi) >= h_size)) { throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), @@ -340,8 +340,8 @@ QPDF::readLinearizationData() 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); } } @@ -351,16 +351,16 @@ QPDF::readHintStream(Pipeline& pl, qpdf_offset_t offset, size_t length) int obj; int gen; QPDFObjectHandle H = readObjectAtOffset( - false, offset, "linearization hint stream", -1, 0, obj, gen); + false, offset, "linearization hint stream", -1, 0, obj, gen); ObjCache& oc = this->m->obj_cache[QPDFObjGen(obj, gen)]; qpdf_offset_t min_end_offset = oc.end_before_space; qpdf_offset_t max_end_offset = oc.end_after_space; if (! H.isStream()) { - throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), - "linearization dictionary", - this->m->file->getLastOffset(), - "hint table is not a stream"); + 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(); @@ -373,28 +373,28 @@ QPDF::readHintStream(Pipeline& pl, qpdf_offset_t offset, size_t length) QPDFObjectHandle length_obj = Hdict.getKey("/Length"); if (length_obj.isIndirect()) { - QTC::TC("qpdf", "QPDF hint table length indirect"); - // Force resolution - (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; + QTC::TC("qpdf", "QPDF hint table length indirect"); + // Force resolution + (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 { - QTC::TC("qpdf", "QPDF hint table length direct"); + 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)) + (computed_end > max_end_offset)) { - *this->m->err_stream << "expected = " << computed_end + *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; @@ -426,28 +426,28 @@ QPDF::readHPageOffset(BitStream h) entries.clear(); int nitems = this->m->linp.npages; load_vector_int(h, nitems, entries, - t.nbits_delta_nobjects, - &HPageOffsetEntry::delta_nobjects); + t.nbits_delta_nobjects, + &HPageOffsetEntry::delta_nobjects); load_vector_int(h, nitems, entries, - t.nbits_delta_page_length, - &HPageOffsetEntry::delta_page_length); + t.nbits_delta_page_length, + &HPageOffsetEntry::delta_page_length); load_vector_int(h, nitems, entries, - t.nbits_nshared_objects, - &HPageOffsetEntry::nshared_objects); + t.nbits_nshared_objects, + &HPageOffsetEntry::nshared_objects); load_vector_vector(h, nitems, entries, - &HPageOffsetEntry::nshared_objects, - t.nbits_shared_identifier, - &HPageOffsetEntry::shared_identifiers); + &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); + &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); + t.nbits_delta_content_offset, + &HPageOffsetEntry::delta_content_offset); load_vector_int(h, nitems, entries, - t.nbits_delta_content_length, - &HPageOffsetEntry::delta_content_length); + t.nbits_delta_content_length, + &HPageOffsetEntry::delta_content_length); } void @@ -464,32 +464,32 @@ QPDF::readHSharedObject(BitStream h) 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); + (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); + t.nbits_delta_group_length, + &HSharedObjectEntry::delta_group_length); load_vector_int(h, nitems, entries, - 1, &HSharedObjectEntry::signature_present); + 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); - } - } + 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); + } + } } load_vector_int(h, nitems, entries, - t.nbits_nobjects, - &HSharedObjectEntry::nobjects_minus_one); + t.nbits_nobjects, + &HSharedObjectEntry::nobjects_minus_one); } void @@ -520,49 +520,49 @@ QPDF::checkLinearizationInternal() std::vector<QPDFObjectHandle> const& pages = getAllPages(); if (p.first_page_object != pages.at(0).getObjectID()) { - QTC::TC("qpdf", "QPDF err /O mismatch"); - errors.push_back("first page object (/O) mismatch"); + 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) { - // Not tested in the test suite - errors.push_back("page count (/N) mismatch"); + // Not tested in the test suite + errors.push_back("page count (/N) mismatch"); } 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"); - } + 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"); + } } // T: offset of whitespace character preceding xref entry for object 0 this->m->file->seek(p.xref_zero_offset, SEEK_SET); while (1) { - char ch; - this->m->file->read(&ch, 1); - if (! ((ch == ' ') || (ch == '\r') || (ch == '\n'))) - { - this->m->file->seek(-1, SEEK_CUR); - break; - } + char ch; + this->m->file->read(&ch, 1); + 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) { - 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())); + 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())); } // P: first page number -- Implementation note 124 says Acrobat @@ -575,8 +575,8 @@ QPDF::checkLinearizationInternal() if (this->m->uncompressed_after_compressed) { - errors.push_back("linearized file contains an uncompressed object" - " after a compressed one in a cross-reference stream"); + errors.push_back("linearized file contains an uncompressed object" + " after a compressed one in a cross-reference stream"); } // Further checking requires optimization and order calculation. @@ -585,20 +585,20 @@ QPDF::checkLinearizationInternal() // figure out which objects are compressed and which are // uncompressed. { // local scope - 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) - { - QPDFObjGen const& og = (*iter).first; - QPDFXRefEntry const& entry = (*iter).second; - if (entry.getType() == 2) - { - object_stream_data[og.getObj()] = entry.getObjStreamNumber(); - } - } - optimize(object_stream_data, false); - calculateLinearizationData(object_stream_data); + 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) + { + QPDFObjGen const& og = (*iter).first; + QPDFXRefEntry const& entry = (*iter).second; + if (entry.getType() == 2) + { + object_stream_data[og.getObj()] = entry.getObjStreamNumber(); + } + } + optimize(object_stream_data, false); + calculateLinearizationData(object_stream_data); } // E: offset of end of first page -- Implementation note 123 says @@ -619,26 +619,26 @@ QPDF::checkLinearizationInternal() 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) + QPDFObjGen og((*iter).getObjGen()); + if (this->m->obj_cache.count(og) == 0) { // All objects have to have been dereferenced to be classified. throw std::logic_error("linearization part6 object not in cache"); } - ObjCache const& oc = this->m->obj_cache[og]; - min_E = std::max(min_E, oc.end_before_space); - max_E = std::max(max_E, oc.end_after_space); + ObjCache const& oc = this->m->obj_cache[og]; + min_E = std::max(min_E, oc.end_before_space); + max_E = std::max(max_E, oc.end_after_space); } 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)); + 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)); } // Check hint tables @@ -659,22 +659,22 @@ QPDF::checkLinearizationInternal() // code. if (! errors.empty()) { - result = false; - for (std::list<std::string>::iterator iter = errors.begin(); - iter != errors.end(); ++iter) - { - *this->m->err_stream << "WARNING: " << (*iter) << std::endl; - } + result = false; + for (std::list<std::string>::iterator iter = errors.begin(); + iter != errors.end(); ++iter) + { + *this->m->err_stream << "WARNING: " << (*iter) << std::endl; + } } if (! warnings.empty()) { - result = false; - for (std::list<std::string>::iterator iter = warnings.begin(); - iter != warnings.end(); ++iter) - { - *this->m->err_stream << "WARNING: " << (*iter) << std::endl; - } + result = false; + for (std::list<std::string>::iterator iter = warnings.begin(); + iter != warnings.end(); ++iter) + { + *this->m->err_stream << "WARNING: " << (*iter) << std::endl; + } } return result; @@ -690,14 +690,14 @@ QPDF::maxEnd(ObjUser const& ou) 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) + QPDFObjGen const& og = *iter; + 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); + end = std::max(end, this->m->obj_cache[og].end_after_space); } return end; } @@ -710,72 +710,72 @@ QPDF::getLinearizationOffset(QPDFObjGen const& og) switch (entry.getType()) { case 1: - result = entry.getOffset(); - break; + result = entry.getOffset(); + break; case 2: - // For compressed objects, return the offset of the object - // stream that contains them. - result = getLinearizationOffset( + // For compressed objects, return the offset of the object + // stream that contains them. + result = getLinearizationOffset( QPDFObjGen(entry.getObjStreamNumber(), 0)); - break; + break; default: - stopOnError( - "getLinearizationOffset called for xref entry not of type 1 or 2"); - break; + stopOnError( + "getLinearizationOffset called for xref entry not of type 1 or 2"); + break; } return result; } QPDFObjectHandle QPDF::getUncompressedObject(QPDFObjectHandle& obj, - std::map<int, int> const& object_stream_data) + std::map<int, int> const& object_stream_data) { if (obj.isNull() || (object_stream_data.count(obj.getObjectID()) == 0)) { - return obj; + return obj; } else { - int repl = (*(object_stream_data.find(obj.getObjectID()))).second; - return objGenToIndirect(QPDFObjGen(repl, 0)); + 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) + std::list<std::string>& errors) { int length = 0; for (int i = 0; i < n; ++i) { - QPDFObjGen og(first_object + i, 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) + QPDFObjGen og(first_object + i, 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) { stopOnError("found unknown object while" " calculating length for linearization data"); } - length += toI(this->m->obj_cache[og].end_after_space - + 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) + 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 @@ -796,7 +796,7 @@ QPDF::checkHPageOffset(std::list<std::string>& errors, int npages = toI(pages.size()); qpdf_offset_t table_offset = adjusted_offset( - this->m->page_offset_hints.first_page_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) { @@ -805,124 +805,124 @@ QPDF::checkHPageOffset(std::list<std::string>& errors, qpdf_offset_t offset = getLinearizationOffset(first_page_og); if (table_offset != offset) { - warnings.push_back("first page object offset mismatch"); + warnings.push_back("first page object offset mismatch"); } 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) + QPDFObjGen page_og(pages.at(toS(pageno)).getObjGen()); + int first_object = page_og.getObj(); + if (this->m->xref_table.count(page_og) == 0) { stopOnError("unknown object in page offset hint table"); } - offset = getLinearizationOffset(page_og); + offset = getLinearizationOffset(page_og); - HPageOffsetEntry& he = + HPageOffsetEntry& he = this->m->page_offset_hints.entries.at(toS(pageno)); - CHPageOffsetEntry& ce = + 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) - { - // 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)); - } - - // 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 + + 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)); + } + + // 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) - { - // 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) + ")"); - } - - offset += h_length; - - // Translate shared object indexes to object numbers. - std::set<int> hint_shared; - std::set<int> computed_shared; - - 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) - { - int idx = he.shared_identifiers.at(i); - if (shared_idx_to_obj.count(idx) == 0) + 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) + ")"); + } + + offset += h_length; + + // Translate shared object indexes to object numbers. + std::set<int> hint_shared; + std::set<int> computed_shared; + + 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) + { + 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"); } - hint_shared.insert(shared_idx_to_obj[idx]); - } + hint_shared.insert(shared_idx_to_obj[idx]); + } - 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) + 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"); } - 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)) - { - // pdlin puts thumbnails here even though it shouldn't - warnings.push_back( - "page " + QUtil::int_to_string(pageno) + - ": shared object " + QUtil::int_to_string(*iter) + - ": in hint table but not computed list"); - } - } - - for (std::set<int>::iterator iter = computed_shared.begin(); - 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. - warnings.push_back( - "page " + QUtil::int_to_string(pageno) + - ": shared object " + QUtil::int_to_string(*iter) + - ": in computed list but not 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)) + { + // pdlin puts thumbnails here even though it shouldn't + warnings.push_back( + "page " + QUtil::int_to_string(pageno) + + ": shared object " + QUtil::int_to_string(*iter) + + ": in hint table but not computed list"); + } + } + + for (std::set<int>::iterator iter = computed_shared.begin(); + 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. + warnings.push_back( + "page " + QUtil::int_to_string(pageno) + + ": shared object " + QUtil::int_to_string(*iter) + + ": in computed list but not hint table"); + } + } } } 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) + 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 @@ -945,73 +945,73 @@ QPDF::checkHSharedObject(std::list<std::string>& errors, HSharedObject& so = this->m->shared_object_hints; if (so.nshared_total < so.nshared_first_page) { - errors.push_back("shared object hint table: ntotal < nfirst_page"); + errors.push_back("shared object hint table: ntotal < nfirst_page"); } 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) - { - 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 - { - int obj = this->m->part8.at(0).getObjectID(); - 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)); - } - } - - cur_object = so.first_shared_obj; - - QPDFObjGen og(cur_object, 0); - if (this->m->xref_table.count(og) == 0) + // 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) + { + 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 + { + int obj = this->m->part8.at(0).getObjectID(); + 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)); + } + } + + cur_object = so.first_shared_obj; + + QPDFObjGen og(cur_object, 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 = + qpdf_offset_t offset = getLinearizationOffset(og); + qpdf_offset_t h_offset = adjusted_offset(so.first_shared_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)); - } - } - - idx_to_obj[i] = cur_object; - HSharedObjectEntry& se = so.entries.at(toS(i)); - 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) - { - 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)); - } - cur_object += nobjects; - } + 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)); + } + } + + idx_to_obj[i] = cur_object; + HSharedObjectEntry& se = so.entries.at(toS(i)); + 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) + { + 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)); + } + cur_object += nobjects; + } } } @@ -1028,60 +1028,60 @@ QPDF::checkHOutlines(std::list<std::string>& warnings) 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.nobjects == 0) + { + return; + } - if (this->m->c_outline_data.first_object == - this->m->outline_hints.first_object) - { - // Check length and offset. Acrobat gets these wrong. - QPDFObjectHandle outlines = getRoot().getKey("/Outlines"); + if (this->m->c_outline_data.first_object == + this->m->outline_hints.first_object) + { + // Check length and offset. Acrobat gets these wrong. + QPDFObjectHandle outlines = getRoot().getKey("/Outlines"); 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. - warnings.push_back( - "/Outlines key of root dictionary is not indirect"); + warnings.push_back( + "/Outlines key of root dictionary is not indirect"); return; } - QPDFObjGen og(outlines.getObjGen()); - if (this->m->xref_table.count(og) == 0) + QPDFObjGen og(outlines.getObjGen()); + if (this->m->xref_table.count(og) == 0) { stopOnError("unknown object in outlines hint table"); } - qpdf_offset_t offset = getLinearizationOffset(og); - ObjUser ou(ObjUser::ou_root_key, "/Outlines"); - int length = toI(maxEnd(ou) - offset); - qpdf_offset_t table_offset = - adjusted_offset(this->m->outline_hints.first_object_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) - { - warnings.push_back( - "incorrect length in outlines table: hint table = " + - QUtil::int_to_string(table_length) + - "; computed = " + QUtil::int_to_string(length)); - } - } - else - { - warnings.push_back("incorrect first object number in outline " - "hints table."); - } + qpdf_offset_t offset = getLinearizationOffset(og); + ObjUser ou(ObjUser::ou_root_key, "/Outlines"); + int length = toI(maxEnd(ou) - offset); + qpdf_offset_t table_offset = + adjusted_offset(this->m->outline_hints.first_object_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) + { + warnings.push_back( + "incorrect length in outlines table: hint table = " + + QUtil::int_to_string(table_length) + + "; computed = " + QUtil::int_to_string(length)); + } + } + else + { + warnings.push_back("incorrect first object number in outline " + "hints table."); + } } else { - warnings.push_back("incorrect object count in outline hint table"); + warnings.push_back("incorrect object count in outline hint table"); } } @@ -1090,13 +1090,13 @@ QPDF::showLinearizationData() { try { - readLinearizationData(); - checkLinearizationInternal(); - dumpLinearizationDataInternal(); + readLinearizationData(); + checkLinearizationInternal(); + dumpLinearizationDataInternal(); } catch (QPDFExc& e) { - *this->m->err_stream << e.what() << std::endl; + *this->m->err_stream << e.what() << std::endl; } } @@ -1108,15 +1108,15 @@ QPDF::dumpLinearizationDataInternal() << std::endl; *this->m->out_stream - << "file_size: " << this->m->linp.file_size << std::endl - << "first_page_object: " << this->m->linp.first_page_object << std::endl - << "first_page_end: " << this->m->linp.first_page_end << std::endl - << "npages: " << this->m->linp.npages << std::endl - << "xref_zero_offset: " << this->m->linp.xref_zero_offset << std::endl - << "first_page: " << this->m->linp.first_page << std::endl - << "H_offset: " << this->m->linp.H_offset << std::endl - << "H_length: " << this->m->linp.H_length << std::endl - << std::endl; + << "file_size: " << this->m->linp.file_size << std::endl + << "first_page_object: " << this->m->linp.first_page_object << std::endl + << "first_page_end: " << this->m->linp.first_page_end << std::endl + << "npages: " << this->m->linp.npages << std::endl + << "xref_zero_offset: " << this->m->linp.xref_zero_offset << std::endl + << "first_page: " << this->m->linp.first_page << std::endl + << "H_offset: " << this->m->linp.H_offset << std::endl + << "H_length: " << this->m->linp.H_length << std::endl + << std::endl; *this->m->out_stream << "Page Offsets Hint Table" << std::endl << std::endl; @@ -1128,10 +1128,10 @@ QPDF::dumpLinearizationDataInternal() if (this->m->outline_hints.nobjects > 0) { - *this->m->out_stream << std::endl + *this->m->out_stream << std::endl << "Outlines Hint Table" << std::endl << std::endl; - dumpHGeneric(this->m->outline_hints); + dumpHGeneric(this->m->outline_hints); } } @@ -1143,7 +1143,7 @@ QPDF::adjusted_offset(qpdf_offset_t offset) // itself. if (offset >= this->m->linp.H_offset) { - return offset + this->m->linp.H_length; + return offset + this->m->linp.H_length; } return offset; } @@ -1154,55 +1154,55 @@ QPDF::dumpHPageOffset() { HPageOffset& t = this->m->page_offset_hints; *this->m->out_stream - << "min_nobjects: " << t.min_nobjects - << std::endl - << "first_page_offset: " << adjusted_offset(t.first_page_offset) - << 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 - << "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; + << "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_content_offset: " << t.nbits_delta_content_offset + << 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; 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 - << " length: " << pe.delta_page_length + t.min_page_length - << std::endl - // content offset is relative to page, not file - << " content_offset: " - << pe.delta_content_offset + t.min_content_offset << std::endl - << " 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) - { - *this->m->out_stream << " identifier " << i2 << ": " + HPageOffsetEntry& pe = t.entries.at(i1); + *this->m->out_stream + << "Page " << i1 << ":" << 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 + << " content_offset: " + << pe.delta_content_offset + t.min_content_offset << std::endl + << " 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) + { + *this->m->out_stream << " identifier " << i2 << ": " << pe.shared_identifiers.at(i2) << std::endl; - *this->m->out_stream << " numerator " << i2 << ": " + *this->m->out_stream << " numerator " << i2 << ": " << pe.shared_numerators.at(i2) << std::endl; - } + } } } @@ -1211,39 +1211,39 @@ 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; + << "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 + 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; - // 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) - { - *this->m->out_stream << " signature present" << std::endl; - } - if (se.nobjects_minus_one != 0) - { - *this->m->out_stream << " nobjects: " + // 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) + { + *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; - } + } } } @@ -1251,14 +1251,14 @@ 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; + << "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 @@ -1279,11 +1279,11 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) 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( - "INTERNAL ERROR: QPDF::calculateLinearizationData " - "called before optimize()"); + // 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( + "INTERNAL ERROR: QPDF::calculateLinearizationData " + "called before optimize()"); } // Separate objects into the categories sufficient for us to @@ -1347,22 +1347,22 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) bool outlines_in_first_page = false; QPDFObjectHandle pagemode = root.getKey("/PageMode"); QTC::TC("qpdf", "QPDF categorize pagemode present", - pagemode.isName() ? 1 : 0); + pagemode.isName() ? 1 : 0); if (pagemode.isName()) { - if (pagemode.getName() == "/UseOutlines") - { - if (root.hasKey("/Outlines")) - { - outlines_in_first_page = true; - } - else - { - QTC::TC("qpdf", "QPDF UseOutlines but no Outlines"); - } - } - QTC::TC("qpdf", "QPDF categorize pagemode outlines", - outlines_in_first_page ? 1 : 0); + if (pagemode.getName() == "/UseOutlines") + { + if (root.hasKey("/Outlines")) + { + outlines_in_first_page = true; + } + else + { + QTC::TC("qpdf", "QPDF UseOutlines but no Outlines"); + } + } + QTC::TC("qpdf", "QPDF categorize pagemode outlines", + outlines_in_first_page ? 1 : 0); } std::set<std::string> open_document_keys; @@ -1384,121 +1384,121 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) std::set<QPDFObjGen> lc_root; for (std::map<QPDFObjGen, std::set<ObjUser> >::iterator oiter = - this->m->object_to_obj_users.begin(); - oiter != this->m->object_to_obj_users.end(); ++oiter) - { - QPDFObjGen const& og = (*oiter).first; - - std::set<ObjUser>& ous = (*oiter).second; - - bool in_open_document = false; - bool in_first_page = false; - int other_pages = 0; - int thumbs = 0; - int others = 0; - bool in_outlines = false; - bool is_root = false; - - for (std::set<ObjUser>::iterator uiter = ous.begin(); - uiter != ous.end(); ++uiter) - { - ObjUser const& ou = *uiter; - switch (ou.ou_type) - { - case ObjUser::ou_trailer_key: - if (ou.key == "/Encrypt") - { - in_open_document = true; - } - else - { - ++others; - } - break; - - case ObjUser::ou_thumb: - ++thumbs; - break; - - case ObjUser::ou_root_key: - if (open_document_keys.count(ou.key) > 0) - { - in_open_document = true; - } - else if (ou.key == "/Outlines") - { - in_outlines = true; - } - else - { - ++others; - } - break; - - case ObjUser::ou_page: - if (ou.pageno == 0) - { - in_first_page = true; - } - else - { - ++other_pages; - } - break; - - case ObjUser::ou_root: - is_root = true; - break; - - case ObjUser::ou_bad: - stopOnError( - "INTERNAL ERROR: QPDF::calculateLinearizationData: " - "invalid user type"); - break; - } - } - - if (is_root) - { - lc_root.insert(og); - } - else if (in_outlines) - { - lc_outlines.insert(og); - } - else if (in_open_document) - { - lc_open_document.insert(og); - } - else if ((in_first_page) && - (others == 0) && (other_pages == 0) && (thumbs == 0)) - { - lc_first_page_private.insert(og); - } - else if (in_first_page) - { - lc_first_page_shared.insert(og); - } - else if ((other_pages == 1) && (others == 0) && (thumbs == 0)) - { - lc_other_page_private.insert(og); - } - else if (other_pages > 1) - { - lc_other_page_shared.insert(og); - } - else if ((thumbs == 1) && (others == 0)) - { - lc_thumbnail_private.insert(og); - } - else if (thumbs > 1) - { - lc_thumbnail_shared.insert(og); - } - else - { - lc_other.insert(og); - } + this->m->object_to_obj_users.begin(); + oiter != this->m->object_to_obj_users.end(); ++oiter) + { + QPDFObjGen const& og = (*oiter).first; + + std::set<ObjUser>& ous = (*oiter).second; + + bool in_open_document = false; + bool in_first_page = false; + int other_pages = 0; + int thumbs = 0; + int others = 0; + bool in_outlines = false; + bool is_root = false; + + for (std::set<ObjUser>::iterator uiter = ous.begin(); + uiter != ous.end(); ++uiter) + { + ObjUser const& ou = *uiter; + switch (ou.ou_type) + { + case ObjUser::ou_trailer_key: + if (ou.key == "/Encrypt") + { + in_open_document = true; + } + else + { + ++others; + } + break; + + case ObjUser::ou_thumb: + ++thumbs; + break; + + case ObjUser::ou_root_key: + if (open_document_keys.count(ou.key) > 0) + { + in_open_document = true; + } + else if (ou.key == "/Outlines") + { + in_outlines = true; + } + else + { + ++others; + } + break; + + case ObjUser::ou_page: + if (ou.pageno == 0) + { + in_first_page = true; + } + else + { + ++other_pages; + } + break; + + case ObjUser::ou_root: + is_root = true; + break; + + case ObjUser::ou_bad: + stopOnError( + "INTERNAL ERROR: QPDF::calculateLinearizationData: " + "invalid user type"); + break; + } + } + + if (is_root) + { + lc_root.insert(og); + } + else if (in_outlines) + { + lc_outlines.insert(og); + } + else if (in_open_document) + { + lc_open_document.insert(og); + } + else if ((in_first_page) && + (others == 0) && (other_pages == 0) && (thumbs == 0)) + { + lc_first_page_private.insert(og); + } + else if (in_first_page) + { + lc_first_page_shared.insert(og); + } + else if ((other_pages == 1) && (others == 0) && (thumbs == 0)) + { + lc_other_page_private.insert(og); + } + else if (other_pages > 1) + { + lc_other_page_shared.insert(og); + } + else if ((thumbs == 1) && (others == 0)) + { + lc_thumbnail_private.insert(og); + } + else if (thumbs > 1) + { + lc_thumbnail_shared.insert(og); + } + else + { + lc_other.insert(og); + } } // Generate ordering for objects in the output file. Sometimes we @@ -1518,14 +1518,14 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) // Premature optimization is the root of all evil. std::vector<QPDFObjectHandle> pages; { // local scope - // Map all page objects to the containing object stream. This - // 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) - { - pages.push_back(getUncompressedObject(*iter, object_stream_data)); - } + // Map all page objects to the containing object stream. This + // 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) + { + pages.push_back(getUncompressedObject(*iter, object_stream_data)); + } } int npages = toI(pages.size()); @@ -1553,9 +1553,9 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_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)); + this->m->part4.push_back(objGenToIndirect(*iter)); } // Part 6: first page objects. Note: implementation note 124 @@ -1572,9 +1572,9 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) QPDFObjGen first_page_og(pages.at(0).getObjGen()); if (! lc_first_page_private.count(first_page_og)) { - stopOnError( - "INTERNAL ERROR: QPDF::calculateLinearizationData: first page " - "object not in lc_first_page_private"); + stopOnError( + "INTERNAL ERROR: QPDF::calculateLinearizationData: first page " + "object not in lc_first_page_private"); } lc_first_page_private.erase(first_page_og); this->m->c_linp.first_page_object = pages.at(0).getObjectID(); @@ -1586,21 +1586,21 @@ 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)); + 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)); + this->m->part6.push_back(objGenToIndirect(*iter)); } // Place the outline dictionary if it goes in the first page section. if (outlines_in_first_page) { - pushOutlinesToPart(this->m->part6, lc_outlines, object_stream_data); + pushOutlinesToPart(this->m->part6, lc_outlines, object_stream_data); } // Fill in page offset hint table information for the first page. @@ -1617,59 +1617,59 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) // For each page in order: for (size_t i = 1; i < toS(npages); ++i) { - // Place this page's page object + // Place this page's page object - QPDFObjGen page_og(pages.at(i).getObjGen()); - if (! lc_other_page_private.count(page_og)) - { - stopOnError( - "INTERNAL ERROR: " - "QPDF::calculateLinearizationData: page object for page " + - QUtil::uint_to_string(i) + " not in lc_other_page_private"); - } - lc_other_page_private.erase(page_og); - this->m->part7.push_back(pages.at(i)); + QPDFObjGen page_og(pages.at(i).getObjGen()); + if (! lc_other_page_private.count(page_og)) + { + stopOnError( + "INTERNAL ERROR: " + "QPDF::calculateLinearizationData: page object for page " + + QUtil::uint_to_string(i) + " not in lc_other_page_private"); + } + lc_other_page_private.erase(page_og); + this->m->part7.push_back(pages.at(i)); - // Place all non-shared objects referenced by this page, - // updating the page object count for the hint table. + // Place all non-shared objects referenced by this page, + // updating the page object count for the hint table. - this->m->c_page_offset_data.entries.at(i).nobjects = 1; + this->m->c_page_offset_data.entries.at(i).nobjects = 1; - ObjUser ou(ObjUser::ou_page, toI(i)); - if (this->m->obj_user_to_objects.count(ou) == 0) + ObjUser ou(ObjUser::ou_page, toI(i)); + 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) - { - QPDFObjGen const& og = (*iter); - 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; - } - } + std::set<QPDFObjGen> ogs = this->m->obj_user_to_objects[ou]; + for (std::set<QPDFObjGen>::iterator iter = ogs.begin(); + iter != ogs.end(); ++iter) + { + QPDFObjGen const& og = (*iter); + 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; + } + } } // That should have covered all part7 objects. if (! lc_other_page_private.empty()) { - stopOnError( - "INTERNAL ERROR:" - " QPDF::calculateLinearizationData: lc_other_page_private is " - "not empty after generation of part7"); + stopOnError( + "INTERNAL ERROR:" + " QPDF::calculateLinearizationData: lc_other_page_private is " + "not empty after generation of part7"); } // Part 8: other pages' shared objects // 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)); + this->m->part8.push_back(objGenToIndirect(*iter)); } // Part 9: other objects @@ -1683,21 +1683,21 @@ 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")]; + this->m->obj_user_to_objects[ObjUser(ObjUser::ou_root_key, "/Pages")]; 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)) - { - lc_other.erase(og); - this->m->part9.push_back(objGenToIndirect(og)); - } + QPDFObjGen const& og = *iter; + if (lc_other.count(og)) + { + lc_other.erase(og); + this->m->part9.push_back(objGenToIndirect(og)); + } } // Place private thumbnail images in page order. Slightly more @@ -1705,67 +1705,67 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) // thumbnail hint tables. 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()) - { - // Output the thumbnail itself - QPDFObjGen thumb_og(thumb.getObjGen()); - if (lc_thumbnail_private.count(thumb_og)) - { - lc_thumbnail_private.erase(thumb_og); - this->m->part9.push_back(thumb); - } - 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 - // it had been, there's nothing to prevent it from - // having been in some set other than - // lc_thumbnail_private. - } - std::set<QPDFObjGen>& ogs = - this->m->obj_user_to_objects[ + QPDFObjectHandle thumb = pages.at(i).getKey("/Thumb"); + thumb = getUncompressedObject(thumb, object_stream_data); + if (! thumb.isNull()) + { + // Output the thumbnail itself + QPDFObjGen thumb_og(thumb.getObjGen()); + if (lc_thumbnail_private.count(thumb_og)) + { + lc_thumbnail_private.erase(thumb_og); + this->m->part9.push_back(thumb); + } + 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 + // it had been, there's nothing to prevent it from + // having been in some set other than + // lc_thumbnail_private. + } + std::set<QPDFObjGen>& ogs = + this->m->obj_user_to_objects[ ObjUser(ObjUser::ou_thumb, toI(i))]; - for (std::set<QPDFObjGen>::iterator iter = ogs.begin(); - iter != ogs.end(); ++iter) - { - QPDFObjGen const& og = *iter; - if (lc_thumbnail_private.count(og)) - { - lc_thumbnail_private.erase(og); - this->m->part9.push_back(objGenToIndirect(og)); - } - } - } + for (std::set<QPDFObjGen>::iterator iter = ogs.begin(); + iter != ogs.end(); ++iter) + { + QPDFObjGen const& og = *iter; + 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"); + 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)); + this->m->part9.push_back(objGenToIndirect(*iter)); } // Place outlines unless in first page if (! outlines_in_first_page) { - pushOutlinesToPart(this->m->part9, lc_outlines, object_stream_data); + pushOutlinesToPart(this->m->part9, lc_outlines, object_stream_data); } // Place all remaining objects for (std::set<QPDFObjGen>::iterator iter = lc_other.begin(); - iter != lc_other.end(); ++iter) + iter != lc_other.end(); ++iter) { - this->m->part9.push_back(objGenToIndirect(*iter)); + this->m->part9.push_back(objGenToIndirect(*iter)); } // Make sure we got everything exactly once. @@ -1776,12 +1776,12 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) size_t num_wanted = this->m->object_to_obj_users.size(); 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)); + 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)); } // Calculate shared object hint table information including @@ -1800,33 +1800,33 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) this->m->c_shared_object_data.nshared_first_page = toI(this->m->part6.size()); this->m->c_shared_object_data.nshared_total = - this->m->c_shared_object_data.nshared_first_page + + this->m->c_shared_object_data.nshared_first_page + toI(this->m->part8.size()); std::vector<CHSharedObjectEntry>& shared = - this->m->c_shared_object_data.entries; + 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)); + 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()) { - 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) - { - QPDFObjectHandle& oh = *iter; - int obj = oh.getObjectID(); - obj_to_index[obj] = toI(shared.size()); - shared.push_back(CHSharedObjectEntry(obj)); - } + 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) + { + QPDFObjectHandle& oh = *iter; + int obj = oh.getObjectID(); + obj_to_index[obj] = toI(shared.size()); + shared.push_back(CHSharedObjectEntry(obj)); + } } if (static_cast<size_t>(this->m->c_shared_object_data.nshared_total) != this->m->c_shared_object_data.entries.size()) @@ -1840,26 +1840,26 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) 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) + 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) { 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) - { - QPDFObjGen const& og = *iter; - if ((this->m->object_to_obj_users[og].size() > 1) && - (obj_to_index.count(og.getObj()) > 0)) - { - int idx = obj_to_index[og.getObj()]; - ++pe.nshared_objects; - pe.shared_identifiers.push_back(idx); - } - } + std::set<QPDFObjGen> const& ogs = this->m->obj_user_to_objects[ou]; + for (std::set<QPDFObjGen>::const_iterator iter = ogs.begin(); + iter != ogs.end(); ++iter) + { + QPDFObjGen const& og = *iter; + if ((this->m->object_to_obj_users[og].size() > 1) && + (obj_to_index.count(og.getObj()) > 0)) + { + int idx = obj_to_index[og.getObj()]; + ++pe.nshared_objects; + pe.shared_identifiers.push_back(idx); + } + } } } @@ -1873,23 +1873,23 @@ QPDF::pushOutlinesToPart( QPDFObjectHandle outlines = root.getKey("/Outlines"); if (outlines.isNull()) { - return; + 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 - : (&part == (&this->m->part9)) ? 1 - : 9999)); // can't happen + ((&part == (&this->m->part6)) ? 0 + : (&part == (&this->m->part9)) ? 1 + : 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; + part.push_back(objGenToIndirect(*iter)); + ++this->m->c_outline_data.nobjects; } } @@ -1934,12 +1934,12 @@ QPDF::outputLengthNextN( int length = 0; for (int i = 0; i < n; ++i) { - if (lengths.count(first + i) == 0) + if (lengths.count(first + i) == 0) { stopOnError("found item with unknown length" " while writing linearization data"); } - length += toI((*(lengths.find(first + toI(i)))).second); + length += toI((*(lengths.find(first + toI(i)))).second); } return length; } @@ -1966,7 +1966,7 @@ QPDF::calculateHPageOffset( int min_nobjects = cphe.at(0).nobjects; int max_nobjects = min_nobjects; int min_length = outputLengthNextN( - pages.at(0).getObjectID(), min_nobjects, lengths, obj_renumber); + pages.at(0).getObjectID(), min_nobjects, lengths, obj_renumber); int max_length = min_length; int max_shared = cphe.at(0).nshared_objects; @@ -1977,26 +1977,26 @@ QPDF::calculateHPageOffset( 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. + // Calculate values for each page, assigning full values to + // the delta items. They will be adjusted later. - // Repeat calculations for page 0 so we can assign to phe[i] - // without duplicating those assignments. + // Repeat calculations for page 0 so we can assign to phe[i] + // without duplicating those assignments. - int nobjects = cphe.at(i).nobjects; - int length = outputLengthNextN( - pages.at(i).getObjectID(), nobjects, lengths, obj_renumber); - int nshared = cphe.at(i).nshared_objects; + int nobjects = cphe.at(i).nobjects; + int length = outputLengthNextN( + pages.at(i).getObjectID(), nobjects, lengths, obj_renumber); + int nshared = cphe.at(i).nshared_objects; - min_nobjects = std::min(min_nobjects, nobjects); - max_nobjects = std::max(max_nobjects, nobjects); - min_length = std::min(min_length, length); - max_length = std::max(max_length, length); - max_shared = std::max(max_shared, nshared); + min_nobjects = std::min(min_nobjects, nobjects); + max_nobjects = std::max(max_nobjects, nobjects); + min_length = std::min(min_length, length); + max_length = std::max(max_length, length); + max_shared = std::max(max_shared, nshared); - phe.at(i).delta_nobjects = nobjects; - phe.at(i).delta_page_length = length; - phe.at(i).nshared_objects = nshared; + phe.at(i).delta_nobjects = nobjects; + phe.at(i).delta_page_length = length; + phe.at(i).nshared_objects = nshared; } ph.min_nobjects = min_nobjects; @@ -2008,8 +2008,8 @@ QPDF::calculateHPageOffset( ph.nbits_delta_page_length = nbits(max_length - min_length); ph.nbits_nshared_objects = nbits(max_shared); ph.nbits_shared_identifier = - nbits(this->m->c_shared_object_data.nshared_total); - ph.shared_denominator = 4; // doesn't matter + nbits(this->m->c_shared_object_data.nshared_total); + ph.shared_denominator = 4; // doesn't matter // It isn't clear how to compute content offset and content // length. Since we are not interleaving page objects with the @@ -2021,23 +2021,23 @@ QPDF::calculateHPageOffset( for (size_t i = 0; i < npages; ++i) { - // Adjust delta entries - if ((phe.at(i).delta_nobjects < min_nobjects) || + // Adjust delta entries + if ((phe.at(i).delta_nobjects < min_nobjects) || (phe.at(i).delta_page_length < min_length)) { stopOnError("found too small delta nobjects or delta page length" " while writing linearization data"); } - phe.at(i).delta_nobjects -= min_nobjects; - phe.at(i).delta_page_length -= min_length; - phe.at(i).delta_content_length = phe.at(i).delta_page_length; + phe.at(i).delta_nobjects -= min_nobjects; + 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) - { - phe.at(i).shared_identifiers.push_back( - cphe.at(i).shared_identifiers.at(j)); - phe.at(i).shared_numerators.push_back(0); - } + 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); + } } } @@ -2054,18 +2054,18 @@ QPDF::calculateHSharedObject( soe.clear(); int min_length = outputLengthNextN( - csoe.at(0).object, 1, lengths, obj_renumber); + csoe.at(0).object, 1, lengths, obj_renumber); int max_length = min_length; 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); - min_length = std::min(min_length, length); - max_length = std::max(max_length, length); + // Assign absolute numbers to deltas; adjust later + 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; + soe.at(i).delta_group_length = length; } if (soe.size() != QIntC::to_size(cso.nshared_total)) { @@ -2076,23 +2076,23 @@ QPDF::calculateHSharedObject( so.nshared_first_page = cso.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 = - (*(xref.find(so.first_shared_obj))).second.getOffset(); + so.first_shared_obj = + (*(obj_renumber.find(cso.first_shared_obj))).second; + so.first_shared_offset = + (*(xref.find(so.first_shared_obj))).second.getOffset(); } 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) { - // Adjust deltas - if (soe.at(i).delta_group_length < min_length) + // Adjust deltas + if (soe.at(i).delta_group_length < min_length) { stopOnError("found too small group length while" " writing linearization data"); } - soe.at(i).delta_group_length -= min_length; + soe.at(i).delta_group_length -= min_length; } } @@ -2106,31 +2106,31 @@ QPDF::calculateHOutline( if (cho.nobjects == 0) { - return; + return; } HGeneric& ho = this->m->outline_hints; ho.first_object = - (*(obj_renumber.find(cho.first_object))).second; + (*(obj_renumber.find(cho.first_object))).second; ho.first_object_offset = - (*(xref.find(ho.first_object))).second.getOffset(); + (*(xref.find(ho.first_object))).second.getOffset(); ho.nobjects = cho.nobjects; ho.group_length = outputLengthNextN( - cho.first_object, ho.nobjects, lengths, obj_renumber); + 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) + 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), + 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 @@ -2141,18 +2141,18 @@ 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) + 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)), + 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(); } @@ -2181,28 +2181,28 @@ QPDF::writeHPageOffset(BitWriter& w) std::vector<HPageOffsetEntry>& entries = t.entries; write_vector_int(w, nitems, entries, - t.nbits_delta_nobjects, - &HPageOffsetEntry::delta_nobjects); + t.nbits_delta_nobjects, + &HPageOffsetEntry::delta_nobjects); write_vector_int(w, nitems, entries, - t.nbits_delta_page_length, - &HPageOffsetEntry::delta_page_length); + t.nbits_delta_page_length, + &HPageOffsetEntry::delta_page_length); write_vector_int(w, nitems, entries, - t.nbits_nshared_objects, - &HPageOffsetEntry::nshared_objects); + t.nbits_nshared_objects, + &HPageOffsetEntry::nshared_objects); write_vector_vector(w, nitems, entries, - &HPageOffsetEntry::nshared_objects, - t.nbits_shared_identifier, - &HPageOffsetEntry::shared_identifiers); + &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); + &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); + t.nbits_delta_content_offset, + &HPageOffsetEntry::delta_content_offset); write_vector_int(w, nitems, entries, - t.nbits_delta_content_length, - &HPageOffsetEntry::delta_content_length); + t.nbits_delta_content_length, + &HPageOffsetEntry::delta_content_length); } void @@ -2219,28 +2219,28 @@ QPDF::writeHSharedObject(BitWriter& w) 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); + (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); + t.nbits_delta_group_length, + &HSharedObjectEntry::delta_group_length); write_vector_int(w, nitems, entries, - 1, &HSharedObjectEntry::signature_present); + 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 signature were present, we'd have to write a 128-bit hash. + 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); + t.nbits_nobjects, + &HSharedObjectEntry::nobjects_minus_one); } void @@ -2254,10 +2254,10 @@ QPDF::writeHGeneric(BitWriter& w, HGeneric& t) 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) + 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); @@ -2277,8 +2277,8 @@ QPDF::generateHintStream(std::map<int, QPDFXRefEntry> const& xref, O = 0; if (this->m->outline_hints.nobjects > 0) { - O = toI(c.getCount()); - writeHGeneric(w, this->m->outline_hints); + O = toI(c.getCount()); + writeHGeneric(w, this->m->outline_hints); } c.finish(); |