2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-06-01 01:40:51 +00:00

In QPDFWriter replace map lenghts with ObjTable new_obj

This commit is contained in:
m-holger 2024-02-27 17:04:44 +00:00
parent ccad589f7d
commit ef3a8025fb
4 changed files with 29 additions and 48 deletions

View File

@ -744,14 +744,13 @@ class QPDF
generateHintStream( generateHintStream(
QPDF& qpdf, QPDF& qpdf,
QPDFWriter::NewObjTable const& new_obj, QPDFWriter::NewObjTable const& new_obj,
std::map<int, qpdf_offset_t> const& lengths,
QPDFWriter::ObjTable const& obj, QPDFWriter::ObjTable const& obj,
std::shared_ptr<Buffer>& hint_stream, std::shared_ptr<Buffer>& hint_stream,
int& S, int& S,
int& O, int& O,
bool compressed) bool compressed)
{ {
return qpdf.generateHintStream(new_obj, lengths, obj, hint_stream, S, O, compressed); return qpdf.generateHintStream(new_obj, obj, hint_stream, S, O, compressed);
} }
static void static void
@ -1103,7 +1102,6 @@ class QPDF
void generateHintStream( void generateHintStream(
QPDFWriter::NewObjTable const& new_obj, QPDFWriter::NewObjTable const& new_obj,
std::map<int, qpdf_offset_t> const& lengths,
QPDFWriter::ObjTable const& obj, QPDFWriter::ObjTable const& obj,
std::shared_ptr<Buffer>& hint_stream, std::shared_ptr<Buffer>& hint_stream,
int& S, int& S,
@ -1378,20 +1376,13 @@ class QPDF
int outputLengthNextN( int outputLengthNextN(
int in_object, int in_object,
int n, int n,
std::map<int, qpdf_offset_t> const& lengths,
QPDFWriter::ObjTable const& obj);
void calculateHPageOffset(
QPDFWriter::NewObjTable const& new_obj, QPDFWriter::NewObjTable const& new_obj,
std::map<int, qpdf_offset_t> const& lengths,
QPDFWriter::ObjTable const& obj);
void calculateHSharedObject(
QPDFWriter::NewObjTable const& new_obj,
std::map<int, qpdf_offset_t> const& lengths,
QPDFWriter::ObjTable const& obj);
void calculateHOutline(
QPDFWriter::NewObjTable const& new_obj,
std::map<int, qpdf_offset_t> const& lengths,
QPDFWriter::ObjTable const& obj); QPDFWriter::ObjTable const& obj);
void
calculateHPageOffset(QPDFWriter::NewObjTable const& new_obj, QPDFWriter::ObjTable const& obj);
void
calculateHSharedObject(QPDFWriter::NewObjTable const& new_obj, QPDFWriter::ObjTable const& obj);
void calculateHOutline(QPDFWriter::NewObjTable const& new_obj, QPDFWriter::ObjTable const& obj);
void writeHPageOffset(BitWriter&); void writeHPageOffset(BitWriter&);
void writeHSharedObject(BitWriter&); void writeHSharedObject(BitWriter&);
void writeHGeneric(BitWriter&, HGeneric&); void writeHGeneric(BitWriter&, HGeneric&);

View File

@ -1050,7 +1050,8 @@ QPDFWriter::closeObject(int objid)
// Write a newline before endobj as it makes the file easier to repair. // Write a newline before endobj as it makes the file easier to repair.
writeString("\nendobj\n"); writeString("\nendobj\n");
writeStringQDF("\n"); writeStringQDF("\n");
m->lengths[objid] = m->pipeline->getCount() - m->new_obj[objid].xref.getOffset(); auto& new_obj = m->new_obj[objid];
new_obj.length = m->pipeline->getCount() - new_obj.xref.getOffset();
} }
void void
@ -2309,8 +2310,7 @@ QPDFWriter::writeHintStream(int hint_id)
int S = 0; int S = 0;
int O = 0; int O = 0;
bool compressed = (m->compress_streams && !m->qdf_mode); bool compressed = (m->compress_streams && !m->qdf_mode);
QPDF::Writer::generateHintStream( QPDF::Writer::generateHintStream(m->pdf, m->new_obj, m->obj, hint_buffer, S, O, compressed);
m->pdf, m->new_obj, m->lengths, m->obj, hint_buffer, S, O, compressed);
openObject(hint_id); openObject(hint_id);
setDataKey(hint_id); setDataKey(hint_id);

