mirror of
https://github.com/qpdf/qpdf.git
synced 2025-01-02 22:50:20 +00:00
Implement changes suggested by Zarko and our subsequent conversations:
- Add a way to set the minimum PDF version - Add a way to force the PDF version - Have isEncrypted return true if an /Encrypt dictionary exists even when we can't read the file - Allow qpdf_init_write to be called multiple times - Update some comments in headers git-svn-id: svn+q:///qpdf/trunk@748 71b93d88-0707-0410-a8cf-f5a4172ac649
This commit is contained in:
parent
c1e53f1480
commit
c2023db265
@ -1,5 +1,9 @@
|
|||||||
2009-10-04 Jay Berkenbilt <ejb@ql.org>
|
2009-10-04 Jay Berkenbilt <ejb@ql.org>
|
||||||
|
|
||||||
|
* Add methods to QPDFWriter and corresponding command line
|
||||||
|
arguments to qpdf to set the minimum output PDF version and also
|
||||||
|
to force the version to a particular value.
|
||||||
|
|
||||||
* libqpdf/QPDF.cc (processXRefStream): warn and ignore extra xref
|
* libqpdf/QPDF.cc (processXRefStream): warn and ignore extra xref
|
||||||
stream entries when stream is larger than reported size. This
|
stream entries when stream is larger than reported size. This
|
||||||
used to be a fatal error. (Fixes qpdf-Bugs-2872265.)
|
used to be a fatal error. (Fixes qpdf-Bugs-2872265.)
|
||||||
|
12
TODO
12
TODO
@ -1,15 +1,3 @@
|
|||||||
Now
|
|
||||||
===
|
|
||||||
|
|
||||||
* Add functions to set minimum version and to force pdf version
|
|
||||||
|
|
||||||
* Make multiple calls to init_write safe; document that write
|
|
||||||
parameter settings must be repeated
|
|
||||||
|
|
||||||
* qpdf_is_encrypted returns false for encrypted file when incorrect
|
|
||||||
password is given
|
|
||||||
|
|
||||||
|
|
||||||
2.1
|
2.1
|
||||||
===
|
===
|
||||||
|
|
||||||
|
@ -34,7 +34,13 @@ class Pl_Count;
|
|||||||
class QPDFWriter
|
class QPDFWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Passing null as filename means write to stdout
|
// Passing null as filename means write to stdout. QPDFWriter
|
||||||
|
// will create a zero-length output file upon construction. If
|
||||||
|
// write fails, the empty or partially written file will not be
|
||||||
|
// deleted. This is by design: sometimes the partial file may be
|
||||||
|
// useful for tracking down problems. If your application doesn't
|
||||||
|
// want the partially written file to be left behind, you should
|
||||||
|
// delete it the eventual call to write fails.
|
||||||
DLL_EXPORT
|
DLL_EXPORT
|
||||||
QPDFWriter(QPDF& pdf, char const* filename);
|
QPDFWriter(QPDF& pdf, char const* filename);
|
||||||
DLL_EXPORT
|
DLL_EXPORT
|
||||||
@ -78,6 +84,30 @@ class QPDFWriter
|
|||||||
DLL_EXPORT
|
DLL_EXPORT
|
||||||
void setQDFMode(bool);
|
void setQDFMode(bool);
|
||||||
|
|
||||||
|
// Set the minimum PDF version. If the PDF version of the input
|
||||||
|
// file (or previously set minimum version) is less than the
|
||||||
|
// version passed to this method, the PDF version of the output
|
||||||
|
// file will be set to this value. If the original PDF file's
|
||||||
|
// version or previously set minimum version is already this
|
||||||
|
// version or later, the original file's version will be used.
|
||||||
|
// QPDFWriter automatically sets the minimum version to 1.4 when
|
||||||
|
// R3 encryption parameters are used, and to 1.5 when object
|
||||||
|
// streams are used.
|
||||||
|
DLL_EXPORT
|
||||||
|
void setMinimumPDFVersion(std::string const&);
|
||||||
|
|
||||||
|
// Force the PDF version of the output file to be a given version.
|
||||||
|
// Use of this function may create PDF files that will not work
|
||||||
|
// properly with older PDF viewers. When a PDF version is set
|
||||||
|
// using this function, qpdf will use this version even if the
|
||||||
|
// file contains features that are not supported in that version
|
||||||
|
// of PDF. In other words, you should only use this function if
|
||||||
|
// you are sure the PDF file in question has no features of newer
|
||||||
|
// versions of PDF or if you are willing to create files that old
|
||||||
|
// viewers may try to open but not be able to properly interpret.
|
||||||
|
DLL_EXPORT
|
||||||
|
void forcePDFVersion(std::string const&);
|
||||||
|
|
||||||
// Cause a static /ID value to be generated. Use only in test
|
// Cause a static /ID value to be generated. Use only in test
|
||||||
// suites.
|
// suites.
|
||||||
DLL_EXPORT
|
DLL_EXPORT
|
||||||
@ -241,6 +271,7 @@ class QPDFWriter
|
|||||||
std::string id1; // for /ID key of
|
std::string id1; // for /ID key of
|
||||||
std::string id2; // trailer dictionary
|
std::string id2; // trailer dictionary
|
||||||
std::string min_pdf_version;
|
std::string min_pdf_version;
|
||||||
|
std::string forced_pdf_version;
|
||||||
int encryption_dict_objid;
|
int encryption_dict_objid;
|
||||||
std::string cur_data_key;
|
std::string cur_data_key;
|
||||||
std::list<PointerHolder<Pipeline> > to_delete;
|
std::list<PointerHolder<Pipeline> > to_delete;
|
||||||
|
@ -189,7 +189,12 @@ extern "C" {
|
|||||||
/* Supply the name of the file to be written and initialize the
|
/* Supply the name of the file to be written and initialize the
|
||||||
* qpdf_data object to handle writing operations. This function
|
* qpdf_data object to handle writing operations. This function
|
||||||
* also attempts to create the file. The PDF data is not written
|
* also attempts to create the file. The PDF data is not written
|
||||||
* until the call to qpdf_write.
|
* until the call to qpdf_write. qpdf_init_write may be called
|
||||||
|
* multiple times for the same qpdf_data object. When
|
||||||
|
* qpdf_init_write is called, all information from previous calls
|
||||||
|
* to functions that set write parameters (qpdf_set_linearization,
|
||||||
|
* etc.) is lost, so any write parameter functions must be called
|
||||||
|
* again.
|
||||||
*/
|
*/
|
||||||
DLL_EXPORT
|
DLL_EXPORT
|
||||||
QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename);
|
QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename);
|
||||||
@ -256,6 +261,12 @@ extern "C" {
|
|||||||
DLL_EXPORT
|
DLL_EXPORT
|
||||||
void qpdf_set_linearization(qpdf_data qpdf, QPDF_BOOL value);
|
void qpdf_set_linearization(qpdf_data qpdf, QPDF_BOOL value);
|
||||||
|
|
||||||
|
DLL_EXPORT
|
||||||
|
void qpdf_set_minimum_pdf_version(qpdf_data qpdf, char const* version);
|
||||||
|
|
||||||
|
DLL_EXPORT
|
||||||
|
void qpdf_force_pdf_version(qpdf_data qpdf, char const* version);
|
||||||
|
|
||||||
/* Do actual write operation. */
|
/* Do actual write operation. */
|
||||||
DLL_EXPORT
|
DLL_EXPORT
|
||||||
QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf);
|
QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf);
|
||||||
|
@ -99,6 +99,37 @@ QPDFWriter::setQDFMode(bool val)
|
|||||||
this->qdf_mode = val;
|
this->qdf_mode = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QPDFWriter::setMinimumPDFVersion(std::string const& version)
|
||||||
|
{
|
||||||
|
bool set_version = false;
|
||||||
|
if (this->min_pdf_version.empty())
|
||||||
|
{
|
||||||
|
set_version = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float v = atof(version.c_str());
|
||||||
|
float mv = atof(this->min_pdf_version.c_str());
|
||||||
|
if (v > mv)
|
||||||
|
{
|
||||||
|
QTC::TC("qpdf", "QPDFWriter increasing minimum version");
|
||||||
|
set_version = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (set_version)
|
||||||
|
{
|
||||||
|
this->min_pdf_version = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QPDFWriter::forcePDFVersion(std::string const& version)
|
||||||
|
{
|
||||||
|
this->forced_pdf_version = version;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
QPDFWriter::setStaticID(bool val)
|
QPDFWriter::setStaticID(bool val)
|
||||||
{
|
{
|
||||||
@ -147,7 +178,7 @@ QPDFWriter::setR2EncryptionParameters(
|
|||||||
clear.insert(6);
|
clear.insert(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->min_pdf_version = "1.3";
|
setMinimumPDFVersion("1.3");
|
||||||
setEncryptionParameters(user_password, owner_password, 1, 2, 5, clear);
|
setEncryptionParameters(user_password, owner_password, 1, 2, 5, clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +252,7 @@ QPDFWriter::setR3EncryptionParameters(
|
|||||||
// no default so gcc warns for missing cases
|
// no default so gcc warns for missing cases
|
||||||
}
|
}
|
||||||
|
|
||||||
this->min_pdf_version = "1.4";
|
setMinimumPDFVersion("1.4");
|
||||||
setEncryptionParameters(user_password, owner_password, 2, 3, 16, clear);
|
setEncryptionParameters(user_password, owner_password, 2, 3, 16, clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1361,7 +1392,7 @@ QPDFWriter::write()
|
|||||||
|
|
||||||
if (! this->object_stream_to_objects.empty())
|
if (! this->object_stream_to_objects.empty())
|
||||||
{
|
{
|
||||||
this->min_pdf_version = "1.5";
|
setMinimumPDFVersion("1.5");
|
||||||
}
|
}
|
||||||
|
|
||||||
generateID();
|
generateID();
|
||||||
@ -1417,15 +1448,12 @@ QPDFWriter::writeEncryptionDictionary()
|
|||||||
void
|
void
|
||||||
QPDFWriter::writeHeader()
|
QPDFWriter::writeHeader()
|
||||||
{
|
{
|
||||||
std::string version = pdf.getPDFVersion();
|
setMinimumPDFVersion(pdf.getPDFVersion());
|
||||||
if (! this->min_pdf_version.empty())
|
std::string version = this->min_pdf_version;
|
||||||
|
if (! this->forced_pdf_version.empty())
|
||||||
{
|
{
|
||||||
float ov = atof(version.c_str());
|
QTC::TC("qpdf", "QPDFWriter using forced PDF version");
|
||||||
float mv = atof(this->min_pdf_version.c_str());
|
version = this->forced_pdf_version;
|
||||||
if (mv > ov)
|
|
||||||
{
|
|
||||||
version = this->min_pdf_version;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
writeString("%PDF-");
|
writeString("%PDF-");
|
||||||
|
@ -289,6 +289,11 @@ QPDF::initializeEncryption()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Go ahead and set this->encryption here. That way, isEncrypted
|
||||||
|
// will return true even if there were errors reading the
|
||||||
|
// encryption dictionary.
|
||||||
|
this->encrypted = true;
|
||||||
|
|
||||||
QPDFObjectHandle id_obj = this->trailer.getKey("/ID");
|
QPDFObjectHandle id_obj = this->trailer.getKey("/ID");
|
||||||
if (! (id_obj.isArray() &&
|
if (! (id_obj.isArray() &&
|
||||||
(id_obj.getArrayNItems() == 2) &&
|
(id_obj.getArrayNItems() == 2) &&
|
||||||
@ -377,7 +382,6 @@ QPDF::initializeEncryption()
|
|||||||
throw QPDFExc(this->file.getName() + ": invalid password");
|
throw QPDFExc(this->file.getName() + ": invalid password");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->encrypted = true;
|
|
||||||
this->encryption_key = compute_encryption_key(this->user_password, data);
|
this->encryption_key = compute_encryption_key(this->user_password, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,6 +252,12 @@ DLL_EXPORT
|
|||||||
QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename)
|
QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename)
|
||||||
{
|
{
|
||||||
QPDF_ERROR_CODE status = QPDF_SUCCESS;
|
QPDF_ERROR_CODE status = QPDF_SUCCESS;
|
||||||
|
if (qpdf->qpdf_writer)
|
||||||
|
{
|
||||||
|
QTC::TC("qpdf", "qpdf-c called qpdf_init_write multiple times");
|
||||||
|
delete qpdf->qpdf_writer;
|
||||||
|
qpdf->qpdf_writer = 0;
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
qpdf->qpdf_writer = new QPDFWriter(*(qpdf->qpdf), filename);
|
qpdf->qpdf_writer = new QPDFWriter(*(qpdf->qpdf), filename);
|
||||||
@ -390,6 +396,20 @@ void qpdf_set_linearization(qpdf_data qpdf, QPDF_BOOL value)
|
|||||||
qpdf->qpdf_writer->setLinearization(value);
|
qpdf->qpdf_writer->setLinearization(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DLL_EXPORT
|
||||||
|
void qpdf_set_minimum_pdf_version(qpdf_data qpdf, char const* version)
|
||||||
|
{
|
||||||
|
QTC::TC("qpdf", "qpdf-c called qpdf_set_minimum_pdf_version");
|
||||||
|
qpdf->qpdf_writer->setMinimumPDFVersion(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
DLL_EXPORT
|
||||||
|
void qpdf_force_pdf_version(qpdf_data qpdf, char const* version)
|
||||||
|
{
|
||||||
|
QTC::TC("qpdf", "qpdf-c called qpdf_force_pdf_version");
|
||||||
|
qpdf->qpdf_writer->forcePDFVersion(version);
|
||||||
|
}
|
||||||
|
|
||||||
DLL_EXPORT
|
DLL_EXPORT
|
||||||
QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf)
|
QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf)
|
||||||
{
|
{
|
||||||
|
@ -20,7 +20,8 @@ static void report_errors()
|
|||||||
|
|
||||||
static void test01(char const* infile,
|
static void test01(char const* infile,
|
||||||
char const* password,
|
char const* password,
|
||||||
char const* outfile)
|
char const* outfile,
|
||||||
|
char const* outfile2)
|
||||||
{
|
{
|
||||||
qpdf_read(qpdf, infile, password);
|
qpdf_read(qpdf, infile, password);
|
||||||
printf("version: %s\n", qpdf_get_pdf_version(qpdf));
|
printf("version: %s\n", qpdf_get_pdf_version(qpdf));
|
||||||
@ -53,7 +54,8 @@ static void test01(char const* infile,
|
|||||||
|
|
||||||
static void test02(char const* infile,
|
static void test02(char const* infile,
|
||||||
char const* password,
|
char const* password,
|
||||||
char const* outfile)
|
char const* outfile,
|
||||||
|
char const* outfile2)
|
||||||
{
|
{
|
||||||
qpdf_set_suppress_warnings(qpdf, QPDF_TRUE);
|
qpdf_set_suppress_warnings(qpdf, QPDF_TRUE);
|
||||||
if (((qpdf_read(qpdf, infile, password) & QPDF_ERRORS) == 0) &&
|
if (((qpdf_read(qpdf, infile, password) & QPDF_ERRORS) == 0) &&
|
||||||
@ -67,7 +69,8 @@ static void test02(char const* infile,
|
|||||||
|
|
||||||
static void test03(char const* infile,
|
static void test03(char const* infile,
|
||||||
char const* password,
|
char const* password,
|
||||||
char const* outfile)
|
char const* outfile,
|
||||||
|
char const* outfile2)
|
||||||
{
|
{
|
||||||
qpdf_read(qpdf, infile, password);
|
qpdf_read(qpdf, infile, password);
|
||||||
qpdf_init_write(qpdf, outfile);
|
qpdf_init_write(qpdf, outfile);
|
||||||
@ -79,7 +82,8 @@ static void test03(char const* infile,
|
|||||||
|
|
||||||
static void test04(char const* infile,
|
static void test04(char const* infile,
|
||||||
char const* password,
|
char const* password,
|
||||||
char const* outfile)
|
char const* outfile,
|
||||||
|
char const* outfile2)
|
||||||
{
|
{
|
||||||
qpdf_set_ignore_xref_streams(qpdf, QPDF_TRUE);
|
qpdf_set_ignore_xref_streams(qpdf, QPDF_TRUE);
|
||||||
qpdf_read(qpdf, infile, password);
|
qpdf_read(qpdf, infile, password);
|
||||||
@ -91,7 +95,8 @@ static void test04(char const* infile,
|
|||||||
|
|
||||||
static void test05(char const* infile,
|
static void test05(char const* infile,
|
||||||
char const* password,
|
char const* password,
|
||||||
char const* outfile)
|
char const* outfile,
|
||||||
|
char const* outfile2)
|
||||||
{
|
{
|
||||||
qpdf_read(qpdf, infile, password);
|
qpdf_read(qpdf, infile, password);
|
||||||
qpdf_init_write(qpdf, outfile);
|
qpdf_init_write(qpdf, outfile);
|
||||||
@ -103,7 +108,8 @@ static void test05(char const* infile,
|
|||||||
|
|
||||||
static void test06(char const* infile,
|
static void test06(char const* infile,
|
||||||
char const* password,
|
char const* password,
|
||||||
char const* outfile)
|
char const* outfile,
|
||||||
|
char const* outfile2)
|
||||||
{
|
{
|
||||||
qpdf_read(qpdf, infile, password);
|
qpdf_read(qpdf, infile, password);
|
||||||
qpdf_init_write(qpdf, outfile);
|
qpdf_init_write(qpdf, outfile);
|
||||||
@ -115,7 +121,8 @@ static void test06(char const* infile,
|
|||||||
|
|
||||||
static void test07(char const* infile,
|
static void test07(char const* infile,
|
||||||
char const* password,
|
char const* password,
|
||||||
char const* outfile)
|
char const* outfile,
|
||||||
|
char const* outfile2)
|
||||||
{
|
{
|
||||||
qpdf_read(qpdf, infile, password);
|
qpdf_read(qpdf, infile, password);
|
||||||
qpdf_init_write(qpdf, outfile);
|
qpdf_init_write(qpdf, outfile);
|
||||||
@ -127,7 +134,8 @@ static void test07(char const* infile,
|
|||||||
|
|
||||||
static void test08(char const* infile,
|
static void test08(char const* infile,
|
||||||
char const* password,
|
char const* password,
|
||||||
char const* outfile)
|
char const* outfile,
|
||||||
|
char const* outfile2)
|
||||||
{
|
{
|
||||||
qpdf_read(qpdf, infile, password);
|
qpdf_read(qpdf, infile, password);
|
||||||
qpdf_init_write(qpdf, outfile);
|
qpdf_init_write(qpdf, outfile);
|
||||||
@ -140,7 +148,8 @@ static void test08(char const* infile,
|
|||||||
|
|
||||||
static void test09(char const* infile,
|
static void test09(char const* infile,
|
||||||
char const* password,
|
char const* password,
|
||||||
char const* outfile)
|
char const* outfile,
|
||||||
|
char const* outfile2)
|
||||||
{
|
{
|
||||||
qpdf_read(qpdf, infile, password);
|
qpdf_read(qpdf, infile, password);
|
||||||
qpdf_init_write(qpdf, outfile);
|
qpdf_init_write(qpdf, outfile);
|
||||||
@ -152,7 +161,8 @@ static void test09(char const* infile,
|
|||||||
|
|
||||||
static void test10(char const* infile,
|
static void test10(char const* infile,
|
||||||
char const* password,
|
char const* password,
|
||||||
char const* outfile)
|
char const* outfile,
|
||||||
|
char const* outfile2)
|
||||||
{
|
{
|
||||||
qpdf_set_attempt_recovery(qpdf, QPDF_FALSE);
|
qpdf_set_attempt_recovery(qpdf, QPDF_FALSE);
|
||||||
qpdf_read(qpdf, infile, password);
|
qpdf_read(qpdf, infile, password);
|
||||||
@ -161,7 +171,8 @@ static void test10(char const* infile,
|
|||||||
|
|
||||||
static void test11(char const* infile,
|
static void test11(char const* infile,
|
||||||
char const* password,
|
char const* password,
|
||||||
char const* outfile)
|
char const* outfile,
|
||||||
|
char const* outfile2)
|
||||||
{
|
{
|
||||||
qpdf_read(qpdf, infile, password);
|
qpdf_read(qpdf, infile, password);
|
||||||
qpdf_init_write(qpdf, outfile);
|
qpdf_init_write(qpdf, outfile);
|
||||||
@ -174,7 +185,8 @@ static void test11(char const* infile,
|
|||||||
|
|
||||||
static void test12(char const* infile,
|
static void test12(char const* infile,
|
||||||
char const* password,
|
char const* password,
|
||||||
char const* outfile)
|
char const* outfile,
|
||||||
|
char const* outfile2)
|
||||||
{
|
{
|
||||||
qpdf_read(qpdf, infile, password);
|
qpdf_read(qpdf, infile, password);
|
||||||
qpdf_init_write(qpdf, outfile);
|
qpdf_init_write(qpdf, outfile);
|
||||||
@ -188,7 +200,8 @@ static void test12(char const* infile,
|
|||||||
|
|
||||||
static void test13(char const* infile,
|
static void test13(char const* infile,
|
||||||
char const* password,
|
char const* password,
|
||||||
char const* outfile)
|
char const* outfile,
|
||||||
|
char const* outfile2)
|
||||||
{
|
{
|
||||||
qpdf_read(qpdf, infile, password);
|
qpdf_read(qpdf, infile, password);
|
||||||
printf("user password: %s\n", qpdf_get_user_password(qpdf));
|
printf("user password: %s\n", qpdf_get_user_password(qpdf));
|
||||||
@ -199,15 +212,33 @@ static void test13(char const* infile,
|
|||||||
report_errors();
|
report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test14(char const* infile,
|
||||||
|
char const* password,
|
||||||
|
char const* outfile,
|
||||||
|
char const* outfile2)
|
||||||
|
{
|
||||||
|
qpdf_read(qpdf, infile, password);
|
||||||
|
qpdf_init_write(qpdf, outfile);
|
||||||
|
qpdf_set_static_ID(qpdf, QPDF_TRUE);
|
||||||
|
qpdf_set_minimum_pdf_version(qpdf, "1.6");
|
||||||
|
qpdf_write(qpdf);
|
||||||
|
qpdf_init_write(qpdf, outfile2);
|
||||||
|
qpdf_set_static_ID(qpdf, QPDF_TRUE);
|
||||||
|
qpdf_force_pdf_version(qpdf, "1.4");
|
||||||
|
qpdf_write(qpdf);
|
||||||
|
report_errors();
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
char* whoami = 0;
|
char* whoami = 0;
|
||||||
char* p = 0;
|
char* p = 0;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
char const* infile;
|
char const* infile = 0;
|
||||||
char const* password;
|
char const* password = 0;
|
||||||
char const* outfile;
|
char const* outfile = 0;
|
||||||
void (*fn)(char const*, char const*, char const*) = 0;
|
char const* outfile2 = 0;
|
||||||
|
void (*fn)(char const*, char const*, char const*, char const*) = 0;
|
||||||
|
|
||||||
if ((p = strrchr(argv[0], '/')) != NULL)
|
if ((p = strrchr(argv[0], '/')) != NULL)
|
||||||
{
|
{
|
||||||
@ -221,7 +252,7 @@ int main(int argc, char* argv[])
|
|||||||
{
|
{
|
||||||
whoami = argv[0];
|
whoami = argv[0];
|
||||||
}
|
}
|
||||||
if (argc != 5)
|
if (argc < 5)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "usage: %s n infile password outfile\n", whoami);
|
fprintf(stderr, "usage: %s n infile password outfile\n", whoami);
|
||||||
exit(2);
|
exit(2);
|
||||||
@ -231,6 +262,7 @@ int main(int argc, char* argv[])
|
|||||||
infile = argv[2];
|
infile = argv[2];
|
||||||
password = argv[3];
|
password = argv[3];
|
||||||
outfile = argv[4];
|
outfile = argv[4];
|
||||||
|
outfile2 = (argc > 5 ? argv[5] : 0);
|
||||||
|
|
||||||
fn = ((n == 1) ? test01 :
|
fn = ((n == 1) ? test01 :
|
||||||
(n == 2) ? test02 :
|
(n == 2) ? test02 :
|
||||||
@ -245,6 +277,7 @@ int main(int argc, char* argv[])
|
|||||||
(n == 11) ? test11 :
|
(n == 11) ? test11 :
|
||||||
(n == 12) ? test12 :
|
(n == 12) ? test12 :
|
||||||
(n == 13) ? test13 :
|
(n == 13) ? test13 :
|
||||||
|
(n == 14) ? test14 :
|
||||||
0);
|
0);
|
||||||
|
|
||||||
if (fn == 0)
|
if (fn == 0)
|
||||||
@ -254,7 +287,7 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
qpdf = qpdf_init();
|
qpdf = qpdf_init();
|
||||||
fn(infile, password, outfile);
|
fn(infile, password, outfile, outfile2);
|
||||||
qpdf_cleanup(&qpdf);
|
qpdf_cleanup(&qpdf);
|
||||||
assert(qpdf == 0);
|
assert(qpdf == 0);
|
||||||
|
|
||||||
|
36
qpdf/qpdf.cc
36
qpdf/qpdf.cc
@ -103,6 +103,8 @@ familiar with the PDF file format or who are PDF developers.\n\
|
|||||||
--object-streams=mode controls handing of object streams\n\
|
--object-streams=mode controls handing of object streams\n\
|
||||||
--ignore-xref-streams tells qpdf to ignore any cross-reference streams\n\
|
--ignore-xref-streams tells qpdf to ignore any cross-reference streams\n\
|
||||||
--qdf turns on \"QDF mode\" (below)\n\
|
--qdf turns on \"QDF mode\" (below)\n\
|
||||||
|
--min-version=version sets the minimum PDF version of the output file\n\
|
||||||
|
--force-version=version forces this to be the PDF version of the output file\n\
|
||||||
\n\
|
\n\
|
||||||
Values for stream data options:\n\
|
Values for stream data options:\n\
|
||||||
\n\
|
\n\
|
||||||
@ -119,6 +121,12 @@ Values for object stream mode:\n\
|
|||||||
In qdf mode, by default, content normalization is turned on, and the\n\
|
In qdf mode, by default, content normalization is turned on, and the\n\
|
||||||
stream data mode is set to uncompress.\n\
|
stream data mode is set to uncompress.\n\
|
||||||
\n\
|
\n\
|
||||||
|
Setting the minimum PDF version of the output file may raise the version\n\
|
||||||
|
but will never lower it. Forcing the PDF version of the output file may\n\
|
||||||
|
set the PDF version to a lower value than actually allowed by the file's\n\
|
||||||
|
contents. You should only do this if you have no other possible way to\n\
|
||||||
|
open the file or if you know that the file definitely doesn't include\n\
|
||||||
|
features not supported later versions.\n\
|
||||||
\n\
|
\n\
|
||||||
Testing, Inspection, and Debugging Options\n\
|
Testing, Inspection, and Debugging Options\n\
|
||||||
------------------------------------------\n\
|
------------------------------------------\n\
|
||||||
@ -518,6 +526,8 @@ int main(int argc, char* argv[])
|
|||||||
QPDFWriter::object_stream_e object_stream_mode = QPDFWriter::o_preserve;
|
QPDFWriter::object_stream_e object_stream_mode = QPDFWriter::o_preserve;
|
||||||
bool ignore_xref_streams = false;
|
bool ignore_xref_streams = false;
|
||||||
bool qdf_mode = false;
|
bool qdf_mode = false;
|
||||||
|
std::string min_version;
|
||||||
|
std::string force_version;
|
||||||
|
|
||||||
bool static_id = false;
|
bool static_id = false;
|
||||||
bool suppress_original_object_id = false;
|
bool suppress_original_object_id = false;
|
||||||
@ -651,6 +661,24 @@ int main(int argc, char* argv[])
|
|||||||
{
|
{
|
||||||
qdf_mode = true;
|
qdf_mode = true;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(arg, "min-version") == 0)
|
||||||
|
{
|
||||||
|
if (parameter == 0)
|
||||||
|
{
|
||||||
|
usage("--min-version be given as"
|
||||||
|
"--min-version=version");
|
||||||
|
}
|
||||||
|
min_version = parameter;
|
||||||
|
}
|
||||||
|
else if (strcmp(arg, "force-version") == 0)
|
||||||
|
{
|
||||||
|
if (parameter == 0)
|
||||||
|
{
|
||||||
|
usage("--force-version be given as"
|
||||||
|
"--force-version=version");
|
||||||
|
}
|
||||||
|
force_version = parameter;
|
||||||
|
}
|
||||||
else if (strcmp(arg, "static-id") == 0)
|
else if (strcmp(arg, "static-id") == 0)
|
||||||
{
|
{
|
||||||
static_id = true;
|
static_id = true;
|
||||||
@ -977,6 +1005,14 @@ int main(int argc, char* argv[])
|
|||||||
{
|
{
|
||||||
w.setObjectStreamMode(object_stream_mode);
|
w.setObjectStreamMode(object_stream_mode);
|
||||||
}
|
}
|
||||||
|
if (! min_version.empty())
|
||||||
|
{
|
||||||
|
w.setMinimumPDFVersion(min_version);
|
||||||
|
}
|
||||||
|
if (! force_version.empty())
|
||||||
|
{
|
||||||
|
w.forcePDFVersion(force_version);
|
||||||
|
}
|
||||||
w.write();
|
w.write();
|
||||||
}
|
}
|
||||||
if (! pdf.getWarnings().empty())
|
if (! pdf.getWarnings().empty())
|
||||||
|
@ -153,3 +153,8 @@ qpdf-c called qpdf_allow_modify_form 0
|
|||||||
qpdf-c called qpdf_allow_modify_annotation 0
|
qpdf-c called qpdf_allow_modify_annotation 0
|
||||||
qpdf-c called qpdf_allow_modify_other 0
|
qpdf-c called qpdf_allow_modify_other 0
|
||||||
qpdf-c called qpdf_allow_modify_all 0
|
qpdf-c called qpdf_allow_modify_all 0
|
||||||
|
QPDFWriter increasing minimum version 0
|
||||||
|
QPDFWriter using forced PDF version 0
|
||||||
|
qpdf-c called qpdf_set_minimum_pdf_version 0
|
||||||
|
qpdf-c called qpdf_force_pdf_version 0
|
||||||
|
qpdf-c called qpdf_init_write multiple times 0
|
||||||
|
@ -81,7 +81,7 @@ flush_tiff_cache();
|
|||||||
show_ntests();
|
show_ntests();
|
||||||
# ----------
|
# ----------
|
||||||
$td->notify("--- Miscellaneous Tests ---");
|
$td->notify("--- Miscellaneous Tests ---");
|
||||||
$n_tests += 7;
|
$n_tests += 14;
|
||||||
|
|
||||||
foreach (my $i = 1; $i <= 3; ++$i)
|
foreach (my $i = 1; $i <= 3; ++$i)
|
||||||
{
|
{
|
||||||
@ -115,6 +115,44 @@ $td->runtest("show new xref stream",
|
|||||||
$td->EXIT_STATUS => 0},
|
$td->EXIT_STATUS => 0},
|
||||||
$td->NORMALIZE_NEWLINES);
|
$td->NORMALIZE_NEWLINES);
|
||||||
|
|
||||||
|
# Min/Force version
|
||||||
|
$td->runtest("set min version",
|
||||||
|
{$td->COMMAND => "qpdf --min-version=1.6 good1.pdf a.pdf"},
|
||||||
|
{$td->STRING => "",
|
||||||
|
$td->EXIT_STATUS => 0},
|
||||||
|
$td->NORMALIZE_NEWLINES);
|
||||||
|
$td->runtest("check version",
|
||||||
|
{$td->COMMAND => "qpdf --check a.pdf"},
|
||||||
|
{$td->FILE => "min-version.out",
|
||||||
|
$td->EXIT_STATUS => 0},
|
||||||
|
$td->NORMALIZE_NEWLINES);
|
||||||
|
$td->runtest("force version",
|
||||||
|
{$td->COMMAND => "qpdf --force-version=1.4 a.pdf b.pdf"},
|
||||||
|
{$td->STRING => "",
|
||||||
|
$td->EXIT_STATUS => 0},
|
||||||
|
$td->NORMALIZE_NEWLINES);
|
||||||
|
$td->runtest("check version",
|
||||||
|
{$td->COMMAND => "qpdf --check b.pdf"},
|
||||||
|
{$td->FILE => "forced-version.out",
|
||||||
|
$td->EXIT_STATUS => 0},
|
||||||
|
$td->NORMALIZE_NEWLINES);
|
||||||
|
unlink "a.pdf", "b.pdf" or die;
|
||||||
|
$td->runtest("C API: min/force versions",
|
||||||
|
{$td->COMMAND => "qpdf-ctest 14 object-stream.pdf '' a.pdf b.pdf"},
|
||||||
|
{$td->STRING => "",
|
||||||
|
$td->EXIT_STATUS => 0},
|
||||||
|
$td->NORMALIZE_NEWLINES);
|
||||||
|
$td->runtest("C check version 1",
|
||||||
|
{$td->COMMAND => "qpdf --check a.pdf"},
|
||||||
|
{$td->FILE => "min-version.out",
|
||||||
|
$td->EXIT_STATUS => 0},
|
||||||
|
$td->NORMALIZE_NEWLINES);
|
||||||
|
$td->runtest("C check version 2",
|
||||||
|
{$td->COMMAND => "qpdf --check b.pdf"},
|
||||||
|
{$td->FILE => "forced-version.out",
|
||||||
|
$td->EXIT_STATUS => 0},
|
||||||
|
$td->NORMALIZE_NEWLINES);
|
||||||
|
|
||||||
show_ntests();
|
show_ntests();
|
||||||
# ----------
|
# ----------
|
||||||
$td->notify("--- Error Condition Tests ---");
|
$td->notify("--- Error Condition Tests ---");
|
||||||
@ -883,7 +921,7 @@ foreach my $d (@cenc)
|
|||||||
my ($n, $infile, $pass, $description, $output) = @$d;
|
my ($n, $infile, $pass, $description, $output) = @$d;
|
||||||
my $outfile = $description;
|
my $outfile = $description;
|
||||||
$outfile =~ s/ /-/g;
|
$outfile =~ s/ /-/g;
|
||||||
my $outfile = "c-$outfile.pdf";
|
$outfile = "c-$outfile.pdf";
|
||||||
$td->runtest("C API encryption: $description",
|
$td->runtest("C API encryption: $description",
|
||||||
{$td->COMMAND => "qpdf-ctest $n $infile $pass a.pdf"},
|
{$td->COMMAND => "qpdf-ctest $n $infile $pass a.pdf"},
|
||||||
{$td->STRING => $output, $td->EXIT_STATUS => 0},
|
{$td->STRING => $output, $td->EXIT_STATUS => 0},
|
||||||
|
5
qpdf/qtest/qpdf/forced-version.out
Normal file
5
qpdf/qtest/qpdf/forced-version.out
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
checking b.pdf
|
||||||
|
PDF Version: 1.4
|
||||||
|
File is not encrypted
|
||||||
|
File is not linearized
|
||||||
|
No errors found
|
5
qpdf/qtest/qpdf/min-version.out
Normal file
5
qpdf/qtest/qpdf/min-version.out
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
checking a.pdf
|
||||||
|
PDF Version: 1.6
|
||||||
|
File is not encrypted
|
||||||
|
File is not linearized
|
||||||
|
No errors found
|
Loading…
Reference in New Issue
Block a user