mirror of
https://github.com/qpdf/qpdf.git
synced 2024-06-05 11:50:53 +00:00
Add QPDFWriter::getFinalVersion (fixes #266)
This commit is contained in:
parent
837dcf8fc2
commit
16fd6e64f9
|
@ -1,5 +1,10 @@
|
||||||
2019-01-04 Jay Berkenbilt <ejb@ql.org>
|
2019-01-04 Jay Berkenbilt <ejb@ql.org>
|
||||||
|
|
||||||
|
* Add new method QPDFWriter::getFinalVersion, which returns the
|
||||||
|
PDF version that will ultimately be written to the final file. See
|
||||||
|
comments in QPDFWriter.hh for some restrictions on its use. Fixes
|
||||||
|
#266.
|
||||||
|
|
||||||
* When unexpected errors are found while checking linearization
|
* When unexpected errors are found while checking linearization
|
||||||
data, print an error message instead of calling assert, which
|
data, print an error message instead of calling assert, which
|
||||||
cause the program to crash. Fixes #209, #231.
|
cause the program to crash. Fixes #209, #231.
|
||||||
|
|
|
@ -404,6 +404,18 @@ class QPDFWriter
|
||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
void registerProgressReporter(PointerHolder<ProgressReporter>);
|
void registerProgressReporter(PointerHolder<ProgressReporter>);
|
||||||
|
|
||||||
|
// Return the PDF version that will be written into the header.
|
||||||
|
// Calling this method does all the preparation for writing, so it
|
||||||
|
// is an error to call any methods that may cause a change to the
|
||||||
|
// version. Adding new objects to the original file after calling
|
||||||
|
// this may also cause problems. It is safe to update existing
|
||||||
|
// objects or stream contents after calling this method, e.g., to
|
||||||
|
// include the final version number in metadata.
|
||||||
|
QPDF_DLL
|
||||||
|
std::string getFinalVersion();
|
||||||
|
|
||||||
|
// Write the final file. There is no expectation of being able to
|
||||||
|
// call write() more than once.
|
||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
void write();
|
void write();
|
||||||
|
|
||||||
|
@ -473,6 +485,7 @@ class QPDFWriter
|
||||||
void writeLinearized();
|
void writeLinearized();
|
||||||
void enqueuePart(std::vector<QPDFObjectHandle>& part);
|
void enqueuePart(std::vector<QPDFObjectHandle>& part);
|
||||||
void writeEncryptionDictionary();
|
void writeEncryptionDictionary();
|
||||||
|
void doWriteSetup();
|
||||||
void writeHeader();
|
void writeHeader();
|
||||||
void writeHintStream(int hint_id);
|
void writeHintStream(int hint_id);
|
||||||
qpdf_offset_t writeXRefTable(
|
qpdf_offset_t writeXRefTable(
|
||||||
|
@ -598,6 +611,7 @@ class QPDFWriter
|
||||||
bool deterministic_id;
|
bool deterministic_id;
|
||||||
Pl_MD5* md5_pipeline;
|
Pl_MD5* md5_pipeline;
|
||||||
std::string deterministic_id_data;
|
std::string deterministic_id_data;
|
||||||
|
bool did_write_setup;
|
||||||
|
|
||||||
// For linearization only
|
// For linearization only
|
||||||
std::string lin_pass1_filename;
|
std::string lin_pass1_filename;
|
||||||
|
|
|
@ -63,6 +63,7 @@ QPDFWriter::Members::Members(QPDF& pdf) :
|
||||||
max_ostream_index(0),
|
max_ostream_index(0),
|
||||||
deterministic_id(false),
|
deterministic_id(false),
|
||||||
md5_pipeline(0),
|
md5_pipeline(0),
|
||||||
|
did_write_setup(false),
|
||||||
events_expected(0),
|
events_expected(0),
|
||||||
events_seen(0),
|
events_seen(0),
|
||||||
next_progress_report(0)
|
next_progress_report(0)
|
||||||
|
@ -2358,8 +2359,14 @@ QPDFWriter::prepareFileForWrite()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
QPDFWriter::write()
|
QPDFWriter::doWriteSetup()
|
||||||
{
|
{
|
||||||
|
if (this->m->did_write_setup)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->m->did_write_setup = true;
|
||||||
|
|
||||||
// Do preliminary setup
|
// Do preliminary setup
|
||||||
|
|
||||||
if (this->m->linearized)
|
if (this->m->linearized)
|
||||||
|
@ -2507,6 +2514,23 @@ QPDFWriter::write()
|
||||||
setMinimumPDFVersion("1.5");
|
setMinimumPDFVersion("1.5");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setMinimumPDFVersion(this->m->pdf.getPDFVersion(),
|
||||||
|
this->m->pdf.getExtensionLevel());
|
||||||
|
this->m->final_pdf_version = this->m->min_pdf_version;
|
||||||
|
this->m->final_extension_level = this->m->min_extension_level;
|
||||||
|
if (! this->m->forced_pdf_version.empty())
|
||||||
|
{
|
||||||
|
QTC::TC("qpdf", "QPDFWriter using forced PDF version");
|
||||||
|
this->m->final_pdf_version = this->m->forced_pdf_version;
|
||||||
|
this->m->final_extension_level = this->m->forced_extension_level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QPDFWriter::write()
|
||||||
|
{
|
||||||
|
doWriteSetup();
|
||||||
|
|
||||||
// Set up progress reporting. We spent about equal amounts of time
|
// Set up progress reporting. We spent about equal amounts of time
|
||||||
// preparing and writing one pass. To get a rough estimate of
|
// preparing and writing one pass. To get a rough estimate of
|
||||||
// progress, we track handling of indirect objects. For linearized
|
// progress, we track handling of indirect objects. For linearized
|
||||||
|
@ -2569,20 +2593,16 @@ QPDFWriter::writeEncryptionDictionary()
|
||||||
closeObject(this->m->encryption_dict_objid);
|
closeObject(this->m->encryption_dict_objid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
QPDFWriter::getFinalVersion()
|
||||||
|
{
|
||||||
|
doWriteSetup();
|
||||||
|
return this->m->final_pdf_version;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
QPDFWriter::writeHeader()
|
QPDFWriter::writeHeader()
|
||||||
{
|
{
|
||||||
setMinimumPDFVersion(this->m->pdf.getPDFVersion(),
|
|
||||||
this->m->pdf.getExtensionLevel());
|
|
||||||
this->m->final_pdf_version = this->m->min_pdf_version;
|
|
||||||
this->m->final_extension_level = this->m->min_extension_level;
|
|
||||||
if (! this->m->forced_pdf_version.empty())
|
|
||||||
{
|
|
||||||
QTC::TC("qpdf", "QPDFWriter using forced PDF version");
|
|
||||||
this->m->final_pdf_version = this->m->forced_pdf_version;
|
|
||||||
this->m->final_extension_level = this->m->forced_extension_level;
|
|
||||||
}
|
|
||||||
|
|
||||||
writeString("%PDF-");
|
writeString("%PDF-");
|
||||||
writeString(this->m->final_pdf_version);
|
writeString(this->m->final_pdf_version);
|
||||||
if (this->m->pclm)
|
if (this->m->pclm)
|
||||||
|
|
|
@ -173,6 +173,16 @@ $td->runtest("\@file exists and file doesn't",
|
||||||
{$td->FILE => "check-at-file.out", $td->EXIT_STATUS => 0},
|
{$td->FILE => "check-at-file.out", $td->EXIT_STATUS => 0},
|
||||||
$td->NORMALIZE_NEWLINES);
|
$td->NORMALIZE_NEWLINES);
|
||||||
|
|
||||||
|
show_ntests();
|
||||||
|
# ----------
|
||||||
|
$td->notify("--- Final Version ---");
|
||||||
|
$n_tests += 1;
|
||||||
|
|
||||||
|
$td->runtest("check final version",
|
||||||
|
{$td->COMMAND => "test_driver 54 minimal.pdf"},
|
||||||
|
{$td->STRING => "test 54 done\n", $td->EXIT_STATUS => 0},
|
||||||
|
$td->NORMALIZE_NEWLINES);
|
||||||
|
|
||||||
show_ntests();
|
show_ntests();
|
||||||
# ----------
|
# ----------
|
||||||
$td->notify("--- Dangling Refs ---");
|
$td->notify("--- Dangling Refs ---");
|
||||||
|
|
|
@ -1865,6 +1865,18 @@ void runtest(int n, char const* filename1, char const* arg2)
|
||||||
w.setStaticID(true);
|
w.setStaticID(true);
|
||||||
w.write();
|
w.write();
|
||||||
}
|
}
|
||||||
|
else if (n == 54)
|
||||||
|
{
|
||||||
|
// Test getFinalVersion. This must be invoked with a file
|
||||||
|
// whose final version is not 1.5.
|
||||||
|
QPDFWriter w(pdf, "a.pdf");
|
||||||
|
assert(pdf.getPDFVersion() != "1.5");
|
||||||
|
w.setObjectStreamMode(qpdf_o_generate);
|
||||||
|
if (w.getFinalVersion() != "1.5")
|
||||||
|
{
|
||||||
|
std::cout << "oops: " << w.getFinalVersion() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw std::runtime_error(std::string("invalid test ") +
|
throw std::runtime_error(std::string("invalid test ") +
|
||||||
|
|
Loading…
Reference in New Issue
Block a user