View File

@ -1457,33 +1457,29 @@ nbits(int val)
int int
QPDF::outputLengthNextN( QPDF::outputLengthNextN(
int in_object, int in_object, int n, QPDFWriter::NewObjTable const& new_obj, QPDFWriter::ObjTable const& obj)
int n,
std::map<int, qpdf_offset_t> const& lengths,
QPDFWriter::ObjTable const& obj)
{ {
// Figure out the length of a series of n consecutive objects in the output file starting with // Figure out the length of a series of n consecutive objects in the output file starting with
// whatever object in_object from the input file mapped to. // whatever object in_object from the input file mapped to.
int first = obj[in_object].renumber; int first = obj[in_object].renumber;
int last = first + n;
if (first <= 0) { if (first <= 0) {
stopOnError("found object that is not renumbered while writing linearization data"); stopOnError("found object that is not renumbered while writing linearization data");
} }
int length = 0; qpdf_offset_t length = 0;
for (int i = 0; i < n; ++i) { for (int i = first; i < last; ++i) {
if (lengths.count(first + i) == 0) { auto l = new_obj[i].length;
if (l == 0) {
stopOnError("found item with unknown length while writing linearization data"); stopOnError("found item with unknown length while writing linearization data");
} }
length += toI((*(lengths.find(first + toI(i)))).second); length += l;
} }
return length; return toI(length);
} }
void void
QPDF::calculateHPageOffset( QPDF::calculateHPageOffset(QPDFWriter::NewObjTable const& new_obj, QPDFWriter::ObjTable const& obj)
QPDFWriter::NewObjTable const& new_obj,
std::map<int, qpdf_offset_t> const& lengths,
QPDFWriter::ObjTable const& obj)
{ {
// Page Offset Hint Table // Page Offset Hint Table
@ -1498,7 +1494,7 @@ QPDF::calculateHPageOffset(
int min_nobjects = cphe.at(0).nobjects; int min_nobjects = cphe.at(0).nobjects;
int max_nobjects = min_nobjects; int max_nobjects = min_nobjects;
int min_length = outputLengthNextN(pages.at(0).getObjectID(), min_nobjects, lengths, obj); int min_length = outputLengthNextN(pages.at(0).getObjectID(), min_nobjects, new_obj, obj);
int max_length = min_length; int max_length = min_length;
int max_shared = cphe.at(0).nshared_objects; int max_shared = cphe.at(0).nshared_objects;
@ -1515,7 +1511,7 @@ QPDF::calculateHPageOffset(
// assignments. // assignments.
int nobjects = cphe.at(i).nobjects; int nobjects = cphe.at(i).nobjects;
int length = outputLengthNextN(pages.at(i).getObjectID(), nobjects, lengths, obj); int length = outputLengthNextN(pages.at(i).getObjectID(), nobjects, new_obj, obj);
int nshared = cphe.at(i).nshared_objects; int nshared = cphe.at(i).nshared_objects;
min_nobjects = std::min(min_nobjects, nobjects); min_nobjects = std::min(min_nobjects, nobjects);
@ -1565,9 +1561,7 @@ QPDF::calculateHPageOffset(
void void
QPDF::calculateHSharedObject( QPDF::calculateHSharedObject(
QPDFWriter::NewObjTable const& new_obj, QPDFWriter::NewObjTable const& new_obj, QPDFWriter::ObjTable const& obj)
std::map<int, qpdf_offset_t> const& lengths,
QPDFWriter::ObjTable const& obj)
{ {
CHSharedObject& cso = m->c_shared_object_data; CHSharedObject& cso = m->c_shared_object_data;
std::vector<CHSharedObjectEntry>& csoe = cso.entries; std::vector<CHSharedObjectEntry>& csoe = cso.entries;
@ -1575,12 +1569,12 @@ QPDF::calculateHSharedObject(
std::vector<HSharedObjectEntry>& soe = so.entries; std::vector<HSharedObjectEntry>& soe = so.entries;
soe.clear(); soe.clear();
int min_length = outputLengthNextN(csoe.at(0).object, 1, lengths, obj); int min_length = outputLengthNextN(csoe.at(0).object, 1, new_obj, obj);
int max_length = min_length; int max_length = min_length;
for (size_t i = 0; i < toS(cso.nshared_total); ++i) { for (size_t i = 0; i < toS(cso.nshared_total); ++i) {
// Assign absolute numbers to deltas; adjust later // Assign absolute numbers to deltas; adjust later
int length = outputLengthNextN(csoe.at(i).object, 1, lengths, obj); int length = outputLengthNextN(csoe.at(i).object, 1, new_obj, obj);
min_length = std::min(min_length, length); min_length = std::min(min_length, length);
max_length = std::max(max_length, length); max_length = std::max(max_length, length);
soe.emplace_back(); soe.emplace_back();
@ -1610,10 +1604,7 @@ QPDF::calculateHSharedObject(
} }
void void
QPDF::calculateHOutline( QPDF::calculateHOutline(QPDFWriter::NewObjTable const& new_obj, QPDFWriter::ObjTable const& obj)
QPDFWriter::NewObjTable const& new_obj,
std::map<int, qpdf_offset_t> const& lengths,
QPDFWriter::ObjTable const& obj)
{ {
HGeneric& cho = m->c_outline_data; HGeneric& cho = m->c_outline_data;
@ -1626,7 +1617,7 @@ QPDF::calculateHOutline(
ho.first_object = obj[cho.first_object].renumber; ho.first_object = obj[cho.first_object].renumber;
ho.first_object_offset = new_obj[ho.first_object].xref.getOffset(); ho.first_object_offset = new_obj[ho.first_object].xref.getOffset();
ho.nobjects = cho.nobjects; ho.nobjects = cho.nobjects;
ho.group_length = outputLengthNextN(cho.first_object, ho.nobjects, lengths, obj); ho.group_length = outputLengthNextN(cho.first_object, ho.nobjects, new_obj, obj);
} }
template <class T, class int_type> template <class T, class int_type>
@ -1756,7 +1747,6 @@ QPDF::writeHGeneric(BitWriter& w, HGeneric& t)
void void
QPDF::generateHintStream( QPDF::generateHintStream(
QPDFWriter::NewObjTable const& new_obj, QPDFWriter::NewObjTable const& new_obj,
std::map<int, qpdf_offset_t> const& lengths,
QPDFWriter::ObjTable const& obj, QPDFWriter::ObjTable const& obj,
std::shared_ptr<Buffer>& hint_buffer, std::shared_ptr<Buffer>& hint_buffer,
int& S, int& S,
@ -1764,9 +1754,9 @@ QPDF::generateHintStream(
bool compressed) bool compressed)
{ {
// Populate actual hint table values // Populate actual hint table values
calculateHPageOffset(new_obj, lengths, obj); calculateHPageOffset(new_obj, obj);
calculateHSharedObject(new_obj, lengths, obj); calculateHSharedObject(new_obj, obj);
calculateHOutline(new_obj, lengths, obj); calculateHOutline(new_obj, obj);
// Write the hint stream itself into a compressed memory buffer. Write through a counter so we // Write the hint stream itself into a compressed memory buffer. Write through a counter so we
// can get offsets. // can get offsets.

View File

@ -18,6 +18,7 @@ struct QPDFWriter::Object
struct QPDFWriter::NewObject struct QPDFWriter::NewObject
{ {
QPDFXRefEntry xref; QPDFXRefEntry xref;
qpdf_offset_t length{0};
}; };
class QPDFWriter::ObjTable: public ::ObjTable<QPDFWriter::Object> class QPDFWriter::ObjTable: public ::ObjTable<QPDFWriter::Object>
@ -102,7 +103,6 @@ class QPDFWriter::Members
size_t object_queue_front{0}; size_t object_queue_front{0};
QPDFWriter::ObjTable obj; QPDFWriter::ObjTable obj;
QPDFWriter::NewObjTable new_obj; QPDFWriter::NewObjTable new_obj;
std::map<int, qpdf_offset_t> lengths;
int next_objid{1}; int next_objid{1};
int cur_stream_length_id{0}; int cur_stream_length_id{0};
size_t cur_stream_length{0}; size_t cur_stream_length{0};