diff options
Diffstat (limited to 'libqpdf/QPDF_linearization.cc')
-rw-r--r-- | libqpdf/QPDF_linearization.cc | 440 |
1 files changed, 222 insertions, 218 deletions
diff --git a/libqpdf/QPDF_linearization.cc b/libqpdf/QPDF_linearization.cc index b05b1d4c..3d04ab90 100644 --- a/libqpdf/QPDF_linearization.cc +++ b/libqpdf/QPDF_linearization.cc @@ -72,7 +72,7 @@ QPDF::checkLinearization() } catch (QPDFExc& e) { - *out_stream << e.what() << std::endl; + *this->m->out_stream << e.what() << std::endl; } return result; } @@ -82,7 +82,7 @@ QPDF::isLinearized() { // If the first object in the file is a dictionary with a suitable // /Linearized key and has an /L key that accurately indicates the - // file size, initialize this->lindict and return true. + // file size, initialize this->m->lindict and return true. // A linearized PDF spec's first object will be contained within // the first 1024 bytes of the file and will be a dictionary with @@ -95,10 +95,10 @@ QPDF::isLinearized() static int const tbuf_size = 1025; char* buf = new char[tbuf_size]; - this->file->seek(0, SEEK_SET); + this->m->file->seek(0, SEEK_SET); PointerHolder<char> b(true, buf); memset(buf, '\0', tbuf_size); - this->file->read(buf, tbuf_size - 1); + this->m->file->read(buf, tbuf_size - 1); int lindict_obj = -1; char* p = buf; @@ -115,16 +115,16 @@ QPDF::isLinearized() } // Seek to the digit. Then skip over digits for a potential // next iteration. - this->file->seek(p - buf, SEEK_SET); + this->m->file->seek(p - buf, SEEK_SET); while (((p - buf) < tbuf_size) && QUtil::is_digit(*p)) { ++p; } - QPDFTokenizer::Token t1 = readToken(this->file, true); - QPDFTokenizer::Token t2 = readToken(this->file, true); - QPDFTokenizer::Token t3 = readToken(this->file, true); - QPDFTokenizer::Token t4 = readToken(this->file, true); + QPDFTokenizer::Token t1 = readToken(this->m->file, true); + QPDFTokenizer::Token t2 = readToken(this->m->file, true); + QPDFTokenizer::Token t3 = readToken(this->m->file, true); + QPDFTokenizer::Token t4 = readToken(this->m->file, true); if ((t1.getType() == QPDFTokenizer::tt_integer) && (t2.getType() == QPDFTokenizer::tt_integer) && (t3 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "obj")) && @@ -158,19 +158,19 @@ QPDF::isLinearized() if (L.isInteger()) { qpdf_offset_t Li = L.getIntValue(); - this->file->seek(0, SEEK_END); - if (Li != this->file->tell()) + this->m->file->seek(0, SEEK_END); + if (Li != this->m->file->tell()) { QTC::TC("qpdf", "QPDF /L mismatch"); return false; } else { - this->linp.file_size = Li; + this->m->linp.file_size = Li; } } - this->lindict = candidate; + this->m->lindict = candidate; return true; } @@ -191,12 +191,12 @@ QPDF::readLinearizationData() } // /L is read and stored in linp by isLinearized() - QPDFObjectHandle H = lindict.getKey("/H"); - QPDFObjectHandle O = lindict.getKey("/O"); - QPDFObjectHandle E = lindict.getKey("/E"); - QPDFObjectHandle N = lindict.getKey("/N"); - QPDFObjectHandle T = lindict.getKey("/T"); - QPDFObjectHandle P = lindict.getKey("/P"); + QPDFObjectHandle H = this->m->lindict.getKey("/H"); + QPDFObjectHandle O = this->m->lindict.getKey("/O"); + QPDFObjectHandle E = this->m->lindict.getKey("/E"); + QPDFObjectHandle N = this->m->lindict.getKey("/N"); + QPDFObjectHandle T = this->m->lindict.getKey("/T"); + QPDFObjectHandle P = this->m->lindict.getKey("/P"); if (! (H.isArray() && O.isInteger() && @@ -205,9 +205,9 @@ QPDF::readLinearizationData() T.isInteger() && (P.isInteger() || P.isNull()))) { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "linearization dictionary", - this->file->getLastOffset(), + this->m->file->getLastOffset(), "some keys in linearization dictionary are of " "the wrong type"); } @@ -216,9 +216,9 @@ QPDF::readLinearizationData() unsigned int n_H_items = H.getArrayNItems(); if (! ((n_H_items == 2) || (n_H_items == 4))) { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "linearization dictionary", - this->file->getLastOffset(), + this->m->file->getLastOffset(), "H has the wrong number of items"); } @@ -232,9 +232,9 @@ QPDF::readLinearizationData() } else { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "linearization dictionary", - this->file->getLastOffset(), + this->m->file->getLastOffset(), "some H items are of the wrong type"); } } @@ -272,20 +272,20 @@ QPDF::readLinearizationData() // accurate and bail right now if it's not. if (N.getIntValue() != static_cast<long long>(getAllPages().size())) { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "linearization hint table", - this->file->getLastOffset(), + this->m->file->getLastOffset(), "/N does not match number of pages"); } // file_size initialized by isLinearized() - this->linp.first_page_object = O.getIntValue(); - this->linp.first_page_end = E.getIntValue(); - this->linp.npages = N.getIntValue(); - this->linp.xref_zero_offset = T.getIntValue(); - this->linp.first_page = first_page; - this->linp.H_offset = H0_offset; - this->linp.H_length = H0_length; + this->m->linp.first_page_object = O.getIntValue(); + this->m->linp.first_page_end = E.getIntValue(); + this->m->linp.npages = N.getIntValue(); + this->m->linp.xref_zero_offset = T.getIntValue(); + this->m->linp.first_page = first_page; + this->m->linp.H_offset = H0_offset; + this->m->linp.H_length = H0_length; // Read hint streams @@ -320,9 +320,9 @@ QPDF::readLinearizationData() int HSi = HS.getIntValue(); if ((HSi < 0) || (HSi >= h_size)) { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "linearization hint table", - this->file->getLastOffset(), + this->m->file->getLastOffset(), "/S (shared object) offset is out of bounds"); } readHSharedObject(BitStream(h_buf + HSi, h_size - HSi)); @@ -332,13 +332,13 @@ QPDF::readLinearizationData() int HOi = HO.getIntValue(); if ((HOi < 0) || (HOi >= h_size)) { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "linearization hint table", - this->file->getLastOffset(), + this->m->file->getLastOffset(), "/O (outline) offset is out of bounds"); } readHGeneric(BitStream(h_buf + HOi, h_size - HOi), - this->outline_hints); + this->m->outline_hints); } } @@ -349,14 +349,14 @@ QPDF::readHintStream(Pipeline& pl, qpdf_offset_t offset, size_t length) int gen; QPDFObjectHandle H = readObjectAtOffset( false, offset, "linearization hint stream", -1, 0, obj, gen); - ObjCache& oc = this->obj_cache[QPDFObjGen(obj, gen)]; + ObjCache& oc = this->m->obj_cache[QPDFObjGen(obj, gen)]; qpdf_offset_t min_end_offset = oc.end_before_space; qpdf_offset_t max_end_offset = oc.end_after_space; if (! H.isStream()) { - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "linearization dictionary", - this->file->getLastOffset(), + this->m->file->getLastOffset(), "hint table is not a stream"); } @@ -373,7 +373,7 @@ QPDF::readHintStream(Pipeline& pl, qpdf_offset_t offset, size_t length) QTC::TC("qpdf", "QPDF hint table length indirect"); // Force resolution (void) length_obj.getIntValue(); - ObjCache& oc = this->obj_cache[length_obj.getObjGen()]; + ObjCache& oc = this->m->obj_cache[length_obj.getObjGen()]; min_end_offset = oc.end_before_space; max_end_offset = oc.end_after_space; } @@ -385,12 +385,12 @@ QPDF::readHintStream(Pipeline& pl, qpdf_offset_t offset, size_t length) if ((computed_end < min_end_offset) || (computed_end > max_end_offset)) { - *out_stream << "expected = " << computed_end - << "; actual = " << min_end_offset << ".." - << max_end_offset << std::endl; - throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), + *this->m->out_stream << "expected = " << computed_end + << "; actual = " << min_end_offset << ".." + << max_end_offset << std::endl; + throw QPDFExc(qpdf_e_damaged_pdf, this->m->file->getName(), "linearization dictionary", - this->file->getLastOffset(), + this->m->file->getLastOffset(), "hint table length mismatch"); } H.pipeStreamData(&pl, 0, qpdf_dl_specialized); @@ -403,7 +403,7 @@ QPDF::readHPageOffset(BitStream h) // All comments referring to the PDF spec refer to the spec for // version 1.4. - HPageOffset& t = this->page_offset_hints; + HPageOffset& t = this->m->page_offset_hints; t.min_nobjects = h.getBits(32); // 1 t.first_page_offset = h.getBits(32); // 2 @@ -421,7 +421,7 @@ QPDF::readHPageOffset(BitStream h) std::vector<HPageOffsetEntry>& entries = t.entries; entries.clear(); - unsigned int nitems = this->linp.npages; + unsigned int nitems = this->m->linp.npages; load_vector_int(h, nitems, entries, t.nbits_delta_nobjects, &HPageOffsetEntry::delta_nobjects); @@ -450,7 +450,7 @@ QPDF::readHPageOffset(BitStream h) void QPDF::readHSharedObject(BitStream h) { - HSharedObject& t = this->shared_object_hints; + HSharedObject& t = this->m->shared_object_hints; t.first_shared_obj = h.getBits(32); // 1 t.first_shared_offset = h.getBits(32); // 2 @@ -509,7 +509,7 @@ QPDF::checkLinearizationInternal() // Check all values in linearization parameter dictionary - LinParameters& p = this->linp; + LinParameters& p = this->m->linp; // L: file size in bytes -- checked by isLinearized @@ -533,7 +533,7 @@ QPDF::checkLinearizationInternal() { QPDFObjectHandle const& page = pages.at(i); QPDFObjGen og(page.getObjGen()); - if (this->xref_table[og].getType() == 2) + if (this->m->xref_table[og].getType() == 2) { errors.push_back("page dictionary for page " + QUtil::int_to_string(i) + " is compressed"); @@ -541,25 +541,25 @@ QPDF::checkLinearizationInternal() } // T: offset of whitespace character preceding xref entry for object 0 - this->file->seek(p.xref_zero_offset, SEEK_SET); + this->m->file->seek(p.xref_zero_offset, SEEK_SET); while (1) { char ch; - this->file->read(&ch, 1); + this->m->file->read(&ch, 1); if (! ((ch == ' ') || (ch == '\r') || (ch == '\n'))) { - this->file->seek(-1, SEEK_CUR); + this->m->file->seek(-1, SEEK_CUR); break; } } - if (this->file->tell() != this->first_xref_item_offset) + if (this->m->file->tell() != this->m->first_xref_item_offset) { QTC::TC("qpdf", "QPDF err /T mismatch"); errors.push_back("space before first xref item (/T) mismatch " "(computed = " + - QUtil::int_to_string(this->first_xref_item_offset) + + QUtil::int_to_string(this->m->first_xref_item_offset) + "; file = " + - QUtil::int_to_string(this->file->tell())); + QUtil::int_to_string(this->m->file->tell())); } // P: first page number -- Implementation note 124 says Acrobat @@ -570,7 +570,7 @@ QPDF::checkLinearizationInternal() // at the end of the containing xref section if any object streams // are in use. - if (this->uncompressed_after_compressed) + if (this->m->uncompressed_after_compressed) { errors.push_back("linearized file contains an uncompressed object" " after a compressed one in a cross-reference stream"); @@ -584,8 +584,8 @@ QPDF::checkLinearizationInternal() { // local scope std::map<int, int> object_stream_data; for (std::map<QPDFObjGen, QPDFXRefEntry>::const_iterator iter = - this->xref_table.begin(); - iter != this->xref_table.end(); ++iter) + this->m->xref_table.begin(); + iter != this->m->xref_table.end(); ++iter) { QPDFObjGen const& og = (*iter).first; QPDFXRefEntry const& entry = (*iter).second; @@ -609,22 +609,22 @@ QPDF::checkLinearizationInternal() // agree with pdlin. As of this writing, the test suite doesn't // contain any files with threads. - if (this->part6.empty()) + if (this->m->part6.empty()) { throw std::logic_error("linearization part 6 unexpectedly empty"); } qpdf_offset_t min_E = -1; qpdf_offset_t max_E = -1; - for (std::vector<QPDFObjectHandle>::iterator iter = this->part6.begin(); - iter != this->part6.end(); ++iter) + for (std::vector<QPDFObjectHandle>::iterator iter = this->m->part6.begin(); + iter != this->m->part6.end(); ++iter) { QPDFObjGen og((*iter).getObjGen()); - if (this->obj_cache.count(og) == 0) + if (this->m->obj_cache.count(og) == 0) { // All objects have to have been dereferenced to be classified. throw std::logic_error("linearization part6 object not in cache"); } - ObjCache const& oc = this->obj_cache[og]; + ObjCache const& oc = this->m->obj_cache[og]; min_E = std::max(min_E, oc.end_before_space); max_E = std::max(max_E, oc.end_after_space); } @@ -655,7 +655,7 @@ QPDF::checkLinearizationInternal() for (std::list<std::string>::iterator iter = errors.begin(); iter != errors.end(); ++iter) { - *out_stream << "ERROR: " << (*iter) << std::endl; + *this->m->out_stream << "ERROR: " << (*iter) << std::endl; } } @@ -665,7 +665,7 @@ QPDF::checkLinearizationInternal() for (std::list<std::string>::iterator iter = warnings.begin(); iter != warnings.end(); ++iter) { - *out_stream << "WARNING: " << (*iter) << std::endl; + *this->m->out_stream << "WARNING: " << (*iter) << std::endl; } } @@ -675,15 +675,15 @@ QPDF::checkLinearizationInternal() qpdf_offset_t QPDF::maxEnd(ObjUser const& ou) { - assert(this->obj_user_to_objects.count(ou) > 0); - std::set<QPDFObjGen> const& ogs = this->obj_user_to_objects[ou]; + assert(this->m->obj_user_to_objects.count(ou) > 0); + std::set<QPDFObjGen> const& ogs = this->m->obj_user_to_objects[ou]; qpdf_offset_t end = 0; for (std::set<QPDFObjGen>::const_iterator iter = ogs.begin(); iter != ogs.end(); ++iter) { QPDFObjGen const& og = *iter; - assert(this->obj_cache.count(og) > 0); - end = std::max(end, this->obj_cache[og].end_after_space); + assert(this->m->obj_cache.count(og) > 0); + end = std::max(end, this->m->obj_cache[og].end_after_space); } return end; } @@ -691,7 +691,7 @@ QPDF::maxEnd(ObjUser const& ou) qpdf_offset_t QPDF::getLinearizationOffset(QPDFObjGen const& og) { - QPDFXRefEntry entry = this->xref_table[og]; + QPDFXRefEntry entry = this->m->xref_table[og]; qpdf_offset_t result = 0; switch (entry.getType()) { @@ -737,7 +737,7 @@ QPDF::lengthNextN(int first_object, int n, for (int i = 0; i < n; ++i) { QPDFObjGen og(first_object + i, 0); - if (this->xref_table.count(og) == 0) + if (this->m->xref_table.count(og) == 0) { errors.push_back( "no xref table entry for " + @@ -745,8 +745,8 @@ QPDF::lengthNextN(int first_object, int n, } else { - assert(this->obj_cache.count(og) > 0); - length += this->obj_cache[og].end_after_space - + assert(this->m->obj_cache.count(og) > 0); + length += this->m->obj_cache[og].end_after_space - getLinearizationOffset(og); } } @@ -778,9 +778,9 @@ QPDF::checkHPageOffset(std::list<std::string>& errors, unsigned int npages = pages.size(); int table_offset = adjusted_offset( - this->page_offset_hints.first_page_offset); + this->m->page_offset_hints.first_page_offset); QPDFObjGen first_page_og(pages.at(0).getObjGen()); - assert(this->xref_table.count(first_page_og) > 0); + assert(this->m->xref_table.count(first_page_og) > 0); int offset = getLinearizationOffset(first_page_og); if (table_offset != offset) { @@ -791,13 +791,13 @@ QPDF::checkHPageOffset(std::list<std::string>& errors, { QPDFObjGen page_og(pages.at(pageno).getObjGen()); int first_object = page_og.getObj(); - assert(this->xref_table.count(page_og) > 0); + assert(this->m->xref_table.count(page_og) > 0); offset = getLinearizationOffset(page_og); - HPageOffsetEntry& he = this->page_offset_hints.entries.at(pageno); - CHPageOffsetEntry& ce = this->c_page_offset_data.entries.at(pageno); + HPageOffsetEntry& he = this->m->page_offset_hints.entries.at(pageno); + CHPageOffsetEntry& ce = this->m->c_page_offset_data.entries.at(pageno); int h_nobjects = he.delta_nobjects + - this->page_offset_hints.min_nobjects; + this->m->page_offset_hints.min_nobjects; if (h_nobjects != ce.nobjects) { // This happens with pdlin when there are thumbnails. @@ -812,7 +812,7 @@ QPDF::checkHPageOffset(std::list<std::string>& errors, // computed value if there is a discrepancy. int length = lengthNextN(first_object, h_nobjects, errors); int h_length = he.delta_page_length + - this->page_offset_hints.min_page_length; + this->m->page_offset_hints.min_page_length; if (length != h_length) { // This condition almost certainly indicates a bad hint @@ -853,12 +853,12 @@ QPDF::checkHPageOffset(std::list<std::string>& errors, for (int i = 0; i < ce.nshared_objects; ++i) { int idx = ce.shared_identifiers.at(i); - if (idx >= this->c_shared_object_data.nshared_total) + if (idx >= this->m->c_shared_object_data.nshared_total) { throw std::logic_error( "index out of bounds for shared object hint table"); } - int obj = this->c_shared_object_data.entries.at(idx).object; + int obj = this->m->c_shared_object_data.entries.at(idx).object; computed_shared.insert(obj); } @@ -916,7 +916,7 @@ QPDF::checkHSharedObject(std::list<std::string>& errors, // these whenever there are no shared objects not referenced by // the first page (i.e., nshared_total == nshared_first_page). - HSharedObject& so = this->shared_object_hints; + HSharedObject& so = this->m->shared_object_hints; if (so.nshared_total < so.nshared_first_page) { errors.push_back("shared object hint table: ntotal < nfirst_page"); @@ -932,7 +932,7 @@ QPDF::checkHSharedObject(std::list<std::string>& errors, if (i == so.nshared_first_page) { QTC::TC("qpdf", "QPDF lin check shared past first page"); - if (this->part8.empty()) + if (this->m->part8.empty()) { errors.push_back( "part 8 is empty but nshared_total > " @@ -940,7 +940,7 @@ QPDF::checkHSharedObject(std::list<std::string>& errors, } else { - int obj = this->part8.at(0).getObjectID(); + int obj = this->m->part8.at(0).getObjectID(); if (obj != so.first_shared_obj) { errors.push_back( @@ -955,7 +955,7 @@ QPDF::checkHSharedObject(std::list<std::string>& errors, cur_object = so.first_shared_obj; QPDFObjGen og(cur_object, 0); - assert(this->xref_table.count(og) > 0); + assert(this->m->xref_table.count(og) > 0); int offset = getLinearizationOffset(og); int h_offset = adjusted_offset(so.first_shared_offset); if (offset != h_offset) @@ -996,15 +996,15 @@ QPDF::checkHOutlines(std::list<std::string>& warnings) // wrong starting place). pdlin appears to generate correct // values in those cases. - if (this->c_outline_data.nobjects == this->outline_hints.nobjects) + if (this->m->c_outline_data.nobjects == this->m->outline_hints.nobjects) { - if (this->c_outline_data.nobjects == 0) + if (this->m->c_outline_data.nobjects == 0) { return; } - if (this->c_outline_data.first_object == - this->outline_hints.first_object) + if (this->m->c_outline_data.first_object == + this->m->outline_hints.first_object) { // Check length and offset. Acrobat gets these wrong. QPDFObjectHandle outlines = getRoot().getKey("/Outlines"); @@ -1018,12 +1018,12 @@ QPDF::checkHOutlines(std::list<std::string>& warnings) return; } QPDFObjGen og(outlines.getObjGen()); - assert(this->xref_table.count(og) > 0); + assert(this->m->xref_table.count(og) > 0); int offset = getLinearizationOffset(og); ObjUser ou(ObjUser::ou_root_key, "/Outlines"); int length = maxEnd(ou) - offset; int table_offset = - adjusted_offset(this->outline_hints.first_object_offset); + adjusted_offset(this->m->outline_hints.first_object_offset); if (offset != table_offset) { warnings.push_back( @@ -1031,7 +1031,7 @@ QPDF::checkHOutlines(std::list<std::string>& warnings) QUtil::int_to_string(table_offset) + "; computed = " + QUtil::int_to_string(offset)); } - int table_length = this->outline_hints.group_length; + int table_length = this->m->outline_hints.group_length; if (length != table_length) { warnings.push_back( @@ -1063,41 +1063,42 @@ QPDF::showLinearizationData() } catch (QPDFExc& e) { - *out_stream << e.what() << std::endl; + *this->m->out_stream << e.what() << std::endl; } } void QPDF::dumpLinearizationDataInternal() { - *out_stream << this->file->getName() << ": linearization data:" << std::endl - << std::endl; - - *out_stream - << "file_size: " << this->linp.file_size << std::endl - << "first_page_object: " << this->linp.first_page_object << std::endl - << "first_page_end: " << this->linp.first_page_end << std::endl - << "npages: " << this->linp.npages << std::endl - << "xref_zero_offset: " << this->linp.xref_zero_offset << std::endl - << "first_page: " << this->linp.first_page << std::endl - << "H_offset: " << this->linp.H_offset << std::endl - << "H_length: " << this->linp.H_length << std::endl + *this->m->out_stream + << this->m->file->getName() << ": linearization data:" << std::endl + << std::endl; + + *this->m->out_stream + << "file_size: " << this->m->linp.file_size << std::endl + << "first_page_object: " << this->m->linp.first_page_object << std::endl + << "first_page_end: " << this->m->linp.first_page_end << std::endl + << "npages: " << this->m->linp.npages << std::endl + << "xref_zero_offset: " << this->m->linp.xref_zero_offset << std::endl + << "first_page: " << this->m->linp.first_page << std::endl + << "H_offset: " << this->m->linp.H_offset << std::endl + << "H_length: " << this->m->linp.H_length << std::endl << std::endl; - *out_stream << "Page Offsets Hint Table" << std::endl - << std::endl; + *this->m->out_stream << "Page Offsets Hint Table" << std::endl + << std::endl; dumpHPageOffset(); - *out_stream << std::endl - << "Shared Objects Hint Table" << std::endl - << std::endl; + *this->m->out_stream << std::endl + << "Shared Objects Hint Table" << std::endl + << std::endl; dumpHSharedObject(); - if (this->outline_hints.nobjects > 0) + if (this->m->outline_hints.nobjects > 0) { - *out_stream << std::endl - << "Outlines Hint Table" << std::endl - << std::endl; - dumpHGeneric(this->outline_hints); + *this->m->out_stream << std::endl + << "Outlines Hint Table" << std::endl + << std::endl; + dumpHGeneric(this->m->outline_hints); } } @@ -1107,9 +1108,9 @@ QPDF::adjusted_offset(int offset) // All offsets >= H_offset have to be increased by H_length // since all hint table location values disregard the hint table // itself. - if (offset >= this->linp.H_offset) + if (offset >= this->m->linp.H_offset) { - return offset + this->linp.H_length; + return offset + this->m->linp.H_length; } return offset; } @@ -1118,8 +1119,8 @@ QPDF::adjusted_offset(int offset) void QPDF::dumpHPageOffset() { - HPageOffset& t = this->page_offset_hints; - *out_stream + HPageOffset& t = this->m->page_offset_hints; + *this->m->out_stream << "min_nobjects: " << t.min_nobjects << std::endl << "first_page_offset: " << adjusted_offset(t.first_page_offset) @@ -1147,10 +1148,10 @@ QPDF::dumpHPageOffset() << "shared_denominator: " << t.shared_denominator << std::endl; - for (int i1 = 0; i1 < this->linp.npages; ++i1) + for (int i1 = 0; i1 < this->m->linp.npages; ++i1) { HPageOffsetEntry& pe = t.entries.at(i1); - *out_stream + *this->m->out_stream << "Page " << i1 << ":" << std::endl << " nobjects: " << pe.delta_nobjects + t.min_nobjects << std::endl @@ -1164,10 +1165,10 @@ QPDF::dumpHPageOffset() << " nshared_objects: " << pe.nshared_objects << std::endl; for (int i2 = 0; i2 < pe.nshared_objects; ++i2) { - *out_stream << " identifier " << i2 << ": " - << pe.shared_identifiers.at(i2) << std::endl; - *out_stream << " numerator " << i2 << ": " - << pe.shared_numerators.at(i2) << std::endl; + *this->m->out_stream << " identifier " << i2 << ": " + << pe.shared_identifiers.at(i2) << std::endl; + *this->m->out_stream << " numerator " << i2 << ": " + << pe.shared_numerators.at(i2) << std::endl; } } } @@ -1175,8 +1176,8 @@ QPDF::dumpHPageOffset() void QPDF::dumpHSharedObject() { - HSharedObject& t = this->shared_object_hints; - *out_stream + HSharedObject& t = this->m->shared_object_hints; + *this->m->out_stream << "first_shared_obj: " << t.first_shared_obj << std::endl << "first_shared_offset: " << adjusted_offset(t.first_shared_offset) @@ -1195,19 +1196,20 @@ QPDF::dumpHSharedObject() for (int i = 0; i < t.nshared_total; ++i) { HSharedObjectEntry& se = t.entries.at(i); - *out_stream << "Shared Object " << i << ":" << std::endl; - *out_stream << " group length: " - << se.delta_group_length + t.min_group_length << std::endl; + *this->m->out_stream + << "Shared Object " << i << ":" << std::endl + << " group length: " + << se.delta_group_length + t.min_group_length << std::endl; // PDF spec says signature present nobjects_minus_one are // always 0, so print them only if they have a non-zero value. if (se.signature_present) { - *out_stream << " signature present" << std::endl; + *this->m->out_stream << " signature present" << std::endl; } if (se.nobjects_minus_one != 0) { - *out_stream << " nobjects: " - << se.nobjects_minus_one + 1 << std::endl; + *this->m->out_stream << " nobjects: " + << se.nobjects_minus_one + 1 << std::endl; } } } @@ -1215,7 +1217,7 @@ QPDF::dumpHSharedObject() void QPDF::dumpHGeneric(HGeneric& t) { - *out_stream + *this->m->out_stream << "first_object: " << t.first_object << std::endl << "first_object_offset: " << adjusted_offset(t.first_object_offset) @@ -1242,7 +1244,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) // this function. Note that actual offsets and lengths are not // computed here, but anything related to object ordering is. - if (this->object_to_obj_users.empty()) + if (this->m->object_to_obj_users.empty()) { // Note that we can't call optimize here because we don't know // whether it should be called with or without allow changes. @@ -1298,15 +1300,15 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) // * outlines: part 6 or 9 - this->part4.clear(); - this->part6.clear(); - this->part7.clear(); - this->part8.clear(); - this->part9.clear(); - this->c_linp = LinParameters(); - this->c_page_offset_data = CHPageOffset(); - this->c_shared_object_data = CHSharedObject(); - this->c_outline_data = HGeneric(); + this->m->part4.clear(); + this->m->part6.clear(); + this->m->part7.clear(); + this->m->part8.clear(); + this->m->part9.clear(); + this->m->c_linp = LinParameters(); + this->m->c_page_offset_data = CHPageOffset(); + this->m->c_shared_object_data = CHSharedObject(); + this->m->c_outline_data = HGeneric(); QPDFObjectHandle root = getRoot(); bool outlines_in_first_page = false; @@ -1349,8 +1351,8 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) std::set<QPDFObjGen> lc_root; for (std::map<QPDFObjGen, std::set<ObjUser> >::iterator oiter = - this->object_to_obj_users.begin(); - oiter != this->object_to_obj_users.end(); ++oiter) + this->m->object_to_obj_users.begin(); + oiter != this->m->object_to_obj_users.end(); ++oiter) { QPDFObjGen const& og = (*oiter).first; @@ -1505,17 +1507,18 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) // npages is the size of the existing pages vector, which has been // created by traversing the pages tree, and as such is a // reasonable size. - this->c_linp.npages = npages; - this->c_page_offset_data.entries = std::vector<CHPageOffsetEntry>(npages); + this->m->c_linp.npages = npages; + this->m->c_page_offset_data.entries = + std::vector<CHPageOffsetEntry>(npages); // Part 4: open document objects. We don't care about the order. assert(lc_root.size() == 1); - this->part4.push_back(objGenToIndirect(*(lc_root.begin()))); + this->m->part4.push_back(objGenToIndirect(*(lc_root.begin()))); for (std::set<QPDFObjGen>::iterator iter = lc_open_document.begin(); iter != lc_open_document.end(); ++iter) { - this->part4.push_back(objGenToIndirect(*iter)); + this->m->part4.push_back(objGenToIndirect(*iter)); } // Part 6: first page objects. Note: implementation note 124 @@ -1533,8 +1536,8 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) "object not in lc_first_page_private"); } lc_first_page_private.erase(first_page_og); - this->c_linp.first_page_object = pages.at(0).getObjectID(); - this->part6.push_back(pages.at(0)); + this->m->c_linp.first_page_object = pages.at(0).getObjectID(); + this->m->part6.push_back(pages.at(0)); // The PDF spec "recommends" an order for the rest of the objects, // but we are going to disregard it except to the extent that it @@ -1544,19 +1547,19 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) for (std::set<QPDFObjGen>::iterator iter = lc_first_page_private.begin(); iter != lc_first_page_private.end(); ++iter) { - this->part6.push_back(objGenToIndirect(*iter)); + this->m->part6.push_back(objGenToIndirect(*iter)); } for (std::set<QPDFObjGen>::iterator iter = lc_first_page_shared.begin(); iter != lc_first_page_shared.end(); ++iter) { - this->part6.push_back(objGenToIndirect(*iter)); + this->m->part6.push_back(objGenToIndirect(*iter)); } // Place the outline dictionary if it goes in the first page section. if (outlines_in_first_page) { - pushOutlinesToPart(this->part6, lc_outlines, object_stream_data); + pushOutlinesToPart(this->m->part6, lc_outlines, object_stream_data); } // Fill in page offset hint table information for the first page. @@ -1565,7 +1568,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) // in garbage values for all the shared object identifiers on the // first page. - this->c_page_offset_data.entries.at(0).nobjects = this->part6.size(); + this->m->c_page_offset_data.entries.at(0).nobjects = this->m->part6.size(); // Part 7: other pages' private objects @@ -1583,16 +1586,16 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) QUtil::int_to_string(i) + " not in lc_other_page_private"); } lc_other_page_private.erase(page_og); - this->part7.push_back(pages.at(i)); + this->m->part7.push_back(pages.at(i)); // Place all non-shared objects referenced by this page, // updating the page object count for the hint table. - this->c_page_offset_data.entries.at(i).nobjects = 1; + this->m->c_page_offset_data.entries.at(i).nobjects = 1; ObjUser ou(ObjUser::ou_page, i); - assert(this->obj_user_to_objects.count(ou) > 0); - std::set<QPDFObjGen> ogs = this->obj_user_to_objects[ou]; + assert(this->m->obj_user_to_objects.count(ou) > 0); + std::set<QPDFObjGen> ogs = this->m->obj_user_to_objects[ou]; for (std::set<QPDFObjGen>::iterator iter = ogs.begin(); iter != ogs.end(); ++iter) { @@ -1600,8 +1603,8 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) if (lc_other_page_private.count(og)) { lc_other_page_private.erase(og); - this->part7.push_back(objGenToIndirect(og)); - ++this->c_page_offset_data.entries.at(i).nobjects; + this->m->part7.push_back(objGenToIndirect(og)); + ++this->m->c_page_offset_data.entries.at(i).nobjects; } } } @@ -1620,7 +1623,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) for (std::set<QPDFObjGen>::iterator iter = lc_other_page_shared.begin(); iter != lc_other_page_shared.end(); ++iter) { - this->part8.push_back(objGenToIndirect(*iter)); + this->m->part8.push_back(objGenToIndirect(*iter)); } // Part 9: other objects @@ -1634,7 +1637,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) // Place the pages tree. std::set<QPDFObjGen> pages_ogs = - this->obj_user_to_objects[ObjUser(ObjUser::ou_root_key, "/Pages")]; + this->m->obj_user_to_objects[ObjUser(ObjUser::ou_root_key, "/Pages")]; assert(! pages_ogs.empty()); for (std::set<QPDFObjGen>::iterator iter = pages_ogs.begin(); iter != pages_ogs.end(); ++iter) @@ -1643,7 +1646,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) if (lc_other.count(og)) { lc_other.erase(og); - this->part9.push_back(objGenToIndirect(og)); + this->m->part9.push_back(objGenToIndirect(og)); } } @@ -1661,7 +1664,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) if (lc_thumbnail_private.count(thumb_og)) { lc_thumbnail_private.erase(thumb_og); - this->part9.push_back(thumb); + this->m->part9.push_back(thumb); } else { @@ -1673,7 +1676,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) // lc_thumbnail_private. } std::set<QPDFObjGen>& ogs = - this->obj_user_to_objects[ObjUser(ObjUser::ou_thumb, i)]; + this->m->obj_user_to_objects[ObjUser(ObjUser::ou_thumb, i)]; for (std::set<QPDFObjGen>::iterator iter = ogs.begin(); iter != ogs.end(); ++iter) { @@ -1681,7 +1684,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) if (lc_thumbnail_private.count(og)) { lc_thumbnail_private.erase(og); - this->part9.push_back(objGenToIndirect(og)); + this->m->part9.push_back(objGenToIndirect(og)); } } } @@ -1698,28 +1701,28 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) for (std::set<QPDFObjGen>::iterator iter = lc_thumbnail_shared.begin(); iter != lc_thumbnail_shared.end(); ++iter) { - this->part9.push_back(objGenToIndirect(*iter)); + this->m->part9.push_back(objGenToIndirect(*iter)); } // Place outlines unless in first page if (! outlines_in_first_page) { - pushOutlinesToPart(this->part9, lc_outlines, object_stream_data); + pushOutlinesToPart(this->m->part9, lc_outlines, object_stream_data); } // Place all remaining objects for (std::set<QPDFObjGen>::iterator iter = lc_other.begin(); iter != lc_other.end(); ++iter) { - this->part9.push_back(objGenToIndirect(*iter)); + this->m->part9.push_back(objGenToIndirect(*iter)); } // Make sure we got everything exactly once. unsigned int num_placed = - this->part4.size() + this->part6.size() + this->part7.size() + - this->part8.size() + this->part9.size(); - unsigned int num_wanted = this->object_to_obj_users.size(); + this->m->part4.size() + this->m->part6.size() + this->m->part7.size() + + this->m->part8.size() + this->m->part9.size(); + unsigned int num_wanted = this->m->object_to_obj_users.size(); if (num_placed != num_wanted) { throw std::logic_error( @@ -1743,28 +1746,29 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) // can map from object number only without regards to generation. std::map<int, int> obj_to_index; - this->c_shared_object_data.nshared_first_page = this->part6.size(); - this->c_shared_object_data.nshared_total = - this->c_shared_object_data.nshared_first_page + this->part8.size(); + this->m->c_shared_object_data.nshared_first_page = this->m->part6.size(); + this->m->c_shared_object_data.nshared_total = + this->m->c_shared_object_data.nshared_first_page + + this->m->part8.size(); std::vector<CHSharedObjectEntry>& shared = - this->c_shared_object_data.entries; - for (std::vector<QPDFObjectHandle>::iterator iter = this->part6.begin(); - iter != this->part6.end(); ++iter) + this->m->c_shared_object_data.entries; + for (std::vector<QPDFObjectHandle>::iterator iter = this->m->part6.begin(); + iter != this->m->part6.end(); ++iter) { QPDFObjectHandle& oh = *iter; int obj = oh.getObjectID(); obj_to_index[obj] = shared.size(); shared.push_back(CHSharedObjectEntry(obj)); } - QTC::TC("qpdf", "QPDF lin part 8 empty", this->part8.empty() ? 1 : 0); - if (! this->part8.empty()) + QTC::TC("qpdf", "QPDF lin part 8 empty", this->m->part8.empty() ? 1 : 0); + if (! this->m->part8.empty()) { - this->c_shared_object_data.first_shared_obj = - this->part8.at(0).getObjectID(); + this->m->c_shared_object_data.first_shared_obj = + this->m->part8.at(0).getObjectID(); for (std::vector<QPDFObjectHandle>::iterator iter = - this->part8.begin(); - iter != this->part8.end(); ++iter) + this->m->part8.begin(); + iter != this->m->part8.end(); ++iter) { QPDFObjectHandle& oh = *iter; int obj = oh.getObjectID(); @@ -1772,8 +1776,8 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) shared.push_back(CHSharedObjectEntry(obj)); } } - if (static_cast<size_t>(this->c_shared_object_data.nshared_total) != - this->c_shared_object_data.entries.size()) + if (static_cast<size_t>(this->m->c_shared_object_data.nshared_total) != + this->m->c_shared_object_data.entries.size()) { throw std::logic_error( "shared object hint table has wrong number of entries"); @@ -1784,15 +1788,15 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) for (unsigned int i = 1; i < npages; ++i) { - CHPageOffsetEntry& pe = this->c_page_offset_data.entries.at(i); + CHPageOffsetEntry& pe = this->m->c_page_offset_data.entries.at(i); ObjUser ou(ObjUser::ou_page, i); - assert(this->obj_user_to_objects.count(ou) > 0); - std::set<QPDFObjGen> const& ogs = this->obj_user_to_objects[ou]; + assert(this->m->obj_user_to_objects.count(ou) > 0); + std::set<QPDFObjGen> const& ogs = this->m->obj_user_to_objects[ou]; for (std::set<QPDFObjGen>::const_iterator iter = ogs.begin(); iter != ogs.end(); ++iter) { QPDFObjGen const& og = *iter; - if ((this->object_to_obj_users[og].size() > 1) && + if ((this->m->object_to_obj_users[og].size() > 1) && (obj_to_index.count(og.getObj()) > 0)) { int idx = obj_to_index[og.getObj()]; @@ -1818,18 +1822,18 @@ QPDF::pushOutlinesToPart( outlines = getUncompressedObject(outlines, object_stream_data); QPDFObjGen outlines_og(outlines.getObjGen()); QTC::TC("qpdf", "QPDF lin outlines in part", - ((&part == (&this->part6)) ? 0 - : (&part == (&this->part9)) ? 1 + ((&part == (&this->m->part6)) ? 0 + : (&part == (&this->m->part9)) ? 1 : 9999)); // can't happen - this->c_outline_data.first_object = outlines_og.getObj(); - this->c_outline_data.nobjects = 1; + this->m->c_outline_data.first_object = outlines_og.getObj(); + this->m->c_outline_data.nobjects = 1; lc_outlines.erase(outlines_og); part.push_back(outlines); for (std::set<QPDFObjGen>::iterator iter = lc_outlines.begin(); iter != lc_outlines.end(); ++iter) { part.push_back(objGenToIndirect(*iter)); - ++this->c_outline_data.nobjects; + ++this->m->c_outline_data.nobjects; } } @@ -1843,11 +1847,11 @@ QPDF::getLinearizedParts( std::vector<QPDFObjectHandle>& part9) { calculateLinearizationData(object_stream_data); - part4 = this->part4; - part6 = this->part6; - part7 = this->part7; - part8 = this->part8; - part9 = this->part9; + part4 = this->m->part4; + part6 = this->m->part6; + part7 = this->m->part7; + part8 = this->m->part8; + part9 = this->m->part9; } static inline int nbits(int val) @@ -1889,7 +1893,7 @@ QPDF::calculateHPageOffset( std::vector<QPDFObjectHandle> const& pages = getAllPages(); unsigned int npages = pages.size(); - CHPageOffset& cph = this->c_page_offset_data; + CHPageOffset& cph = this->m->c_page_offset_data; std::vector<CHPageOffsetEntry>& cphe = cph.entries; // Calculate minimum and maximum values for number of objects per @@ -1902,7 +1906,7 @@ QPDF::calculateHPageOffset( int max_length = min_length; int max_shared = cphe.at(0).nshared_objects; - HPageOffset& ph = this->page_offset_hints; + HPageOffset& ph = this->m->page_offset_hints; std::vector<HPageOffsetEntry>& phe = ph.entries; // npages is the size of the existing pages array. phe = std::vector<HPageOffsetEntry>(npages); @@ -1940,7 +1944,7 @@ QPDF::calculateHPageOffset( ph.nbits_delta_page_length = nbits(max_length - min_length); ph.nbits_nshared_objects = nbits(max_shared); ph.nbits_shared_identifier = - nbits(this->c_shared_object_data.nshared_total); + nbits(this->m->c_shared_object_data.nshared_total); ph.shared_denominator = 4; // doesn't matter // It isn't clear how to compute content offset and content @@ -1975,9 +1979,9 @@ QPDF::calculateHSharedObject( std::map<int, qpdf_offset_t> const& lengths, std::map<int, int> const& obj_renumber) { - CHSharedObject& cso = this->c_shared_object_data; + CHSharedObject& cso = this->m->c_shared_object_data; std::vector<CHSharedObjectEntry>& csoe = cso.entries; - HSharedObject& so = this->shared_object_hints; + HSharedObject& so = this->m->shared_object_hints; std::vector<HSharedObjectEntry>& soe = so.entries; soe.clear(); @@ -2026,14 +2030,14 @@ QPDF::calculateHOutline( std::map<int, qpdf_offset_t> const& lengths, std::map<int, int> const& obj_renumber) { - HGeneric& cho = this->c_outline_data; + HGeneric& cho = this->m->c_outline_data; if (cho.nobjects == 0) { return; } - HGeneric& ho = this->outline_hints; + HGeneric& ho = this->m->outline_hints; ho.first_object = (*(obj_renumber.find(cho.first_object))).second; @@ -2083,7 +2087,7 @@ write_vector_vector(BitWriter& w, void QPDF::writeHPageOffset(BitWriter& w) { - HPageOffset& t = this->page_offset_hints; + HPageOffset& t = this->m->page_offset_hints; w.writeBits(t.min_nobjects, 32); // 1 w.writeBits(t.first_page_offset, 32); // 2 @@ -2130,7 +2134,7 @@ QPDF::writeHPageOffset(BitWriter& w) void QPDF::writeHSharedObject(BitWriter& w) { - HSharedObject& t = this->shared_object_hints; + HSharedObject& t = this->m->shared_object_hints; w.writeBits(t.first_shared_obj, 32); // 1 w.writeBits(t.first_shared_offset, 32); // 2 @@ -2193,10 +2197,10 @@ QPDF::generateHintStream(std::map<int, QPDFXRefEntry> const& xref, S = c.getCount(); writeHSharedObject(w); O = 0; - if (this->outline_hints.nobjects > 0) + if (this->m->outline_hints.nobjects > 0) { O = c.getCount(); - writeHGeneric(w, this->outline_hints); + writeHGeneric(w, this->m->outline_hints); } c.finish(); |