mirror of
https://github.com/qpdf/qpdf.git
synced 2024-10-31 19:02:30 +00:00
In QPDFWriter replace map obj_renumber_no_gen with ObjTable obj
This commit is contained in:
parent
8791b5f8d0
commit
84e25919cb
@ -41,6 +41,7 @@
|
|||||||
#include <qpdf/QPDFObjectHandle.hh>
|
#include <qpdf/QPDFObjectHandle.hh>
|
||||||
#include <qpdf/QPDFStreamFilter.hh>
|
#include <qpdf/QPDFStreamFilter.hh>
|
||||||
#include <qpdf/QPDFTokenizer.hh>
|
#include <qpdf/QPDFTokenizer.hh>
|
||||||
|
#include <qpdf/QPDFWriter.hh>
|
||||||
#include <qpdf/QPDFXRefEntry.hh>
|
#include <qpdf/QPDFXRefEntry.hh>
|
||||||
|
|
||||||
class QPDF_Stream;
|
class QPDF_Stream;
|
||||||
@ -744,14 +745,13 @@ class QPDF
|
|||||||
QPDF& qpdf,
|
QPDF& qpdf,
|
||||||
std::map<int, QPDFXRefEntry> const& xref,
|
std::map<int, QPDFXRefEntry> const& xref,
|
||||||
std::map<int, qpdf_offset_t> const& lengths,
|
std::map<int, qpdf_offset_t> const& lengths,
|
||||||
std::map<int, int> const& obj_renumber,
|
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(
|
return qpdf.generateHintStream(xref, lengths, obj, hint_stream, S, O, compressed);
|
||||||
xref, lengths, obj_renumber, hint_stream, S, O, compressed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1104,7 +1104,7 @@ class QPDF
|
|||||||
void generateHintStream(
|
void generateHintStream(
|
||||||
std::map<int, QPDFXRefEntry> const& xref,
|
std::map<int, QPDFXRefEntry> const& xref,
|
||||||
std::map<int, qpdf_offset_t> const& lengths,
|
std::map<int, qpdf_offset_t> const& lengths,
|
||||||
std::map<int, int> const& obj_renumber,
|
QPDFWriter::ObjTable const& obj,
|
||||||
std::shared_ptr<Buffer>& hint_stream,
|
std::shared_ptr<Buffer>& hint_stream,
|
||||||
int& S,
|
int& S,
|
||||||
int& O,
|
int& O,
|
||||||
@ -1379,19 +1379,19 @@ class QPDF
|
|||||||
int in_object,
|
int in_object,
|
||||||
int n,
|
int n,
|
||||||
std::map<int, qpdf_offset_t> const& lengths,
|
std::map<int, qpdf_offset_t> const& lengths,
|
||||||
std::map<int, int> const& obj_renumber);
|
QPDFWriter::ObjTable const& obj);
|
||||||
void calculateHPageOffset(
|
void calculateHPageOffset(
|
||||||
std::map<int, QPDFXRefEntry> const& xref,
|
std::map<int, QPDFXRefEntry> const& xref,
|
||||||
std::map<int, qpdf_offset_t> const& lengths,
|
std::map<int, qpdf_offset_t> const& lengths,
|
||||||
std::map<int, int> const& obj_renumber);
|
QPDFWriter::ObjTable const& obj);
|
||||||
void calculateHSharedObject(
|
void calculateHSharedObject(
|
||||||
std::map<int, QPDFXRefEntry> const& xref,
|
std::map<int, QPDFXRefEntry> const& xref,
|
||||||
std::map<int, qpdf_offset_t> const& lengths,
|
std::map<int, qpdf_offset_t> const& lengths,
|
||||||
std::map<int, int> const& obj_renumber);
|
QPDFWriter::ObjTable const& obj);
|
||||||
void calculateHOutline(
|
void calculateHOutline(
|
||||||
std::map<int, QPDFXRefEntry> const& xref,
|
std::map<int, QPDFXRefEntry> const& xref,
|
||||||
std::map<int, qpdf_offset_t> const& lengths,
|
std::map<int, qpdf_offset_t> const& lengths,
|
||||||
std::map<int, int> const& obj_renumber);
|
QPDFWriter::ObjTable const& obj);
|
||||||
void writeHPageOffset(BitWriter&);
|
void writeHPageOffset(BitWriter&);
|
||||||
void writeHSharedObject(BitWriter&);
|
void writeHSharedObject(BitWriter&);
|
||||||
void writeHGeneric(BitWriter&, HGeneric&);
|
void writeHGeneric(BitWriter&, HGeneric&);
|
||||||
|
@ -610,7 +610,6 @@ class QPDFWriter
|
|||||||
void computeDeterministicIDData();
|
void computeDeterministicIDData();
|
||||||
|
|
||||||
void discardGeneration(std::map<QPDFObjGen, int> const& in, std::map<int, int>& out);
|
void discardGeneration(std::map<QPDFObjGen, int> const& in, std::map<int, int>& out);
|
||||||
void discardGeneration(std::map<int, int>& out);
|
|
||||||
|
|
||||||
class Members;
|
class Members;
|
||||||
|
|
||||||
|
@ -2303,7 +2303,7 @@ QPDFWriter::writeHintStream(int hint_id)
|
|||||||
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->xref, m->lengths, m->obj_renumber_no_gen, hint_buffer, S, O, compressed);
|
m->pdf, m->xref, m->lengths, m->obj, hint_buffer, S, O, compressed);
|
||||||
|
|
||||||
openObject(hint_id);
|
openObject(hint_id);
|
||||||
setDataKey(hint_id);
|
setDataKey(hint_id);
|
||||||
@ -2545,26 +2545,6 @@ QPDFWriter::discardGeneration(std::map<QPDFObjGen, int> const& in, std::map<int,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
QPDFWriter::discardGeneration(std::map<int, int>& out)
|
|
||||||
{
|
|
||||||
// There are deep assumptions in the linearization code in QPDF that there is only one object
|
|
||||||
// with each object number; i.e., you can't have two objects with the same object number and
|
|
||||||
// different generations. This is a pretty safe assumption because Adobe Reader and Acrobat
|
|
||||||
// can't actually handle this case. There is not much if any code in QPDF outside linearization
|
|
||||||
// that assumes this, but the linearization code as currently implemented would do weird things
|
|
||||||
// if we found such a case. In order to avoid breaking ABI changes in QPDF, we will first
|
|
||||||
// assert that this condition holds. Then we can create new maps for QPDF that throw away
|
|
||||||
// generation numbers.
|
|
||||||
|
|
||||||
out.clear();
|
|
||||||
m->obj.forEach([&out](auto id, auto const& item) -> void {
|
|
||||||
if (item.renumber > 0) {
|
|
||||||
out[id] = item.renumber;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
QPDFWriter::writeLinearized()
|
QPDFWriter::writeLinearized()
|
||||||
{
|
{
|
||||||
@ -2887,8 +2867,6 @@ QPDFWriter::writeLinearized()
|
|||||||
writeString(std::to_string(first_xref_offset));
|
writeString(std::to_string(first_xref_offset));
|
||||||
writeString("\n%%EOF\n");
|
writeString("\n%%EOF\n");
|
||||||
|
|
||||||
discardGeneration(m->obj_renumber_no_gen);
|
|
||||||
|
|
||||||
if (pass == 1) {
|
if (pass == 1) {
|
||||||
if (m->deterministic_id) {
|
if (m->deterministic_id) {
|
||||||
QTC::TC("qpdf", "QPDFWriter linearized deterministic ID", need_xref_stream ? 0 : 1);
|
QTC::TC("qpdf", "QPDFWriter linearized deterministic ID", need_xref_stream ? 0 : 1);
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <qpdf/Pl_Flate.hh>
|
#include <qpdf/Pl_Flate.hh>
|
||||||
#include <qpdf/QPDFExc.hh>
|
#include <qpdf/QPDFExc.hh>
|
||||||
#include <qpdf/QPDFLogger.hh>
|
#include <qpdf/QPDFLogger.hh>
|
||||||
|
#include <qpdf/QPDFWriter_private.hh>
|
||||||
#include <qpdf/QTC.hh>
|
#include <qpdf/QTC.hh>
|
||||||
#include <qpdf/QUtil.hh>
|
#include <qpdf/QUtil.hh>
|
||||||
|
|
||||||
@ -1459,15 +1460,15 @@ QPDF::outputLengthNextN(
|
|||||||
int in_object,
|
int in_object,
|
||||||
int n,
|
int n,
|
||||||
std::map<int, qpdf_offset_t> const& lengths,
|
std::map<int, qpdf_offset_t> const& lengths,
|
||||||
std::map<int, int> const& obj_renumber)
|
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.
|
||||||
|
|
||||||
if (obj_renumber.count(in_object) == 0) {
|
int first = obj[in_object].renumber;
|
||||||
|
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 first = (*(obj_renumber.find(in_object))).second;
|
|
||||||
int length = 0;
|
int length = 0;
|
||||||
for (int i = 0; i < n; ++i) {
|
for (int i = 0; i < n; ++i) {
|
||||||
if (lengths.count(first + i) == 0) {
|
if (lengths.count(first + i) == 0) {
|
||||||
@ -1482,7 +1483,7 @@ void
|
|||||||
QPDF::calculateHPageOffset(
|
QPDF::calculateHPageOffset(
|
||||||
std::map<int, QPDFXRefEntry> const& xref,
|
std::map<int, QPDFXRefEntry> const& xref,
|
||||||
std::map<int, qpdf_offset_t> const& lengths,
|
std::map<int, qpdf_offset_t> const& lengths,
|
||||||
std::map<int, int> const& obj_renumber)
|
QPDFWriter::ObjTable const& obj)
|
||||||
{
|
{
|
||||||
// Page Offset Hint Table
|
// Page Offset Hint Table
|
||||||
|
|
||||||
@ -1497,8 +1498,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 =
|
int min_length = outputLengthNextN(pages.at(0).getObjectID(), min_nobjects, lengths, obj);
|
||||||
outputLengthNextN(pages.at(0).getObjectID(), min_nobjects, lengths, obj_renumber);
|
|
||||||
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 +1515,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_renumber);
|
int length = outputLengthNextN(pages.at(i).getObjectID(), nobjects, lengths, 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);
|
||||||
@ -1530,8 +1530,7 @@ QPDF::calculateHPageOffset(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ph.min_nobjects = min_nobjects;
|
ph.min_nobjects = min_nobjects;
|
||||||
int in_page0_id = pages.at(0).getObjectID();
|
int out_page0_id = obj[pages.at(0)].renumber;
|
||||||
int out_page0_id = (*(obj_renumber.find(in_page0_id))).second;
|
|
||||||
ph.first_page_offset = (*(xref.find(out_page0_id))).second.getOffset();
|
ph.first_page_offset = (*(xref.find(out_page0_id))).second.getOffset();
|
||||||
ph.nbits_delta_nobjects = nbits(max_nobjects - min_nobjects);
|
ph.nbits_delta_nobjects = nbits(max_nobjects - min_nobjects);
|
||||||
ph.min_page_length = min_length;
|
ph.min_page_length = min_length;
|
||||||
@ -1569,7 +1568,7 @@ void
|
|||||||
QPDF::calculateHSharedObject(
|
QPDF::calculateHSharedObject(
|
||||||
std::map<int, QPDFXRefEntry> const& xref,
|
std::map<int, QPDFXRefEntry> const& xref,
|
||||||
std::map<int, qpdf_offset_t> const& lengths,
|
std::map<int, qpdf_offset_t> const& lengths,
|
||||||
std::map<int, int> const& obj_renumber)
|
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;
|
||||||
@ -1577,12 +1576,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_renumber);
|
int min_length = outputLengthNextN(csoe.at(0).object, 1, lengths, 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_renumber);
|
int length = outputLengthNextN(csoe.at(i).object, 1, lengths, 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();
|
||||||
@ -1595,7 +1594,7 @@ QPDF::calculateHSharedObject(
|
|||||||
so.nshared_total = cso.nshared_total;
|
so.nshared_total = cso.nshared_total;
|
||||||
so.nshared_first_page = cso.nshared_first_page;
|
so.nshared_first_page = cso.nshared_first_page;
|
||||||
if (so.nshared_total > so.nshared_first_page) {
|
if (so.nshared_total > so.nshared_first_page) {
|
||||||
so.first_shared_obj = (*(obj_renumber.find(cso.first_shared_obj))).second;
|
so.first_shared_obj = obj[cso.first_shared_obj].renumber;
|
||||||
so.first_shared_offset = (*(xref.find(so.first_shared_obj))).second.getOffset();
|
so.first_shared_offset = (*(xref.find(so.first_shared_obj))).second.getOffset();
|
||||||
}
|
}
|
||||||
so.min_group_length = min_length;
|
so.min_group_length = min_length;
|
||||||
@ -1614,7 +1613,7 @@ void
|
|||||||
QPDF::calculateHOutline(
|
QPDF::calculateHOutline(
|
||||||
std::map<int, QPDFXRefEntry> const& xref,
|
std::map<int, QPDFXRefEntry> const& xref,
|
||||||
std::map<int, qpdf_offset_t> const& lengths,
|
std::map<int, qpdf_offset_t> const& lengths,
|
||||||
std::map<int, int> const& obj_renumber)
|
QPDFWriter::ObjTable const& obj)
|
||||||
{
|
{
|
||||||
HGeneric& cho = m->c_outline_data;
|
HGeneric& cho = m->c_outline_data;
|
||||||
|
|
||||||
@ -1624,10 +1623,10 @@ QPDF::calculateHOutline(
|
|||||||
|
|
||||||
HGeneric& ho = m->outline_hints;
|
HGeneric& ho = m->outline_hints;
|
||||||
|
|
||||||
ho.first_object = (*(obj_renumber.find(cho.first_object))).second;
|
ho.first_object = obj[cho.first_object].renumber;
|
||||||
ho.first_object_offset = (*(xref.find(ho.first_object))).second.getOffset();
|
ho.first_object_offset = (*(xref.find(ho.first_object))).second.getOffset();
|
||||||
ho.nobjects = cho.nobjects;
|
ho.nobjects = cho.nobjects;
|
||||||
ho.group_length = outputLengthNextN(cho.first_object, ho.nobjects, lengths, obj_renumber);
|
ho.group_length = outputLengthNextN(cho.first_object, ho.nobjects, lengths, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class int_type>
|
template <class T, class int_type>
|
||||||
@ -1758,16 +1757,16 @@ void
|
|||||||
QPDF::generateHintStream(
|
QPDF::generateHintStream(
|
||||||
std::map<int, QPDFXRefEntry> const& xref,
|
std::map<int, QPDFXRefEntry> const& xref,
|
||||||
std::map<int, qpdf_offset_t> const& lengths,
|
std::map<int, qpdf_offset_t> const& lengths,
|
||||||
std::map<int, int> const& obj_renumber,
|
QPDFWriter::ObjTable const& obj,
|
||||||
std::shared_ptr<Buffer>& hint_buffer,
|
std::shared_ptr<Buffer>& hint_buffer,
|
||||||
int& S,
|
int& S,
|
||||||
int& O,
|
int& O,
|
||||||
bool compressed)
|
bool compressed)
|
||||||
{
|
{
|
||||||
// Populate actual hint table values
|
// Populate actual hint table values
|
||||||
calculateHPageOffset(xref, lengths, obj_renumber);
|
calculateHPageOffset(xref, lengths, obj);
|
||||||
calculateHSharedObject(xref, lengths, obj_renumber);
|
calculateHSharedObject(xref, lengths, obj);
|
||||||
calculateHOutline(xref, lengths, obj_renumber);
|
calculateHOutline(xref, lengths, 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.
|
||||||
|
@ -99,7 +99,6 @@ class QPDFWriter::Members
|
|||||||
|
|
||||||
// For linearization only
|
// For linearization only
|
||||||
std::string lin_pass1_filename;
|
std::string lin_pass1_filename;
|
||||||
std::map<int, int> obj_renumber_no_gen;
|
|
||||||
std::map<int, int> object_to_object_stream_no_gen;
|
std::map<int, int> object_to_object_stream_no_gen;
|
||||||
|
|
||||||
// For progress reporting
|
// For progress reporting
|
||||||
|
Loading…
Reference in New Issue
Block a user