mirror of
https://github.com/qpdf/qpdf.git
synced 2025-01-03 15:17:29 +00:00
Merge pull request #978 from m-holger/reflow
Code tidy - reflow comments and strings
This commit is contained in:
commit
44dce4e298
@ -14,3 +14,4 @@ d740c6ccced02147f84a39d5e5f0984d12bac6cb
|
||||
60965d5f4d608bdccc2ffd4e8753e12cbbbd71d2
|
||||
# Reflow comments and strings to 100 columns
|
||||
698a70e6a84cf7c0db667e9d9e021b4c34c85a3e
|
||||
3c5700c255f4603b5df9c6d183d13dd71a083cc3
|
||||
|
@ -8,11 +8,10 @@
|
||||
#include <iostream>
|
||||
|
||||
//
|
||||
// This example attaches a file to an input file, adds a page to the
|
||||
// beginning of the file that includes a file attachment annotation,
|
||||
// and writes the result to an output file. It also illustrates a
|
||||
// number of new API calls that were added in qpdf 10.2 as well as
|
||||
// the use of the qpdf literal syntax introduced in qpdf 10.6.
|
||||
// This example attaches a file to an input file, adds a page to the beginning of the file that
|
||||
// includes a file attachment annotation, and writes the result to an output file. It also
|
||||
// illustrates a number of new API calls that were added in qpdf 10.2 as well as the use of the qpdf
|
||||
// literal syntax introduced in qpdf 10.6.
|
||||
//
|
||||
|
||||
static char const* whoami = nullptr;
|
||||
@ -43,8 +42,8 @@ process(
|
||||
QPDF q;
|
||||
q.processFile(infilename, password);
|
||||
|
||||
// Create an indirect object for the built-in Helvetica font. This
|
||||
// uses the qpdf literal syntax introduced in qpdf 10.6.
|
||||
// Create an indirect object for the built-in Helvetica font. This uses the qpdf literal syntax
|
||||
// introduced in qpdf 10.6.
|
||||
auto f1 = q.makeIndirectObject(
|
||||
// force line-break
|
||||
"<<"
|
||||
@ -55,9 +54,8 @@ process(
|
||||
" /Encoding /WinAnsiEncoding"
|
||||
">>"_qpdf);
|
||||
|
||||
// Create a resources dictionary with fonts. This uses the new
|
||||
// parse introduced in qpdf 10.2 that takes a QPDF* and allows
|
||||
// indirect object references.
|
||||
// Create a resources dictionary with fonts. This uses the new parse introduced in qpdf 10.2
|
||||
// that takes a QPDF* and allows indirect object references.
|
||||
auto resources = q.makeIndirectObject(
|
||||
// line-break
|
||||
QPDFObjectHandle::parse(
|
||||
@ -97,8 +95,8 @@ process(
|
||||
"S\n");
|
||||
auto apdict = ap.getDict();
|
||||
|
||||
// The following four lines demonstrate the use of the qpdf literal syntax
|
||||
// introduced in qpdf 10.6. They could have been written as:
|
||||
// The following four lines demonstrate the use of the qpdf literal syntax introduced in
|
||||
// qpdf 10.6. They could have been written as:
|
||||
// apdict.replaceKey("/Resources", QPDFObjectHandle::newDictionary());
|
||||
// apdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject"));
|
||||
// apdict.replaceKey("/Subtype", QPDFObjectHandle::newName("/Form"));
|
||||
|
@ -8,9 +8,9 @@
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
// This program demonstrates extraction of bookmarks using the qpdf
|
||||
// outlines API. Note that all the information shown by this program
|
||||
// can also be obtained from a PDF file using qpdf's --json option.
|
||||
// This program demonstrates extraction of bookmarks using the qpdf outlines API. Note that all the
|
||||
// information shown by this program can also be obtained from a PDF file using qpdf's --json
|
||||
// option.
|
||||
//
|
||||
// Ignore calls to QTC::TC - they are for qpdf CI testing only.
|
||||
|
||||
@ -118,11 +118,10 @@ show_bookmark_details(QPDFOutlineObjectHelper outline, std::vector<int> numbers)
|
||||
void
|
||||
extract_bookmarks(std::vector<QPDFOutlineObjectHelper> outlines, std::vector<int>& numbers)
|
||||
{
|
||||
// For style == st_numbers, numbers.at(n) contains the numerical
|
||||
// label for the outline, so we count up from 1.
|
||||
// For style == st_lines, numbers.at(n) == 0 indicates the last
|
||||
// outline at level n, and we don't otherwise care what the value
|
||||
// is, so we count up to zero.
|
||||
// For style == st_numbers, numbers.at(n) contains the numerical label for the outline, so we
|
||||
// count up from 1.
|
||||
// For style == st_lines, numbers.at(n) == 0 indicates the last outline at level n, and we don't
|
||||
// otherwise care what the value is, so we count up to zero.
|
||||
numbers.push_back((style == st_lines) ? -QIntC::to_int(outlines.size()) : 0);
|
||||
for (auto& outline: outlines) {
|
||||
++(numbers.back());
|
||||
|
@ -1,7 +1,4 @@
|
||||
/*
|
||||
* This is an example program to demonstrate use of object handle
|
||||
* functions in the C API.
|
||||
*/
|
||||
/* This is an example program to demonstrate use of object handle functions in the C API. */
|
||||
|
||||
#include <qpdf/qpdf-c.h>
|
||||
#include <stdio.h>
|
||||
@ -20,8 +17,7 @@ usage()
|
||||
QPDF_BOOL
|
||||
modify_file(qpdf_data qpdf)
|
||||
{
|
||||
/* This small example performs the following operation on the
|
||||
* document catalog (a.k.a. root):
|
||||
/* This small example performs the following operation on the document catalog (a.k.a. root):
|
||||
* - Remove PageLayout
|
||||
* - Remove OpenAction
|
||||
* - If there are outlines, set PageMode to UseOutlines; otherwise,
|
||||
@ -72,8 +68,7 @@ main(int argc, char* argv[])
|
||||
|
||||
if (((qpdf_read(qpdf, infile, password) & QPDF_ERRORS) == 0) && modify_file(qpdf) &&
|
||||
((qpdf_init_write(qpdf, outfile) & QPDF_ERRORS) == 0)) {
|
||||
/* Use static ID for testing only. For production, a
|
||||
* non-static ID is used. See also
|
||||
/* Use static ID for testing only. For production, a non-static ID is used. See also
|
||||
* qpdf_set_deterministic_ID. */
|
||||
qpdf_set_static_ID(qpdf, QPDF_TRUE); /* for testing only */
|
||||
qpdf_write(qpdf);
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// This example illustrates the use of QPDFObjectHandle::TokenFilter
|
||||
// with filterContents. See also pdf-filter-tokens.cc for an example
|
||||
// that uses QPDFObjectHandle::TokenFilter with addContentTokenFilter.
|
||||
// This example illustrates the use of QPDFObjectHandle::TokenFilter with filterContents. See also
|
||||
// pdf-filter-tokens.cc for an example that uses QPDFObjectHandle::TokenFilter with
|
||||
// addContentTokenFilter.
|
||||
//
|
||||
|
||||
#include <cstdlib>
|
||||
@ -46,16 +46,15 @@ StringCounter::handleToken(QPDFTokenizer::Token const& token)
|
||||
if (token.getType() == QPDFTokenizer::tt_string) {
|
||||
++this->count;
|
||||
}
|
||||
// Preserve input verbatim by passing each token to any specified
|
||||
// downstream filter.
|
||||
// Preserve input verbatim by passing each token to any specified downstream filter.
|
||||
writeToken(token);
|
||||
}
|
||||
|
||||
void
|
||||
StringCounter::handleEOF()
|
||||
{
|
||||
// Write a comment at the end of the stream just to show how we
|
||||
// can enhance the output if we want.
|
||||
// Write a comment at the end of the stream just to show how we can enhance the output if we
|
||||
// want.
|
||||
write("\n% strings found: ");
|
||||
write(std::to_string(this->count));
|
||||
}
|
||||
@ -82,10 +81,9 @@ main(int argc, char* argv[])
|
||||
int pageno = 0;
|
||||
for (auto& page: QPDFPageDocumentHelper(pdf).getAllPages()) {
|
||||
++pageno;
|
||||
// Pass the contents of a page through our string counter.
|
||||
// If it's an even page, capture the output. This
|
||||
// illustrates that you may capture any output generated
|
||||
// by the filter, or you may ignore it.
|
||||
// Pass the contents of a page through our string counter. If it's an even page, capture
|
||||
// the output. This illustrates that you may capture any output generated by the filter,
|
||||
// or you may ignore it.
|
||||
StringCounter counter;
|
||||
if (pageno % 2) {
|
||||
// Ignore output for odd pages.
|
||||
|
@ -1,7 +1,6 @@
|
||||
//
|
||||
// This is an example of creating a PDF file from scratch. It
|
||||
// illustrates use of several QPDF operations for creating objects and
|
||||
// streams. It also serves as an illustration of how to use
|
||||
// This is an example of creating a PDF file from scratch. It illustrates use of several QPDF
|
||||
// operations for creating objects and streams. It also serves as an illustration of how to use
|
||||
// StreamDataProvider with different types of filters.
|
||||
//
|
||||
|
||||
@ -20,8 +19,8 @@
|
||||
|
||||
static char const* whoami = nullptr;
|
||||
|
||||
// This is a simple StreamDataProvider that writes image data for an
|
||||
// orange square of the given width and height.
|
||||
// This is a simple StreamDataProvider that writes image data for an orange square of the given
|
||||
// width and height.
|
||||
class ImageProvider: public QPDFObjectHandle::StreamDataProvider
|
||||
{
|
||||
public:
|
||||
@ -130,8 +129,7 @@ usage()
|
||||
static QPDFObjectHandle
|
||||
createPageContents(QPDF& pdf, std::string const& text)
|
||||
{
|
||||
// Create a stream that displays our image and the given text in
|
||||
// our font.
|
||||
// Create a stream that displays our image and the given text in our font.
|
||||
std::string contents = "BT /F1 24 Tf 72 320 Td (" + text +
|
||||
") Tj ET\n"
|
||||
"q 244 0 0 144 184 100 cm /Im1 Do Q\n";
|
||||
@ -159,11 +157,9 @@ add_page(
|
||||
{
|
||||
QPDF& pdf(dh.getQPDF());
|
||||
|
||||
// Create a stream to encode our image. QPDFWriter will fill in
|
||||
// the length and will respect our filters based on stream data
|
||||
// mode. Since we are not specifying, QPDFWriter will compress
|
||||
// with /FlateDecode if we don't provide any other form of
|
||||
// compression.
|
||||
// Create a stream to encode our image. QPDFWriter will fill in the length and will respect our
|
||||
// filters based on stream data mode. Since we are not specifying, QPDFWriter will compress with
|
||||
// /FlateDecode if we don't provide any other form of compression.
|
||||
auto* p = new ImageProvider(color_space, filter);
|
||||
std::shared_ptr<QPDFObjectHandle::StreamDataProvider> provider(p);
|
||||
size_t width = p->getWidth();
|
||||
@ -219,20 +215,17 @@ check(
|
||||
std::vector<std::string> const& color_spaces,
|
||||
std::vector<std::string> const& filters)
|
||||
{
|
||||
// Each stream is compressed the way it is supposed to be. We will
|
||||
// add additional tests in qpdf.test to exercise QPDFWriter more
|
||||
// fully. In this case, we want to make sure that we actually have
|
||||
// RunLengthDecode and DCTDecode where we are supposed to and
|
||||
// FlateDecode where we provided no filters.
|
||||
// Each stream is compressed the way it is supposed to be. We will add additional tests in
|
||||
// qpdf.test to exercise QPDFWriter more fully. In this case, we want to make sure that we
|
||||
// actually have RunLengthDecode and DCTDecode where we are supposed to and FlateDecode where we
|
||||
// provided no filters.
|
||||
|
||||
// Each image is correct. For non-lossy image compression, the
|
||||
// uncompressed image data should exactly match what ImageProvider
|
||||
// provided. For the DCTDecode data, allow for some fuzz to handle
|
||||
// jpeg compression as well as its variance on different systems.
|
||||
// Each image is correct. For non-lossy image compression, the uncompressed image data should
|
||||
// exactly match what ImageProvider provided. For the DCTDecode data, allow for some fuzz to
|
||||
// handle jpeg compression as well as its variance on different systems.
|
||||
|
||||
// These tests should use QPDFObjectHandle's stream data retrieval
|
||||
// methods, but don't try to fully exercise them here. That is
|
||||
// done elsewhere.
|
||||
// These tests should use QPDFObjectHandle's stream data retrieval methods, but don't try to
|
||||
// fully exercise them here. That is done elsewhere.
|
||||
|
||||
size_t n_color_spaces = color_spaces.size();
|
||||
size_t n_filters = filters.size();
|
||||
@ -254,8 +247,8 @@ check(
|
||||
// Check filter and color space.
|
||||
std::string desired_color_space = color_spaces[(pageno - 1) / n_color_spaces];
|
||||
std::string desired_filter = filters[(pageno - 1) % n_filters];
|
||||
// In the default mode, QPDFWriter will compress with
|
||||
// /FlateDecode if no filters are provided.
|
||||
// In the default mode, QPDFWriter will compress with /FlateDecode if no filters are
|
||||
// provided.
|
||||
if (desired_filter == "null") {
|
||||
desired_filter = "/FlateDecode";
|
||||
}
|
||||
@ -288,11 +281,9 @@ check(
|
||||
std::cout << "page " << pageno << ": image data length mismatch" << std::endl;
|
||||
this_errors = errors = true;
|
||||
} else {
|
||||
// Compare bytes. For JPEG, allow a certain number of
|
||||
// the bytes to be off desired by more than a given
|
||||
// tolerance. Any of the samples may be a little off
|
||||
// because of lossy compression, and around sharp
|
||||
// edges, things can be quite off. For non-lossy
|
||||
// Compare bytes. For JPEG, allow a certain number of the bytes to be off desired by
|
||||
// more than a given tolerance. Any of the samples may be a little off because of
|
||||
// lossy compression, and around sharp edges, things can be quite off. For non-lossy
|
||||
// compression, do not allow any tolerance.
|
||||
unsigned char const* actual_bytes = actual_data->getBuffer();
|
||||
unsigned char const* desired_bytes = desired_data->getBuffer();
|
||||
@ -332,8 +323,7 @@ create_pdf(char const* filename)
|
||||
// Start with an empty PDF that has no pages or non-required objects.
|
||||
pdf.emptyPDF();
|
||||
|
||||
// Add an indirect object to contain a font descriptor for the
|
||||
// built-in Helvetica font.
|
||||
// Add an indirect object to contain a font descriptor for the built-in Helvetica font.
|
||||
QPDFObjectHandle font = pdf.makeIndirectObject(
|
||||
// line-break
|
||||
"<<"
|
||||
@ -362,8 +352,7 @@ create_pdf(char const* filename)
|
||||
QPDFWriter w(pdf, filename);
|
||||
w.write();
|
||||
|
||||
// For test suite, verify that everything is the way it is
|
||||
// supposed to be.
|
||||
// For test suite, verify that everything is the way it is supposed to be.
|
||||
check(filename, color_spaces, filters);
|
||||
}
|
||||
|
||||
|
@ -8,43 +8,35 @@
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
// This example shows you everything you need to know to implement a
|
||||
// custom stream filter for encoding and decoding as well as a stream
|
||||
// data provider that modifies the stream's dictionary. This example
|
||||
// uses the pattern of having the stream data provider class use a
|
||||
// second QPDF instance with copies of streams from the original QPDF
|
||||
// so that the stream data provider can access the original stream
|
||||
// data. This is implemented very efficiently inside the qpdf library as
|
||||
// the second QPDF instance knows how to read the stream data from the
|
||||
// original input file, so no extra copies of the original stream data
|
||||
// are made.
|
||||
// This example shows you everything you need to know to implement a custom stream filter for
|
||||
// encoding and decoding as well as a stream data provider that modifies the stream's dictionary.
|
||||
// This example uses the pattern of having the stream data provider class use a second QPDF instance
|
||||
// with copies of streams from the original QPDF so that the stream data provider can access the
|
||||
// original stream data. This is implemented very efficiently inside the qpdf library as the second
|
||||
// QPDF instance knows how to read the stream data from the original input file, so no extra copies
|
||||
// of the original stream data are made.
|
||||
|
||||
// This example creates an imaginary filter called /XORDecode. There
|
||||
// is no such filter in PDF, so the streams created by the example
|
||||
// would not be usable by any PDF reader. However, the techniques here
|
||||
// would work if you were going to implement support for a filter that
|
||||
// qpdf does not support natively. For example, using the techniques
|
||||
// shown here, it would be possible to create an application that
|
||||
// downsampled or re-encoded images or that re-compressed streams
|
||||
// using a more efficient "deflate" implementation than zlib.
|
||||
// This example creates an imaginary filter called /XORDecode. There is no such filter in PDF, so
|
||||
// the streams created by the example would not be usable by any PDF reader. However, the techniques
|
||||
// here would work if you were going to implement support for a filter that qpdf does not support
|
||||
// natively. For example, using the techniques shown here, it would be possible to create an
|
||||
// application that downsampled or re-encoded images or that re-compressed streams using a more
|
||||
// efficient "deflate" implementation than zlib.
|
||||
|
||||
// Comments appear throughout the code describing each piece of code
|
||||
// and its purpose. You can read the file top to bottom, or you can
|
||||
// start with main() and follow the flow.
|
||||
// Comments appear throughout the code describing each piece of code and its purpose. You can read
|
||||
// the file top to bottom, or you can start with main() and follow the flow.
|
||||
|
||||
// Please also see the test suite, qtest/custom-filter.test, which
|
||||
// contains additional comments describing how to observe the results
|
||||
// of running this example on test files that are specifically crafted
|
||||
// for it.
|
||||
// Please also see the test suite, qtest/custom-filter.test, which contains additional comments
|
||||
// describing how to observe the results of running this example on test files that are specifically
|
||||
// crafted for it.
|
||||
|
||||
static char const* whoami = nullptr;
|
||||
|
||||
class Pl_XOR: public Pipeline
|
||||
{
|
||||
// This class implements a Pipeline for the made-up XOR decoder.
|
||||
// It is initialized with a single-byte "key" and just XORs each
|
||||
// byte with that key. This makes it reversible, so there is no
|
||||
// distinction between encoding and decoding.
|
||||
// This class implements a Pipeline for the made-up XOR decoder. It is initialized with a
|
||||
// single-byte "key" and just XORs each byte with that key. This makes it reversible, so there
|
||||
// is no distinction between encoding and decoding.
|
||||
|
||||
public:
|
||||
Pl_XOR(char const* identifier, Pipeline* next, unsigned char key);
|
||||
@ -79,17 +71,14 @@ Pl_XOR::finish()
|
||||
|
||||
class SF_XORDecode: public QPDFStreamFilter
|
||||
{
|
||||
// This class implements a QPDFStreamFilter that knows how to
|
||||
// validate and interpret decode parameters (/DecodeParms) for the
|
||||
// made-up /XORDecode stream filter. Since this is not a real
|
||||
// stream filter, no actual PDF reader would know how to interpret
|
||||
// it. This is just to illustrate how to create a stream filter.
|
||||
// In main(), we call QPDF::registerStreamFilter to tell the
|
||||
// library about the filter. See comments in QPDFStreamFilter.hh
|
||||
// for details on how to implement the methods. For purposes of
|
||||
// example, we are calling this a "specialized" compression
|
||||
// filter, which just means QPDF assumes that it should not
|
||||
// "uncompress" the stream by default.
|
||||
// This class implements a QPDFStreamFilter that knows how to validate and interpret decode
|
||||
// parameters (/DecodeParms) for the made-up /XORDecode stream filter. Since this is not a real
|
||||
// stream filter, no actual PDF reader would know how to interpret it. This is just to
|
||||
// illustrate how to create a stream filter. In main(), we call QPDF::registerStreamFilter to
|
||||
// tell the library about the filter. See comments in QPDFStreamFilter.hh for details on how to
|
||||
// implement the methods. For purposes of example, we are calling this a "specialized"
|
||||
// compression filter, which just means QPDF assumes that it should not "uncompress" the stream
|
||||
// by default.
|
||||
public:
|
||||
~SF_XORDecode() override = default;
|
||||
bool setDecodeParms(QPDFObjectHandle decode_parms) override;
|
||||
@ -98,33 +87,28 @@ class SF_XORDecode: public QPDFStreamFilter
|
||||
|
||||
private:
|
||||
unsigned char key;
|
||||
// It is the responsibility of the QPDFStreamFilter implementation
|
||||
// to ensure that the pipeline returned by getDecodePipeline() is
|
||||
// deleted when the class is deleted. The easiest way to do this
|
||||
// is to stash the pipeline in a std::shared_ptr, which enables us
|
||||
// to use the default destructor implementation.
|
||||
// It is the responsibility of the QPDFStreamFilter implementation to ensure that the pipeline
|
||||
// returned by getDecodePipeline() is deleted when the class is deleted. The easiest way to do
|
||||
// this is to stash the pipeline in a std::shared_ptr, which enables us to use the default
|
||||
// destructor implementation.
|
||||
std::shared_ptr<Pl_XOR> pipeline;
|
||||
};
|
||||
|
||||
bool
|
||||
SF_XORDecode::setDecodeParms(QPDFObjectHandle decode_parms)
|
||||
{
|
||||
// For purposes of example, we store the key in a separate stream.
|
||||
// We could just as well store the key directly in /DecodeParms,
|
||||
// but this example uses a stream to illustrate how one might do
|
||||
// that. For example, if implementing /JBIG2Decode, one would need
|
||||
// to handle the /JBIG2Globals key, which points to a stream. See
|
||||
// comments in SF_XORDecode::registerStream for additional notes
|
||||
// on this.
|
||||
// For purposes of example, we store the key in a separate stream. We could just as well store
|
||||
// the key directly in /DecodeParms, but this example uses a stream to illustrate how one might
|
||||
// do that. For example, if implementing /JBIG2Decode, one would need to handle the
|
||||
// /JBIG2Globals key, which points to a stream. See comments in SF_XORDecode::registerStream for
|
||||
// additional notes on this.
|
||||
try {
|
||||
// Expect /DecodeParms to be a dictionary with a /KeyStream
|
||||
// key that points to a one-byte stream whose single byte is
|
||||
// the key. If we are successful at retrieving the key, return
|
||||
// true, indicating that we are able to process with the given
|
||||
// decode parameters. Under any other circumstances, return
|
||||
// false. For other examples of QPDFStreamFilter
|
||||
// implementations, look at the classes whose names start with
|
||||
// SF_ in the qpdf library implementation.
|
||||
// Expect /DecodeParms to be a dictionary with a /KeyStream key that points to a one-byte
|
||||
// stream whose single byte is the key. If we are successful at retrieving the key, return
|
||||
// true, indicating that we are able to process with the given decode parameters. Under any
|
||||
// other circumstances, return false. For other examples of QPDFStreamFilter
|
||||
// implementations, look at the classes whose names start with SF_ in the qpdf library
|
||||
// implementation.
|
||||
auto buf = decode_parms.getKey("/KeyStream").getStreamData();
|
||||
if (buf->getSize() != 1) {
|
||||
return false;
|
||||
@ -140,14 +124,12 @@ SF_XORDecode::setDecodeParms(QPDFObjectHandle decode_parms)
|
||||
Pipeline*
|
||||
SF_XORDecode::getDecodePipeline(Pipeline* next)
|
||||
{
|
||||
// Return a pipeline that the qpdf library should pass the stream
|
||||
// data through. The pipeline should receive encoded data and pass
|
||||
// decoded data to "next". getDecodePipeline() can always count on
|
||||
// setDecodeParms() having been called first. The setDecodeParms()
|
||||
// method should store any parameters needed by the pipeline. To
|
||||
// ensure that the pipeline we return disappears when the class
|
||||
// disappears, stash it in a std::shared_ptr<Pl_XOR> and retrieve
|
||||
// the raw pointer from there.
|
||||
// Return a pipeline that the qpdf library should pass the stream data through. The pipeline
|
||||
// should receive encoded data and pass decoded data to "next". getDecodePipeline() can always
|
||||
// count on setDecodeParms() having been called first. The setDecodeParms() method should store
|
||||
// any parameters needed by the pipeline. To ensure that the pipeline we return disappears when
|
||||
// the class disappears, stash it in a std::shared_ptr<Pl_XOR> and retrieve the raw pointer from
|
||||
// there.
|
||||
this->pipeline = std::make_shared<Pl_XOR>("xor", next, this->key);
|
||||
return this->pipeline.get();
|
||||
}
|
||||
@ -155,46 +137,37 @@ SF_XORDecode::getDecodePipeline(Pipeline* next)
|
||||
bool
|
||||
SF_XORDecode::isSpecializedCompression()
|
||||
{
|
||||
// The default implementation of QPDFStreamFilter would return
|
||||
// false, so if you want a specialized or lossy compression
|
||||
// filter, override one of the methods as described in
|
||||
// The default implementation of QPDFStreamFilter would return false, so if you want a
|
||||
// specialized or lossy compression filter, override one of the methods as described in
|
||||
// QPDFStreamFilter.hh.
|
||||
return true;
|
||||
}
|
||||
|
||||
class StreamReplacer: public QPDFObjectHandle::StreamDataProvider
|
||||
{
|
||||
// This class implements a StreamDataProvider that, under specific
|
||||
// conditions, replaces the stream data with data encoded with the
|
||||
// made-up /XORDecode filter.
|
||||
// This class implements a StreamDataProvider that, under specific conditions, replaces the
|
||||
// stream data with data encoded with the made-up /XORDecode filter.
|
||||
|
||||
// The flow for this class is as follows:
|
||||
//
|
||||
// * The main application iterates through streams that should be
|
||||
// replaced and calls registerStream. registerStream in turn
|
||||
// calls maybeReplace passing nullptr to pipeline and the
|
||||
// address of a valid QPDFObjectHandle to dict_updates. The
|
||||
// stream passed in for this call is the stream for the original
|
||||
// QPDF object. It has not yet been altered, so we have access
|
||||
// to its original dictionary and data. As described in the
|
||||
// method, the method when called in this way makes a
|
||||
// determination as to whether the stream should be replaced. If
|
||||
// so, registerStream makes whatever changes are required. We
|
||||
// have to do this now because we can't modify the stream during
|
||||
// the writing process.
|
||||
// * The main application iterates through streams that should be replaced and calls
|
||||
// registerStream. registerStream in turn calls maybeReplace passing nullptr to pipeline and
|
||||
// the address of a valid QPDFObjectHandle to dict_updates. The stream passed in for this call
|
||||
// is the stream for the original QPDF object. It has not yet been altered, so we have access
|
||||
// to its original dictionary and data. As described in the method, the method when called in
|
||||
// this way makes a determination as to whether the stream should be replaced. If so,
|
||||
// registerStream makes whatever changes are required. We have to do this now because we can't
|
||||
// modify the stream during the writing process.
|
||||
//
|
||||
// * provideStreamData(), which is called by QPDFWriter during the
|
||||
// write process, actually writes the modified stream data. It
|
||||
// calls maybeReplace again, but this time it passes a valid
|
||||
// pipeline and passes nullptr to dict_updates. In this mode,
|
||||
// the stream dictionary has already been altered, and the
|
||||
// original stream data is no longer directly accessible. Trying
|
||||
// to retrieve the stream data would cause an infinite loop because
|
||||
// it would just end up calling provideStreamData again. This is
|
||||
// why maybeReplace uses a stashed copy of the original stream.
|
||||
// * provideStreamData(), which is called by QPDFWriter during the write process, actually
|
||||
// writes the modified stream data. It calls maybeReplace again, but this time it passes a
|
||||
// valid pipeline and passes nullptr to dict_updates. In this mode, the stream dictionary has
|
||||
// already been altered, and the original stream data is no longer directly accessible. Trying
|
||||
// to retrieve the stream data would cause an infinite loop because it would just end up
|
||||
// calling provideStreamData again. This is why maybeReplace uses a stashed copy of the
|
||||
// original stream.
|
||||
|
||||
// Additional explanation can be found in the method
|
||||
// implementations.
|
||||
// Additional explanation can be found in the method implementations.
|
||||
|
||||
public:
|
||||
StreamReplacer(QPDF* pdf);
|
||||
@ -211,17 +184,16 @@ class StreamReplacer: public QPDFObjectHandle::StreamDataProvider
|
||||
Pipeline* pipeline,
|
||||
QPDFObjectHandle* dict_updates);
|
||||
|
||||
// Hang onto a reference to the QPDF object containing the streams
|
||||
// we are replacing. We need this to create a new stream.
|
||||
// Hang onto a reference to the QPDF object containing the streams we are replacing. We need
|
||||
// this to create a new stream.
|
||||
QPDF* pdf;
|
||||
|
||||
// Map the object/generation in original file to the copied stream
|
||||
// in "other". We use this to retrieve the original data.
|
||||
// Map the object/generation in original file to the copied stream in "other". We use this to
|
||||
// retrieve the original data.
|
||||
std::map<QPDFObjGen, QPDFObjectHandle> copied_streams;
|
||||
|
||||
// Each stream gets is own "key" for the XOR filter. We use a
|
||||
// single instance of StreamReplacer for all streams, so stash all
|
||||
// the keys here.
|
||||
// Each stream gets is own "key" for the XOR filter. We use a single instance of StreamReplacer
|
||||
// for all streams, so stash all the keys here.
|
||||
std::map<QPDFObjGen, unsigned char> keys;
|
||||
};
|
||||
|
||||
@ -237,49 +209,38 @@ StreamReplacer::maybeReplace(
|
||||
Pipeline* pipeline,
|
||||
QPDFObjectHandle* dict_updates)
|
||||
{
|
||||
// As described in the class comments, this method is called
|
||||
// twice. Before writing has started pipeline is nullptr, and
|
||||
// dict_updates is provided. In this mode, we figure out whether
|
||||
// we should replace the stream and, if so, take care of the
|
||||
// necessary setup. When we are actually ready to supply the data,
|
||||
// this method is called again with pipeline populated and
|
||||
// dict_updates as a nullptr. In this mode, we are not allowed to
|
||||
// change anything, since writing is already in progress. We
|
||||
// must simply provide the stream data.
|
||||
// As described in the class comments, this method is called twice. Before writing has started
|
||||
// pipeline is nullptr, and dict_updates is provided. In this mode, we figure out whether we
|
||||
// should replace the stream and, if so, take care of the necessary setup. When we are actually
|
||||
// ready to supply the data, this method is called again with pipeline populated and
|
||||
// dict_updates as a nullptr. In this mode, we are not allowed to change anything, since writing
|
||||
// is already in progress. We must simply provide the stream data.
|
||||
|
||||
// The return value indicates whether or not we should replace the
|
||||
// stream. If the first call returns false, there will be no
|
||||
// second call. If the second call returns false, something went
|
||||
// wrong since the method should always make the same decision for
|
||||
// a given stream.
|
||||
// The return value indicates whether or not we should replace the stream. If the first call
|
||||
// returns false, there will be no second call. If the second call returns false, something went
|
||||
// wrong since the method should always make the same decision for a given stream.
|
||||
|
||||
// For this example, all the determination logic could have
|
||||
// appeared inside the if (dict_updates) block rather than being
|
||||
// duplicated, but in some cases, there may be a reason to
|
||||
// duplicate things. For example, if you wanted to write code that
|
||||
// re-encoded an image if the new encoding was more efficient,
|
||||
// you'd have to actually try it out. Then you would either have
|
||||
// to cache the result somewhere or just repeat the calculations,
|
||||
// depending on space/time constraints, etc.
|
||||
// For this example, all the determination logic could have appeared inside the if
|
||||
// (dict_updates) block rather than being duplicated, but in some cases, there may be a reason
|
||||
// to duplicate things. For example, if you wanted to write code that re-encoded an image if the
|
||||
// new encoding was more efficient, you'd have to actually try it out. Then you would either
|
||||
// have to cache the result somewhere or just repeat the calculations, depending on space/time
|
||||
// constraints, etc.
|
||||
|
||||
// In our contrived example, we are replacing the data for all
|
||||
// streams that have /DoXOR = true in the stream dictionary. If
|
||||
// this were a more realistic application, our criteria would be
|
||||
// more sensible. For example, an image downsampler might choose
|
||||
// to replace a stream that represented an image with a high pixel
|
||||
// density.
|
||||
// In our contrived example, we are replacing the data for all streams that have /DoXOR = true
|
||||
// in the stream dictionary. If this were a more realistic application, our criteria would be
|
||||
// more sensible. For example, an image downsampler might choose to replace a stream that
|
||||
// represented an image with a high pixel density.
|
||||
auto dict = stream.getDict();
|
||||
auto mark = dict.getKey("/DoXOR");
|
||||
if (!(mark.isBool() && mark.getBoolValue())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We can't replace the stream data if we can't get the original
|
||||
// stream data for any reason. A more realistic application may
|
||||
// actually look at the data here as well, or it may be able to
|
||||
// make all its decisions from the stream dictionary. However,
|
||||
// it's a good idea to make sure we can retrieve the filtered data
|
||||
// if we are going to need it later.
|
||||
// We can't replace the stream data if we can't get the original stream data for any reason. A
|
||||
// more realistic application may actually look at the data here as well, or it may be able to
|
||||
// make all its decisions from the stream dictionary. However, it's a good idea to make sure we
|
||||
// can retrieve the filtered data if we are going to need it later.
|
||||
std::shared_ptr<Buffer> out;
|
||||
try {
|
||||
out = stream.getStreamData();
|
||||
@ -288,19 +249,15 @@ StreamReplacer::maybeReplace(
|
||||
}
|
||||
|
||||
if (dict_updates) {
|
||||
// It's not safe to make any modifications to any objects
|
||||
// during the writing process since the updated objects may
|
||||
// have already been written. In this mode, when dict_updates
|
||||
// is provided, we have not started writing. Store the
|
||||
// modifications we intend to make to the stream dictionary
|
||||
// here. We're just storing /OrigLength for purposes of
|
||||
// example. Again, a realistic application would make other
|
||||
// changes. For example, an image resampler might change the
|
||||
// dimensions or other properties of the image.
|
||||
// It's not safe to make any modifications to any objects during the writing process since
|
||||
// the updated objects may have already been written. In this mode, when dict_updates is
|
||||
// provided, we have not started writing. Store the modifications we intend to make to the
|
||||
// stream dictionary here. We're just storing /OrigLength for purposes of example. Again, a
|
||||
// realistic application would make other changes. For example, an image resampler might
|
||||
// change the dimensions or other properties of the image.
|
||||
dict_updates->replaceKey(
|
||||
"/OrigLength", QPDFObjectHandle::newInteger(QIntC::to_longlong(out->getSize())));
|
||||
// We are also storing the "key" that we will access when
|
||||
// writing the data.
|
||||
// We are also storing the "key" that we will access when writing the data.
|
||||
this->keys[og] = QIntC::to_uchar((og.getObj() * QIntC::to_int(out->getSize())) & 0xff);
|
||||
}
|
||||
|
||||
@ -319,21 +276,18 @@ StreamReplacer::registerStream(
|
||||
{
|
||||
QPDFObjGen og(stream.getObjGen());
|
||||
|
||||
// We don't need to process a stream more than once. In this
|
||||
// example, we are just iterating through objects, but if we were
|
||||
// doing something like iterating through images on pages, we
|
||||
// We don't need to process a stream more than once. In this example, we are just iterating
|
||||
// through objects, but if we were doing something like iterating through images on pages, we
|
||||
// might realistically encounter the same stream more than once.
|
||||
if (this->copied_streams.count(og) > 0) {
|
||||
return;
|
||||
}
|
||||
// Store something in copied_streams so that we don't
|
||||
// double-process even in the negative case. This gets replaced
|
||||
// later if needed.
|
||||
// Store something in copied_streams so that we don't double-process even in the negative case.
|
||||
// This gets replaced later if needed.
|
||||
this->copied_streams[og] = QPDFObjectHandle::newNull();
|
||||
|
||||
// Call maybeReplace with dict_updates. In this mode, it
|
||||
// determines whether we should replace the stream data and, if
|
||||
// so, supplies dictionary updates we should make.
|
||||
// Call maybeReplace with dict_updates. In this mode, it determines whether we should replace
|
||||
// the stream data and, if so, supplies dictionary updates we should make.
|
||||
bool should_replace = false;
|
||||
QPDFObjectHandle dict_updates = QPDFObjectHandle::newDictionary();
|
||||
try {
|
||||
@ -343,9 +297,8 @@ StreamReplacer::registerStream(
|
||||
}
|
||||
|
||||
if (should_replace) {
|
||||
// Copy the stream so we can get to the original data from the
|
||||
// stream data provider. This doesn't actually copy any data,
|
||||
// but the copy retains the original stream data after the
|
||||
// Copy the stream so we can get to the original data from the stream data provider. This
|
||||
// doesn't actually copy any data, but the copy retains the original stream data after the
|
||||
// original one is modified.
|
||||
this->copied_streams[og] = stream.copyStream();
|
||||
// Update the stream dictionary with any changes.
|
||||
@ -353,20 +306,17 @@ StreamReplacer::registerStream(
|
||||
for (auto const& k: dict_updates.getKeys()) {
|
||||
dict.replaceKey(k, dict_updates.getKey(k));
|
||||
}
|
||||
// Create the key stream that will be referenced from
|
||||
// /DecodeParms. We have to do this now since you can't modify
|
||||
// or create objects during write.
|
||||
// Create the key stream that will be referenced from /DecodeParms. We have to do this now
|
||||
// since you can't modify or create objects during write.
|
||||
char p[1] = {static_cast<char>(this->keys[og])};
|
||||
std::string p_str(p, 1);
|
||||
QPDFObjectHandle dp_stream = this->pdf->newStream(p_str);
|
||||
// Create /DecodeParms as expected by our fictitious
|
||||
// /XORDecode filter.
|
||||
// Create /DecodeParms as expected by our fictitious /XORDecode filter.
|
||||
QPDFObjectHandle decode_parms =
|
||||
QPDFObjectHandle::newDictionary({{"/KeyStream", dp_stream}});
|
||||
stream.replaceStreamData(self, QPDFObjectHandle::newName("/XORDecode"), decode_parms);
|
||||
// Further, if /ProtectXOR = true, we disable filtering on write
|
||||
// so that QPDFWriter will not decode the stream even though we
|
||||
// have registered a stream filter for /XORDecode.
|
||||
// Further, if /ProtectXOR = true, we disable filtering on write so that QPDFWriter will not
|
||||
// decode the stream even though we have registered a stream filter for /XORDecode.
|
||||
auto protect = dict.getKey("/ProtectXOR");
|
||||
if (protect.isBool() && protect.getBoolValue()) {
|
||||
stream.setFilterOnWrite(false);
|
||||
@ -378,14 +328,12 @@ void
|
||||
StreamReplacer::provideStreamData(QPDFObjGen const& og, Pipeline* pipeline)
|
||||
{
|
||||
QPDFObjectHandle orig = this->copied_streams[og];
|
||||
// call maybeReplace again, this time with the pipeline and no
|
||||
// dict_updates. In this mode, maybeReplace doesn't make any
|
||||
// changes. We have to hand it the original stream data, which we
|
||||
// call maybeReplace again, this time with the pipeline and no dict_updates. In this mode,
|
||||
// maybeReplace doesn't make any changes. We have to hand it the original stream data, which we
|
||||
// get from copied_streams.
|
||||
if (!maybeReplace(og, orig, pipeline, nullptr)) {
|
||||
// Since this only gets called for streams we already
|
||||
// determined we are replacing, a false return would indicate
|
||||
// a logic error.
|
||||
// Since this only gets called for streams we already determined we are replacing, a false
|
||||
// return would indicate a logic error.
|
||||
throw std::logic_error("should_replace return false in provideStreamData");
|
||||
}
|
||||
}
|
||||
@ -396,17 +344,15 @@ process(char const* infilename, char const* outfilename, bool decode_specialized
|
||||
QPDF qpdf;
|
||||
qpdf.processFile(infilename);
|
||||
|
||||
// Create a single StreamReplacer instance. The interface requires
|
||||
// a std::shared_ptr in various places, so allocate a StreamReplacer
|
||||
// and stash it in a std::shared_ptr.
|
||||
// Create a single StreamReplacer instance. The interface requires a std::shared_ptr in various
|
||||
// places, so allocate a StreamReplacer and stash it in a std::shared_ptr.
|
||||
auto* replacer = new StreamReplacer(&qpdf);
|
||||
std::shared_ptr<QPDFObjectHandle::StreamDataProvider> p(replacer);
|
||||
|
||||
for (auto& o: qpdf.getAllObjects()) {
|
||||
if (o.isStream()) {
|
||||
// Call registerStream for every stream. Only ones that
|
||||
// registerStream decides to replace will actually be
|
||||
// replaced.
|
||||
// Call registerStream for every stream. Only ones that registerStream decides to
|
||||
// replace will actually be replaced.
|
||||
replacer->registerStream(o, p);
|
||||
}
|
||||
}
|
||||
@ -454,9 +400,8 @@ main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
try {
|
||||
// Register our fictitious filter. This enables QPDFWriter to
|
||||
// decode our streams. This is not a real filter, so no real
|
||||
// PDF reading application would be able to interpret it. This
|
||||
// Register our fictitious filter. This enables QPDFWriter to decode our streams. This is
|
||||
// not a real filter, so no real PDF reading application would be able to interpret it. This
|
||||
// is just for illustrative purposes.
|
||||
QPDF::registerStreamFilter("/XORDecode", [] { return std::make_shared<SF_XORDecode>(); });
|
||||
// Do the actual processing.
|
||||
|
@ -14,18 +14,16 @@ void
|
||||
usage()
|
||||
{
|
||||
std::cerr << "Usage: " << whoami << " infile.pdf outfile.pdf [in-password]" << std::endl
|
||||
<< "Double size of all pages in infile.pdf;"
|
||||
<< " write output to outfile.pdf" << std::endl;
|
||||
<< "Double size of all pages in infile.pdf; write output to outfile.pdf" << std::endl;
|
||||
exit(2);
|
||||
}
|
||||
|
||||
// If there is a box of name box_name, replace it with a new box whose
|
||||
// elements are double the values of the original box.
|
||||
// If there is a box of name box_name, replace it with a new box whose elements are double the
|
||||
// values of the original box.
|
||||
static void
|
||||
doubleBoxSize(QPDFPageObjectHelper& page, char const* box_name)
|
||||
{
|
||||
// We need to use getAttribute rather than getKey as some boxes could
|
||||
// be inherited.
|
||||
// We need to use getAttribute rather than getKey as some boxes could be inherited.
|
||||
auto box = page.getAttribute(box_name, true);
|
||||
if (box.isNull()) {
|
||||
return;
|
||||
|
@ -1,7 +1,6 @@
|
||||
//
|
||||
// This example illustrates the use of QPDFObjectHandle::TokenFilter
|
||||
// with addContentTokenFilter. Please see comments inline for details.
|
||||
// See also pdf-count-strings.cc for a use of
|
||||
// This example illustrates the use of QPDFObjectHandle::TokenFilter with addContentTokenFilter.
|
||||
// Please see comments inline for details. See also pdf-count-strings.cc for a use of
|
||||
// QPDFObjectHandle::TokenFilter with filterContents.
|
||||
//
|
||||
|
||||
@ -26,9 +25,8 @@ usage()
|
||||
exit(2);
|
||||
}
|
||||
|
||||
// The StringReverser class is a trivial example of using a token
|
||||
// filter. This class only overrides the pure virtual handleToken
|
||||
// function and preserves the default handleEOF function.
|
||||
// The StringReverser class is a trivial example of using a token filter. This class only overrides
|
||||
// the pure virtual handleToken function and preserves the default handleEOF function.
|
||||
class StringReverser: public QPDFObjectHandle::TokenFilter
|
||||
{
|
||||
public:
|
||||
@ -39,15 +37,12 @@ class StringReverser: public QPDFObjectHandle::TokenFilter
|
||||
void
|
||||
StringReverser::handleToken(QPDFTokenizer::Token const& token)
|
||||
{
|
||||
// For string tokens, reverse the characters. For other tokens,
|
||||
// just pass them through. Notice that we construct a new string
|
||||
// token and write that, thus allowing the library to handle any
|
||||
// subtleties about properly encoding unprintable characters. This
|
||||
// function doesn't handle multibyte characters at all. It's not
|
||||
// intended to be an example of the correct way to reverse
|
||||
// strings. It's just intended to give a simple example of a
|
||||
// pretty minimal filter and to show an example of writing a
|
||||
// constructed token.
|
||||
// For string tokens, reverse the characters. For other tokens, just pass them through. Notice
|
||||
// that we construct a new string token and write that, thus allowing the library to handle any
|
||||
// subtleties about properly encoding unprintable characters. This function doesn't handle
|
||||
// multibyte characters at all. It's not intended to be an example of the correct way to reverse
|
||||
// strings. It's just intended to give a simple example of a pretty minimal filter and to show
|
||||
// an example of writing a constructed token.
|
||||
if (token.getType() == QPDFTokenizer::tt_string) {
|
||||
std::string value = token.getValue();
|
||||
std::reverse(value.begin(), value.end());
|
||||
@ -57,9 +52,8 @@ StringReverser::handleToken(QPDFTokenizer::Token const& token)
|
||||
}
|
||||
}
|
||||
|
||||
// The ColorToGray filter finds all "rg" operators in the content
|
||||
// stream and replaces them with "g" operators, thus mapping color to
|
||||
// grayscale. Note that it only applies to content streams, not
|
||||
// The ColorToGray filter finds all "rg" operators in the content stream and replaces them with "g"
|
||||
// operators, thus mapping color to grayscale. Note that it only applies to content streams, not
|
||||
// images, so this will not replace color images with grayscale
|
||||
// images.
|
||||
class ColorToGray: public QPDFObjectHandle::TokenFilter
|
||||
@ -99,29 +93,23 @@ ColorToGray::numericValue(QPDFTokenizer::Token const& token)
|
||||
void
|
||||
ColorToGray::handleToken(QPDFTokenizer::Token const& token)
|
||||
{
|
||||
// Track the number of non-ignorable tokens we've seen. If we see
|
||||
// an "rg" following three numbers, convert it to a grayscale
|
||||
// value. Keep writing tokens to the output as we can.
|
||||
// Track the number of non-ignorable tokens we've seen. If we see an "rg" following three
|
||||
// numbers, convert it to a grayscale value. Keep writing tokens to the output as we can.
|
||||
|
||||
// There are several things to notice here. We keep two stacks:
|
||||
// one of "meaningful" tokens, and one of all tokens. This way we
|
||||
// can preserve whitespace or comments that we encounter in the
|
||||
// stream and there preserve layout. As we receive tokens, we keep
|
||||
// the last four meaningful tokens. If we see three numbers
|
||||
// followed by rg, we use the three numbers to calculate a gray
|
||||
// value that is perceptually similar to the color value and then
|
||||
// write the "g" operator to the output, discarding any spaces or
|
||||
// comments encountered embedded in the "rg" operator.
|
||||
// There are several things to notice here. We keep two stacks: one of "meaningful" tokens, and
|
||||
// one of all tokens. This way we can preserve whitespace or comments that we encounter in the
|
||||
// stream and there preserve layout. As we receive tokens, we keep the last four meaningful
|
||||
// tokens. If we see three numbers followed by rg, we use the three numbers to calculate a gray
|
||||
// value that is perceptually similar to the color value and then write the "g" operator to the
|
||||
// output, discarding any spaces or comments encountered embedded in the "rg" operator.
|
||||
|
||||
// The stack and all_stack members are updated in such a way that
|
||||
// they always contain exactly the same non-ignorable tokens. The
|
||||
// stack member contains the tokens that would be left if you
|
||||
// The stack and all_stack members are updated in such a way that they always contain exactly
|
||||
// the same non-ignorable tokens. The stack member contains the tokens that would be left if you
|
||||
// removed all space and comment tokens from all_stack.
|
||||
|
||||
// On each new token, flush out any space or comment tokens. Store
|
||||
// the incoming token. If we just got an rg preceded by the right
|
||||
// kinds of operands, replace the command. Flush any additional
|
||||
// accumulated tokens to keep the stack only four tokens deep.
|
||||
// On each new token, flush out any space or comment tokens. Store the incoming token. If we
|
||||
// just got an rg preceded by the right kinds of operands, replace the command. Flush any
|
||||
// additional accumulated tokens to keep the stack only four tokens deep.
|
||||
|
||||
while ((!this->all_stack.empty()) && isIgnorable(this->all_stack.at(0).getType())) {
|
||||
writeToken(this->all_stack.at(0));
|
||||
@ -182,11 +170,9 @@ main(int argc, char* argv[])
|
||||
QPDF pdf;
|
||||
pdf.processFile(infilename);
|
||||
for (auto& page: QPDFPageDocumentHelper(pdf).getAllPages()) {
|
||||
// Attach two token filters to each page of this file.
|
||||
// When the file is written, or when the pages' contents
|
||||
// are retrieved in any other way, the filters will be
|
||||
// applied. See comments on the filters for additional
|
||||
// details.
|
||||
// Attach two token filters to each page of this file. When the file is written, or when
|
||||
// the pages' contents are retrieved in any other way, the filters will be applied. See
|
||||
// comments on the filters for additional details.
|
||||
page.addContentTokenFilter(
|
||||
std::shared_ptr<QPDFObjectHandle::TokenFilter>(new StringReverser));
|
||||
page.addContentTokenFilter(
|
||||
|
@ -20,15 +20,12 @@ usage()
|
||||
exit(2);
|
||||
}
|
||||
|
||||
// Derive a class from StreamDataProvider to provide updated stream
|
||||
// data. The main purpose of using this object is to avoid having to
|
||||
// allocate memory up front for the objects. We want to replace the
|
||||
// stream data with a function of the original stream data. In order
|
||||
// to do this without actually holding all the images in memory, we
|
||||
// create copies of the streams. Copying the streams doesn't actually
|
||||
// copy the data. Internally, the qpdf library is holding onto the
|
||||
// location of the original stream data, which makes it possible for
|
||||
// the StreamDataProvider to access it when it needs it.
|
||||
// Derive a class from StreamDataProvider to provide updated stream data. The main purpose of using
|
||||
// this object is to avoid having to allocate memory up front for the objects. We want to replace
|
||||
// the stream data with a function of the original stream data. In order to do this without actually
|
||||
// holding all the images in memory, we create copies of the streams. Copying the streams doesn't
|
||||
// actually copy the data. Internally, the qpdf library is holding onto the location of the original
|
||||
// stream data, which makes it possible for the StreamDataProvider to access it when it needs it.
|
||||
class ImageInverter: public QPDFObjectHandle::StreamDataProvider
|
||||
{
|
||||
public:
|
||||
@ -46,42 +43,35 @@ void
|
||||
ImageInverter::registerImage(
|
||||
QPDFObjectHandle image, std::shared_ptr<QPDFObjectHandle::StreamDataProvider> self)
|
||||
{
|
||||
// replaceStreamData requires a pointer holder to the stream data
|
||||
// provider, but there's no way for us to generate one ourselves,
|
||||
// so we have to have it handed to us. Don't be tempted to have
|
||||
// the class contain a std::shared_ptr to itself as a member. Doing
|
||||
// this will prevent the class from ever being deleted since the
|
||||
// reference count will never drop to zero (and std::shared_ptr
|
||||
// doesn't have weak references).
|
||||
// replaceStreamData requires a pointer holder to the stream data provider, but there's no way
|
||||
// for us to generate one ourselves, so we have to have it handed to us. Don't be tempted to
|
||||
// have the class contain a std::shared_ptr to itself as a member. Doing this will prevent the
|
||||
// class from ever being deleted since the reference count will never drop to zero (and
|
||||
// std::shared_ptr doesn't have weak references).
|
||||
|
||||
QPDFObjGen og(image.getObjGen());
|
||||
// Store information about the images based on the object and
|
||||
// generation number. Recall that a single image object may be
|
||||
// used more than once, so no need to update the same stream
|
||||
// multiple times.
|
||||
// Store information about the images based on the object and generation number. Recall that a
|
||||
// single image object may be used more than once, so no need to update the same stream multiple
|
||||
// times.
|
||||
if (this->copied_images.count(og) > 0) {
|
||||
return;
|
||||
}
|
||||
this->copied_images[og] = image.copyStream();
|
||||
|
||||
// Register our stream data provider for this stream. Future calls
|
||||
// to getStreamData or pipeStreamData will use the new
|
||||
// information. Provide null for both filter and decode
|
||||
// parameters. Note that this does not mean the image data will be
|
||||
// uncompressed when we write the file. By default, QPDFWriter
|
||||
// will use /FlateDecode for anything that is uncompressed or
|
||||
// filterable in the input QPDF object, so we don't have to deal
|
||||
// with it explicitly here. We could explicitly use /DCTDecode and
|
||||
// write through a DCT filter if we wanted.
|
||||
// Register our stream data provider for this stream. Future calls to getStreamData or
|
||||
// pipeStreamData will use the new information. Provide null for both filter and decode
|
||||
// parameters. Note that this does not mean the image data will be uncompressed when we write
|
||||
// the file. By default, QPDFWriter will use /FlateDecode for anything that is uncompressed or
|
||||
// filterable in the input QPDF object, so we don't have to deal with it explicitly here. We
|
||||
// could explicitly use /DCTDecode and write through a DCT filter if we wanted.
|
||||
image.replaceStreamData(self, QPDFObjectHandle::newNull(), QPDFObjectHandle::newNull());
|
||||
}
|
||||
|
||||
void
|
||||
ImageInverter::provideStreamData(QPDFObjGen const& og, Pipeline* pipeline)
|
||||
{
|
||||
// Use the object and generation number supplied to look up the
|
||||
// image data. Then invert the image data and write the inverted
|
||||
// data to the pipeline.
|
||||
// Use the object and generation number supplied to look up the image data. Then invert the
|
||||
// image data and write the inverted data to the pipeline.
|
||||
std::shared_ptr<Buffer> data = this->copied_images[og].getStreamData(qpdf_dl_all);
|
||||
size_t size = data->getSize();
|
||||
unsigned char* buf = data->getBuffer();
|
||||
@ -130,11 +120,9 @@ main(int argc, char* argv[])
|
||||
QPDFObjectHandle color_space = image_dict.getKey("/ColorSpace");
|
||||
QPDFObjectHandle bits_per_component = image_dict.getKey("/BitsPerComponent");
|
||||
|
||||
// For our example, we can only work with images 8-bit
|
||||
// grayscale images that we can fully decode. Use
|
||||
// pipeStreamData with a null pipeline to determine
|
||||
// whether the image is filterable. Directly inspect
|
||||
// keys to determine the image type.
|
||||
// For our example, we can only work with 8-bit grayscale images that we can fully
|
||||
// decode. Use pipeStreamData with a null pipeline to determine whether the image
|
||||
// is filterable. Directly inspect keys to determine the image type.
|
||||
if (image.pipeStreamData(nullptr, qpdf_ef_compress, qpdf_dl_all) &&
|
||||
color_space.isNameAndEquals("/DeviceGray") && bits_per_component.isInteger() &&
|
||||
(bits_per_component.getIntValue() == 8)) {
|
||||
@ -146,8 +134,7 @@ main(int argc, char* argv[])
|
||||
// Write out a new file
|
||||
QPDFWriter w(qpdf, outfilename);
|
||||
if (static_id) {
|
||||
// For the test suite, uncompress streams and use static
|
||||
// IDs.
|
||||
// For the test suite, uncompress streams and use static IDs.
|
||||
w.setStaticID(true); // for testing only
|
||||
}
|
||||
w.write();
|
||||
|
@ -51,8 +51,7 @@ main(int argc, char* argv[])
|
||||
|
||||
if (((qpdf_read(qpdf, infile, password) & QPDF_ERRORS) == 0) &&
|
||||
((qpdf_init_write(qpdf, outfile) & QPDF_ERRORS) == 0)) {
|
||||
/* Use static ID for testing only. For production, a
|
||||
* non-static ID is used. See also
|
||||
/* Use static ID for testing only. For production, a non-static ID is used. See also
|
||||
* qpdf_set_deterministic_ID. */
|
||||
qpdf_set_static_ID(qpdf, QPDF_TRUE); /* for testing only */
|
||||
qpdf_set_linearization(qpdf, QPDF_TRUE);
|
||||
|
@ -29,24 +29,19 @@ main(int argc, char* argv[])
|
||||
QPDF qpdf;
|
||||
qpdf.emptyPDF();
|
||||
|
||||
// This example doesn't do anything particularly useful other than
|
||||
// just illustrate how to use the APIs for name and number trees.
|
||||
// It also demonstrates use of the iterators for dictionaries and
|
||||
// arrays introduced at the same time with qpdf 10.2.
|
||||
// This example doesn't do anything particularly useful other than just illustrate how to use
|
||||
// the APIs for name and number trees. It also demonstrates use of the iterators for
|
||||
// dictionaries and arrays introduced at the same time with qpdf 10.2.
|
||||
|
||||
// To use this example, compile it and run it. Study the output
|
||||
// and compare it to what you expect. When done, look at the
|
||||
// generated output file in a text editor to inspect the structure
|
||||
// of the trees as left in the file.
|
||||
// To use this example, compile it and run it. Study the output and compare it to what you
|
||||
// expect. When done, look at the generated output file in a text editor to inspect the
|
||||
// structure of the trees as left in the file.
|
||||
|
||||
// We're just going to create some name and number trees, hang
|
||||
// them off the document catalog (root), and write an empty PDF to
|
||||
// a file. The PDF will have no pages and won't be viewable, but
|
||||
// you can look at it in a text editor to see the resulting
|
||||
// structure of the PDF.
|
||||
// We're just going to create some name and number trees, hang them off the document catalog
|
||||
// (root), and write an empty PDF to a file. The PDF will have no pages and won't be viewable,
|
||||
// but you can look at it in a text editor to see the resulting structure of the PDF.
|
||||
|
||||
// Create a dictionary off the root where we will hang our name
|
||||
// and number tree.
|
||||
// Create a dictionary off the root where we will hang our name and number trees.
|
||||
auto root = qpdf.getRoot();
|
||||
auto example = QPDFObjectHandle::newDictionary();
|
||||
root.replaceKey("/Example", example);
|
||||
@ -75,8 +70,8 @@ main(int argc, char* argv[])
|
||||
std::cout << " " << i.first << " -> " << i.second.unparse() << std::endl;
|
||||
}
|
||||
|
||||
// This is a small tree, so everything will be at the root. We can
|
||||
// look at it using dictionary and array iterators.
|
||||
// This is a small tree, so everything will be at the root. We can look at it using dictionary
|
||||
// and array iterators.
|
||||
std::cout << "Keys in name tree object:" << std::endl;
|
||||
QPDFObjectHandle names;
|
||||
for (auto const& i: name_tree_oh.ditems()) {
|
||||
@ -121,15 +116,12 @@ main(int argc, char* argv[])
|
||||
<< std::endl;
|
||||
std::cout << "Has K?: " << name_tree.hasName("K") << std::endl;
|
||||
|
||||
// Illustrate some more advanced usage using number trees. These
|
||||
// calls work for name trees too.
|
||||
// Illustrate some more advanced usage using number trees. These calls work for name trees too.
|
||||
|
||||
// The safe way to populate a tree is to call insert repeatedly as
|
||||
// above, but if you know you are definitely inserting items in
|
||||
// order, it is more efficient to insert them using insertAfter,
|
||||
// which avoids doing a binary search through the tree for each
|
||||
// insertion. Note that if you don't insert items in order using
|
||||
// this method, you will create an invalid tree.
|
||||
// The safe way to populate a tree is to call insert repeatedly as above, but if you know you
|
||||
// are definitely inserting items in order, it is more efficient to insert them using
|
||||
// insertAfter, which avoids doing a binary search through the tree for each insertion. Note
|
||||
// that if you don't insert items in order using this method, you will create an invalid tree.
|
||||
auto number_tree = QPDFNumberTreeObjectHelper::newEmpty(qpdf);
|
||||
auto number_tree_oh = number_tree.getObjectHandle();
|
||||
example.replaceKey("/NumberTree", number_tree_oh);
|
||||
@ -149,9 +141,8 @@ main(int argc, char* argv[])
|
||||
++n;
|
||||
}
|
||||
|
||||
// When you remove an item with an iterator, the iterator
|
||||
// advances. This makes it possible to filter while iterating.
|
||||
// Remove all items that are multiples of 5.
|
||||
// When you remove an item with an iterator, the iterator advances. This makes it possible to
|
||||
// filter while iterating. Remove all items that are multiples of 5.
|
||||
iter2 = number_tree.begin();
|
||||
while (iter2 != number_tree.end()) {
|
||||
if (iter2->first % 5 == 0) {
|
||||
|
@ -6,10 +6,9 @@
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
// This program demonstrates use of form XObjects to overlay a page
|
||||
// from one file onto all pages of another file. The qpdf program's
|
||||
// --overlay and --underlay options provide a more general version of
|
||||
// this capability.
|
||||
// This program demonstrates use of form XObjects to overlay a page from one file onto all pages of
|
||||
// another file. The qpdf program's --overlay and --underlay options provide a more general version
|
||||
// of this capability.
|
||||
|
||||
static char const* whoami = nullptr;
|
||||
|
||||
@ -44,24 +43,21 @@ stamp_page(char const* infile, char const* stampfile, char const* outfile)
|
||||
int min_suffix = 1;
|
||||
std::string name = resources.getUniqueResourceName("/Fx", min_suffix);
|
||||
|
||||
// Generate content to place the form XObject centered within
|
||||
// destination page's trim box.
|
||||
// Generate content to place the form XObject centered within destination page's trim box.
|
||||
QPDFMatrix m;
|
||||
std::string content =
|
||||
ph.placeFormXObject(stamp_fo, name, ph.getTrimBox().getArrayAsRectangle(), m);
|
||||
if (!content.empty()) {
|
||||
// Append the content to the page's content. Surround the
|
||||
// original content with q...Q to the new content from the
|
||||
// page's original content.
|
||||
// Append the content to the page's content. Surround the original content with q...Q to
|
||||
// the new content from the page's original content.
|
||||
resources.mergeResources("<< /XObject << >> >>"_qpdf);
|
||||
resources.getKey("/XObject").replaceKey(name, stamp_fo);
|
||||
ph.addPageContents(inpdf.newStream("q\n"), true);
|
||||
ph.addPageContents(inpdf.newStream("\nQ\n" + content), false);
|
||||
}
|
||||
// Copy the annotations and form fields from the original page
|
||||
// to the new page. For more efficiency when copying multiple
|
||||
// pages, we can create a QPDFAcroFormDocumentHelper and pass
|
||||
// it in. See comments in QPDFPageObjectHelper.hh for details.
|
||||
// Copy the annotations and form fields from the original page to the new page. For more
|
||||
// efficiency when copying multiple pages, we can create a QPDFAcroFormDocumentHelper and
|
||||
// pass it in. See comments in QPDFPageObjectHelper.hh for details.
|
||||
ph.copyAnnotations(stamp_page_1, m);
|
||||
}
|
||||
|
||||
|
@ -13,8 +13,8 @@ void
|
||||
usage()
|
||||
{
|
||||
std::cerr << "Usage: " << whoami << " filename page-number" << std::endl
|
||||
<< "Prints a dump of the objects in the content streams"
|
||||
<< " of the given page." << std::endl
|
||||
<< "Prints a dump of the objects in the content streams of the given page."
|
||||
<< std::endl
|
||||
<< "Pages are numbered from 1." << std::endl;
|
||||
exit(2);
|
||||
}
|
||||
|
@ -29,42 +29,34 @@ main(int argc, char* argv[])
|
||||
char const* outfilename = argv[2];
|
||||
char const* value = argv[3];
|
||||
|
||||
// This is a contrived example that just goes through a file page
|
||||
// by page and sets the value of any text fields it finds to a
|
||||
// fixed value as given on the command line. The purpose here is
|
||||
// to illustrate use of the helper classes around interactive
|
||||
// forms.
|
||||
// This is a contrived example that just goes through a file page by page and sets the value of
|
||||
// any text fields it finds to a fixed value as given on the command line. The purpose here is
|
||||
// to illustrate use of the helper classes around interactive forms.
|
||||
|
||||
try {
|
||||
QPDF qpdf;
|
||||
qpdf.processFile(infilename);
|
||||
|
||||
// We will iterate through form fields by starting at the page
|
||||
// level and looking at each field for each page. We could
|
||||
// also called QPDFAcroFormDocumentHelper::getFormFields to
|
||||
// iterate at the field level, but doing it as below
|
||||
// illustrates how we can map from annotations to fields.
|
||||
// We will iterate through form fields by starting at the page level and looking at each
|
||||
// field for each page. We could also call QPDFAcroFormDocumentHelper::getFormFields to
|
||||
// iterate at the field level, but doing it as below illustrates how we can map from
|
||||
// annotations to fields.
|
||||
|
||||
QPDFAcroFormDocumentHelper afdh(qpdf);
|
||||
for (auto const& page: QPDFPageDocumentHelper(qpdf).getAllPages()) {
|
||||
// Get all widget annotations for each page. Widget
|
||||
// annotations are the ones that contain the details of
|
||||
// what's in a form field.
|
||||
// Get all widget annotations for each page. Widget annotations are the ones that
|
||||
// contain the details of what's in a form field.
|
||||
for (auto& annot: afdh.getWidgetAnnotationsForPage(page)) {
|
||||
// For each annotation, find its associated field. If
|
||||
// it's a text field, set its value.
|
||||
// For each annotation, find its associated field. If it's a text field, set its
|
||||
// value.
|
||||
QPDFFormFieldObjectHelper ffh = afdh.getFieldForAnnotation(annot);
|
||||
if (ffh.getFieldType() == "/Tx") {
|
||||
// Set the value. Passing false as the second
|
||||
// value prevents qpdf from setting
|
||||
// /NeedAppearances to true (but will not turn it
|
||||
// off if it's already on), so we call
|
||||
// generateAppearance after setting the value. You
|
||||
// may or may not want to do this depending on
|
||||
// whether the appearance streams generated by
|
||||
// qpdf are good enough for your purposes. For
|
||||
// additional details, please see comments in
|
||||
// QPDFFormFieldObjectHelper.hh for this method.
|
||||
// Set the value. Passing false as the second parameter prevents qpdf from
|
||||
// setting /NeedAppearances to true (but will not turn it off if it's already
|
||||
// on), so we call generateAppearance after setting the value. You may or may
|
||||
// not want to do this depending on whether the appearance streams generated by
|
||||
// qpdf are good enough for your purposes. For additional details, please see
|
||||
// comments in QPDFFormFieldObjectHelper.hh for this method.
|
||||
ffh.setV(value, false);
|
||||
ffh.generateAppearance(annot);
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
//
|
||||
// This is a stand-alone example of splitting a PDF into individual
|
||||
// pages. It does essentially the same thing that qpdf --split-pages
|
||||
// does.
|
||||
// This is a stand-alone example of splitting a PDF into individual pages. It does essentially the
|
||||
// same thing that qpdf --split-pages does.
|
||||
//
|
||||
|
||||
#include <qpdf/QIntC.hh>
|
||||
@ -32,8 +31,7 @@ process(char const* whoami, char const* infile, std::string outprefix)
|
||||
QPDFPageDocumentHelper(outpdf).addPage(page, false);
|
||||
QPDFWriter outpdfw(outpdf, outfile.c_str());
|
||||
if (static_id) {
|
||||
// For the test suite, uncompress streams and use static
|
||||
// IDs.
|
||||
// For the test suite, uncompress streams and use static IDs.
|
||||
outpdfw.setStaticID(true); // for testing only
|
||||
outpdfw.setStreamDataMode(qpdf_s_uncompress);
|
||||
}
|
||||
|
@ -3,8 +3,7 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// This program is a simple demonstration of different ways to use the
|
||||
// QPDFJob API.
|
||||
// This program is a simple demonstration of different ways to use the QPDFJob API.
|
||||
|
||||
static char const* whoami = nullptr;
|
||||
|
||||
@ -28,10 +27,9 @@ main(int argc, char* argv[])
|
||||
usage();
|
||||
}
|
||||
|
||||
// The examples below all catch std::exception. Note that
|
||||
// QPDFUsage can be caught separately to report on errors in using
|
||||
// the API itself. For CLI, this is command-line usage. For JSON
|
||||
// or the API, it would be errors from the equivalent invocation.
|
||||
// The examples below all catch std::exception. Note that QPDFUsage can be caught separately to
|
||||
// report on errors in using the API itself. For CLI, this is command-line usage. For JSON or
|
||||
// the API, it would be errors from the equivalent invocation.
|
||||
|
||||
// Note that staticId is used for testing only.
|
||||
|
||||
|
@ -6,10 +6,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// This example demonstrates how we can redirect where saved output
|
||||
// goes by calling the default logger's setSave method before running
|
||||
// something with QPDFJob. See qpdfjob-c-save-attachment.c for an
|
||||
// implementation that uses the C API.
|
||||
// This example demonstrates how we can redirect where saved output goes by calling the default
|
||||
// logger's setSave method before running something with QPDFJob. See qpdfjob-c-save-attachment.c
|
||||
// for an implementation that uses the C API.
|
||||
|
||||
static int
|
||||
save_to_file(char const* data, size_t len, void* udata)
|
||||
@ -79,9 +78,8 @@ main(int argc, char* argv[])
|
||||
};
|
||||
outfile = do_fopen(outfilename);
|
||||
|
||||
/* Use qpdflogger_set_save with a callback function to redirect
|
||||
* saved data. You can use other qpdf logger functions to capture
|
||||
* informational output, warnings, and errors.
|
||||
/* Use qpdflogger_set_save with a callback function to redirect saved data. You can use other
|
||||
* qpdf logger functions to capture informational output, warnings, and errors.
|
||||
*/
|
||||
qpdflogger_set_save(l, qpdf_log_dest_custom, save_to_file, (void*)outfile, 0);
|
||||
qpdflogger_cleanup(&l);
|
||||
|
@ -1,7 +1,4 @@
|
||||
/*
|
||||
* This is an example program to linearize a PDF file using the C
|
||||
* QPDFJob API.
|
||||
*/
|
||||
/* This is an example program to linearize a PDF file using the C QPDFJob API. */
|
||||
|
||||
#include <qpdf/qpdfjob-c.h>
|
||||
#include <stdio.h>
|
||||
@ -48,14 +45,12 @@ main(int argc, char* argv[])
|
||||
new_argv[4] = "--static-id"; /* for testing only */
|
||||
new_argv[5] = NULL;
|
||||
|
||||
/* See qpdf-job.cc for a C++ example of using the json interface.
|
||||
* To use that from C just like the argv one, call
|
||||
* qpdfjob_run_from_json instead and pass the json string as a
|
||||
* single char const* argument.
|
||||
/* See qpdf-job.cc for a C++ example of using the json interface. To use that from C just like
|
||||
* the argv one, call qpdfjob_run_from_json instead and pass the json string as a single char
|
||||
* const* argument.
|
||||
*
|
||||
* See qpdfjob-c-save-attachment.c for an example of using the
|
||||
* full form of the qpdfjob interface with init and cleanup
|
||||
* functions.
|
||||
* See qpdfjob-c-save-attachment.c for an example of using the full form of the qpdfjob
|
||||
* interface with init and cleanup functions.
|
||||
*/
|
||||
r = qpdfjob_run_from_argv(new_argv);
|
||||
return r;
|
||||
|
@ -6,10 +6,9 @@
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
// This example demonstrates how we can use the QPDFJob createQPDF and writeQPDF
|
||||
// methods to add custom transformations to the output produced by QPDFJob runs.
|
||||
// The example is a full copy of the qpdf program modified to allways remove all
|
||||
// annotations from the final output.
|
||||
// This example demonstrates how we can use the QPDFJob createQPDF and writeQPDF methods to add
|
||||
// custom transformations to the output produced by QPDFJob runs. The example is a full copy of the
|
||||
// qpdf program modified to allways remove all annotations from the final output.
|
||||
|
||||
static char const* whoami = nullptr;
|
||||
|
||||
|
@ -3,10 +3,9 @@
|
||||
#include <qpdf/QPDFLogger.hh>
|
||||
#include <qpdf/QUtil.hh>
|
||||
|
||||
// This example demonstrates how we can redirect where saved output
|
||||
// goes by calling the default logger's setSave method before running
|
||||
// something with QPDFJob. See qpdfjob-c-save-attachment.c for an
|
||||
// implementation that uses the C API.
|
||||
// This example demonstrates how we can redirect where saved output goes by calling the default
|
||||
// logger's setSave method before running something with QPDFJob. See qpdfjob-c-save-attachment.c
|
||||
// for an implementation that uses the C API.
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDF_BUFFERINPUTSOURCE_HH
|
||||
#define QPDF_BUFFERINPUTSOURCE_HH
|
||||
@ -28,8 +25,8 @@
|
||||
class QPDF_DLL_CLASS BufferInputSource: public InputSource
|
||||
{
|
||||
public:
|
||||
// If own_memory is true, BufferInputSource will delete the buffer
|
||||
// when finished with it. Otherwise, the caller owns the memory.
|
||||
// If own_memory is true, BufferInputSource will delete the buffer when finished with it.
|
||||
// Otherwise, the caller owns the memory.
|
||||
QPDF_DLL
|
||||
BufferInputSource(std::string const& description, Buffer* buf, bool own_memory = false);
|
||||
QPDF_DLL
|
||||
|
@ -2,31 +2,27 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDF_CLOSEDFILEINPUTSOURCE_HH
|
||||
#define QPDF_CLOSEDFILEINPUTSOURCE_HH
|
||||
|
||||
// This is an input source that reads from files, like
|
||||
// FileInputSource, except that it opens and close the file
|
||||
// surrounding every operation. This decreases efficiency, but it allows
|
||||
// many more of these to exist at once than the maximum number of open
|
||||
// file descriptors. This is used for merging large numbers of files.
|
||||
// This is an input source that reads from files, like FileInputSource, except that it opens and
|
||||
// closes the file surrounding every operation. This decreases efficiency, but it allows many more
|
||||
// of these to exist at once than the maximum number of open file descriptors. This is used for
|
||||
// merging large numbers of files.
|
||||
|
||||
#include <qpdf/InputSource.hh>
|
||||
#include <qpdf/PointerHolder.hh> // unused -- remove in qpdf 12 (see #785)
|
||||
@ -57,10 +53,9 @@ class QPDF_DLL_CLASS ClosedFileInputSource: public InputSource
|
||||
QPDF_DLL
|
||||
virtual void unreadCh(char ch);
|
||||
|
||||
// The file stays open between calls to stayOpen(true) and
|
||||
// stayOpen(false). You can use this to surround multiple
|
||||
// operations on a single ClosedFileInputSource to reduce the
|
||||
// overhead of a separate open/close on each call.
|
||||
// The file stays open between calls to stayOpen(true) and stayOpen(false). You can use this to
|
||||
// surround multiple operations on a single ClosedFileInputSource to reduce the overhead of a
|
||||
// separate open/close on each call.
|
||||
QPDF_DLL
|
||||
void stayOpen(bool);
|
||||
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDF_FILEINPUTSOURCE_HH
|
||||
#define QPDF_FILEINPUTSOURCE_HH
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDF_INPUTSOURCE_HH
|
||||
#define QPDF_INPUTSOURCE_HH
|
||||
@ -30,9 +27,8 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
// Remember to use QPDF_DLL_CLASS on anything derived from InputSource
|
||||
// so it will work with dynamic_cast across the shared object
|
||||
// boundary.
|
||||
// Remember to use QPDF_DLL_CLASS on anything derived from InputSource so it will work with
|
||||
// dynamic_cast across the shared object boundary.
|
||||
class QPDF_DLL_CLASS InputSource
|
||||
{
|
||||
public:
|
||||
@ -61,12 +57,10 @@ class QPDF_DLL_CLASS InputSource
|
||||
QPDF_DLL
|
||||
std::string readLine(size_t max_line_length);
|
||||
|
||||
// Find first or last occurrence of a sequence of characters
|
||||
// starting within the range defined by offset and len such that,
|
||||
// when the input source is positioned at the beginning of that
|
||||
// sequence, finder.check() returns true. If len is 0, the search
|
||||
// proceeds until EOF. If a qualifying pattern is found, these
|
||||
// methods return true and leave the input source positioned
|
||||
// Find first or last occurrence of a sequence of characters starting within the range defined
|
||||
// by offset and len such that, when the input source is positioned at the beginning of that
|
||||
// sequence, finder.check() returns true. If len is 0, the search proceeds until EOF. If a
|
||||
// qualifying pattern is found, these methods return true and leave the input source positioned
|
||||
// wherever check() left it at the end of the matching pattern.
|
||||
QPDF_DLL
|
||||
bool findFirst(char const* start_chars, qpdf_offset_t offset, size_t len, Finder& finder);
|
||||
@ -80,11 +74,9 @@ class QPDF_DLL_CLASS InputSource
|
||||
virtual void rewind() = 0;
|
||||
virtual size_t read(char* buffer, size_t length) = 0;
|
||||
|
||||
// Note: you can only unread the character you just read. The
|
||||
// specific character is ignored by some implementations, and the
|
||||
// implementation doesn't check this. Use of unreadCh is
|
||||
// semantically equivalent to seek(-1, SEEK_CUR) but is much more
|
||||
// efficient.
|
||||
// Note: you can only unread the character you just read. The specific character is ignored by
|
||||
// some implementations, and the implementation doesn't check this. Use of unreadCh is
|
||||
// semantically equivalent to seek(-1, SEEK_CUR) but is much more efficient.
|
||||
virtual void unreadCh(char ch) = 0;
|
||||
|
||||
// The following methods are for use by QPDFTokenizer
|
||||
@ -149,9 +141,8 @@ InputSource::fastTell()
|
||||
inline bool
|
||||
InputSource::fastRead(char& ch)
|
||||
{
|
||||
// Before calling fastRead, fastTell must be called to prepare the buffer.
|
||||
// Once reading is complete, fastUnread must be called to set the correct
|
||||
// file position.
|
||||
// Before calling fastRead, fastTell must be called to prepare the buffer. Once reading is
|
||||
// complete, fastUnread must be called to set the correct file position.
|
||||
if (this->buf_idx < this->buf_len) {
|
||||
ch = this->buffer[this->buf_idx];
|
||||
++(this->buf_idx);
|
||||
|
@ -69,7 +69,7 @@ class JSON
|
||||
// to pass that `first` through to all the methods that are called to add top-level items to the
|
||||
// container as well as to close the container. This lets the JSON object use it to keep track
|
||||
// of when it's writing a first object and when it's not. If incrementally writing multiple
|
||||
// levels of depth, a new `first` should used for each new container that is opened.
|
||||
// levels of depth, a new `first` should be used for each new container that is opened.
|
||||
//
|
||||
// "depth" -- Indicate the level of depth. This is used for consistent indentation. When writing
|
||||
// incrementally, whenever you call a method to add an item to a container, the value of `depth`
|
||||
@ -208,7 +208,7 @@ class JSON
|
||||
QPDF_DLL
|
||||
bool checkSchema(JSON schema, std::list<std::string>& errors);
|
||||
|
||||
// An pointer to a Reactor class can be passed to parse, which will enable the caller to react
|
||||
// A pointer to a Reactor class can be passed to parse, which will enable the caller to react
|
||||
// to incremental events in the construction of the JSON object. This makes it possible to
|
||||
// implement SAX-like handling of very large JSON objects.
|
||||
class QPDF_DLL_CLASS Reactor
|
||||
|
@ -2,26 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
|
||||
// This class implements a simple writer for saving QPDF objects to
|
||||
// new PDF files. See comments through the header file for additional
|
||||
// details.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef PDFVERSION_HH
|
||||
#define PDFVERSION_HH
|
||||
@ -32,10 +25,9 @@
|
||||
class PDFVersion
|
||||
{
|
||||
public:
|
||||
// Represent a PDF version. PDF versions are typically
|
||||
// major.minor, but PDF 1.7 has several extension levels as the
|
||||
// ISO 32000 spec was in progress. This class helps with
|
||||
// comparison of versions.
|
||||
// Represent a PDF version. PDF versions are typically major.minor, but PDF 1.7 has several
|
||||
// extension levels as the ISO 32000 spec was in progress. This class helps with comparison of
|
||||
// versions.
|
||||
QPDF_DLL
|
||||
PDFVersion();
|
||||
QPDF_DLL
|
||||
@ -49,13 +41,12 @@ class PDFVersion
|
||||
QPDF_DLL
|
||||
bool operator==(PDFVersion const& rhs) const;
|
||||
|
||||
// Replace this version with the other one if the other one is
|
||||
// greater.
|
||||
// Replace this version with the other one if the other one is greater.
|
||||
QPDF_DLL
|
||||
void updateIfGreater(PDFVersion const& other);
|
||||
|
||||
// Initialize a string and integer suitable for passing to
|
||||
// QPDFWriter::setMinimumPDFVersion or QPDFWriter::forcePDFVersion.
|
||||
// Initialize a string and integer suitable for passing to QPDFWriter::setMinimumPDFVersion or
|
||||
// QPDFWriter::forcePDFVersion.
|
||||
QPDF_DLL
|
||||
void getVersion(std::string& version, int& extension_level) const;
|
||||
|
||||
|
@ -26,8 +26,7 @@
|
||||
//
|
||||
// The client is required to call finish() before destroying a Pipeline in order to avoid loss of
|
||||
// data. A Pipeline class should not throw an exception in the destructor if this hasn't been done
|
||||
// though since doing so causes too much trouble when deleting
|
||||
// pipelines during error conditions.
|
||||
// though since doing so causes too much trouble when deleting pipelines during error conditions.
|
||||
//
|
||||
// Some pipelines are reusable (i.e., you can call write() after calling finish() and can call
|
||||
// finish() multiple times) while others are not. It is up to the caller to use a pipeline
|
||||
|
@ -47,8 +47,8 @@ class QPDF_DLL_CLASS Pl_Buffer: public Pipeline
|
||||
void finish() override;
|
||||
|
||||
// Each call to getBuffer() resets this object -- see notes above.
|
||||
// The caller is responsible for deleting the returned Buffer
|
||||
// object. See also getBufferSharedPointer() and getMallocBuffer().
|
||||
// The caller is responsible for deleting the returned Buffer object. See also
|
||||
// getBufferSharedPointer() and getMallocBuffer().
|
||||
QPDF_DLL
|
||||
Buffer* getBuffer();
|
||||
|
||||
|
@ -2,31 +2,27 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef PL_CONCATENATE_HH
|
||||
#define PL_CONCATENATE_HH
|
||||
|
||||
// This pipeline will drop all regular finished calls rather than
|
||||
// passing them onto next. To finish downstream streams, call
|
||||
// manualFinish. This makes it possible to pipe multiple streams
|
||||
// (e.g. with QPDFObjectHandle::pipeStreamData) to a downstream like
|
||||
// Pl_Flate that can't handle multiple calls to finish().
|
||||
// This pipeline will drop all regular finish calls rather than passing them onto next. To finish
|
||||
// downstream streams, call manualFinish. This makes it possible to pipe multiple streams (e.g.
|
||||
// with QPDFObjectHandle::pipeStreamData) to a downstream like Pl_Flate that can't handle multiple
|
||||
// calls to finish().
|
||||
|
||||
#include <qpdf/Pipeline.hh>
|
||||
|
||||
@ -44,8 +40,7 @@ class QPDF_DLL_CLASS Pl_Concatenate: public Pipeline
|
||||
QPDF_DLL
|
||||
virtual void finish();
|
||||
|
||||
// At the very end, call manualFinish to actually finish the rest of
|
||||
// the pipeline.
|
||||
// At the very end, call manualFinish to actually finish the rest of the pipeline.
|
||||
QPDF_DLL
|
||||
void manualFinish();
|
||||
|
||||
|
@ -2,28 +2,24 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef PL_COUNT_HH
|
||||
#define PL_COUNT_HH
|
||||
|
||||
// This pipeline is reusable; i.e., it is safe to call write() after
|
||||
// calling finish().
|
||||
// This pipeline is reusable; i.e., it is safe to call write() after calling finish().
|
||||
|
||||
#include <qpdf/Pipeline.hh>
|
||||
#include <qpdf/Types.h>
|
||||
@ -42,8 +38,8 @@ class QPDF_DLL_CLASS Pl_Count: public Pipeline
|
||||
// Returns the number of bytes written
|
||||
QPDF_DLL
|
||||
qpdf_offset_t getCount() const;
|
||||
// Returns the last character written, or '\0' if no characters
|
||||
// have been written (in which case getCount() returns 0)
|
||||
// Returns the last character written, or '\0' if no characters have been written (in which case
|
||||
// getCount() returns 0)
|
||||
QPDF_DLL
|
||||
unsigned char getLastChar() const;
|
||||
|
||||
@ -60,8 +56,7 @@ class QPDF_DLL_CLASS Pl_Count: public Pipeline
|
||||
Members();
|
||||
Members(Members const&) = delete;
|
||||
|
||||
// Must be qpdf_offset_t, not size_t, to handle writing more than
|
||||
// size_t can handle.
|
||||
// Must be qpdf_offset_t, not size_t, to handle writing more than size_t can handle.
|
||||
qpdf_offset_t count;
|
||||
unsigned char last_char;
|
||||
};
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef PL_DCT_HH
|
||||
#define PL_DCT_HH
|
||||
@ -27,8 +24,7 @@
|
||||
#include <qpdf/Pl_Buffer.hh>
|
||||
#include <cstddef>
|
||||
|
||||
// jpeglib.h must be included after cstddef or else it messes up the
|
||||
// definition of size_t.
|
||||
// jpeglib.h must be included after cstddef or else it messes up the definition of size_t.
|
||||
#include <jpeglib.h>
|
||||
|
||||
class QPDF_DLL_CLASS Pl_DCT: public Pipeline
|
||||
|
@ -2,31 +2,26 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef PL_DISCARD_HH
|
||||
#define PL_DISCARD_HH
|
||||
|
||||
// This pipeline discards its output. It is an end-of-line pipeline
|
||||
// (with no next).
|
||||
// This pipeline discards its output. It is an end-of-line pipeline (with no next).
|
||||
|
||||
// This pipeline is reusable; i.e., it is safe to call write() after
|
||||
// calling finish().
|
||||
// This pipeline is reusable; i.e., it is safe to call write() after calling finish().
|
||||
|
||||
#include <qpdf/Pipeline.hh>
|
||||
|
||||
|
@ -2,38 +2,33 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef PL_FUNCTION_HH
|
||||
#define PL_FUNCTION_HH
|
||||
|
||||
// This pipeline calls an arbitrary function with whatever data is
|
||||
// passed to it. This pipeline can be reused.
|
||||
// This pipeline calls an arbitrary function with whatever data is passed to it. This pipeline can
|
||||
// be reused.
|
||||
//
|
||||
// For this pipeline, "next" may be null. If a next pointer is
|
||||
// provided, this pipeline will also pass the data through to it and
|
||||
// will forward finish() to it.
|
||||
// For this pipeline, "next" may be null. If a next pointer is provided, this pipeline will also
|
||||
// pass the data through to it and will forward finish() to it.
|
||||
//
|
||||
// It is okay to not call finish() on this pipeline if it has no
|
||||
// "next".
|
||||
// It is okay to not call finish() on this pipeline if it has no "next".
|
||||
//
|
||||
// It is okay to keep calling write() after a previous write throws an
|
||||
// exception as long as the delegated function allows it.
|
||||
// It is okay to keep calling write() after a previous write throws an exception as long as the
|
||||
// delegated function allows it.
|
||||
|
||||
#include <qpdf/Pipeline.hh>
|
||||
|
||||
@ -48,10 +43,9 @@ class QPDF_DLL_CLASS Pl_Function: public Pipeline
|
||||
QPDF_DLL
|
||||
Pl_Function(char const* identifier, Pipeline* next, writer_t fn);
|
||||
|
||||
// The supplied C-style function is called every time write is
|
||||
// called. The udata option is passed into the function with each
|
||||
// call. If the function returns a non-zero value, a runtime error
|
||||
// is thrown.
|
||||
// The supplied C-style function is called every time write is called. The udata option is
|
||||
// passed into the function with each call. If the function returns a non-zero value, a runtime
|
||||
// error is thrown.
|
||||
typedef int (*writer_c_t)(unsigned char const*, size_t, void*);
|
||||
QPDF_DLL
|
||||
Pl_Function(char const* identifier, Pipeline* next, writer_c_t fn, void* udata);
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
// End-of-line pipeline that simply writes its data to a stdio FILE* object.
|
||||
|
||||
@ -35,8 +32,7 @@
|
||||
class QPDF_DLL_CLASS Pl_OStream: public Pipeline
|
||||
{
|
||||
public:
|
||||
// os is externally maintained; this class just writes to and
|
||||
// flushes it. It does not close it.
|
||||
// os is externally maintained; this class just writes to and flushes it. It does not close it.
|
||||
QPDF_DLL
|
||||
Pl_OStream(char const* identifier, std::ostream& os);
|
||||
QPDF_DLL
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef PL_QPDFTOKENIZER_HH
|
||||
#define PL_QPDFTOKENIZER_HH
|
||||
@ -31,22 +28,19 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
// Tokenize the incoming text using QPDFTokenizer and pass the tokens
|
||||
// in turn to a QPDFObjectHandle::TokenFilter object. All bytes of
|
||||
// incoming content will be included in exactly one token and passed
|
||||
// downstream.
|
||||
// Tokenize the incoming text using QPDFTokenizer and pass the tokens in turn to a
|
||||
// QPDFObjectHandle::TokenFilter object. All bytes of incoming content will be included in exactly
|
||||
// one token and passed downstream.
|
||||
|
||||
// This is a very low-level interface for working with token filters.
|
||||
// Most code will want to use QPDFObjectHandle::filterPageContents or
|
||||
// QPDFObjectHandle::addTokenFilter. See QPDFObjectHandle.hh for
|
||||
// details.
|
||||
// This is a very low-level interface for working with token filters. Most code will want to use
|
||||
// QPDFObjectHandle::filterPageContents or QPDFObjectHandle::addTokenFilter. See QPDFObjectHandle.hh
|
||||
// for details.
|
||||
|
||||
class QPDF_DLL_CLASS Pl_QPDFTokenizer: public Pipeline
|
||||
{
|
||||
public:
|
||||
// Whatever pipeline is provided as "next" will be set as the
|
||||
// pipeline that the token filter writes to. If next is not
|
||||
// provided, any output written by the filter will be discarded.
|
||||
// Whatever pipeline is provided as "next" will be set as the pipeline that the token filter
|
||||
// writes to. If next is not provided, any output written by the filter will be discarded.
|
||||
QPDF_DLL
|
||||
Pl_QPDFTokenizer(
|
||||
char const* identifier, QPDFObjectHandle::TokenFilter* filter, Pipeline* next = nullptr);
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef PL_RUNLENGTH_HH
|
||||
#define PL_RUNLENGTH_HH
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
// End-of-line pipeline that simply writes its data to a stdio FILE* object.
|
||||
|
||||
@ -35,8 +32,7 @@
|
||||
class QPDF_DLL_CLASS Pl_StdioFile: public Pipeline
|
||||
{
|
||||
public:
|
||||
// f is externally maintained; this class just writes to and
|
||||
// flushes it. It does not close it.
|
||||
// f is externally maintained; this class just writes to and flushes it. It does not close it.
|
||||
QPDF_DLL
|
||||
Pl_StdioFile(char const* identifier, FILE* f);
|
||||
QPDF_DLL
|
||||
|
@ -2,39 +2,34 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef PL_STRING_HH
|
||||
#define PL_STRING_HH
|
||||
|
||||
// This pipeline accumulates the data passed to it into a std::string,
|
||||
// a reference to which is passed in at construction. Each subsequent
|
||||
// use of this pipeline appends to the data accumulated so far.
|
||||
// This pipeline accumulates the data passed to it into a std::string, a reference to which is
|
||||
// passed in at construction. Each subsequent use of this pipeline appends to the data accumulated
|
||||
// so far.
|
||||
//
|
||||
// For this pipeline, "next" may be null. If a next pointer is
|
||||
// provided, this pipeline will also pass the data through to it and
|
||||
// will forward finish() to it.
|
||||
// For this pipeline, "next" may be null. If a next pointer is provided, this pipeline will also
|
||||
// pass the data through to it and will forward finish() to it.
|
||||
//
|
||||
// It is okay to not call finish() on this pipeline if it has no
|
||||
// "next". This makes it easy to stick this in front of another
|
||||
// pipeline to capture data that is written to the other pipeline
|
||||
// without interfering with when finish is called on the other
|
||||
// pipeline and without having to put a Pl_Concatenate after it.
|
||||
// It is okay to not call finish() on this pipeline if it has no "next". This makes it easy to stick
|
||||
// this in front of another pipeline to capture data that is written to the other pipeline without
|
||||
// interfering with when finish is called on the other pipeline and without having to put a
|
||||
// Pl_Concatenate after it.
|
||||
|
||||
#include <qpdf/Pipeline.hh>
|
||||
|
||||
|
@ -68,7 +68,7 @@ class QPDF
|
||||
// read until they are needed. A QPDF object may be associated with only one file in its
|
||||
// lifetime. This method must be called before any methods that potentially ask for information
|
||||
// about the PDF file are called. Prior to calling this, the only methods that are allowed are
|
||||
// those that set parameters. If the input file is not encrypted,either a null password or an
|
||||
// those that set parameters. If the input file is not encrypted, either a null password or an
|
||||
// empty password can be used. If the file is encrypted, either the user password or the owner
|
||||
// password may be supplied. The method setPasswordIsHexKey may be called prior to calling this
|
||||
// method or any of the other process methods to force the password to be interpreted as a raw
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFANNOTATIONOBJECTHELPER_HH
|
||||
#define QPDFANNOTATIONOBJECTHELPER_HH
|
||||
@ -35,19 +32,16 @@ class QPDFAnnotationObjectHelper: public QPDFObjectHelper
|
||||
QPDF_DLL
|
||||
virtual ~QPDFAnnotationObjectHelper() = default;
|
||||
|
||||
// This class provides helper methods for annotations. More
|
||||
// functionality will likely be added in the future.
|
||||
// This class provides helper methods for annotations. More functionality will likely be added
|
||||
// in the future.
|
||||
|
||||
// Some functionality for annotations is also implemented in
|
||||
// QPDFAcroFormDocumentHelper and QPDFFormFieldObjectHelper. In
|
||||
// some cases, functions defined there work for other annotations
|
||||
// besides widget annotations, but they are implemented with form
|
||||
// fields so that they can properly handle form fields when
|
||||
// needed.
|
||||
// Some functionality for annotations is also implemented in QPDFAcroFormDocumentHelper and
|
||||
// QPDFFormFieldObjectHelper. In some cases, functions defined there work for other annotations
|
||||
// besides widget annotations, but they are implemented with form fields so that they can
|
||||
// properly handle form fields when needed.
|
||||
|
||||
// Return the subtype of the annotation as a string (e.g.
|
||||
// "/Widget"). Returns the empty string if the subtype (which is
|
||||
// required by the spec) is missing.
|
||||
// Return the subtype of the annotation as a string (e.g. "/Widget"). Returns an empty string
|
||||
// if the subtype (which is required by the spec) is missing.
|
||||
QPDF_DLL
|
||||
std::string getSubtype();
|
||||
|
||||
@ -57,39 +51,32 @@ class QPDFAnnotationObjectHelper: public QPDFObjectHelper
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle getAppearanceDictionary();
|
||||
|
||||
// Return the appearance state as given in "/AS", or the empty
|
||||
// string if none is given.
|
||||
// Return the appearance state as given in "/AS", or an empty string if none is given.
|
||||
QPDF_DLL
|
||||
std::string getAppearanceState();
|
||||
|
||||
// Return flags from "/F". The value is a logical or of
|
||||
// pdf_annotation_flag_e as defined in qpdf/Constants.h.
|
||||
// Return flags from "/F". The value is a logical or of pdf_annotation_flag_e as defined in
|
||||
// qpdf/Constants.h.
|
||||
QPDF_DLL
|
||||
int getFlags();
|
||||
|
||||
// Return a specific stream. "which" may be one of "/N", "/R", or
|
||||
// "/D" to indicate the normal, rollover, or down appearance
|
||||
// stream. (Any value may be passed to "which"; if an appearance
|
||||
// stream of that name exists, it will be returned.) If the value
|
||||
// associated with "which" in the appearance dictionary is a
|
||||
// subdictionary, an appearance state may be specified to select
|
||||
// which appearance stream is desired. If not specified, the
|
||||
// appearance state in "/AS" will used.
|
||||
// Return a specific stream. "which" may be one of "/N", "/R", or "/D" to indicate the normal,
|
||||
// rollover, or down appearance stream. (Any value may be passed to "which"; if an appearance
|
||||
// stream of that name exists, it will be returned.) If the value associated with "which" in the
|
||||
// appearance dictionary is a subdictionary, an appearance state may be specified to select
|
||||
// which appearance stream is desired. If not specified, the appearance state in "/AS" will
|
||||
// used.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle getAppearanceStream(std::string const& which, std::string const& state = "");
|
||||
|
||||
// Generate text suitable for addition to the containing page's
|
||||
// content stream that draws this annotation's appearance stream
|
||||
// as a form XObject. The value "name" is the resource name that
|
||||
// will be used to refer to the form xobject. The value "rotate"
|
||||
// should be set to the page's /Rotate value or 0 if none. The
|
||||
// values of required_flags and forbidden_flags are constructed by
|
||||
// logically "or"ing annotation flags of type
|
||||
// pdf_annotation_flag_e defined in qpdf/Constants.h. Content will
|
||||
// be returned only if all required_flags are set and no
|
||||
// forbidden_flags are set. For example, including an_no_view in
|
||||
// forbidden_flags could be useful for creating an on-screen view,
|
||||
// and including an_print to required_flags could be useful if
|
||||
// Generate text suitable for addition to the containing page's content stream that draws this
|
||||
// annotation's appearance stream as a form XObject. The value "name" is the resource name that
|
||||
// will be used to refer to the form xobject. The value "rotate" should be set to the page's
|
||||
// /Rotate value or 0 if none. The values of required_flags and forbidden_flags are constructed
|
||||
// by logically "or"ing annotation flags of type pdf_annotation_flag_e defined in
|
||||
// qpdf/Constants.h. Content will be returned only if all required_flags are set and no
|
||||
// forbidden_flags are set. For example, including an_no_view in forbidden_flags could be useful
|
||||
// for creating an on-screen view, and including an_print to required_flags could be useful if
|
||||
// preparing to print.
|
||||
QPDF_DLL
|
||||
std::string getPageContentForAppearance(
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFCRYPTOPROVIDER_HH
|
||||
#define QPDFCRYPTOPROVIDER_HH
|
||||
@ -30,35 +27,30 @@
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
// This class is part of qpdf's pluggable crypto provider support.
|
||||
// Most users won't need to know or care about this class, but you can
|
||||
// use it if you want to supply your own crypto implementation. See
|
||||
// also comments in QPDFCryptoImpl.hh.
|
||||
// This class is part of qpdf's pluggable crypto provider support. Most users won't need to know or
|
||||
// care about this class, but you can use it if you want to supply your own crypto implementation.
|
||||
// See also comments in QPDFCryptoImpl.hh.
|
||||
|
||||
class QPDFCryptoProvider
|
||||
{
|
||||
public:
|
||||
// Methods for getting and registering crypto implementations.
|
||||
// These methods are not thread-safe.
|
||||
// Methods for getting and registering crypto implementations. These methods are not
|
||||
// thread-safe.
|
||||
|
||||
// Return an instance of a crypto provider using the default
|
||||
// implementation.
|
||||
// Return an instance of a crypto provider using the default implementation.
|
||||
QPDF_DLL
|
||||
static std::shared_ptr<QPDFCryptoImpl> getImpl();
|
||||
|
||||
// Return an instance of the crypto provider registered using the
|
||||
// given name.
|
||||
// Return an instance of the crypto provider registered using the given name.
|
||||
QPDF_DLL
|
||||
static std::shared_ptr<QPDFCryptoImpl> getImpl(std::string const& name);
|
||||
|
||||
// Register the given type (T) as a crypto implementation. T must
|
||||
// be derived from QPDFCryptoImpl and must have a constructor that
|
||||
// takes no arguments.
|
||||
// Register the given type (T) as a crypto implementation. T must be derived from QPDFCryptoImpl
|
||||
// and must have a constructor that takes no arguments.
|
||||
template <typename T>
|
||||
QPDF_DLL static void registerImpl(std::string const& name);
|
||||
|
||||
// Set the crypto provider registered with the given name as the
|
||||
// default crypto implementation.
|
||||
// Set the crypto provider registered with the given name as the default crypto implementation.
|
||||
QPDF_DLL
|
||||
static void setDefaultProvider(std::string const& name);
|
||||
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFDOCUMENTHELPER_HH
|
||||
#define QPDFDOCUMENTHELPER_HH
|
||||
@ -25,16 +22,13 @@
|
||||
#include <qpdf/DLL.h>
|
||||
#include <qpdf/QPDF.hh>
|
||||
|
||||
// This is a base class for QPDF Document Helper classes. Document
|
||||
// helpers are classes that provide a convenient, higher-level API for
|
||||
// accessing document-level structures with a PDF file. Document
|
||||
// helpers are always initialized with a reference to a QPDF object,
|
||||
// and the object can always be retrieved. The intention is that you
|
||||
// may freely intermix use of document helpers with the underlying
|
||||
// QPDF object unless there is a specific comment in a specific helper
|
||||
// method that says otherwise. The pattern of using helper objects was
|
||||
// introduced to allow creation of higher level helper functions
|
||||
// without polluting the public interface of QPDF.
|
||||
// This is a base class for QPDF Document Helper classes. Document helpers are classes that provide
|
||||
// a convenient, higher-level API for accessing document-level structures within a PDF file.
|
||||
// Document helpers are always initialized with a reference to a QPDF object, and the object can
|
||||
// always be retrieved. The intention is that you may freely intermix use of document helpers with
|
||||
// the underlying QPDF object unless there is a specific comment in a specific helper method that
|
||||
// says otherwise. The pattern of using helper objects was introduced to allow creation of higher
|
||||
// level helper functions without polluting the public interface of QPDF.
|
||||
|
||||
class QPDF_DLL_CLASS QPDFDocumentHelper
|
||||
{
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFEFSTREAMOBJECTHELPER_HH
|
||||
#define QPDFEFSTREAMOBJECTHELPER_HH
|
||||
@ -29,9 +26,8 @@
|
||||
#include <qpdf/QPDFObjectHandle.hh>
|
||||
#include <functional>
|
||||
|
||||
// This class provides a higher level interface around Embedded File
|
||||
// Streams, which are discussed in section 7.11.4 of the ISO-32000 PDF
|
||||
// specification.
|
||||
// This class provides a higher level interface around Embedded File Streams, which are discussed in
|
||||
// section 7.11.4 of the ISO-32000 PDF specification.
|
||||
|
||||
class QPDFEFStreamObjectHelper: public QPDFObjectHelper
|
||||
{
|
||||
@ -41,11 +37,10 @@ class QPDFEFStreamObjectHelper: public QPDFObjectHelper
|
||||
QPDF_DLL
|
||||
virtual ~QPDFEFStreamObjectHelper() = default;
|
||||
|
||||
// Date parameters are strings that conform to the PDF spec for
|
||||
// date/time strings, which is "D:yyyymmddhhmmss<z>" where <z> is
|
||||
// either "Z" for UTC or "-hh'mm'" or "+hh'mm'" for timezone
|
||||
// offset. Examples: "D:20210207161528-05'00'",
|
||||
// "D:20210207211528Z". See QUtil::qpdf_time_to_pdf_time.
|
||||
// Date parameters are strings that conform to the PDF spec for date/time strings, which is
|
||||
// "D:yyyymmddhhmmss<z>" where <z> is either "Z" for UTC or "-hh'mm'" or "+hh'mm'" for timezone
|
||||
// offset. Examples: "D:20210207161528-05'00'", "D:20210207211528Z". See
|
||||
// QUtil::qpdf_time_to_pdf_time.
|
||||
|
||||
QPDF_DLL
|
||||
std::string getCreationDate();
|
||||
@ -57,32 +52,27 @@ class QPDFEFStreamObjectHelper: public QPDFObjectHelper
|
||||
// Subtype is a mime type such as "text/plain"
|
||||
QPDF_DLL
|
||||
std::string getSubtype();
|
||||
// Return the checksum as stored in the object as a binary string.
|
||||
// This does not check consistency with the data. If not present,
|
||||
// return an empty string. The PDF spec specifies this as an MD5
|
||||
// checksum and notes that it is not to be used for security
|
||||
// purposes since MD5 is known not to be secure.
|
||||
// Return the checksum as stored in the object as a binary string. This does not check
|
||||
// consistency with the data. If not present, return an empty string. The PDF spec specifies
|
||||
// this as an MD5 checksum and notes that it is not to be used for security purposes since MD5
|
||||
// is known to be insecure.
|
||||
QPDF_DLL
|
||||
std::string getChecksum();
|
||||
|
||||
// Setters return a reference to this object so that they can be
|
||||
// used as fluent interfaces, e.g.
|
||||
// Setters return a reference to this object so that they can be used as fluent interfaces, e.g.
|
||||
// efsoh.setCreationDate(x).setModDate(y);
|
||||
|
||||
// Create a new embedded file stream with the given stream data,
|
||||
// which can be provided in any of several ways. To get the new
|
||||
// object back, call getObjectHandle() on the returned object. The
|
||||
// checksum and size are computed automatically and stored. Other
|
||||
// parameters may be supplied using setters defined below.
|
||||
// Create a new embedded file stream with the given stream data, which can be provided in any of
|
||||
// several ways. To get the new object back, call getObjectHandle() on the returned object. The
|
||||
// checksum and size are computed automatically and stored. Other parameters may be supplied
|
||||
// using setters defined below.
|
||||
QPDF_DLL
|
||||
static QPDFEFStreamObjectHelper createEFStream(QPDF& qpdf, std::shared_ptr<Buffer> data);
|
||||
QPDF_DLL
|
||||
static QPDFEFStreamObjectHelper createEFStream(QPDF& qpdf, std::string const& data);
|
||||
// The provider function must write the data to the given
|
||||
// pipeline. The function may be called multiple times by the qpdf
|
||||
// library. You can pass QUtil::file_provider(filename) as the
|
||||
// provider to have the qpdf library provide the contents of
|
||||
// filename as a binary.
|
||||
// The provider function must write the data to the given pipeline. The function may be called
|
||||
// multiple times by the qpdf library. You can pass QUtil::file_provider(filename) as the
|
||||
// provider to have the qpdf library provide the contents of filename as a binary.
|
||||
QPDF_DLL
|
||||
static QPDFEFStreamObjectHelper
|
||||
createEFStream(QPDF& qpdf, std::function<void(Pipeline*)> provider);
|
||||
@ -93,8 +83,7 @@ class QPDFEFStreamObjectHelper: public QPDFObjectHelper
|
||||
QPDF_DLL
|
||||
QPDFEFStreamObjectHelper& setModDate(std::string const&);
|
||||
|
||||
// Set subtype as a mime-type, e.g. "text/plain" or
|
||||
// "application/pdf".
|
||||
// Set subtype as a mime-type, e.g. "text/plain" or "application/pdf".
|
||||
QPDF_DLL
|
||||
QPDFEFStreamObjectHelper& setSubtype(std::string const&);
|
||||
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFEMBEDDEDFILEDOCUMENTHELPER_HH
|
||||
#define QPDFEMBEDDEDFILEDOCUMENTHELPER_HH
|
||||
@ -32,9 +29,9 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
// This class provides a higher level interface around document-level
|
||||
// file attachments, also known as embedded files. These are discussed
|
||||
// in sections 7.7.4 and 7.11 of the ISO-32000 PDF specification.
|
||||
// This class provides a higher level interface around document-level file attachments, also known
|
||||
// as embedded files. These are discussed in sections 7.7.4 and 7.11 of the ISO-32000 PDF
|
||||
// specification.
|
||||
|
||||
class QPDFEmbeddedFileDocumentHelper: public QPDFDocumentHelper
|
||||
{
|
||||
@ -50,8 +47,8 @@ class QPDFEmbeddedFileDocumentHelper: public QPDFDocumentHelper
|
||||
QPDF_DLL
|
||||
std::map<std::string, std::shared_ptr<QPDFFileSpecObjectHelper>> getEmbeddedFiles();
|
||||
|
||||
// If an embedded file with the given name exists, return a
|
||||
// (shared) pointer to it. Otherwise, return nullptr.
|
||||
// If an embedded file with the given name exists, return a (shared) pointer to it. Otherwise,
|
||||
// return nullptr.
|
||||
QPDF_DLL
|
||||
std::shared_ptr<QPDFFileSpecObjectHelper> getEmbeddedFile(std::string const& name);
|
||||
|
||||
@ -59,14 +56,11 @@ class QPDFEmbeddedFileDocumentHelper: public QPDFDocumentHelper
|
||||
QPDF_DLL
|
||||
void replaceEmbeddedFile(std::string const& name, QPDFFileSpecObjectHelper const&);
|
||||
|
||||
// Remove an embedded file if present. Return value is true if the
|
||||
// file was present and was removed. This method not only removes
|
||||
// the embedded file from the embedded files name tree but also
|
||||
// nulls out the file specification dictionary. This means that
|
||||
// any references to this file from file attachment annotations
|
||||
// will also stop working. This is the best way to make the
|
||||
// attachment actually disappear from the file and not just from
|
||||
// the list of attachments.
|
||||
// Remove an embedded file if present. Return value is true if the file was present and was
|
||||
// removed. This method not only removes the embedded file from the embedded files name tree but
|
||||
// also nulls out the file specification dictionary. This means that any references to this file
|
||||
// from file attachment annotations will also stop working. This is the best way to make the
|
||||
// attachment actually disappear from the file and not just from the list of attachments.
|
||||
QPDF_DLL
|
||||
bool removeEmbeddedFile(std::string const& name);
|
||||
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFFILESPECOBJECTHELPER_HH
|
||||
#define QPDFFILESPECOBJECTHELPER_HH
|
||||
@ -29,9 +26,8 @@
|
||||
#include <qpdf/QPDFEFStreamObjectHelper.hh>
|
||||
#include <qpdf/QPDFObjectHandle.hh>
|
||||
|
||||
// This class provides a higher level interface around File
|
||||
// Specification dictionaries, which are discussed in section 7.11 of
|
||||
// the ISO-32000 PDF specification.
|
||||
// This class provides a higher level interface around File Specification dictionaries, which are
|
||||
// discussed in section 7.11 of the ISO-32000 PDF specification.
|
||||
|
||||
class QPDFFileSpecObjectHelper: public QPDFObjectHelper
|
||||
{
|
||||
@ -44,45 +40,38 @@ class QPDFFileSpecObjectHelper: public QPDFObjectHelper
|
||||
QPDF_DLL
|
||||
std::string getDescription();
|
||||
|
||||
// Get the main filename for this file specification. In priority
|
||||
// order, check /UF, /F, /Unix, /DOS, /Mac.
|
||||
// Get the main filename for this file specification. In priority order, check /UF, /F, /Unix,
|
||||
// /DOS, /Mac.
|
||||
QPDF_DLL
|
||||
std::string getFilename();
|
||||
|
||||
// Return any of /UF, /F, /Unix, /DOS, /Mac filename keys that may
|
||||
// be present in the object.
|
||||
// Return any of /UF, /F, /Unix, /DOS, /Mac filename keys that may be present in the object.
|
||||
QPDF_DLL
|
||||
std::map<std::string, std::string> getFilenames();
|
||||
|
||||
// Get the requested embedded file stream for this file
|
||||
// specification. If key is empty, In priority order, check /UF,
|
||||
// /F, /Unix, /DOS, /Mac. Returns a null object if not found. If
|
||||
// this is an actual embedded file stream, its data is the content
|
||||
// of the attachment. You can also use
|
||||
// QPDFEFStreamObjectHelper for higher level access to
|
||||
// the parameters.
|
||||
// Get the requested embedded file stream for this file specification. If key is empty, In
|
||||
// priority order, check /UF, /F, /Unix, /DOS, /Mac. Returns a null object if not found. If this
|
||||
// is an actual embedded file stream, its data is the content of the attachment. You can also
|
||||
// use QPDFEFStreamObjectHelper for higher level access to the parameters.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle getEmbeddedFileStream(std::string const& key = "");
|
||||
|
||||
// Return the /EF key of the file spec, which is a map from file
|
||||
// name key to embedded file stream.
|
||||
// Return the /EF key of the file spec, which is a map from file name key to embedded file
|
||||
// stream.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle getEmbeddedFileStreams();
|
||||
|
||||
// Setters return a reference to this object so that they can be
|
||||
// used as fluent interfaces, e.g.
|
||||
// Setters return a reference to this object so that they can be used as fluent interfaces, e.g.
|
||||
// fsoh.setDescription(x).setFilename(y);
|
||||
|
||||
// Create a new filespec as an indirect object with the given
|
||||
// filename, and attach the contents of the specified file as data
|
||||
// in an embedded file stream.
|
||||
// Create a new filespec as an indirect object with the given filename, and attach the contents
|
||||
// of the specified file as data in an embedded file stream.
|
||||
QPDF_DLL
|
||||
static QPDFFileSpecObjectHelper
|
||||
createFileSpec(QPDF& qpdf, std::string const& filename, std::string const& fullpath);
|
||||
|
||||
// Create a new filespec as an indirect object with the given
|
||||
// unicode filename and embedded file stream. The file name will
|
||||
// be used as both /UF and /F. If you need to override, call
|
||||
// Create a new filespec as an indirect object with the given unicode filename and embedded file
|
||||
// stream. The file name will be used as both /UF and /F. If you need to override, call
|
||||
// setFilename.
|
||||
QPDF_DLL
|
||||
static QPDFFileSpecObjectHelper
|
||||
@ -90,11 +79,9 @@ class QPDFFileSpecObjectHelper: public QPDFObjectHelper
|
||||
|
||||
QPDF_DLL
|
||||
QPDFFileSpecObjectHelper& setDescription(std::string const&);
|
||||
// setFilename sets /UF to unicode_name. If compat_name is empty,
|
||||
// it is also set to unicode_name. unicode_name should be a UTF-8
|
||||
// encoded string. compat_name is converted to a string
|
||||
// QPDFObjectHandle literally, preserving whatever encoding it
|
||||
// might happen to have.
|
||||
// setFilename sets /UF to unicode_name. If compat_name is empty, it is also set to
|
||||
// unicode_name. unicode_name should be a UTF-8 encoded string. compat_name is converted to a
|
||||
// string QPDFObjectHandle literally, preserving whatever encoding it might happen to have.
|
||||
QPDF_DLL
|
||||
QPDFFileSpecObjectHelper&
|
||||
setFilename(std::string const& unicode_name, std::string const& compat_name = "");
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFLOGGER_HH
|
||||
#define QPDFLOGGER_HH
|
||||
@ -33,19 +30,15 @@ class QPDFLogger
|
||||
QPDF_DLL
|
||||
static std::shared_ptr<QPDFLogger> create();
|
||||
|
||||
// Return the default logger. In general, you should use the
|
||||
// default logger. You can also create your own loggers and use
|
||||
// them QPDF and QPDFJob objects, but there are few reasons to do
|
||||
// so. One reason may if you are using multiple QPDF or QPDFJob
|
||||
// objects in different threads and want to capture output and
|
||||
// errors to different streams. (Note that a single QPDF or
|
||||
// QPDFJob can't be safely used from multiple threads, but it is
|
||||
// safe to use separate QPDF and QPDFJob objects on separate
|
||||
// threads.) Another possible reason would be if you are writing
|
||||
// an application that uses the qpdf library directly and qpdf is
|
||||
// also used by a downstream library or if you are using qpdf from
|
||||
// a library and don't want to interfere with potential uses of
|
||||
// qpdf by other libraries or applications.
|
||||
// Return the default logger. In general, you should use the default logger. You can also create
|
||||
// your own loggers and use them with QPDF and QPDFJob objects, but there are few reasons to do
|
||||
// so. One reason may be that you are using multiple QPDF or QPDFJob objects in different
|
||||
// threads and want to capture output and errors to different streams. (Note that a single QPDF
|
||||
// or QPDFJob can't be safely used from multiple threads, but it is safe to use separate QPDF
|
||||
// and QPDFJob objects on separate threads.) Another possible reason would be if you are writing
|
||||
// an application that uses the qpdf library directly and qpdf is also used by a downstream
|
||||
// library or if you are using qpdf from a library and don't want to interfere with potential
|
||||
// uses of qpdf by other libraries or applications.
|
||||
QPDF_DLL
|
||||
static std::shared_ptr<QPDFLogger> defaultLogger();
|
||||
|
||||
@ -56,50 +49,40 @@ class QPDFLogger
|
||||
// error -- standard error
|
||||
// save -- undefined unless set
|
||||
//
|
||||
// "info" is used for diagnostic messages, verbose messages, and
|
||||
// progress messages. "warn" is used for warnings. "error" is used
|
||||
// for errors. "save" is used for saving output -- see below.
|
||||
// "info" is used for diagnostic messages, verbose messages, and progress messages. "warn" is
|
||||
// used for warnings. "error" is used for errors. "save" is used for saving output -- see below.
|
||||
//
|
||||
// On deletion, finish() is called for the standard output and
|
||||
// standard error pipelines, which flushes output. If you supply
|
||||
// any custom pipelines, you must call finish() on them yourself.
|
||||
// Note that calling finish is not needed for string, stdio, or
|
||||
// ostream pipelines.
|
||||
// On deletion, finish() is called for the standard output and standard error pipelines, which
|
||||
// flushes output. If you supply any custom pipelines, you must call finish() on them yourself.
|
||||
// Note that calling finish is not needed for string, stdio, or ostream pipelines.
|
||||
//
|
||||
// NOTES ABOUT THE SAVE PIPELINE
|
||||
//
|
||||
// The save pipeline is used by QPDFJob when some kind of binary
|
||||
// output is being saved. This includes saving attachments and
|
||||
// stream data and also includes when the output file is standard
|
||||
// output. If you want to grab that output, you can call setSave.
|
||||
// See examples/qpdfjob-save-attachment.cc and
|
||||
// examples/qpdfjob-c-save-attachment.c.
|
||||
// The save pipeline is used by QPDFJob when some kind of binary output is being saved. This
|
||||
// includes saving attachments and stream data and also includes when the output file is
|
||||
// standard output. If you want to grab that output, you can call setSave. See
|
||||
// examples/qpdfjob-save-attachment.cc and examples/qpdfjob-c-save-attachment.c.
|
||||
//
|
||||
// You should never set the save pipeline to the same destination
|
||||
// as something else. Doing so will corrupt your save output. If
|
||||
// you want to save to standard output, use the method
|
||||
// saveToStandardOutput(). In addition to setting the save
|
||||
// pipeline, that does the following extra things:
|
||||
// You should never set the save pipeline to the same destination as something else. Doing so
|
||||
// will corrupt your save output. If you want to save to standard output, use the method
|
||||
// saveToStandardOutput(). In addition to setting the save pipeline, that does the following
|
||||
// extra things:
|
||||
//
|
||||
// * If standard output has been used, a logic error is thrown
|
||||
// * If info is set to standard output at the time of the set save
|
||||
// call, it is switched to standard error.
|
||||
// * If info is set to standard output at the time of the set save call, it is switched to
|
||||
// standard error.
|
||||
//
|
||||
// This is not a guarantee. You can still mess this up in ways
|
||||
// that are not checked. Here are a few examples:
|
||||
// This is not a guarantee. You can still mess this up in ways that are not checked. Here are a
|
||||
// few examples:
|
||||
//
|
||||
// * Don't set any pipeline to standard output *after* passing it
|
||||
// to setSave()
|
||||
// * Don't use a separate mechanism to write stdout/stderr other
|
||||
// than QPDFLogger::standardOutput()
|
||||
// * Don't set anything to the same custom pipeline that save is
|
||||
// set to.
|
||||
// * Don't set any pipeline to standard output *after* passing it to setSave()
|
||||
// * Don't use a separate mechanism to write stdout/stderr other than
|
||||
// QPDFLogger::standardOutput()
|
||||
// * Don't set anything to the same custom pipeline that save is set to.
|
||||
//
|
||||
// Just be sure that if you change pipelines around, you should
|
||||
// avoid having the save pipeline also be used for any other
|
||||
// purpose. The special case for saving to standard output allows
|
||||
// you to call saveToStandardOutput() early without having to
|
||||
// worry about the info pipeline.
|
||||
// Just be sure that if you change pipelines around, you should avoid having the save pipeline
|
||||
// also be used for any other purpose. The special case for saving to standard output allows you
|
||||
// to call saveToStandardOutput() early without having to worry about the info pipeline.
|
||||
|
||||
QPDF_DLL
|
||||
void info(char const*);
|
||||
@ -145,9 +128,8 @@ class QPDFLogger
|
||||
QPDF_DLL
|
||||
void saveToStandardOutput(bool only_if_not_set);
|
||||
|
||||
// Shortcut for logic to reset output to new output/error streams.
|
||||
// out_stream is used for info, err_stream is used for error, and
|
||||
// warning is cleared so that it follows error.
|
||||
// Shortcut for logic to reset output to new output/error streams. out_stream is used for info,
|
||||
// err_stream is used for error, and warning is cleared so that it follows error.
|
||||
QPDF_DLL
|
||||
void setOutputStreams(std::ostream* out_stream, std::ostream* err_stream);
|
||||
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFMATRIX_HH
|
||||
#define QPDFMATRIX_HH
|
||||
@ -26,8 +23,7 @@
|
||||
#include <qpdf/QPDFObjectHandle.hh>
|
||||
#include <string>
|
||||
|
||||
// This class represents a PDF transformation matrix using a tuple
|
||||
// such that
|
||||
// This class represents a PDF transformation matrix using a tuple such that
|
||||
//
|
||||
// ┌ ┐
|
||||
// │ a b 0 │
|
||||
@ -45,8 +41,7 @@ class QPDFMatrix
|
||||
QPDF_DLL
|
||||
QPDFMatrix(QPDFObjectHandle::Matrix const&);
|
||||
|
||||
// Returns the six values separated by spaces as real numbers with
|
||||
// trimmed zeroes.
|
||||
// Returns the six values separated by spaces as real numbers with trimmed zeroes.
|
||||
QPDF_DLL
|
||||
std::string unparse() const;
|
||||
|
||||
@ -75,14 +70,12 @@ class QPDFMatrix
|
||||
QPDF_DLL
|
||||
void transform(double x, double y, double& xp, double& yp) const;
|
||||
|
||||
// Transform a rectangle by creating a new rectangle that tightly
|
||||
// bounds the polygon resulting from transforming the four
|
||||
// corners.
|
||||
// Transform a rectangle by creating a new rectangle that tightly bounds the polygon resulting
|
||||
// from transforming the four corners.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle::Rectangle transformRectangle(QPDFObjectHandle::Rectangle r) const;
|
||||
|
||||
// operator== tests for exact equality, not considering deltas for
|
||||
// floating point.
|
||||
// operator== tests for exact equality, not considering deltas for floating point.
|
||||
QPDF_DLL
|
||||
bool operator==(QPDFMatrix const& rhs) const;
|
||||
QPDF_DLL
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFNAMETREEOBJECTHELPER_HH
|
||||
#define QPDFNAMETREEOBJECTHELPER_HH
|
||||
@ -30,13 +27,11 @@
|
||||
|
||||
#include <qpdf/DLL.h>
|
||||
|
||||
// This is an object helper for name trees. See section 7.9.6 in the
|
||||
// PDF spec (ISO 32000) for a description of name trees. When looking
|
||||
// up items in the name tree, use UTF-8 strings. All names are
|
||||
// normalized for lookup purposes.
|
||||
// This is an object helper for name trees. See section 7.9.6 in the PDF spec (ISO 32000) for a
|
||||
// description of name trees. When looking up items in the name tree, use UTF-8 strings. All names
|
||||
// are normalized for lookup purposes.
|
||||
|
||||
// See examples/pdf-name-number-tree.cc for a demonstration of using
|
||||
// QPDFNameTreeObjectHelper.
|
||||
// See examples/pdf-name-number-tree.cc for a demonstration of using QPDFNameTreeObjectHelper.
|
||||
|
||||
class NNTreeImpl;
|
||||
class NNTreeIterator;
|
||||
@ -45,8 +40,8 @@ class NNTreeDetails;
|
||||
class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper
|
||||
{
|
||||
public:
|
||||
// The qpdf object is required so that this class can issue
|
||||
// warnings, attempt repairs, and add indirect objects.
|
||||
// The qpdf object is required so that this class can issue warnings, attempt repairs, and add
|
||||
// indirect objects.
|
||||
QPDF_DLL
|
||||
QPDFNameTreeObjectHelper(QPDFObjectHandle, QPDF&, bool auto_repair = true);
|
||||
|
||||
@ -57,13 +52,11 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper
|
||||
QPDF_DLL
|
||||
virtual ~QPDFNameTreeObjectHelper();
|
||||
|
||||
// Return whether the number tree has an explicit entry for this
|
||||
// number.
|
||||
// Return whether the name tree has an explicit entry for this name.
|
||||
QPDF_DLL
|
||||
bool hasName(std::string const& utf8);
|
||||
|
||||
// Find an object by name. If found, returns true and initializes
|
||||
// oh. See also find().
|
||||
// Find an object by name. If found, returns true and initializes oh. See also find().
|
||||
QPDF_DLL
|
||||
bool findObject(std::string const& utf8, QPDFObjectHandle& oh);
|
||||
|
||||
@ -115,21 +108,17 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
// DANGER: this method can create inconsistent trees if not
|
||||
// used properly! Insert a new item immediately after the
|
||||
// current iterator and increment so that it points to the new
|
||||
// item. If the current iterator is end(), insert at the
|
||||
// beginning. This method does not check for proper ordering,
|
||||
// so if you use it, you must ensure that the item you are
|
||||
// inserting belongs where you are putting it. The reason for
|
||||
// this method is that it is more efficient than insert() and
|
||||
// can be used safely when you are creating a new tree and
|
||||
// inserting items in sorted order.
|
||||
// DANGER: this method can create inconsistent trees if not used properly! Insert a new item
|
||||
// immediately after the current iterator and increment so that it points to the new item.
|
||||
// If the current iterator is end(), insert at the beginning. This method does not check for
|
||||
// proper ordering, so if you use it, you must ensure that the item you are inserting
|
||||
// belongs where you are putting it. The reason for this method is that it is more efficient
|
||||
// than insert() and can be used safely when you are creating a new tree and inserting items
|
||||
// in sorted order.
|
||||
QPDF_DLL
|
||||
void insertAfter(std::string const& key, QPDFObjectHandle value);
|
||||
|
||||
// Remove the current item and advance the iterator to the
|
||||
// next item.
|
||||
// Remove the current item and advance the iterator to the next item.
|
||||
QPDF_DLL
|
||||
void remove();
|
||||
|
||||
@ -141,10 +130,9 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper
|
||||
value_type ivalue;
|
||||
};
|
||||
|
||||
// The iterator looks like map iterator, so i.first is a string
|
||||
// and i.second is a QPDFObjectHandle. Incrementing end() brings
|
||||
// you to the first item. Decrementing end() brings you to the
|
||||
// last item.
|
||||
// The iterator looks like map iterator, so i.first is a string and i.second is a
|
||||
// QPDFObjectHandle. Incrementing end() brings you to the first item. Decrementing end() brings
|
||||
// you to the last item.
|
||||
QPDF_DLL
|
||||
iterator begin() const;
|
||||
QPDF_DLL
|
||||
@ -153,8 +141,8 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper
|
||||
QPDF_DLL
|
||||
iterator last() const;
|
||||
|
||||
// Find the entry with the given key. If return_prev_if_not_found
|
||||
// is true and the item is not found, return the next lower item.
|
||||
// Find the entry with the given key. If return_prev_if_not_found is true and the item is not
|
||||
// found, return the next lower item.
|
||||
QPDF_DLL
|
||||
iterator find(std::string const& key, bool return_prev_if_not_found = false);
|
||||
|
||||
@ -162,20 +150,18 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper
|
||||
QPDF_DLL
|
||||
iterator insert(std::string const& key, QPDFObjectHandle value);
|
||||
|
||||
// Remove an item. Return true if the item was found and removed;
|
||||
// otherwise return false. If value is not null, initialize it to
|
||||
// the value that was removed.
|
||||
// Remove an item. Return true if the item was found and removed; otherwise return false. If
|
||||
// value is not nullptr, initialize it to the value that was removed.
|
||||
QPDF_DLL
|
||||
bool remove(std::string const& key, QPDFObjectHandle* value = nullptr);
|
||||
|
||||
// Return the contents of the name tree as a map. Note that name
|
||||
// trees may be very large, so this may use a lot of RAM. It is
|
||||
// more efficient to use QPDFNameTreeObjectHelper's iterator.
|
||||
// Return the contents of the name tree as a map. Note that name trees may be very large, so
|
||||
// this may use a lot of RAM. It is more efficient to use QPDFNameTreeObjectHelper's iterator.
|
||||
QPDF_DLL
|
||||
std::map<std::string, QPDFObjectHandle> getAsMap() const;
|
||||
|
||||
// Split a node if the number of items exceeds this value. There's
|
||||
// no real reason to ever set this except for testing.
|
||||
// Split a node if the number of items exceeds this value. There's no real reason to ever set
|
||||
// this except for testing.
|
||||
QPDF_DLL
|
||||
void setSplitThreshold(int);
|
||||
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFNUMBERTREEOBJECTHELPER_HH
|
||||
#define QPDFNUMBERTREEOBJECTHELPER_HH
|
||||
@ -29,11 +26,10 @@
|
||||
|
||||
#include <qpdf/DLL.h>
|
||||
|
||||
// This is an object helper for number trees. See section 7.9.7 in the
|
||||
// PDF spec (ISO 32000) for a description of number trees.
|
||||
// This is an object helper for number trees. See section 7.9.7 in the PDF spec (ISO 32000) for a
|
||||
// description of number trees.
|
||||
|
||||
// See examples/pdf-name-number-tree.cc for a demonstration of using
|
||||
// QPDFNumberTreeObjectHelper.
|
||||
// See examples/pdf-name-number-tree.cc for a demonstration of using QPDFNumberTreeObjectHelper.
|
||||
|
||||
class NNTreeImpl;
|
||||
class NNTreeIterator;
|
||||
@ -42,8 +38,8 @@ class NNTreeDetails;
|
||||
class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper
|
||||
{
|
||||
public:
|
||||
// The qpdf object is required so that this class can issue
|
||||
// warnings, attempt repairs, and add indirect objects.
|
||||
// The qpdf object is required so that this class can issue warnings, attempt repairs, and add
|
||||
// indirect objects.
|
||||
QPDF_DLL
|
||||
QPDFNumberTreeObjectHelper(QPDFObjectHandle, QPDF&, bool auto_repair = true);
|
||||
|
||||
@ -62,24 +58,20 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper
|
||||
QPDF_DLL
|
||||
numtree_number getMax();
|
||||
|
||||
// Return whether the number tree has an explicit entry for this
|
||||
// number.
|
||||
// Return whether the number tree has an explicit entry for this number.
|
||||
QPDF_DLL
|
||||
bool hasIndex(numtree_number idx);
|
||||
|
||||
// Find an object with a specific index. If found, returns true
|
||||
// and initializes oh. See also find().
|
||||
// Find an object with a specific index. If found, returns true and initializes oh. See also
|
||||
// find().
|
||||
QPDF_DLL
|
||||
bool findObject(numtree_number idx, QPDFObjectHandle& oh);
|
||||
// Find the object at the index or, if not found, the object whose
|
||||
// index is the highest index less than the requested index. If
|
||||
// the requested index is less than the minimum, return false.
|
||||
// Otherwise, return true, initialize oh to the object, and set
|
||||
// offset to the difference between the requested index and the
|
||||
// actual index. For example, if a number tree has values for 3
|
||||
// and 6 and idx is 5, this method would return true, initialize
|
||||
// oh to the value with index 3, and set offset to 2 (5 - 3). See
|
||||
// also find().
|
||||
// Find the object at the index or, if not found, the object whose index is the highest index
|
||||
// less than the requested index. If the requested index is less than the minimum, return false.
|
||||
// Otherwise, return true, initialize oh to the object, and set offset to the difference between
|
||||
// the requested index and the actual index. For example, if a number tree has values for 3 and
|
||||
// 6 and idx is 5, this method would return true, initialize oh to the value with index 3, and
|
||||
// set offset to 2 (5 - 3). See also find().
|
||||
QPDF_DLL
|
||||
bool findObjectAtOrBelow(numtree_number idx, QPDFObjectHandle& oh, numtree_number& offset);
|
||||
|
||||
@ -131,21 +123,17 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
// DANGER: this method can create inconsistent trees if not
|
||||
// used properly! Insert a new item immediately after the
|
||||
// current iterator and increment so that it points to the new
|
||||
// item. If the current iterator is end(), insert at the
|
||||
// beginning. This method does not check for proper ordering,
|
||||
// so if you use it, you must ensure that the item you are
|
||||
// inserting belongs where you are putting it. The reason for
|
||||
// this method is that it is more efficient than insert() and
|
||||
// can be used safely when you are creating a new tree and
|
||||
// inserting items in sorted order.
|
||||
// DANGER: this method can create inconsistent trees if not used properly! Insert a new item
|
||||
// immediately after the current iterator and increment so that it points to the new item.
|
||||
// If the current iterator is end(), insert at the beginning. This method does not check for
|
||||
// proper ordering, so if you use it, you must ensure that the item you are inserting
|
||||
// belongs where you are putting it. The reason for this method is that it is more efficient
|
||||
// than insert() and can be used safely when you are creating a new tree and inserting items
|
||||
// in sorted order.
|
||||
QPDF_DLL
|
||||
void insertAfter(numtree_number key, QPDFObjectHandle value);
|
||||
|
||||
// Remove the current item and advance the iterator to the
|
||||
// next item.
|
||||
// Remove the current item and advance the iterator to the next item.
|
||||
QPDF_DLL
|
||||
void remove();
|
||||
|
||||
@ -157,10 +145,9 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper
|
||||
value_type ivalue;
|
||||
};
|
||||
|
||||
// The iterator looks like map iterator, so i.first is a string
|
||||
// and i.second is a QPDFObjectHandle. Incrementing end() brings
|
||||
// you to the first item. Decrementing end() brings you to the
|
||||
// last item.
|
||||
// The iterator looks like map iterator, so i.first is a numtree_number and i.second is a
|
||||
// QPDFObjectHandle. Incrementing end() brings you to the first item. Decrementing end() brings
|
||||
// you to the last item.
|
||||
QPDF_DLL
|
||||
iterator begin() const;
|
||||
QPDF_DLL
|
||||
@ -169,8 +156,8 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper
|
||||
QPDF_DLL
|
||||
iterator last() const;
|
||||
|
||||
// Find the entry with the given key. If return_prev_if_not_found
|
||||
// is true and the item is not found, return the next lower item.
|
||||
// Find the entry with the given key. If return_prev_if_not_found is true and the item is not
|
||||
// found, return the next lower item.
|
||||
QPDF_DLL
|
||||
iterator find(numtree_number key, bool return_prev_if_not_found = false);
|
||||
|
||||
@ -178,22 +165,19 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper
|
||||
QPDF_DLL
|
||||
iterator insert(numtree_number key, QPDFObjectHandle value);
|
||||
|
||||
// Remove an item. Return true if the item was found and removed;
|
||||
// otherwise return false. If value is not null, initialize it to
|
||||
// the value that was removed.
|
||||
// Remove an item. Return true if the item was found and removed; otherwise return false. If
|
||||
// value is not nullptr, initialize it to the value that was removed.
|
||||
QPDF_DLL
|
||||
bool remove(numtree_number key, QPDFObjectHandle* value = nullptr);
|
||||
|
||||
// Return the contents of the number tree as a map. Note that
|
||||
// number trees may be very large, so this may use a lot of RAM.
|
||||
// It is more efficient to use QPDFNumberTreeObjectHelper's
|
||||
// iterator.
|
||||
// Return the contents of the number tree as a map. Note that number trees may be very large, so
|
||||
// this may use a lot of RAM. It is more efficient to use QPDFNumberTreeObjectHelper's iterator.
|
||||
typedef std::map<numtree_number, QPDFObjectHandle> idx_map;
|
||||
QPDF_DLL
|
||||
idx_map getAsMap() const;
|
||||
|
||||
// Split a node if the number of items exceeds this value. There's
|
||||
// no real reason to ever set this except for testing.
|
||||
// Split a node if the number of items exceeds this value. There's no real reason to ever set
|
||||
// this except for testing.
|
||||
QPDF_DLL
|
||||
void setSplitThreshold(int);
|
||||
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFOBJGEN_HH
|
||||
#define QPDFOBJGEN_HH
|
||||
@ -29,8 +26,8 @@
|
||||
class QPDFObjectHandle;
|
||||
class QPDFObjectHelper;
|
||||
|
||||
// This class represents an object ID and generation pair. It is
|
||||
// suitable to use as a key in a map or set.
|
||||
// This class represents an object ID and generation pair. It is suitable to use as a key in a map
|
||||
// or set.
|
||||
|
||||
class QPDFObjGen
|
||||
{
|
||||
@ -91,13 +88,11 @@ class QPDFObjGen
|
||||
|
||||
// Convenience class for loop detection when processing objects.
|
||||
//
|
||||
// The class adds 'add' methods to a std::set<QPDFObjGen> which allows
|
||||
// to test whether an QPDFObjGen is present in the set and to insert it in
|
||||
// a single operation. The 'add' method is overloaded to take a QPDFObjGen,
|
||||
// QPDFObjectHandle or an QPDFObjectHelper as parameter.
|
||||
// The class adds 'add' methods to a std::set<QPDFObjGen> which allows to test whether an
|
||||
// QPDFObjGen is present in the set and to insert it in a single operation. The 'add' method is
|
||||
// overloaded to take a QPDFObjGen, QPDFObjectHandle or an QPDFObjectHelper as parameter.
|
||||
//
|
||||
// The erase method is modified to ignore requests to erase
|
||||
// QPDFObjGen(0, 0).
|
||||
// The erase method is modified to ignore requests to erase QPDFObjGen(0, 0).
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
@ -112,8 +107,8 @@ class QPDFObjGen
|
||||
class QPDF_DLL_CLASS set: public std::set<QPDFObjGen>
|
||||
{
|
||||
public:
|
||||
// Add 'og' to the set. Return false if 'og' is already present in
|
||||
// the set. Attempts to insert QPDFObjGen(0, 0) are ignored.
|
||||
// Add 'og' to the set. Return false if 'og' is already present in the set. Attempts to
|
||||
// insert QPDFObjGen(0, 0) are ignored.
|
||||
QPDF_DLL
|
||||
bool
|
||||
add(QPDFObjGen og)
|
||||
@ -150,9 +145,8 @@ class QPDFObjGen
|
||||
};
|
||||
|
||||
private:
|
||||
// This class does not use the Members pattern to avoid a memory
|
||||
// allocation for every one of these. A lot of these get created
|
||||
// and destroyed.
|
||||
// This class does not use the Members pattern to avoid a memory allocation for every one of
|
||||
// these. A lot of these get created and destroyed.
|
||||
int obj{0};
|
||||
int gen{0};
|
||||
};
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFOBJECTHELPER_HH
|
||||
#define QPDFOBJECTHELPER_HH
|
||||
@ -26,16 +23,13 @@
|
||||
|
||||
#include <qpdf/QPDFObjectHandle.hh>
|
||||
|
||||
// This is a base class for QPDF Object Helper classes. Object helpers
|
||||
// are classes that provide a convenient, higher-level API for working
|
||||
// with specific types of QPDF objects. Object helpers are always
|
||||
// initialized with a QPDFObjectHandle, and the underlying object
|
||||
// handle can always be retrieved. The intention is that you may
|
||||
// freely intermix use of document helpers with the underlying QPDF
|
||||
// objects unless there is a specific comment in a specific helper
|
||||
// method that says otherwise. The pattern of using helper objects was
|
||||
// introduced to allow creation of higher level helper functions
|
||||
// without polluting the public interface of QPDFObjectHandle.
|
||||
// This is a base class for QPDF Object Helper classes. Object helpers are classes that provide a
|
||||
// convenient, higher-level API for working with specific types of QPDF objects. Object helpers are
|
||||
// always initialized with a QPDFObjectHandle, and the underlying object handle can always be
|
||||
// retrieved. The intention is that you may freely intermix use of object helpers with the
|
||||
// underlying QPDF objects unless there is a specific comment in a specific helper method that says
|
||||
// otherwise. The pattern of using helper objects was introduced to allow creation of higher level
|
||||
// helper functions without polluting the public interface of QPDFObjectHandle.
|
||||
|
||||
class QPDF_DLL_CLASS QPDFObjectHelper
|
||||
{
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFOUTLINEDOCUMENTHELPER_HH
|
||||
#define QPDFOUTLINEDOCUMENTHELPER_HH
|
||||
@ -33,11 +30,10 @@
|
||||
|
||||
#include <qpdf/DLL.h>
|
||||
|
||||
// This is a document helper for outlines, also known as bookmarks.
|
||||
// Outlines are discussed in section 12.3.3 of the PDF spec
|
||||
// (ISO-32000). With the help of QPDFOutlineObjectHelper, the outlines
|
||||
// tree is traversed, and a bidirectional map is made between pages
|
||||
// and outlines. See also QPDFOutlineObjectHelper.
|
||||
// This is a document helper for outlines, also known as bookmarks. Outlines are discussed in
|
||||
// section 12.3.3 of the PDF spec (ISO-32000). With the help of QPDFOutlineObjectHelper, the
|
||||
// outlines tree is traversed, and a bidirectional map is made between pages and outlines. See also
|
||||
// QPDFOutlineObjectHelper.
|
||||
|
||||
class QPDFOutlineDocumentHelper: public QPDFDocumentHelper
|
||||
{
|
||||
@ -53,15 +49,13 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper
|
||||
QPDF_DLL
|
||||
std::vector<QPDFOutlineObjectHelper> getTopLevelOutlines();
|
||||
|
||||
// If the name is a name object, look it up in the /Dests key of
|
||||
// the document catalog. If the name is a string, look it up in
|
||||
// the name tree pointed to by the /Dests key of the names
|
||||
// If the name is a name object, look it up in the /Dests key of the document catalog. If the
|
||||
// name is a string, look it up in the name tree pointed to by the /Dests key of the names
|
||||
// dictionary.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle resolveNamedDest(QPDFObjectHandle name);
|
||||
|
||||
// Return a list outlines that are known to target the specified
|
||||
// page
|
||||
// Return a list outlines that are known to target the specified page.
|
||||
QPDF_DLL
|
||||
std::vector<QPDFOutlineObjectHelper> getOutlinesForPage(QPDFObjGen const&);
|
||||
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFOUTLINEOBJECTHELPER_HH
|
||||
#define QPDFOUTLINEOBJECTHELPER_HH
|
||||
@ -30,9 +27,8 @@ class QPDFOutlineDocumentHelper;
|
||||
|
||||
#include <qpdf/DLL.h>
|
||||
|
||||
// This is an object helper for outline items. Outlines, also known as
|
||||
// bookmarks, are described in section 12.3.3 of the PDF spec
|
||||
// (ISO-32000). See comments below for details.
|
||||
// This is an object helper for outline items. Outlines, also known as bookmarks, are described in
|
||||
// section 12.3.3 of the PDF spec (ISO-32000). See comments below for details.
|
||||
|
||||
class QPDFOutlineObjectHelper: public QPDFObjectHelper
|
||||
{
|
||||
@ -40,16 +36,15 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper
|
||||
QPDF_DLL
|
||||
virtual ~QPDFOutlineObjectHelper()
|
||||
{
|
||||
// This must be cleared explicitly to avoid circular references
|
||||
// that prevent cleanup of pointer holders.
|
||||
// This must be cleared explicitly to avoid circular references that prevent cleanup of
|
||||
// shared pointers.
|
||||
m->parent = nullptr;
|
||||
}
|
||||
|
||||
// All constructors are private. You can only create one of these
|
||||
// using QPDFOutlineDocumentHelper.
|
||||
// All constructors are private. You can only create one of these using
|
||||
// QPDFOutlineDocumentHelper.
|
||||
|
||||
// Return parent pointer. Returns a null pointer if this is a
|
||||
// top-level outline.
|
||||
// Return parent pointer. Returns a null pointer if this is a top-level outline.
|
||||
QPDF_DLL
|
||||
std::shared_ptr<QPDFOutlineObjectHelper> getParent();
|
||||
|
||||
@ -57,29 +52,25 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper
|
||||
QPDF_DLL
|
||||
std::vector<QPDFOutlineObjectHelper> getKids();
|
||||
|
||||
// Return the destination, regardless of whether it is named or
|
||||
// explicit and whether it is directly provided or in a GoTo
|
||||
// action. Returns a null object if the destination can't be
|
||||
// determined. Named destinations can be resolved using the older
|
||||
// root /Dest dictionary or the current names tree.
|
||||
// Return the destination, regardless of whether it is named or explicit and whether it is
|
||||
// directly provided or in a GoTo action. Returns a null object if the destination can't be
|
||||
// determined. Named destinations can be resolved using the older root /Dest dictionary or the
|
||||
// current names tree.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle getDest();
|
||||
|
||||
// Return the page that the outline points to. Returns a null
|
||||
// object if the destination page can't be determined.
|
||||
// Return the page that the outline points to. Returns a null object if the destination page
|
||||
// can't be determined.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle getDestPage();
|
||||
|
||||
// Returns the value of /Count as present in the object, or 0 if
|
||||
// not present. If count is positive, the outline is open. If
|
||||
// negative, it is closed. Either way, the absolute value is the
|
||||
// number descendant items that would be visible if this were
|
||||
// open.
|
||||
// Returns the value of /Count as present in the object, or 0 if not present. If count is
|
||||
// positive, the outline is open. If negative, it is closed. Either way, the absolute value is
|
||||
// the number of descendant items that would be visible if this were open.
|
||||
QPDF_DLL
|
||||
int getCount();
|
||||
|
||||
// Returns the title as a UTF-8 string. Returns the empty string
|
||||
// if there is no title.
|
||||
// Returns the title as a UTF-8 string. Returns an empty string if there is no title.
|
||||
QPDF_DLL
|
||||
std::string getTitle();
|
||||
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFPAGEDOCUMENTHELPER_HH
|
||||
#define QPDFPAGEDOCUMENTHELPER_HH
|
||||
@ -42,67 +39,53 @@ class QPDFPageDocumentHelper: public QPDFDocumentHelper
|
||||
QPDF_DLL
|
||||
virtual ~QPDFPageDocumentHelper() = default;
|
||||
|
||||
// Traverse page tree, and return all /Page objects wrapped in
|
||||
// QPDFPageObjectHelper objects. Unlike with
|
||||
// QPDF::getAllPages, the vector of pages returned by
|
||||
// this call is not affected by additions or removals of pages. If
|
||||
// you manipulate pages, you will have to call this again to get a
|
||||
// new copy. Please see comments in QPDF.hh for getAllPages() for
|
||||
// additional details.
|
||||
// Traverse page tree, and return all /Page objects wrapped in QPDFPageObjectHelper objects.
|
||||
// Unlike with QPDF::getAllPages, the vector of pages returned by this call is not affected by
|
||||
// additions or removals of pages. If you manipulate pages, you will have to call this again to
|
||||
// get a new copy. Please see comments in QPDF.hh for getAllPages() for additional details.
|
||||
QPDF_DLL
|
||||
std::vector<QPDFPageObjectHelper> getAllPages();
|
||||
|
||||
// The PDF /Pages tree allows inherited values. Working with the
|
||||
// pages of a pdf is much easier when the inheritance is resolved
|
||||
// by explicitly setting the values in each /Page.
|
||||
// The PDF /Pages tree allows inherited values. Working with the pages of a pdf is much easier
|
||||
// when the inheritance is resolved by explicitly setting the values in each /Page.
|
||||
QPDF_DLL
|
||||
void pushInheritedAttributesToPage();
|
||||
|
||||
// This calls QPDFPageObjectHelper::removeUnreferencedResources
|
||||
// for every page in the document. See comments in
|
||||
// QPDFPageObjectHelper.hh for details.
|
||||
// This calls QPDFPageObjectHelper::removeUnreferencedResources for every page in the document.
|
||||
// See comments in QPDFPageObjectHelper.hh for details.
|
||||
QPDF_DLL
|
||||
void removeUnreferencedResources();
|
||||
|
||||
// Add new page at the beginning or the end of the current pdf.
|
||||
// The newpage parameter may be either a direct object, an
|
||||
// indirect object from this QPDF, or an indirect object from
|
||||
// another QPDF. If it is a direct object, it will be made
|
||||
// indirect. If it is an indirect object from another QPDF, this
|
||||
// method will call pushInheritedAttributesToPage on the other
|
||||
// file and then copy the page to this QPDF using the same
|
||||
// underlying code as copyForeignObject. At this stage, if the
|
||||
// indirect object is already in the pages tree, a shallow copy is
|
||||
// made to avoid adding the same page more than once. In version
|
||||
// 10.3.1 and earlier, adding a page that already existed would
|
||||
// throw an exception and could cause qpdf to crash on subsequent
|
||||
// page insertions in some cases. Note that this means that, in
|
||||
// some cases, the page actually added won't be exactly the same
|
||||
// object as the one passed in. If you want to do subsequent
|
||||
// Add a new page at the beginning or the end of the current pdf. The newpage parameter may be
|
||||
// either a direct object, an indirect object from this QPDF, or an indirect object from another
|
||||
// QPDF. If it is a direct object, it will be made indirect. If it is an indirect object from
|
||||
// another QPDF, this method will call pushInheritedAttributesToPage on the other file and then
|
||||
// copy the page to this QPDF using the same underlying code as copyForeignObject. At this
|
||||
// stage, if the indirect object is already in the pages tree, a shallow copy is made to avoid
|
||||
// adding the same page more than once. In version 10.3.1 and earlier, adding a page that
|
||||
// already existed would throw an exception and could cause qpdf to crash on subsequent page
|
||||
// insertions in some cases. Note that this means that, in some cases, the page actually added
|
||||
// won't be exactly the same object as the one passed in. If you want to do subsequent
|
||||
// modification on the page, you should retrieve it again.
|
||||
//
|
||||
// Note that you can call copyForeignObject directly to copy a
|
||||
// page from a different file, but the resulting object will not
|
||||
// be a page in the new file. You could do this, for example, to
|
||||
// convert a page into a form XObject, though for that, you're
|
||||
// better off using QPDFPageObjectHelper::getFormXObjectForPage.
|
||||
// Note that you can call copyForeignObject directly to copy a page from a different file, but
|
||||
// the resulting object will not be a page in the new file. You could do this, for example, to
|
||||
// convert a page into a form XObject, though for that, you're better off using
|
||||
// QPDFPageObjectHelper::getFormXObjectForPage.
|
||||
//
|
||||
// This method does not have any specific awareness of annotations
|
||||
// or form fields, so if you just add a page without thinking
|
||||
// about it, you might end up with two pages that share form
|
||||
// fields or annotations. While the page may look fine, it will
|
||||
// probably not function properly with regard to interactive
|
||||
// features. To work around this, you should called
|
||||
// QPDFAcroFormDocumentHelper::fixCopiedAnnotations. A future
|
||||
// version of qpdf will likely provide a higher-level interface
|
||||
// for copying pages around that will handle document-level
|
||||
// This method does not have any specific awareness of annotations or form fields, so if you
|
||||
// just add a page without thinking about it, you might end up with two pages that share form
|
||||
// fields or annotations. While the page may look fine, it will probably not function properly
|
||||
// with regard to interactive features. To work around this, you should call
|
||||
// QPDFAcroFormDocumentHelper::fixCopiedAnnotations. A future version of qpdf will likely
|
||||
// provide a higher-level interface for copying pages around that will handle document-level
|
||||
// constructs in a less error-prone fashion.
|
||||
|
||||
QPDF_DLL
|
||||
void addPage(QPDFPageObjectHelper newpage, bool first);
|
||||
|
||||
// Add new page before or after refpage. See comments for addPage
|
||||
// for details about what newpage should be.
|
||||
// Add new page before or after refpage. See comments for addPage for details about what newpage
|
||||
// should be.
|
||||
QPDF_DLL
|
||||
void addPageAt(QPDFPageObjectHelper newpage, bool before, QPDFPageObjectHelper refpage);
|
||||
|
||||
@ -110,17 +93,13 @@ class QPDFPageDocumentHelper: public QPDFDocumentHelper
|
||||
QPDF_DLL
|
||||
void removePage(QPDFPageObjectHelper page);
|
||||
|
||||
// For every annotation, integrate the annotation's appearance
|
||||
// stream into the containing page's content streams, merge the
|
||||
// annotation's resources with the page's resources, and remove
|
||||
// the annotation from the page. Handles widget annotations
|
||||
// associated with interactive form fields as a special case,
|
||||
// including removing the /AcroForm key from the document catalog.
|
||||
// The values passed to required_flags and forbidden_flags are
|
||||
// passed along to
|
||||
// QPDFAnnotationObjectHelper::getPageContentForAppearance. See
|
||||
// comments there in QPDFAnnotationObjectHelper.hh for meanings of
|
||||
// those flags.
|
||||
// For every annotation, integrate the annotation's appearance stream into the containing page's
|
||||
// content streams, merge the annotation's resources with the page's resources, and remove the
|
||||
// annotation from the page. Handles widget annotations associated with interactive form fields
|
||||
// as a special case, including removing the /AcroForm key from the document catalog. The values
|
||||
// passed to required_flags and forbidden_flags are passed along to
|
||||
// QPDFAnnotationObjectHelper::getPageContentForAppearance. See comments there in
|
||||
// QPDFAnnotationObjectHelper.hh for meanings of those flags.
|
||||
QPDF_DLL
|
||||
void flattenAnnotations(int required_flags = 0, int forbidden_flags = an_invisible | an_hidden);
|
||||
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFPAGELABELDOCUMENTHELPER_HH
|
||||
#define QPDFPAGELABELDOCUMENTHELPER_HH
|
||||
@ -30,18 +27,15 @@
|
||||
|
||||
#include <qpdf/DLL.h>
|
||||
|
||||
// Page labels are discussed in the PDF spec (ISO-32000) in section
|
||||
// 12.4.2.
|
||||
// Page labels are discussed in the PDF spec (ISO-32000) in section 12.4.2.
|
||||
//
|
||||
// Page labels are implemented as a number tree. Each key is a page
|
||||
// index, numbered from 0. The values are dictionaries with the
|
||||
// following keys, all optional:
|
||||
// Page labels are implemented as a number tree. Each key is a page index, numbered from 0. The
|
||||
// values are dictionaries with the following keys, all optional:
|
||||
//
|
||||
// * /Type: if present, must be /PageLabel
|
||||
// * /S: one of /D, /R, /r, /A, or /a for decimal, upper-case and
|
||||
// lower-case Roman numeral, or upper-case and lower-case alphabetic
|
||||
// * /P: if present, a fixed prefix string that is prepended to each
|
||||
// page number
|
||||
// * /S: one of /D, /R, /r, /A, or /a for decimal, upper-case and lower-case Roman numeral, or
|
||||
// upper-case and lower-case alphabetic
|
||||
// * /P: if present, a fixed prefix string that is prepended to each page number
|
||||
// * /St: the starting number, or 1 if not specified
|
||||
|
||||
class QPDFPageLabelDocumentHelper: public QPDFDocumentHelper
|
||||
@ -55,25 +49,20 @@ class QPDFPageLabelDocumentHelper: public QPDFDocumentHelper
|
||||
QPDF_DLL
|
||||
bool hasPageLabels();
|
||||
|
||||
// Return a page label dictionary representing the page label for
|
||||
// the given page. The page does not need to appear explicitly in
|
||||
// the page label dictionary. This method will adjust /St as
|
||||
// Return a page label dictionary representing the page label for the given page. The page does
|
||||
// not need to appear explicitly in the page label dictionary. This method will adjust /St as
|
||||
// needed to produce a label that is suitable for the page.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle getLabelForPage(long long page_idx);
|
||||
|
||||
// Append to the incoming vector a list of objects suitable for
|
||||
// inclusion in a /PageLabels dictionary's /Nums field. start_idx
|
||||
// and end_idx are the indexes to the starting and ending pages
|
||||
// (inclusive) in the original file, and new_start_idx is the
|
||||
// index to the first page in the new file. For example, if pages
|
||||
// 10 through 12 of one file are being copied to a new file as
|
||||
// pages 6 through 8, you would call getLabelsForPageRange(10, 12,
|
||||
// 6), which would return as many entries as are required to add
|
||||
// to the new file's PageLabels. This method fabricates a suitable
|
||||
// entry even if the original document has no page labels. This
|
||||
// behavior facilitates using this function to incrementally build
|
||||
// up a page labels tree when merging files.
|
||||
// Append to the incoming vector a list of objects suitable for inclusion in a /PageLabels
|
||||
// dictionary's /Nums field. start_idx and end_idx are the indexes to the starting and ending
|
||||
// pages (inclusive) in the original file, and new_start_idx is the index to the first page in
|
||||
// the new file. For example, if pages 10 through 12 of one file are being copied to a new file
|
||||
// as pages 6 through 8, you would call getLabelsForPageRange(10, 12, 6), which would return as
|
||||
// many entries as are required to add to the new file's PageLabels. This method fabricates a
|
||||
// suitable entry even if the original document has no page labels. This behavior facilitates
|
||||
// using this function to incrementally build up a page labels tree when merging files.
|
||||
QPDF_DLL
|
||||
void getLabelsForPageRange(
|
||||
long long start_idx,
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFSTREAMFILTER_HH
|
||||
#define QPDFSTREAMFILTER_HH
|
||||
@ -35,36 +32,29 @@ class QPDF_DLL_CLASS QPDFStreamFilter
|
||||
QPDF_DLL
|
||||
virtual ~QPDFStreamFilter() = default;
|
||||
|
||||
// A QPDFStreamFilter class must implement, at a minimum,
|
||||
// setDecodeParms() and getDecodePipeline(). QPDF will always call
|
||||
// setDecodeParms() before calling getDecodePipeline(). It is
|
||||
// expected that you will store any needed information from
|
||||
// decode_parms (or the decode_parms object itself) in your
|
||||
// instance so that it can be used to construct the decode
|
||||
// pipeline.
|
||||
// A QPDFStreamFilter class must implement, at a minimum, setDecodeParms() and
|
||||
// getDecodePipeline(). QPDF will always call setDecodeParms() before calling
|
||||
// getDecodePipeline(). It is expected that you will store any needed information from
|
||||
// decode_parms (or the decode_parms object itself) in your instance so that it can be used to
|
||||
// construct the decode pipeline.
|
||||
|
||||
// Return a boolean indicating whether your filter can proceed
|
||||
// with the given /DecodeParms. The default implementation accepts
|
||||
// a null object and rejects everything else.
|
||||
// Return a boolean indicating whether your filter can proceed with the given /DecodeParms. The
|
||||
// default implementation accepts a null object and rejects everything else.
|
||||
QPDF_DLL
|
||||
virtual bool setDecodeParms(QPDFObjectHandle decode_parms);
|
||||
|
||||
// Return a pipeline that will decode data encoded with your
|
||||
// filter. Your implementation must ensure that the pipeline is
|
||||
// deleted when the instance of your class is destroyed.
|
||||
// Return a pipeline that will decode data encoded with your filter. Your implementation must
|
||||
// ensure that the pipeline is deleted when the instance of your class is destroyed.
|
||||
QPDF_DLL
|
||||
virtual Pipeline* getDecodePipeline(Pipeline* next) = 0;
|
||||
|
||||
// If your filter implements "specialized" compression or lossy
|
||||
// compression, override one or both of these methods. The default
|
||||
// implementations return false. See comments in QPDFWriter for
|
||||
// details. QPDF defines specialized compression as non-lossy
|
||||
// compression not intended for general-purpose data. qpdf, by
|
||||
// default, doesn't mess with streams that are compressed with
|
||||
// specialized compression, the idea being that the decision to
|
||||
// use that compression scheme would fall outside of what
|
||||
// QPDFWriter would know anything about, so any attempt to decode
|
||||
// and re-encode would probably be undesirable.
|
||||
// If your filter implements "specialized" compression or lossy compression, override one or
|
||||
// both of these methods. The default implementations return false. See comments in QPDFWriter
|
||||
// for details. QPDF defines specialized compression as non-lossy compression not intended for
|
||||
// general-purpose data. qpdf, by default, doesn't mess with streams that are compressed with
|
||||
// specialized compression, the idea being that the decision to use that compression scheme
|
||||
// would fall outside of what QPDFWriter would know anything about, so any attempt to decode and
|
||||
// re-encode would probably be undesirable.
|
||||
QPDF_DLL
|
||||
virtual bool isSpecializedCompression();
|
||||
QPDF_DLL
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFSYSTEMERROR_HH
|
||||
#define QPDFSYSTEMERROR_HH
|
||||
@ -37,9 +34,8 @@ class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error
|
||||
QPDF_DLL
|
||||
virtual ~QPDFSystemError() noexcept = default;
|
||||
|
||||
// To get a complete error string, call what(), provided by
|
||||
// std::exception. The accessors below return the original values
|
||||
// used to create the exception.
|
||||
// To get a complete error string, call what(), provided by std::exception. The accessors below
|
||||
// return the original values used to create the exception.
|
||||
|
||||
QPDF_DLL
|
||||
std::string const& getDescription() const;
|
||||
@ -50,8 +46,8 @@ class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error
|
||||
QPDF_DLL_PRIVATE
|
||||
static std::string createWhat(std::string const& description, int system_errno);
|
||||
|
||||
// This class does not use the Members pattern to avoid needless
|
||||
// memory allocations during exception handling.
|
||||
// This class does not use the Members pattern to avoid needless memory allocations during
|
||||
// exception handling.
|
||||
|
||||
std::string description;
|
||||
int system_errno;
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFUSAGE_HH
|
||||
#define QPDFUSAGE_HH
|
||||
|
@ -2,26 +2,22 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
// This class implements a simple writer for saving QPDF objects to
|
||||
// new PDF files. See comments through the header file for additional
|
||||
// details.
|
||||
// This class implements a simple writer for saving QPDF objects to new PDF files. See comments
|
||||
// through the header file for additional details.
|
||||
|
||||
#ifndef QPDFWRITER_HH
|
||||
#define QPDFWRITER_HH
|
||||
@ -57,21 +53,19 @@ class Pl_MD5;
|
||||
class QPDFWriter
|
||||
{
|
||||
public:
|
||||
// Construct a QPDFWriter object without specifying output. You
|
||||
// must call one of the output setting routines defined below.
|
||||
// Construct a QPDFWriter object without specifying output. You must call one of the output
|
||||
// setting routines defined below.
|
||||
QPDF_DLL
|
||||
QPDFWriter(QPDF& pdf);
|
||||
|
||||
// Create a QPDFWriter object that writes its output to a file or
|
||||
// to stdout. This is equivalent to using the previous
|
||||
// constructor and then calling setOutputFilename(). See
|
||||
// Create a QPDFWriter object that writes its output to a file or to stdout. This is equivalent
|
||||
// to using the previous constructor and then calling setOutputFilename(). See
|
||||
// setOutputFilename() for details.
|
||||
QPDF_DLL
|
||||
QPDFWriter(QPDF& pdf, char const* filename);
|
||||
|
||||
// Create a QPDFWriter object that writes its output to an already
|
||||
// open FILE*. This is equivalent to calling the first
|
||||
// constructor and then calling setOutputFile(). See
|
||||
// Create a QPDFWriter object that writes its output to an already open FILE*. This is
|
||||
// equivalent to calling the first constructor and then calling setOutputFile(). See
|
||||
// setOutputFile() for details.
|
||||
QPDF_DLL
|
||||
QPDFWriter(QPDF& pdf, char const* description, FILE* file, bool close_file);
|
||||
@ -85,15 +79,13 @@ class QPDFWriter
|
||||
QPDF_DLL
|
||||
virtual ~ProgressReporter();
|
||||
|
||||
// This method is called with a value from 0 to 100 to
|
||||
// indicate approximate progress through the write process.
|
||||
// See registerProgressReporter.
|
||||
// This method is called with a value from 0 to 100 to indicate approximate progress through
|
||||
// the write process. See registerProgressReporter.
|
||||
virtual void reportProgress(int) = 0;
|
||||
};
|
||||
|
||||
// This is a progress reporter that takes a function. It is used
|
||||
// by the C APIs, but it is available if you want to just register
|
||||
// a C function as a handler.
|
||||
// This is a progress reporter that takes a function. It is used by the C APIs, but it is
|
||||
// available if you want to just register a C function as a handler.
|
||||
class QPDF_DLL_CLASS FunctionProgressReporter: public ProgressReporter
|
||||
{
|
||||
public:
|
||||
@ -108,39 +100,31 @@ class QPDFWriter
|
||||
std::function<void(int)> handler;
|
||||
};
|
||||
|
||||
// Setting Output. Output may be set only one time. If you don't
|
||||
// use the filename version of the QPDFWriter constructor, you
|
||||
// must call exactly one of these methods.
|
||||
// Setting Output. Output may be set only one time. If you don't use the filename version of
|
||||
// the QPDFWriter constructor, you must call exactly one of these methods.
|
||||
|
||||
// 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.
|
||||
// Passing nullptr 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 if the eventual call to write fails.
|
||||
QPDF_DLL
|
||||
void setOutputFilename(char const* filename);
|
||||
|
||||
// Write to the given FILE*, which must be opened by the caller.
|
||||
// If close_file is true, QPDFWriter will close the file.
|
||||
// Otherwise, the caller must close the file. The file does not
|
||||
// need to be seekable; it will be written to in a single pass.
|
||||
// It must be open in binary mode.
|
||||
// Write to the given FILE*, which must be opened by the caller. If close_file is true,
|
||||
// QPDFWriter will close the file. Otherwise, the caller must close the file. The file does not
|
||||
// need to be seekable; it will be written to in a single pass. It must be open in binary mode.
|
||||
QPDF_DLL
|
||||
void setOutputFile(char const* description, FILE* file, bool close_file);
|
||||
|
||||
// Indicate that QPDFWriter should create a memory buffer to
|
||||
// contain the final PDF file. Obtain the memory by calling
|
||||
// getBuffer().
|
||||
// Indicate that QPDFWriter should create a memory buffer to contain the final PDF file. Obtain
|
||||
// the memory by calling getBuffer().
|
||||
QPDF_DLL
|
||||
void setOutputMemory();
|
||||
|
||||
// Return the buffer object containing the PDF file. If
|
||||
// setOutputMemory() has been called, this method may be called
|
||||
// exactly one time after write() has returned. The caller is
|
||||
// responsible for deleting the buffer when done. See also
|
||||
// getBufferSharedPointer().
|
||||
// Return the buffer object containing the PDF file. If setOutputMemory() has been called, this
|
||||
// method may be called exactly one time after write() has returned. The caller is responsible
|
||||
// for deleting the buffer when done. See also getBufferSharedPointer().
|
||||
QPDF_DLL
|
||||
Buffer* getBuffer();
|
||||
|
||||
@ -148,33 +132,27 @@ class QPDFWriter
|
||||
QPDF_DLL
|
||||
std::shared_ptr<Buffer> getBufferSharedPointer();
|
||||
|
||||
// Supply your own pipeline object. Output will be written to
|
||||
// this pipeline, and QPDFWriter will call finish() on the
|
||||
// pipeline. It is the caller's responsibility to manage the
|
||||
// memory for the pipeline. The pipeline is never deleted by
|
||||
// QPDFWriter, which makes it possible for you to call additional
|
||||
// methods on the pipeline after the writing is finished.
|
||||
// Supply your own pipeline object. Output will be written to this pipeline, and QPDFWriter
|
||||
// will call finish() on the pipeline. It is the caller's responsibility to manage the memory
|
||||
// for the pipeline. The pipeline is never deleted by QPDFWriter, which makes it possible for
|
||||
// you to call additional methods on the pipeline after the writing is finished.
|
||||
QPDF_DLL
|
||||
void setOutputPipeline(Pipeline*);
|
||||
|
||||
// Setting Parameters
|
||||
|
||||
// Set the value of object stream mode. In disable mode, we never
|
||||
// generate any object streams. In preserve mode, we preserve
|
||||
// object stream structure from the original file. In generate
|
||||
// mode, we generate our own object streams. In all cases, we
|
||||
// generate a conventional cross-reference table if there are no
|
||||
// object streams and a cross-reference stream if there are object
|
||||
// streams. The default is o_preserve.
|
||||
// Set the value of object stream mode. In disable mode, we never generate any object streams.
|
||||
// In preserve mode, we preserve object stream structure from the original file. In generate
|
||||
// mode, we generate our own object streams. In all cases, we generate a conventional
|
||||
// cross-reference table if there are no object streams and a cross-reference stream if there
|
||||
// are object streams. The default is o_preserve.
|
||||
QPDF_DLL
|
||||
void setObjectStreamMode(qpdf_object_stream_e);
|
||||
|
||||
// Set value of stream data mode. This is an older interface.
|
||||
// Instead of using this, prefer setCompressStreams() and
|
||||
// setDecodeLevel(). This method is retained for compatibility,
|
||||
// but it does not cover the full range of available
|
||||
// configurations. The mapping between this and the new methods is
|
||||
// as follows:
|
||||
// Set value of stream data mode. This is an older interface. Instead of using this, prefer
|
||||
// setCompressStreams() and setDecodeLevel(). This method is retained for compatibility, but it
|
||||
// does not cover the full range of available configurations. The mapping between this and the
|
||||
// new methods is as follows:
|
||||
//
|
||||
// qpdf_s_uncompress:
|
||||
// setCompressStreams(false)
|
||||
@ -190,205 +168,161 @@ class QPDFWriter
|
||||
QPDF_DLL
|
||||
void setStreamDataMode(qpdf_stream_data_e);
|
||||
|
||||
// If true, compress any uncompressed streams when writing them.
|
||||
// Metadata streams are a special case and are not compressed even
|
||||
// if this is true. This is true by default for QPDFWriter. If you
|
||||
// want QPDFWriter to leave uncompressed streams uncompressed,
|
||||
// pass false to this method.
|
||||
// If true, compress any uncompressed streams when writing them. Metadata streams are a special
|
||||
// case and are not compressed even if this is true. This is true by default for QPDFWriter. If
|
||||
// you want QPDFWriter to leave uncompressed streams uncompressed, pass false to this method.
|
||||
QPDF_DLL
|
||||
void setCompressStreams(bool);
|
||||
|
||||
// When QPDFWriter encounters streams, this parameter controls the
|
||||
// behavior with respect to attempting to apply any filters to the
|
||||
// streams when copying to the output. The decode levels are as
|
||||
// follows:
|
||||
// When QPDFWriter encounters streams, this parameter controls the behavior with respect to
|
||||
// attempting to apply any filters to the streams when copying to the output. The decode levels
|
||||
// are as follows:
|
||||
//
|
||||
// qpdf_dl_none: Do not attempt to apply any filters. Streams
|
||||
// remain as they appear in the original file. Note that
|
||||
// uncompressed streams may still be compressed on output. You can
|
||||
// qpdf_dl_none: Do not attempt to apply any filters. Streams remain as they appear in the
|
||||
// original file. Note that uncompressed streams may still be compressed on output. You can
|
||||
// disable that by calling setCompressStreams(false).
|
||||
//
|
||||
// qpdf_dl_generalized: This is the default. QPDFWriter will apply
|
||||
// LZWDecode, ASCII85Decode, ASCIIHexDecode, and FlateDecode
|
||||
// filters on the input. When combined with
|
||||
// setCompressStreams(true), which the default, the effect of this
|
||||
// is that streams filtered with these older and less efficient
|
||||
// filters will be recompressed with the Flate filter. By default,
|
||||
// as a special case, if a stream is already compressed with
|
||||
// FlateDecode and setCompressStreams is enabled, the original
|
||||
// compressed data will be preserved. This behavior can be
|
||||
// overridden by calling setRecompressFlate(true).
|
||||
// qpdf_dl_generalized: This is the default. QPDFWriter will apply LZWDecode, ASCII85Decode,
|
||||
// ASCIIHexDecode, and FlateDecode filters on the input. When combined with
|
||||
// setCompressStreams(true), which is the default, the effect of this is that streams filtered
|
||||
// with these older and less efficient filters will be recompressed with the Flate filter. By
|
||||
// default, as a special case, if a stream is already compressed with FlateDecode and
|
||||
// setCompressStreams is enabled, the original compressed data will be preserved. This behavior
|
||||
// can be overridden by calling setRecompressFlate(true).
|
||||
//
|
||||
// qpdf_dl_specialized: In addition to uncompressing the
|
||||
// generalized compression formats, supported non-lossy
|
||||
// compression will also be decoded. At present, this includes
|
||||
// the RunLengthDecode filter.
|
||||
// qpdf_dl_specialized: In addition to uncompressing the generalized compression formats,
|
||||
// supported non-lossy compression will also be decoded. At present, this includes the
|
||||
// RunLengthDecode filter.
|
||||
//
|
||||
// qpdf_dl_all: In addition to generalized and non-lossy
|
||||
// specialized filters, supported lossy compression filters will
|
||||
// be applied. At present, this includes DCTDecode (JPEG)
|
||||
// compression. Note that compressing the resulting data with
|
||||
// DCTDecode again will accumulate loss, so avoid multiple
|
||||
// compression and decompression cycles. This is mostly useful for
|
||||
// retrieving image data.
|
||||
// qpdf_dl_all: In addition to generalized and non-lossy specialized filters, supported lossy
|
||||
// compression filters will be applied. At present, this includes DCTDecode (JPEG) compression.
|
||||
// Note that compressing the resulting data with DCTDecode again will accumulate loss, so avoid
|
||||
// multiple compression and decompression cycles. This is mostly useful for retrieving image
|
||||
// data.
|
||||
QPDF_DLL
|
||||
void setDecodeLevel(qpdf_stream_decode_level_e);
|
||||
|
||||
// By default, when both the input and output contents of a stream
|
||||
// are compressed with Flate, qpdf does not uncompress and
|
||||
// recompress the stream. Passing true here causes it to do so.
|
||||
// This can be useful if recompressing all streams with a higher
|
||||
// compression level, which can be set by calling the static
|
||||
// method Pl_Flate::setCompressionLevel.
|
||||
// By default, when both the input and output contents of a stream are compressed with Flate,
|
||||
// qpdf does not uncompress and recompress the stream. Passing true here causes it to do so.
|
||||
// This can be useful if recompressing all streams with a higher compression level, which can be
|
||||
// set by calling the static method Pl_Flate::setCompressionLevel.
|
||||
QPDF_DLL
|
||||
void setRecompressFlate(bool);
|
||||
|
||||
// Set value of content stream normalization. The default is
|
||||
// "false". If true, we attempt to normalize newlines inside of
|
||||
// content streams. Some constructs such as inline images may
|
||||
// thwart our efforts. There may be some cases where this can
|
||||
// damage the content stream. This flag should be used only for
|
||||
// debugging and experimenting with PDF content streams. Never
|
||||
// use it for production files.
|
||||
// Set value of content stream normalization. The default is "false". If true, we attempt to
|
||||
// normalize newlines inside of content streams. Some constructs such as inline images may
|
||||
// thwart our efforts. There may be some cases where this can damage the content stream. This
|
||||
// flag should be used only for debugging and experimenting with PDF content streams. Never use
|
||||
// it for production files.
|
||||
QPDF_DLL
|
||||
void setContentNormalization(bool);
|
||||
|
||||
// Set QDF mode. QDF mode causes special "pretty printing" of
|
||||
// PDF objects, adds comments for easier perusing of files.
|
||||
// Resulting PDF files can be edited in a text editor and then run
|
||||
// through fix-qdf to update cross reference tables and stream
|
||||
// lengths.
|
||||
// Set QDF mode. QDF mode causes special "pretty printing" of PDF objects, adds comments for
|
||||
// easier perusing of files. Resulting PDF files can be edited in a text editor and then run
|
||||
// through fix-qdf to update cross reference tables and stream lengths.
|
||||
QPDF_DLL
|
||||
void setQDFMode(bool);
|
||||
|
||||
// Preserve unreferenced objects. The default behavior is to
|
||||
// discard any object that is not visited during a traversal of
|
||||
// the object structure from the trailer.
|
||||
// Preserve unreferenced objects. The default behavior is to discard any object that is not
|
||||
// visited during a traversal of the object structure from the trailer.
|
||||
QPDF_DLL
|
||||
void setPreserveUnreferencedObjects(bool);
|
||||
|
||||
// Always write a newline before the endstream keyword. This helps
|
||||
// with PDF/A compliance, though it is not sufficient for it.
|
||||
// Always write a newline before the endstream keyword. This helps with PDF/A compliance, though
|
||||
// it is not sufficient for it.
|
||||
QPDF_DLL
|
||||
void setNewlineBeforeEndstream(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.
|
||||
// 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.
|
||||
QPDF_DLL
|
||||
void setMinimumPDFVersion(std::string const&, int extension_level = 0);
|
||||
QPDF_DLL
|
||||
void setMinimumPDFVersion(PDFVersion 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.
|
||||
// If any encryption has been applied to the document either
|
||||
// explicitly or by preserving the encryption of the source
|
||||
// document, forcing the PDF version to a value too low to support
|
||||
// that type of encryption will explicitly disable decryption.
|
||||
// Additionally, forcing to a version below 1.5 will disable
|
||||
// object streams.
|
||||
// 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. If any encryption has been applied to the document either explicitly or by
|
||||
// preserving the encryption of the source document, forcing the PDF version to a value too low
|
||||
// to support that type of encryption will explicitly disable decryption. Additionally, forcing
|
||||
// to a version below 1.5 will disable object streams.
|
||||
QPDF_DLL
|
||||
void forcePDFVersion(std::string const&, int extension_level = 0);
|
||||
|
||||
// Provide additional text to insert in the PDF file somewhere
|
||||
// near the beginning of the file. This can be used to add
|
||||
// comments to the beginning of a PDF file, for example, if those
|
||||
// comments are to be consumed by some other application. No
|
||||
// checks are performed to ensure that the text inserted here is
|
||||
// valid PDF. If you want to insert multiline comments, you will
|
||||
// need to include \n in the string yourself and start each line
|
||||
// with %. An extra newline will be appended if one is not
|
||||
// already present at the end of your text.
|
||||
// Provide additional text to insert in the PDF file somewhere near the beginning of the file.
|
||||
// This can be used to add comments to the beginning of a PDF file, for example, if those
|
||||
// comments are to be consumed by some other application. No checks are performed to ensure
|
||||
// that the text inserted here is valid PDF. If you want to insert multiline comments, you will
|
||||
// need to include \n in the string yourself and start each line with %. An extra newline will
|
||||
// be appended if one is not already present at the end of your text.
|
||||
QPDF_DLL
|
||||
void setExtraHeaderText(std::string const&);
|
||||
|
||||
// Causes a deterministic /ID value to be generated. When this is
|
||||
// set, the current time and output file name are not used as part
|
||||
// of /ID generation. Instead, a digest of all significant parts
|
||||
// of the output file's contents is included in the /ID
|
||||
// calculation. Use of a deterministic /ID can be handy when it is
|
||||
// desirable for a repeat of the same qpdf operation on the same
|
||||
// inputs being written to the same outputs with the same
|
||||
// parameters to generate exactly the same results. This feature
|
||||
// is incompatible with encrypted files because, for encrypted
|
||||
// files, the /ID is generated before any part of the file is
|
||||
// written since it is an input to the encryption process.
|
||||
// Causes a deterministic /ID value to be generated. When this is set, the current time and
|
||||
// output file name are not used as part of /ID generation. Instead, a digest of all significant
|
||||
// parts of the output file's contents is included in the /ID calculation. Use of a
|
||||
// deterministic /ID can be handy when it is desirable for a repeat of the same qpdf operation
|
||||
// on the same inputs being written to the same outputs with the same parameters to generate
|
||||
// exactly the same results. This feature is incompatible with encrypted files because, for
|
||||
// encrypted files, the /ID is generated before any part of the file is written since it is an
|
||||
// input to the encryption process.
|
||||
QPDF_DLL
|
||||
void setDeterministicID(bool);
|
||||
|
||||
// Cause a static /ID value to be generated. Use only in test
|
||||
// suites. See also setDeterministicID.
|
||||
// Cause a static /ID value to be generated. Use only in test suites. See also
|
||||
// setDeterministicID.
|
||||
QPDF_DLL
|
||||
void setStaticID(bool);
|
||||
|
||||
// Use a fixed initialization vector for AES-CBC encryption. This
|
||||
// is not secure. It should be used only in test suites for
|
||||
// creating predictable encrypted output.
|
||||
// Use a fixed initialization vector for AES-CBC encryption. This is not secure. It should be
|
||||
// used only in test suites for creating predictable encrypted output.
|
||||
QPDF_DLL
|
||||
void setStaticAesIV(bool);
|
||||
|
||||
// Suppress inclusion of comments indicating original object IDs
|
||||
// when writing QDF files. This can also be useful for testing,
|
||||
// particularly when using comparison of two qdf files to
|
||||
// Suppress inclusion of comments indicating original object IDs when writing QDF files. This
|
||||
// can also be useful for testing, particularly when using comparison of two qdf files to
|
||||
// determine whether two PDF files have identical content.
|
||||
QPDF_DLL
|
||||
void setSuppressOriginalObjectIDs(bool);
|
||||
|
||||
// Preserve encryption. The default is true unless prefilering,
|
||||
// content normalization, or qdf mode has been selected in which
|
||||
// case encryption is never preserved. Encryption is also not
|
||||
// Preserve encryption. The default is true unless prefilering, content normalization, or qdf
|
||||
// mode has been selected in which case encryption is never preserved. Encryption is also not
|
||||
// preserved if we explicitly set encryption parameters.
|
||||
QPDF_DLL
|
||||
void setPreserveEncryption(bool);
|
||||
|
||||
// Copy encryption parameters from another QPDF object. If you
|
||||
// want to copy encryption from the object you are writing, call
|
||||
// setPreserveEncryption(true) instead.
|
||||
// Copy encryption parameters from another QPDF object. If you want to copy encryption from the
|
||||
// object you are writing, call setPreserveEncryption(true) instead.
|
||||
QPDF_DLL
|
||||
void copyEncryptionParameters(QPDF&);
|
||||
|
||||
// Set up for encrypted output. User and owner password both must
|
||||
// be specified. Either or both may be the empty string. Note
|
||||
// that qpdf does not apply any special treatment to the empty
|
||||
// string, which makes it possible to create encrypted files with
|
||||
// empty owner passwords and non-empty user passwords or with the
|
||||
// same password for both user and owner. Some PDF reading
|
||||
// products don't handle such files very well. Enabling
|
||||
// encryption disables stream prefiltering and content
|
||||
// normalization. Note that setting R2 encryption parameters sets
|
||||
// the PDF version to at least 1.3, setting R3 encryption
|
||||
// parameters pushes the PDF version number to at least 1.4,
|
||||
// setting R4 parameters pushes the version to at least 1.5, or if
|
||||
// AES is used, 1.6, and setting R5 or R6 parameters pushes the
|
||||
// version to at least 1.7 with extension level 3.
|
||||
// Set up for encrypted output. User and owner password both must be specified. Either or both
|
||||
// may be the empty string. Note that qpdf does not apply any special treatment to the empty
|
||||
// string, which makes it possible to create encrypted files with empty owner passwords and
|
||||
// non-empty user passwords or with the same password for both user and owner. Some PDF reading
|
||||
// products don't handle such files very well. Enabling encryption disables stream prefiltering
|
||||
// and content normalization. Note that setting R2 encryption parameters sets the PDF version
|
||||
// to at least 1.3, setting R3 encryption parameters pushes the PDF version number to at
|
||||
// least 1.4, setting R4 parameters pushes the version to at least 1.5, or if AES is used, 1.6,
|
||||
// and setting R5 or R6 parameters pushes the version to at least 1.7 with extension level 3.
|
||||
//
|
||||
// Note about Unicode passwords: the PDF specification requires
|
||||
// passwords to be encoded with PDF Doc encoding for R <= 4 and
|
||||
// UTF-8 for R >= 5. In all cases, these methods take strings of
|
||||
// bytes as passwords. It is up to the caller to ensure that
|
||||
// passwords are properly encoded. The qpdf command-line tool
|
||||
// tries to do this, as discussed in the manual. If you are doing
|
||||
// this from your own application, QUtil contains many transcoding
|
||||
// functions that could be useful to you, most notably
|
||||
// utf8_to_pdf_doc.
|
||||
// Note about Unicode passwords: the PDF specification requires passwords to be encoded with PDF
|
||||
// Doc encoding for R <= 4 and UTF-8 for R >= 5. In all cases, these methods take strings of
|
||||
// bytes as passwords. It is up to the caller to ensure that passwords are properly encoded. The
|
||||
// qpdf command-line tool tries to do this, as discussed in the manual. If you are doing this
|
||||
// from your own application, QUtil contains many transcoding functions that could be useful to
|
||||
// you, most notably utf8_to_pdf_doc.
|
||||
|
||||
// R2 uses RC4, which is a weak cryptographic algorithm. Don't use
|
||||
// it unless you have to. See "Weak Cryptography" in the manual.
|
||||
// This encryption format is deprecated in the PDF 2.0
|
||||
// R2 uses RC4, which is a weak cryptographic algorithm. Don't use it unless you have to. See
|
||||
// "Weak Cryptography" in the manual. This encryption format is deprecated in the PDF 2.0
|
||||
// specification.
|
||||
QPDF_DLL
|
||||
void setR2EncryptionParametersInsecure(
|
||||
@ -398,9 +332,8 @@ class QPDFWriter
|
||||
bool allow_modify,
|
||||
bool allow_extract,
|
||||
bool allow_annotate);
|
||||
// R3 uses RC4, which is a weak cryptographic algorithm. Don't use
|
||||
// it unless you have to. See "Weak Cryptography" in the manual.
|
||||
// This encryption format is deprecated in the PDF 2.0
|
||||
// R3 uses RC4, which is a weak cryptographic algorithm. Don't use it unless you have to. See
|
||||
// "Weak Cryptography" in the manual. This encryption format is deprecated in the PDF 2.0
|
||||
// specification.
|
||||
QPDF_DLL
|
||||
void setR3EncryptionParametersInsecure(
|
||||
@ -413,11 +346,10 @@ class QPDFWriter
|
||||
bool allow_form_filling,
|
||||
bool allow_modify_other,
|
||||
qpdf_r3_print_e print);
|
||||
// When use_aes=false, this call enables R4 with RC4, which is a
|
||||
// weak cryptographic algorithm. Even with use_aes=true, the
|
||||
// overall encryption scheme is weak. Don't use it unless you have
|
||||
// to. See "Weak Cryptography" in the manual. This encryption
|
||||
// format is deprecated in the PDF 2.0 specification.
|
||||
// When use_aes=false, this call enables R4 with RC4, which is a weak cryptographic algorithm.
|
||||
// Even with use_aes=true, the overall encryption scheme is weak. Don't use it unless you have
|
||||
// to. See "Weak Cryptography" in the manual. This encryption format is deprecated in the
|
||||
// PDF 2.0 specification.
|
||||
QPDF_DLL
|
||||
void setR4EncryptionParametersInsecure(
|
||||
char const* user_password,
|
||||
@ -431,9 +363,8 @@ class QPDFWriter
|
||||
qpdf_r3_print_e print,
|
||||
bool encrypt_metadata,
|
||||
bool use_aes);
|
||||
// R5 is deprecated. Do not use it for production use. Writing
|
||||
// R5 is supported by qpdf primarily to generate test files for
|
||||
// applications that may need to test R5 support.
|
||||
// R5 is deprecated. Do not use it for production use. Writing R5 is supported by qpdf
|
||||
// primarily to generate test files for applications that may need to test R5 support.
|
||||
QPDF_DLL
|
||||
void setR5EncryptionParameters(
|
||||
char const* user_password,
|
||||
@ -446,8 +377,7 @@ class QPDFWriter
|
||||
bool allow_modify_other,
|
||||
qpdf_r3_print_e print,
|
||||
bool encrypt_metadata);
|
||||
// This is the only password-based encryption format supported by
|
||||
// the PDF specification.
|
||||
// This is the only password-based encryption format supported by the PDF specification.
|
||||
QPDF_DLL
|
||||
void setR6EncryptionParameters(
|
||||
char const* user_password,
|
||||
@ -461,57 +391,49 @@ class QPDFWriter
|
||||
qpdf_r3_print_e print,
|
||||
bool encrypt_metadata_aes);
|
||||
|
||||
// Create linearized output. Disables qdf mode, content
|
||||
// normalization, and stream prefiltering.
|
||||
// Create linearized output. Disables qdf mode, content normalization, and stream prefiltering.
|
||||
QPDF_DLL
|
||||
void setLinearization(bool);
|
||||
|
||||
// For debugging QPDF: provide the name of a file to write pass1
|
||||
// of linearization to. The only reason to use this is to debug
|
||||
// QPDF. To linearize, QPDF writes out the file in two passes.
|
||||
// Usually the first pass is discarded, but lots of computations
|
||||
// are made in pass 1. If a linearized file comes out wrong, it
|
||||
// can be helpful to look at the first pass.
|
||||
// For debugging QPDF: provide the name of a file to write pass1 of linearization to. The only
|
||||
// reason to use this is to debug QPDF. To linearize, QPDF writes out the file in two passes.
|
||||
// Usually the first pass is discarded, but lots of computations are made in pass 1. If a
|
||||
// linearized file comes out wrong, it can be helpful to look at the first pass.
|
||||
QPDF_DLL
|
||||
void setLinearizationPass1Filename(std::string const&);
|
||||
|
||||
// Create PCLm output. This is only useful for clients that know
|
||||
// how to create PCLm files. If a file is structured exactly as
|
||||
// PCLm requires, this call will tell QPDFWriter to write the PCLm
|
||||
// header, create certain unreferenced streams required by the
|
||||
// standard, and write the objects in the required order. Calling
|
||||
// this on an ordinary PDF serves no purpose. There is no
|
||||
// Create PCLm output. This is only useful for clients that know how to create PCLm files. If a
|
||||
// file is structured exactly as PCLm requires, this call will tell QPDFWriter to write the PCLm
|
||||
// header, create certain unreferenced streams required by the standard, and write the objects
|
||||
// in the required order. Calling this on an ordinary PDF serves no purpose. There is no
|
||||
// command-line argument that causes this method to be called.
|
||||
QPDF_DLL
|
||||
void setPCLm(bool);
|
||||
|
||||
// If you want to be notified of progress, derive a class from
|
||||
// ProgressReporter and override the reportProgress method.
|
||||
// If you want to be notified of progress, derive a class from ProgressReporter and override the
|
||||
// reportProgress method.
|
||||
QPDF_DLL
|
||||
void registerProgressReporter(std::shared_ptr<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
|
||||
// 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.
|
||||
// Write the final file. There is no expectation of being able to call write() more than once.
|
||||
QPDF_DLL
|
||||
void write();
|
||||
|
||||
// Return renumbered ObjGen that was written into the final file.
|
||||
// This method can be used after calling write().
|
||||
// Return renumbered ObjGen that was written into the final file. This method can be used after
|
||||
// calling write().
|
||||
QPDF_DLL
|
||||
QPDFObjGen getRenumberedObjGen(QPDFObjGen);
|
||||
|
||||
// Return XRef entry that was written into the final file.
|
||||
// This method can be used after calling write().
|
||||
// Return XRef entry that was written into the final file. This method can be used after calling
|
||||
// write().
|
||||
QPDF_DLL
|
||||
std::map<QPDFObjGen, QPDFXRefEntry> getWrittenXRefTable();
|
||||
|
||||
@ -525,15 +447,12 @@ class QPDFWriter
|
||||
|
||||
enum trailer_e { t_normal, t_lin_first, t_lin_second };
|
||||
|
||||
// An reference to a PipelinePopper instance is passed into
|
||||
// activatePipelineStack. When the PipelinePopper goes out of
|
||||
// scope, the pipeline stack is popped. PipelinePopper's
|
||||
// destructor calls finish on the current pipeline and pops the
|
||||
// pipeline stack until the top of stack is a previous active top
|
||||
// of stack, and restores the pipeline to that point. It deletes
|
||||
// any pipelines that it pops. If the bp argument is non-null and
|
||||
// any of the stack items are of type Pl_Buffer, the buffer is
|
||||
// retrieved.
|
||||
// An reference to a PipelinePopper instance is passed into activatePipelineStack. When the
|
||||
// PipelinePopper goes out of scope, the pipeline stack is popped. PipelinePopper's destructor
|
||||
// calls finish on the current pipeline and pops the pipeline stack until the top of stack is a
|
||||
// previous active top of stack, and restores the pipeline to that point. It deletes any
|
||||
// pipelines that it pops. If the bp argument is non-null and any of the stack items are of type
|
||||
// Pl_Buffer, the buffer is retrieved.
|
||||
class PipelinePopper
|
||||
{
|
||||
friend class QPDFWriter;
|
||||
@ -672,10 +591,9 @@ class QPDFWriter
|
||||
int linearization_pass);
|
||||
size_t calculateXrefStreamPadding(qpdf_offset_t xref_bytes);
|
||||
|
||||
// When filtering subsections, push additional pipelines to the
|
||||
// stack. When ready to switch, activate the pipeline stack. When
|
||||
// the passed in PipelinePopper goes out of scope, the stack is
|
||||
// popped.
|
||||
// When filtering subsections, push additional pipelines to the stack. When ready to switch,
|
||||
// activate the pipeline stack. When the passed in PipelinePopper goes out of scope, the stack
|
||||
// is popped.
|
||||
Pipeline* pushPipeline(Pipeline*);
|
||||
void activatePipelineStack(PipelinePopper&);
|
||||
void initializePipelineStack(Pipeline*);
|
||||
@ -779,9 +697,8 @@ class QPDFWriter
|
||||
int next_progress_report{0};
|
||||
};
|
||||
|
||||
// Keep all member variables inside the Members object, which we
|
||||
// dynamically allocate. This makes it possible to add new private
|
||||
// members without breaking binary compatibility.
|
||||
// Keep all member variables inside the Members object, which we dynamically allocate. This
|
||||
// makes it possible to add new private members without breaking binary compatibility.
|
||||
std::shared_ptr<Members> m;
|
||||
};
|
||||
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QPDFXREFENTRY_HH
|
||||
#define QPDFXREFENTRY_HH
|
||||
@ -28,8 +25,7 @@
|
||||
class QPDFXRefEntry
|
||||
{
|
||||
public:
|
||||
// Type constants are from the PDF spec section
|
||||
// "Cross-Reference Streams":
|
||||
// Type constants are from the PDF spec section "Cross-Reference Streams":
|
||||
// 0 = free entry; not used
|
||||
// 1 = "uncompressed"; field 1 = offset
|
||||
// 2 = "compressed"; field 1 = object stream number, field 2 = index
|
||||
@ -65,8 +61,8 @@ class QPDFXRefEntry
|
||||
int getObjStreamIndex() const; // only for type 2
|
||||
|
||||
private:
|
||||
// This class does not use the Members pattern to avoid a memory
|
||||
// allocation for every one of these. A lot of these get created.
|
||||
// This class does not use the Members pattern to avoid a memory allocation for every one of
|
||||
// these. A lot of these get created.
|
||||
int type{0};
|
||||
qpdf_offset_t field1{0};
|
||||
int field2{0};
|
||||
|
@ -2,33 +2,28 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QTC_HH
|
||||
#define QTC_HH
|
||||
|
||||
#include <qpdf/DLL.h>
|
||||
|
||||
// Defining QPDF_DISABLE_QTC will effectively compile out any QTC::TC
|
||||
// calls in any code that includes this file, but QTC will still be
|
||||
// built into the library. That way, it is possible to build and
|
||||
// package qpdf with QPDF_DISABLE_QTC while still making QTC::TC
|
||||
// available to end users.
|
||||
// Defining QPDF_DISABLE_QTC will effectively compile out any QTC::TC calls in any code that
|
||||
// includes this file, but QTC will still be built into the library. That way, it is possible to
|
||||
// build and package qpdf with QPDF_DISABLE_QTC while still making QTC::TC available to end users.
|
||||
|
||||
namespace QTC
|
||||
{
|
||||
|
@ -2,22 +2,19 @@
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
// License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
// Please see the manual for additional information.
|
||||
|
||||
#ifndef QUTIL_HH
|
||||
#define QUTIL_HH
|
||||
@ -40,8 +37,7 @@ class Pipeline;
|
||||
|
||||
namespace QUtil
|
||||
{
|
||||
// This is a collection of useful utility functions that don't
|
||||
// really go anywhere else.
|
||||
// This is a collection of useful utility functions that don't really go anywhere else.
|
||||
QPDF_DLL
|
||||
std::string int_to_string(long long, int length = 0);
|
||||
QPDF_DLL
|
||||
@ -53,8 +49,7 @@ namespace QUtil
|
||||
QPDF_DLL
|
||||
std::string double_to_string(double, int decimal_places = 0, bool trim_trailing_zeroes = true);
|
||||
|
||||
// These string to number methods throw std::runtime_error on
|
||||
// underflow/overflow.
|
||||
// These string to number methods throw std::runtime_error on underflow/overflow.
|
||||
QPDF_DLL
|
||||
long long string_to_ll(char const* str);
|
||||
QPDF_DLL
|
||||
@ -64,63 +59,53 @@ namespace QUtil
|
||||
QPDF_DLL
|
||||
unsigned int string_to_uint(char const* str);
|
||||
|
||||
// Returns true if this exactly represents a long long. The
|
||||
// determination is made by converting the string to a long long,
|
||||
// then converting the result back to a string, and then comparing
|
||||
// Returns true if this exactly represents a long long. The determination is made by converting
|
||||
// the string to a long long, then converting the result back to a string, and then comparing
|
||||
// that result with the original string.
|
||||
QPDF_DLL
|
||||
bool is_long_long(char const* str);
|
||||
|
||||
// Pipeline's write method wants unsigned char*, but we often have
|
||||
// some other type of string. These methods do combinations of
|
||||
// const_cast and reinterpret_cast to give us an unsigned char*.
|
||||
// They should only be used when it is known that it is safe.
|
||||
// None of the pipelines in qpdf modify the data passed to them,
|
||||
// so within qpdf, it should always be safe.
|
||||
// Pipeline's write method wants unsigned char*, but we often have some other type of string.
|
||||
// These methods do combinations of const_cast and reinterpret_cast to give us an unsigned
|
||||
// char*. They should only be used when it is known that it is safe. None of the pipelines in
|
||||
// qpdf modify the data passed to them, so within qpdf, it should always be safe.
|
||||
QPDF_DLL
|
||||
unsigned char* unsigned_char_pointer(std::string const& str);
|
||||
QPDF_DLL
|
||||
unsigned char* unsigned_char_pointer(char const* str);
|
||||
|
||||
// Throw QPDFSystemError, which is derived from
|
||||
// std::runtime_error, with a string formed by appending to
|
||||
// "description: " the standard string corresponding to the
|
||||
// current value of errno. You can retrieve the value of errno by
|
||||
// calling getErrno() on the QPDFSystemError. Prior to qpdf 8.2.0,
|
||||
// this method threw system::runtime_error directly, but since
|
||||
// QPDFSystemError is derived from system::runtime_error, old code
|
||||
// that specifically catches std::runtime_error will still work.
|
||||
// Throw QPDFSystemError, which is derived from std::runtime_error, with a string formed by
|
||||
// appending to "description: " the standard string corresponding to the current value of errno.
|
||||
// You can retrieve the value of errno by calling getErrno() on the QPDFSystemError. Prior to
|
||||
// qpdf 8.2.0, this method threw system::runtime_error directly, but since QPDFSystemError is
|
||||
// derived from system::runtime_error, old code that specifically catches std::runtime_error
|
||||
// will still work.
|
||||
QPDF_DLL
|
||||
void throw_system_error(std::string const& description);
|
||||
|
||||
// The status argument is assumed to be the return value of a
|
||||
// standard library call that sets errno when it fails. If status
|
||||
// is -1, convert the current value of errno to a
|
||||
// std::runtime_error that includes the standard error string.
|
||||
// Otherwise, return status.
|
||||
// The status argument is assumed to be the return value of a standard library call that sets
|
||||
// errno when it fails. If status is -1, convert the current value of errno to a
|
||||
// std::runtime_error that includes the standard error string. Otherwise, return status.
|
||||
QPDF_DLL
|
||||
int os_wrapper(std::string const& description, int status);
|
||||
|
||||
// If the open fails, throws std::runtime_error. Otherwise, the
|
||||
// FILE* is returned. The filename should be UTF-8 encoded, even
|
||||
// on Windows. It will be converted as needed on Windows.
|
||||
// If the open fails, throws std::runtime_error. Otherwise, the FILE* is returned. The filename
|
||||
// should be UTF-8 encoded, even on Windows. It will be converted as needed on Windows.
|
||||
QPDF_DLL
|
||||
FILE* safe_fopen(char const* filename, char const* mode);
|
||||
|
||||
// The FILE* argument is assumed to be the return of fopen. If
|
||||
// null, throw std::runtime_error. Otherwise, return the FILE*
|
||||
// argument.
|
||||
// The FILE* argument is assumed to be the return of fopen. If null, throw std::runtime_error.
|
||||
// Otherwise, return the FILE* argument.
|
||||
QPDF_DLL
|
||||
FILE* fopen_wrapper(std::string const&, FILE*);
|
||||
|
||||
// This is a little class to help with automatic closing files.
|
||||
// You can do something like
|
||||
// This is a little class to help with automatic closing files. You can do something like
|
||||
//
|
||||
// QUtil::FileCloser fc(QUtil::safe_fopen(filename, "rb"));
|
||||
//
|
||||
// and then use fc.f to the file. Be sure to actually declare a
|
||||
// variable of type FileCloser. Using it as a temporary won't work
|
||||
// because it will close the file as soon as it goes out of scope.
|
||||
// and then use fc.f to the file. Be sure to actually declare a variable of type FileCloser.
|
||||
// Using it as a temporary won't work because it will close the file as soon as it goes out of
|
||||
// scope.
|
||||
class FileCloser
|
||||
{
|
||||
public:
|
||||
@ -160,28 +145,24 @@ namespace QUtil
|
||||
QPDF_DLL
|
||||
void rename_file(char const* oldname, char const* newname);
|
||||
|
||||
// Write the contents of filename as a binary file to the
|
||||
// pipeline.
|
||||
// Write the contents of filename as a binary file to the pipeline.
|
||||
QPDF_DLL
|
||||
void pipe_file(char const* filename, Pipeline* p);
|
||||
|
||||
// Return a function that will send the contents of the given file
|
||||
// through the given pipeline as binary data.
|
||||
// Return a function that will send the contents of the given file through the given pipeline as
|
||||
// binary data.
|
||||
QPDF_DLL
|
||||
std::function<void(Pipeline*)> file_provider(std::string const& filename);
|
||||
|
||||
// Return the last path element. On Windows, either / or \ are
|
||||
// path separators. Otherwise, only / is a path separator. Strip
|
||||
// any trailing path separators. Then, if any path separators
|
||||
// remain, return everything after the last path separator.
|
||||
// Otherwise, return the whole string. As a special case, if a
|
||||
// string consists entirely of path separators, the first
|
||||
// character is returned.
|
||||
// Return the last path element. On Windows, either / or \ are path separators. Otherwise, only
|
||||
// / is a path separator. Strip any trailing path separators. Then, if any path separators
|
||||
// remain, return everything after the last path separator. Otherwise, return the whole string.
|
||||
// As a special case, if a string consists entirely of path separators, the first character is
|
||||
// returned.
|
||||
QPDF_DLL
|
||||
std::string path_basename(std::string const& filename);
|
||||
|
||||
// Returns a dynamically allocated copy of a string that the
|
||||
// caller has to delete with delete[].
|
||||
// Returns a dynamically allocated copy of a string that the caller has to delete with delete[].
|
||||
QPDF_DLL
|
||||
char* copy_string(std::string const&);
|
||||
|
||||
@ -193,8 +174,7 @@ namespace QUtil
|
||||
QPDF_DLL
|
||||
std::unique_ptr<char[]> make_unique_cstr(std::string const&);
|
||||
|
||||
// Create a shared pointer to an array. From c++20,
|
||||
// std::make_shared<T[]>(n) does this.
|
||||
// Create a shared pointer to an array. From c++20, std::make_shared<T[]>(n) does this.
|
||||
template <typename T>
|
||||
std::shared_ptr<T>
|
||||
make_shared_array(size_t n)
|
||||
@ -202,27 +182,24 @@ namespace QUtil
|
||||
return std::shared_ptr<T>(new T[n], std::default_delete<T[]>());
|
||||
}
|
||||
|
||||
// Returns lower-case hex-encoded version of the string, treating
|
||||
// each character in the input string as unsigned. The output
|
||||
// string will be twice as long as the input string.
|
||||
// Returns lower-case hex-encoded version of the string, treating each character in the input
|
||||
// string as unsigned. The output string will be twice as long as the input string.
|
||||
QPDF_DLL
|
||||
std::string hex_encode(std::string const&);
|
||||
|
||||
// Returns lower-case hex-encoded version of the char including a leading
|
||||
// "#".
|
||||
// Returns lower-case hex-encoded version of the char including a leading "#".
|
||||
QPDF_DLL
|
||||
inline std::string hex_encode_char(char);
|
||||
|
||||
// Returns a string that is the result of decoding the input
|
||||
// string. The input string may consist of mixed case hexadecimal
|
||||
// digits. Any characters that are not hexadecimal digits will be
|
||||
// silently ignored. If there are an odd number of hexadecimal
|
||||
// digits, a trailing 0 will be assumed.
|
||||
// Returns a string that is the result of decoding the input string. The input string may
|
||||
// consist of mixed case hexadecimal digits. Any characters that are not hexadecimal digits will
|
||||
// be silently ignored. If there are an odd number of hexadecimal digits, a trailing 0 will be
|
||||
// assumed.
|
||||
QPDF_DLL
|
||||
std::string hex_decode(std::string const&);
|
||||
|
||||
// Decode a single hex digit into a char in the range 0 <= char < 16. Return
|
||||
// a char >= 16 if digit is not a valid hex digit.
|
||||
// Decode a single hex digit into a char in the range 0 <= char < 16. Return a char >= 16 if
|
||||
// digit is not a valid hex digit.
|
||||
QPDF_DLL
|
||||
inline constexpr char hex_decode_char(char digit) noexcept;
|
||||
|
||||
@ -239,17 +216,15 @@ namespace QUtil
|
||||
QPDF_DLL
|
||||
char* getWhoami(char* argv0);
|
||||
|
||||
// Get the value of an environment variable in a portable fashion.
|
||||
// Returns true iff the variable is defined. If `value' is
|
||||
// non-null, initializes it with the value of the variable.
|
||||
// Get the value of an environment variable in a portable fashion. Returns true iff the variable
|
||||
// is defined. If `value' is non-null, initializes it with the value of the variable.
|
||||
QPDF_DLL
|
||||
bool get_env(std::string const& var, std::string* value = nullptr);
|
||||
|
||||
QPDF_DLL
|
||||
time_t get_current_time();
|
||||
|
||||
// Portable structure representing a point in time with second
|
||||
// granularity and time zone offset
|
||||
// Portable structure representing a point in time with second granularity and time zone offset.
|
||||
struct QPDFTime
|
||||
{
|
||||
QPDFTime() = default;
|
||||
@ -277,12 +252,11 @@ namespace QUtil
|
||||
QPDF_DLL
|
||||
QPDFTime get_current_qpdf_time();
|
||||
|
||||
// Convert a QPDFTime structure to a PDF timestamp string, which
|
||||
// is "D:yyyymmddhhmmss<z>" where <z> is either "Z" for UTC or
|
||||
// "-hh'mm'" or "+hh'mm'" for timezone offset. <z> may also be
|
||||
// omitted. Examples: "D:20210207161528-05'00'",
|
||||
// "D:20210207211528Z", "D:20210207211528". See
|
||||
// get_current_qpdf_time and the QPDFTime structure above.
|
||||
// Convert a QPDFTime structure to a PDF timestamp string, which is "D:yyyymmddhhmmss<z>" where
|
||||
// <z> is either "Z" for UTC or "-hh'mm'" or "+hh'mm'" for timezone offset. <z> may also be
|
||||
// omitted.
|
||||
// Examples: "D:20210207161528-05'00'", "D:20210207211528Z", "D:20210207211528".
|
||||
// See get_current_qpdf_time and the QPDFTime structure above.
|
||||
QPDF_DLL
|
||||
std::string qpdf_time_to_pdf_time(QPDFTime const&);
|
||||
|
||||
@ -290,63 +264,53 @@ namespace QUtil
|
||||
QPDF_DLL
|
||||
std::string qpdf_time_to_iso8601(QPDFTime const&);
|
||||
|
||||
// Convert a PDF timestamp string to a QPDFTime. If syntactically
|
||||
// valid, return true and fill in qtm. If not valid, return false,
|
||||
// and do not modify qtm. If qtm is null, just check the validity
|
||||
// of the string.
|
||||
// Convert a PDF timestamp string to a QPDFTime. If syntactically valid, return true and fill in
|
||||
// qtm. If not valid, return false, and do not modify qtm. If qtm is null, just check the
|
||||
// validity of the string.
|
||||
QPDF_DLL
|
||||
bool pdf_time_to_qpdf_time(std::string const&, QPDFTime* qtm = nullptr);
|
||||
|
||||
// Convert PDF timestamp to a second-granularity ISO-8601
|
||||
// timestamp. If syntactically valid, return true and initialize
|
||||
// iso8601. Otherwise, return false.
|
||||
// Convert PDF timestamp to a second-granularity ISO-8601 timestamp. If syntactically valid,
|
||||
// return true and initialize iso8601. Otherwise, return false.
|
||||
bool pdf_time_to_iso8601(std::string const& pdf_time, std::string& iso8601);
|
||||
|
||||
// Return a string containing the byte representation of the UTF-8
|
||||
// encoding for the unicode value passed in.
|
||||
// Return a string containing the byte representation of the UTF-8 encoding for the unicode
|
||||
// value passed in.
|
||||
QPDF_DLL
|
||||
std::string toUTF8(unsigned long uval);
|
||||
|
||||
// Return a string containing the byte representation of the
|
||||
// UTF-16 big-endian encoding for the unicode value passed in.
|
||||
// Unrepresentable code points are converted to U+FFFD.
|
||||
// Return a string containing the byte representation of the UTF-16 big-endian encoding for the
|
||||
// unicode value passed in. Unrepresentable code points are converted to U+FFFD.
|
||||
QPDF_DLL
|
||||
std::string toUTF16(unsigned long uval);
|
||||
|
||||
// If utf8_val.at(pos) points to the beginning of a valid
|
||||
// UTF-8-encoded character, return the codepoint of the character
|
||||
// and set error to false. Otherwise, return 0xfffd and set error
|
||||
// to true. In all cases, pos is advanced to the next position
|
||||
// that may begin a valid character. When the string has been
|
||||
// consumed, pos will be set to the string length. It is an error
|
||||
// to pass a value of pos that is greater than or equal to the
|
||||
// length of the string.
|
||||
// If utf8_val.at(pos) points to the beginning of a valid UTF-8-encoded character, return the
|
||||
// codepoint of the character and set error to false. Otherwise, return 0xfffd and set error to
|
||||
// true. In all cases, pos is advanced to the next position that may begin a valid character.
|
||||
// When the string has been consumed, pos will be set to the string length. It is an error to
|
||||
// pass a value of pos that is greater than or equal to the length of the string.
|
||||
QPDF_DLL
|
||||
unsigned long get_next_utf8_codepoint(std::string const& utf8_val, size_t& pos, bool& error);
|
||||
|
||||
// Test whether this is a UTF-16 string. This is indicated by
|
||||
// first two bytes being 0xFE 0xFF (big-endian) or 0xFF 0xFE
|
||||
// (little-endian), each of which is the encoding of U+FEFF, the
|
||||
// Unicode marker. Starting in qpdf 10.6.2, this detects
|
||||
// little-endian as well as big-endian. Even though the PDF spec
|
||||
// doesn't allow little-endian, most readers seem to accept it.
|
||||
// Test whether this is a UTF-16 string. This is indicated by first two bytes being 0xFE 0xFF
|
||||
// (big-endian) or 0xFF 0xFE (little-endian), each of which is the encoding of U+FEFF, the
|
||||
// Unicode marker. Starting in qpdf 10.6.2, this detects little-endian as well as big-endian.
|
||||
// Even though the PDF spec doesn't allow little-endian, most readers seem to accept it.
|
||||
QPDF_DLL
|
||||
bool is_utf16(std::string const&);
|
||||
|
||||
// Test whether this is an explicit UTF-8 string as allowed by the
|
||||
// PDF 2.0 spec. This is indicated by first three bytes being 0xEF
|
||||
// 0xBB 0xBF, which is the UTF-8 encoding of U+FEFF.
|
||||
// Test whether this is an explicit UTF-8 string as allowed by the PDF 2.0 spec. This is
|
||||
// indicated by first three bytes being 0xEF 0xBB 0xBF, which is the UTF-8 encoding of U+FEFF.
|
||||
QPDF_DLL
|
||||
bool is_explicit_utf8(std::string const&);
|
||||
|
||||
// Convert a UTF-8 encoded string to UTF-16 big-endian.
|
||||
// Unrepresentable code points are converted to U+FFFD.
|
||||
// Convert a UTF-8 encoded string to UTF-16 big-endian. Unrepresentable code points are
|
||||
// converted to U+FFFD.
|
||||
QPDF_DLL
|
||||
std::string utf8_to_utf16(std::string const& utf8);
|
||||
|
||||
// Convert a UTF-8 encoded string to the specified single-byte
|
||||
// encoding system by replacing all unsupported characters with
|
||||
// the given unknown_char.
|
||||
// Convert a UTF-8 encoded string to the specified single-byte encoding system by replacing all
|
||||
// unsupported characters with the given unknown_char.
|
||||
QPDF_DLL
|
||||
std::string utf8_to_ascii(std::string const& utf8, char unknown_char = '?');
|
||||
QPDF_DLL
|
||||
@ -356,9 +320,8 @@ namespace QUtil
|
||||
QPDF_DLL
|
||||
std::string utf8_to_pdf_doc(std::string const& utf8, char unknown_char = '?');
|
||||
|
||||
// These versions return true if the conversion was successful and
|
||||
// false if any unrepresentable characters were found and had to
|
||||
// be substituted with the unknown character.
|
||||
// These versions return true if the conversion was successful and false if any unrepresentable
|
||||
// characters were found and had to be substituted with the unknown character.
|
||||
QPDF_DLL
|
||||
bool utf8_to_ascii(std::string const& utf8, std::string& ascii, char unknown_char = '?');
|
||||
QPDF_DLL
|
||||
@ -373,9 +336,8 @@ namespace QUtil
|
||||
QPDF_DLL
|
||||
std::string utf16_to_utf8(std::string const& utf16);
|
||||
|
||||
// Convert from the specified single-byte encoding system to
|
||||
// UTF-8. There is no ascii_to_utf8 because all ASCII strings are
|
||||
// already valid UTF-8.
|
||||
// Convert from the specified single-byte encoding system to UTF-8. There is no ascii_to_utf8
|
||||
// because all ASCII strings are already valid UTF-8.
|
||||
QPDF_DLL
|
||||
std::string win_ansi_to_utf8(std::string const& win);
|
||||
QPDF_DLL
|
||||
@ -383,39 +345,33 @@ namespace QUtil
|
||||
QPDF_DLL
|
||||
std::string pdf_doc_to_utf8(std::string const& pdfdoc);
|
||||
|
||||
// Analyze a string for encoding. We can't tell the difference
|
||||
// between any single-byte encodings, and we can't tell for sure
|
||||
// whether a string that happens to be valid UTF-8 isn't a
|
||||
// different encoding, but we can at least tell a few things to
|
||||
// help us guess. If there are no characters with the high bit
|
||||
// set, has_8bit_chars is false, and the other values are also
|
||||
// false, even though ASCII strings are valid UTF-8. is_valid_utf8
|
||||
// means that the string is non-trivially valid UTF-8. Although
|
||||
// the PDF spec requires UTF-16 to be UTF-16BE, qpdf (and just
|
||||
// about everything else) accepts UTF-16LE (as of 10.6.2).
|
||||
// Analyze a string for encoding. We can't tell the difference between any single-byte
|
||||
// encodings, and we can't tell for sure whether a string that happens to be valid UTF-8 isn't a
|
||||
// different encoding, but we can at least tell a few things to help us guess. If there are no
|
||||
// characters with the high bit set, has_8bit_chars is false, and the other values are also
|
||||
// false, even though ASCII strings are valid UTF-8. is_valid_utf8 means that the string is
|
||||
// non-trivially valid UTF-8. Although the PDF spec requires UTF-16 to be UTF-16BE, qpdf (and
|
||||
// just about everything else) accepts UTF-16LE (as of 10.6.2).
|
||||
QPDF_DLL
|
||||
void analyze_encoding(
|
||||
std::string const& str, bool& has_8bit_chars, bool& is_valid_utf8, bool& is_utf16);
|
||||
|
||||
// Try to compensate for previously incorrectly encoded strings.
|
||||
// We want to compensate for the following errors:
|
||||
// Try to compensate for previously incorrectly encoded strings. We want to compensate for the
|
||||
// following errors:
|
||||
//
|
||||
// * The string was supposed to be UTF-8 but was one of the
|
||||
// single-byte encodings
|
||||
// * The string was supposed to be PDF Doc but was either UTF-8 or
|
||||
// one of the other single-byte encodings
|
||||
// * The string was supposed to be UTF-8 but was one of the single-byte encodings
|
||||
// * The string was supposed to be PDF Doc but was either UTF-8 or one of the other single-byte
|
||||
// encodings
|
||||
//
|
||||
// The returned vector always contains the original string first,
|
||||
// and then it contains what the correct string would be in the
|
||||
// event that the original string was the result of any of the
|
||||
// The returned vector always contains the original string first, and then it contains what the
|
||||
// correct string would be in the event that the original string was the result of any of the
|
||||
// above errors.
|
||||
//
|
||||
// This method is useful for attempting to recover a password that
|
||||
// may have been previously incorrectly encoded. For example, the
|
||||
// password was supposed to be UTF-8 but the previous application
|
||||
// used a password encoded in WinAnsi, or if the previous password
|
||||
// was supposed to be PDFDoc but was actually given as UTF-8 or
|
||||
// WinAnsi, this method would find the correct password.
|
||||
// This method is useful for attempting to recover a password that may have been previously
|
||||
// incorrectly encoded. For example, the password was supposed to be UTF-8 but the previous
|
||||
// application used a password encoded in WinAnsi, or if the previous password was supposed to
|
||||
// be PDFDoc but was actually given as UTF-8 or WinAnsi, this method would find the correct
|
||||
// password.
|
||||
QPDF_DLL
|
||||
std::vector<std::string> possible_repaired_encodings(std::string);
|
||||
|
||||
@ -427,30 +383,25 @@ namespace QUtil
|
||||
QPDF_DLL
|
||||
void initializeWithRandomBytes(unsigned char* data, size_t len);
|
||||
|
||||
// Supply a random data provider. Starting in qpdf 10.0.0, qpdf
|
||||
// uses the crypto provider as its source of random numbers. If
|
||||
// you are using the native crypto provider, then qpdf will either
|
||||
// use the operating system's secure random number source or, only
|
||||
// if enabled at build time, an insecure random source from
|
||||
// stdlib. The caller is responsible for managing the memory for
|
||||
// the RandomDataProvider. This method modifies a static variable.
|
||||
// If you are providing your own random data provider, you should
|
||||
// call this at the beginning of your program before creating any
|
||||
// QPDF objects. Passing a null to this method will reset the
|
||||
// library back to its default random data provider.
|
||||
// Supply a random data provider. Starting in qpdf 10.0.0, qpdf uses the crypto provider as its
|
||||
// source of random numbers. If you are using the native crypto provider, then qpdf will either
|
||||
// use the operating system's secure random number source or, only if enabled at build time, an
|
||||
// insecure random source from stdlib. The caller is responsible for managing the memory for the
|
||||
// RandomDataProvider. This method modifies a static variable. If you are providing your own
|
||||
// random data provider, you should call this at the beginning of your program before creating
|
||||
// any QPDF objects. Passing a null to this method will reset the library back to its default
|
||||
// random data provider.
|
||||
QPDF_DLL
|
||||
void setRandomDataProvider(RandomDataProvider*);
|
||||
|
||||
// This returns the random data provider that would be used the
|
||||
// next time qpdf needs random data. It will never return null.
|
||||
// If no random data provider has been provided and the library
|
||||
// was not compiled with any random data provider available, an
|
||||
// exception will be thrown.
|
||||
// This returns the random data provider that would be used the next time qpdf needs random
|
||||
// data. It will never return null. If no random data provider has been provided and the
|
||||
// library was not compiled with any random data provider available, an exception will be
|
||||
// thrown.
|
||||
QPDF_DLL
|
||||
RandomDataProvider* getRandomDataProvider();
|
||||
|
||||
// Filename is UTF-8 encoded, even on Windows, as described in the
|
||||
// comments for safe_fopen.
|
||||
// Filename is UTF-8 encoded, even on Windows, as described in the comments for safe_fopen.
|
||||
QPDF_DLL
|
||||
std::list<std::string> read_lines_from_file(char const* filename, bool preserve_eol = false);
|
||||
QPDF_DLL
|
||||
@ -471,15 +422,13 @@ namespace QUtil
|
||||
QPDF_DLL
|
||||
std::string read_file_into_string(FILE* f, std::string_view filename = "");
|
||||
|
||||
// This used to be called strcasecmp, but that is a macro on some
|
||||
// platforms, so we have to give it a name that is not likely to
|
||||
// be a macro anywhere.
|
||||
// This used to be called strcasecmp, but that is a macro on some platforms, so we have to give
|
||||
// it a name that is not likely to be a macro anywhere.
|
||||
QPDF_DLL
|
||||
int str_compare_nocase(char const*, char const*);
|
||||
|
||||
// These routines help the tokenizer recognize certain character
|
||||
// classes without using ctype, which we avoid because of locale
|
||||
// considerations.
|
||||
// These routines help the tokenizer recognize certain character classes without using ctype,
|
||||
// which we avoid because of locale considerations.
|
||||
QPDF_DLL
|
||||
inline bool is_hex_digit(char);
|
||||
|
||||
@ -492,21 +441,19 @@ namespace QUtil
|
||||
QPDF_DLL
|
||||
inline bool is_number(char const*);
|
||||
|
||||
// This method parses the numeric range syntax used by the qpdf
|
||||
// command-line tool. May throw std::runtime_error.
|
||||
// This method parses the numeric range syntax used by the qpdf command-line tool. May throw
|
||||
// std::runtime_error.
|
||||
QPDF_DLL
|
||||
std::vector<int> parse_numrange(char const* range, int max);
|
||||
|
||||
#ifndef QPDF_NO_WCHAR_T
|
||||
// If you are building qpdf on a stripped down system that doesn't
|
||||
// have wchar_t, such as may be the case in some embedded
|
||||
// environments, you may define QPDF_NO_WCHAR_T in your build.
|
||||
// This symbol is never defined automatically. Search for wchar_t
|
||||
// in qpdf's top-level README.md file for details.
|
||||
// If you are building qpdf on a stripped down system that doesn't have wchar_t, such as may be
|
||||
// the case in some embedded environments, you may define QPDF_NO_WCHAR_T in your build. This
|
||||
// symbol is never defined automatically. Search for wchar_t in qpdf's top-level README.md file
|
||||
// for details.
|
||||
|
||||
// Take an argv array consisting of wchar_t, as when wmain is
|
||||
// invoked, convert all UTF-16 encoded strings to UTF-8, and call
|
||||
// another main.
|
||||
// Take an argv array consisting of wchar_t, as when wmain is invoked, convert all UTF-16
|
||||
// encoded strings to UTF-8, and call another main.
|
||||
QPDF_DLL
|
||||
int call_main_from_wmain(int argc, wchar_t* argv[], std::function<int(int, char*[])> realmain);
|
||||
QPDF_DLL
|
||||
@ -516,13 +463,10 @@ namespace QUtil
|
||||
std::function<int(int, char const* const[])> realmain);
|
||||
#endif // QPDF_NO_WCHAR_T
|
||||
|
||||
// Try to return the maximum amount of memory allocated by the
|
||||
// current process and its threads. Return 0 if unable to
|
||||
// determine. This is Linux-specific and not implemented to be
|
||||
// completely reliable. It is used during development for
|
||||
// performance testing to detect changes that may significantly
|
||||
// change memory usage. It is not recommended for use for other
|
||||
// purposes.
|
||||
// Try to return the maximum amount of memory allocated by the current process and its threads.
|
||||
// Return 0 if unable to determine. This is Linux-specific and not implemented to be completely
|
||||
// reliable. It is used during development for performance testing to detect changes that may
|
||||
// significantly change memory usage. It is not recommended for use for other purposes.
|
||||
QPDF_DLL
|
||||
size_t get_max_memory_usage();
|
||||
}; // namespace QUtil
|
||||
|
@ -2,138 +2,113 @@
|
||||
*
|
||||
* This file is part of qpdf.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*
|
||||
* Versions of qpdf prior to version 7 were released under the terms
|
||||
* of version 2.0 of the Artistic License. At your option, you may
|
||||
* continue to consider qpdf to be licensed under those terms. Please
|
||||
* see the manual for additional information.
|
||||
* Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
* License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
* Please see the manual for additional information.
|
||||
*/
|
||||
|
||||
#ifndef QPDF_C_H
|
||||
#define QPDF_C_H
|
||||
|
||||
/*
|
||||
* This file defines a basic "C" API for qpdf. It provides access to
|
||||
* a subset of the QPDF library's capabilities to make them accessible
|
||||
* to callers who can't handle calling C++ functions or working with
|
||||
* C++ classes. This may be especially useful to Windows users who
|
||||
* are accessing the qpdf DLL directly or to other people programming
|
||||
* in non-C/C++ languages that can call C code but not C++ code.
|
||||
* This file defines a basic "C" API for qpdf. It provides access to a subset of the QPDF library's
|
||||
* capabilities to make them accessible to callers who can't handle calling C++ functions or working
|
||||
* with C++ classes. This may be especially useful to Windows users who are accessing the qpdf DLL
|
||||
* directly or to other people programming in non-C/C++ languages that can call C code but not C++
|
||||
* code.
|
||||
*
|
||||
* There are several things to keep in mind when using the C API.
|
||||
*
|
||||
* Error handling is tricky because the underlying C++ API uses
|
||||
* exception handling. See "ERROR HANDLING" below for a detailed
|
||||
* explanation.
|
||||
* Error handling is tricky because the underlying C++ API uses exception handling. See "ERROR
|
||||
* HANDLING" below for a detailed explanation.
|
||||
*
|
||||
* The C API is not as rich as the C++ API. For any operations
|
||||
* that involve actually manipulating PDF objects, you must use
|
||||
* the C++ API. The C API is primarily useful for doing basic
|
||||
* transformations on PDF files similar to what you might do with
|
||||
* the qpdf command-line tool.
|
||||
* The C API is not as rich as the C++ API. For any operations that involve actually
|
||||
* manipulating PDF objects, you must use the C++ API. The C API is primarily useful for doing
|
||||
* basic transformations on PDF files similar to what you might do with the qpdf command-line
|
||||
* tool.
|
||||
*
|
||||
* These functions store their state in a qpdf_data object.
|
||||
* Individual instances of qpdf_data are not thread-safe: although
|
||||
* you may access different qpdf_data objects from different
|
||||
* threads, you may not access one qpdf_data simultaneously from
|
||||
* multiple threads.
|
||||
* These functions store their state in a qpdf_data object. Individual instances of qpdf_data
|
||||
* are not thread-safe: although you may access different qpdf_data objects from different
|
||||
* threads, you may not access one qpdf_data simultaneously from multiple threads.
|
||||
*
|
||||
* All dynamic memory, except for that of the qpdf_data object
|
||||
* itself, is managed by the library unless otherwise noted. You
|
||||
* must create a qpdf_data object using qpdf_init and free it
|
||||
* using qpdf_cleanup.
|
||||
* All dynamic memory, except for that of the qpdf_data object itself, is managed by the library
|
||||
* unless otherwise noted. You must create a qpdf_data object using qpdf_init and free it using
|
||||
* qpdf_cleanup.
|
||||
*
|
||||
* Many functions return char*. In all cases, the char* values
|
||||
* returned are pointers to data inside the qpdf_data object. As
|
||||
* such, they are always freed by qpdf_cleanup. In most cases,
|
||||
* strings returned by functions here may be invalidated by
|
||||
* subsequent function calls, sometimes even to different
|
||||
* functions. If you want a string to last past the next qpdf call
|
||||
* or after a call to qpdf_cleanup, you should make a copy of it.
|
||||
* Many functions return char*. In all cases, the char* values returned are pointers to data
|
||||
* inside the qpdf_data object. As such, they are always freed by qpdf_cleanup. In most cases,
|
||||
* strings returned by functions here may be invalidated by subsequent function calls, sometimes
|
||||
* even to different functions. If you want a string to last past the next qpdf call or after a
|
||||
* call to qpdf_cleanup, you should make a copy of it.
|
||||
*
|
||||
* Since it is possible for a PDF string to contain null
|
||||
* characters, a function that returns data originating from a PDF
|
||||
* string may also contain null characters. To handle that case,
|
||||
* you call qpdf_get_last_string_length() to get the length of
|
||||
* whatever string was just returned. See STRING FUNCTIONS below.
|
||||
* Since it is possible for a PDF string to contain null characters, a function that returns
|
||||
* data originating from a PDF string may also contain null characters. To handle that case, you
|
||||
* call qpdf_get_last_string_length() to get the length of whatever string was just returned.
|
||||
* See STRING FUNCTIONS below.
|
||||
*
|
||||
* Most functions defined here have obvious counterparts that are
|
||||
* methods to either QPDF or QPDFWriter. Please see comments in
|
||||
* QPDF.hh and QPDFWriter.hh for details on their use. In order
|
||||
* to avoid duplication of information, comments here focus
|
||||
* primarily on differences between the C and C++ API.
|
||||
* Most functions defined here have obvious counterparts that are methods to either QPDF or
|
||||
* QPDFWriter. Please see comments in QPDF.hh and QPDFWriter.hh for details on their use. In
|
||||
* order to avoid duplication of information, comments here focus primarily on differences
|
||||
* between the C and C++ API.
|
||||
*/
|
||||
|
||||
/* ERROR HANDLING -- changed in qpdf 10.5 */
|
||||
|
||||
/* SUMMARY: The only way to know whether a function that does not
|
||||
* return an error code has encountered an error is to call
|
||||
* qpdf_has_error after each function. You can do this even for
|
||||
* functions that do return error codes. You can also call
|
||||
* qpdf_silence_errors to prevent qpdf from writing these errors to
|
||||
* stderr.
|
||||
/* SUMMARY: The only way to know whether a function that does not return an error code has
|
||||
* encountered an error is to call qpdf_has_error after each function. You can do this even for
|
||||
* functions that do return error codes. You can also call qpdf_silence_errors to prevent qpdf from
|
||||
* writing these errors to stderr.
|
||||
*
|
||||
* DETAILS:
|
||||
*
|
||||
* The data type underlying qpdf_data maintains a list of warnings and
|
||||
* a single error. To retrieve warnings, call qpdf_next_warning while
|
||||
* qpdf_more_warnings is true. To retrieve the error, call
|
||||
* The data type underlying qpdf_data maintains a list of warnings and a single error. To retrieve
|
||||
* warnings, call qpdf_next_warning while qpdf_more_warnings is true. To retrieve the error, call
|
||||
* qpdf_get_error when qpdf_has_error is true.
|
||||
*
|
||||
* There are several things that are important to understand.
|
||||
*
|
||||
* Some functions return an error code. The value of the error code is
|
||||
* made up of a bitwise-OR of QPDF_WARNINGS and QPDF_ERRORS. The
|
||||
* QPDF_ERRORS bit is set if there was an error during the *most
|
||||
* recent call* to the API. The QPDF_WARNINGS bit is set if there are
|
||||
* any warnings that have not yet been retrieved by calling
|
||||
* qpdf_more_warnings. It is possible for both its or neither bit to
|
||||
* be set.
|
||||
* Some functions return an error code. The value of the error code is made up of a bitwise-OR of
|
||||
* QPDF_WARNINGS and QPDF_ERRORS. The QPDF_ERRORS bit is set if there was an error during the *most
|
||||
* recent call* to the API. The QPDF_WARNINGS bit is set if there are any warnings that have not yet
|
||||
* been retrieved by calling qpdf_more_warnings. It is possible for both its or neither bit to be
|
||||
* set.
|
||||
*
|
||||
* The expected mode of operation is to go through a series of
|
||||
* operations, checking for errors after each call, but only checking
|
||||
* for warnings at the end. This is similar to how it works in the C++
|
||||
* API where warnings are handled in exactly this way but errors
|
||||
* result in exceptions being thrown. However, in both the C and C++
|
||||
* API, it is possible to check for and handle warnings as they arise.
|
||||
* The expected mode of operation is to go through a series of operations, checking for errors after
|
||||
* each call, but only checking for warnings at the end. This is similar to how it works in the C++
|
||||
* API where warnings are handled in exactly this way but errors result in exceptions being thrown.
|
||||
* However, in both the C and C++ API, it is possible to check for and handle warnings as they
|
||||
* arise.
|
||||
*
|
||||
* Some functions return values (or void) rather than an error code.
|
||||
* This is especially true with the object handling functions. Those
|
||||
* functions can still generate errors. To handle errors in those
|
||||
* cases, you should explicitly call qpdf_has_error(). Note that, if
|
||||
* you want to avoid the inconsistencies in the interface, you can
|
||||
* always check for error conditions in this way rather than looking
|
||||
* at status return codes.
|
||||
* Some functions return values (or void) rather than an error code. This is especially true with
|
||||
* the object handling functions. Those functions can still generate errors. To handle errors in
|
||||
* those cases, you should explicitly call qpdf_has_error(). Note that, if you want to avoid the
|
||||
* inconsistencies in the interface, you can always check for error conditions in this way rather
|
||||
* than looking at status return codes.
|
||||
*
|
||||
* Prior to qpdf 10.5, if one of the functions that does not return an
|
||||
* error code encountered an exception, it would cause the entire
|
||||
* program to crash. Starting in qpdf 10.5, the default response to an
|
||||
* error condition in these situations is to print the error to
|
||||
* standard error, issue exactly one warning indicating that such an
|
||||
* error occurred, and return a sensible fallback value (0 for
|
||||
* numbers, QPDF_FALSE for booleans, "" for strings, or a null or
|
||||
* uninitialized object handle). This is better than the old behavior
|
||||
* but still undesirable as the best option is to explicitly check for
|
||||
* error conditions.
|
||||
* Prior to qpdf 10.5, if one of the functions that does not return an error code encountered an
|
||||
* exception, it would cause the entire program to crash. Starting in qpdf 10.5, the default
|
||||
* response to an error condition in these situations is to print the error to standard error, issue
|
||||
* exactly one warning indicating that such an error occurred, and return a sensible fallback value
|
||||
* (0 for numbers, QPDF_FALSE for booleans, "" for strings, or a null or uninitialized object
|
||||
* handle). This is better than the old behavior but still undesirable as the best option is to
|
||||
* explicitly check for error conditions.
|
||||
*
|
||||
* To prevent qpdf from writing error messages to stderr in this way,
|
||||
* you can call qpdf_silence_errors(). This signals to the qpdf
|
||||
* library that you intend to check the error codes yourself.
|
||||
* To prevent qpdf from writing error messages to stderr in this way, you can call
|
||||
* qpdf_silence_errors(). This signals to the qpdf library that you intend to check the error codes
|
||||
* yourself.
|
||||
*
|
||||
* If you encounter a situation where an exception from the C++ code
|
||||
* is not properly converted to an error as described above, it is a
|
||||
* bug in qpdf, which should be reported at
|
||||
* If you encounter a situation where an exception from the C++ code is not properly converted to an
|
||||
* error as described above, it is a bug in qpdf, which should be reported at
|
||||
* https://github.com/qpdf/qpdf/issues/new.
|
||||
*/
|
||||
|
||||
@ -150,9 +125,8 @@ extern "C" {
|
||||
typedef struct _qpdf_data* qpdf_data;
|
||||
typedef struct _qpdf_error* qpdf_error;
|
||||
|
||||
/* Many functions return an integer error code. Codes are defined
|
||||
* below. See comments at the top of the file for details. Note
|
||||
* that the values below can be logically orred together.
|
||||
/* Many functions return an integer error code. Codes are defined below. See comments at the
|
||||
* top of the file for details. Note that the values below can be logically orred together.
|
||||
*/
|
||||
typedef int QPDF_ERROR_CODE;
|
||||
#define QPDF_SUCCESS 0
|
||||
@ -163,76 +137,68 @@ extern "C" {
|
||||
#define QPDF_TRUE 1
|
||||
#define QPDF_FALSE 0
|
||||
|
||||
/* From qpdf 10.5: call this method to signal to the library that
|
||||
* you are explicitly handling errors from functions that don't
|
||||
* return error codes. Otherwise, the library will print these
|
||||
* error conditions to stderr and issue a warning. Prior to 10.5,
|
||||
* the program would have crashed from an unhandled exception.
|
||||
/* From qpdf 10.5: call this method to signal to the library that you are explicitly handling
|
||||
* errors from functions that don't return error codes. Otherwise, the library will print these
|
||||
* error conditions to stderr and issue a warning. Prior to 10.5, the program would have
|
||||
* crashed from an unhandled exception.
|
||||
*/
|
||||
QPDF_DLL
|
||||
void qpdf_silence_errors(qpdf_data qpdf);
|
||||
|
||||
/* Returns the version of the qpdf software. This is guaranteed to
|
||||
* be a static value.
|
||||
/* Returns the version of the qpdf software. This is guaranteed to be a static value.
|
||||
*/
|
||||
QPDF_DLL
|
||||
char const* qpdf_get_qpdf_version();
|
||||
|
||||
/* Returns dynamically allocated qpdf_data pointer; must be freed
|
||||
* by calling qpdf_cleanup. You must call qpdf_read, one of the
|
||||
* other qpdf_read_* functions, or qpdf_empty_pdf before calling
|
||||
/* Returns dynamically allocated qpdf_data pointer; must be freed by calling qpdf_cleanup. You
|
||||
* must call qpdf_read, one of the other qpdf_read_* functions, or qpdf_empty_pdf before calling
|
||||
* any function that would need to operate on the PDF file.
|
||||
*/
|
||||
QPDF_DLL
|
||||
qpdf_data qpdf_init();
|
||||
|
||||
/* Pass a pointer to the qpdf_data pointer created by qpdf_init to
|
||||
* clean up resources. This does not include buffers initialized
|
||||
* by functions that return stream data but it otherwise includes
|
||||
* all data associated with the QPDF object or any object handles.
|
||||
/* Pass a pointer to the qpdf_data pointer created by qpdf_init to clean up resources. This does
|
||||
* not include buffers initialized by functions that return stream data but it otherwise
|
||||
* includes all data associated with the QPDF object or any object handles.
|
||||
*/
|
||||
QPDF_DLL
|
||||
void qpdf_cleanup(qpdf_data* qpdf);
|
||||
|
||||
/* ERROR REPORTING */
|
||||
|
||||
/* Returns 1 if there is an error condition. The error condition
|
||||
* can be retrieved by a single call to qpdf_get_error.
|
||||
/* Returns 1 if there is an error condition. The error condition can be retrieved by a single
|
||||
* call to qpdf_get_error.
|
||||
*/
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_has_error(qpdf_data qpdf);
|
||||
|
||||
/* Returns the error condition, if any. The return value is a
|
||||
* pointer to data that will become invalid after the next call to
|
||||
* this function, qpdf_next_warning, or qpdf_cleanup. After this
|
||||
* function is called, qpdf_has_error will return QPDF_FALSE until
|
||||
* the next error condition occurs. If there is no error
|
||||
* condition, this function returns a null pointer.
|
||||
/* Returns the error condition, if any. The return value is a pointer to data that will become
|
||||
* invalid after the next call to this function, qpdf_next_warning, or qpdf_cleanup. After this
|
||||
* function is called, qpdf_has_error will return QPDF_FALSE until the next error condition
|
||||
* occurs. If there is no error condition, this function returns a null pointer.
|
||||
*/
|
||||
QPDF_DLL
|
||||
qpdf_error qpdf_get_error(qpdf_data qpdf);
|
||||
|
||||
/* Returns 1 if there are any unretrieved warnings, and zero
|
||||
* otherwise.
|
||||
/* Returns 1 if there are any unretrieved warnings, and zero otherwise.
|
||||
*/
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf);
|
||||
|
||||
/* If there are any warnings, returns a pointer to the next
|
||||
* warning. Otherwise returns a null pointer.
|
||||
/* If there are any warnings, returns a pointer to the next warning. Otherwise returns a null
|
||||
* pointer.
|
||||
*/
|
||||
QPDF_DLL
|
||||
qpdf_error qpdf_next_warning(qpdf_data qpdf);
|
||||
|
||||
/* Extract fields of the error. */
|
||||
|
||||
/* Use this function to get a full error message suitable for
|
||||
* showing to the user. */
|
||||
/* Use this function to get a full error message suitable for showing to the user. */
|
||||
QPDF_DLL
|
||||
char const* qpdf_get_error_full_text(qpdf_data q, qpdf_error e);
|
||||
|
||||
/* Use these functions to extract individual fields from the
|
||||
* error; see QPDFExc.hh for details. */
|
||||
/* Use these functions to extract individual fields from the error; see QPDFExc.hh for details.
|
||||
*/
|
||||
QPDF_DLL
|
||||
enum qpdf_error_code_e qpdf_get_error_code(qpdf_data q, qpdf_error e);
|
||||
QPDF_DLL
|
||||
@ -242,9 +208,8 @@ extern "C" {
|
||||
QPDF_DLL
|
||||
char const* qpdf_get_error_message_detail(qpdf_data q, qpdf_error e);
|
||||
|
||||
/* By default, warnings are written to stderr. Passing true to
|
||||
* this function will prevent warnings from being written to
|
||||
* stderr. They will still be available by calls to
|
||||
/* By default, warnings are written to stderr. Passing true to this function will prevent
|
||||
* warnings from being written to stderr. They will still be available by calls to
|
||||
* qpdf_next_warning.
|
||||
*/
|
||||
QPDF_DLL
|
||||
@ -252,11 +217,9 @@ extern "C" {
|
||||
|
||||
/* LOG FUNCTIONS */
|
||||
|
||||
/* Set or get the current logger. You need to call
|
||||
* qpdflogger_cleanup on the logger handles when you are done with
|
||||
* the handles. The underlying logger is cleaned up automatically
|
||||
* and persists if needed after the logger handle is destroyed.
|
||||
* See comments in qpdflogger-c.h for details.
|
||||
/* Set or get the current logger. You need to call qpdflogger_cleanup on the logger handles when
|
||||
* you are done with the handles. The underlying logger is cleaned up automatically and persists
|
||||
* if needed after the logger handle is destroyed. See comments in qpdflogger-c.h for details.
|
||||
*/
|
||||
|
||||
QPDF_DLL
|
||||
@ -266,8 +229,7 @@ extern "C" {
|
||||
|
||||
/* CHECK FUNCTIONS */
|
||||
|
||||
/* Attempt to read the entire PDF file to see if there are any
|
||||
* errors qpdf can detect.
|
||||
/* Attempt to read the entire PDF file to see if there are any errors qpdf can detect.
|
||||
*/
|
||||
QPDF_DLL
|
||||
QPDF_ERROR_CODE qpdf_check_pdf(qpdf_data qpdf);
|
||||
@ -284,20 +246,17 @@ extern "C" {
|
||||
|
||||
/* This functions process a PDF or JSON input source. */
|
||||
|
||||
/* Calling qpdf_read causes processFile to be called in the C++
|
||||
* API. Basic parsing is performed, but data from the file is
|
||||
* only read as needed. For files without passwords, pass a null
|
||||
* pointer or an empty string as the password.
|
||||
/* Calling qpdf_read causes processFile to be called in the C++ API. Basic parsing is
|
||||
* performed, but data from the file is only read as needed. For files without passwords, pass
|
||||
* a null pointer or an empty string as the password.
|
||||
*/
|
||||
QPDF_DLL
|
||||
QPDF_ERROR_CODE
|
||||
qpdf_read(qpdf_data qpdf, char const* filename, char const* password);
|
||||
|
||||
/* Calling qpdf_read_memory causes processMemoryFile to be called
|
||||
* in the C++ API. Otherwise, it behaves in the same way as
|
||||
* qpdf_read. The description argument will be used in place of
|
||||
* the file name in any error or warning messages generated by the
|
||||
* library.
|
||||
/* Calling qpdf_read_memory causes processMemoryFile to be called in the C++ API. Otherwise, it
|
||||
* behaves in the same way as qpdf_read. The description argument will be used in place of the
|
||||
* file name in any error or warning messages generated by the library.
|
||||
*/
|
||||
QPDF_DLL
|
||||
QPDF_ERROR_CODE qpdf_read_memory(
|
||||
@ -307,22 +266,20 @@ extern "C" {
|
||||
unsigned long long size,
|
||||
char const* password);
|
||||
|
||||
/* Calling qpdf_empty_pdf initializes this qpdf object with an
|
||||
* empty PDF, making it possible to create a PDF from scratch
|
||||
* using the C API. Added in 10.6.
|
||||
/* Calling qpdf_empty_pdf initializes this qpdf object with an empty PDF, making it possible to
|
||||
* create a PDF from scratch using the C API. Added in 10.6.
|
||||
*/
|
||||
QPDF_DLL
|
||||
QPDF_ERROR_CODE qpdf_empty_pdf(qpdf_data qpdf);
|
||||
|
||||
/* Create a PDF from a JSON file. This calls createFromJSON in the
|
||||
* C++ API.
|
||||
/* Create a PDF from a JSON file. This calls createFromJSON in the C++ API.
|
||||
*/
|
||||
QPDF_DLL
|
||||
QPDF_ERROR_CODE
|
||||
qpdf_create_from_json_file(qpdf_data qpdf, char const* filename);
|
||||
|
||||
/* Create a PDF from JSON data in a null-terminated string. This
|
||||
* calls createFromJSON in the C++ API.
|
||||
/* Create a PDF from JSON data in a null-terminated string. This calls createFromJSON in the C++
|
||||
* API.
|
||||
*/
|
||||
QPDF_DLL
|
||||
QPDF_ERROR_CODE
|
||||
@ -330,10 +287,9 @@ extern "C" {
|
||||
|
||||
/* JSON UPDATE FUNCTIONS */
|
||||
|
||||
/* Update a QPDF object from a JSON file or buffer. These
|
||||
* functions call updateFromJSON. One of the other processing
|
||||
* functions has to be called first so that the QPDF object is
|
||||
* initialized with PDF data.
|
||||
/* Update a QPDF object from a JSON file or buffer. These functions call updateFromJSON. One of
|
||||
* the other processing functions has to be called first so that the QPDF object is initialized
|
||||
* with PDF data.
|
||||
*/
|
||||
QPDF_DLL
|
||||
QPDF_ERROR_CODE
|
||||
@ -344,18 +300,16 @@ extern "C" {
|
||||
|
||||
/* READ FUNCTIONS */
|
||||
|
||||
/* Read functions below must be called after qpdf_read or any of
|
||||
* the other functions that process a PDF. */
|
||||
/* Read functions below must be called after qpdf_read or any of the other functions that
|
||||
* process a PDF. */
|
||||
|
||||
/*
|
||||
* NOTE: Functions that return char* are returning a pointer to an
|
||||
* internal buffer that will be reused for each call to a function
|
||||
* that returns a char*. You must use or copy the value before
|
||||
* calling any other qpdf library functions.
|
||||
* NOTE: Functions that return char* are returning a pointer to an internal buffer that will be
|
||||
* reused for each call to a function that returns a char*. You must use or copy the value
|
||||
* before calling any other qpdf library functions.
|
||||
*/
|
||||
|
||||
/* Return the version of the PDF file. See warning above about
|
||||
* functions that return char*. */
|
||||
/* Return the version of the PDF file. See warning above about functions that return char*. */
|
||||
QPDF_DLL
|
||||
char const* qpdf_get_pdf_version(qpdf_data qpdf);
|
||||
|
||||
@ -363,30 +317,26 @@ extern "C" {
|
||||
QPDF_DLL
|
||||
int qpdf_get_pdf_extension_level(qpdf_data qpdf);
|
||||
|
||||
/* Return the user password. If the file is opened using the
|
||||
* owner password, the user password may be retrieved using this
|
||||
* function. If the file is opened using the user password, this
|
||||
* function will return that user password. See warning above
|
||||
* about functions that return char*.
|
||||
/* Return the user password. If the file is opened using the owner password, the user password
|
||||
* may be retrieved using this function. If the file is opened using the user password, this
|
||||
* function will return that user password. See warning above about functions that return
|
||||
* char*.
|
||||
*/
|
||||
QPDF_DLL
|
||||
char const* qpdf_get_user_password(qpdf_data qpdf);
|
||||
|
||||
/* Return the string value of a key in the document's Info
|
||||
* dictionary. The key parameter should include the leading
|
||||
* slash, e.g. "/Author". If the key is not present or has a
|
||||
* non-string value, a null pointer is returned. Otherwise, a
|
||||
* pointer to an internal buffer is returned. See warning above
|
||||
* about functions that return char*.
|
||||
/* Return the string value of a key in the document's Info dictionary. The key parameter should
|
||||
* include the leading slash, e.g. "/Author". If the key is not present or has a non-string
|
||||
* value, a null pointer is returned. Otherwise, a pointer to an internal buffer is returned.
|
||||
* See warning above about functions that return char*.
|
||||
*/
|
||||
QPDF_DLL
|
||||
char const* qpdf_get_info_key(qpdf_data qpdf, char const* key);
|
||||
|
||||
/* Set a value in the info dictionary, possibly replacing an
|
||||
* existing value. The key must include the leading slash
|
||||
* (e.g. "/Author"). Passing a null pointer as a value will
|
||||
* remove the key from the info dictionary. Otherwise, a copy
|
||||
* will be made of the string that is passed in.
|
||||
/* Set a value in the info dictionary, possibly replacing an existing value. The key must
|
||||
* include the leading slash (e.g. "/Author"). Passing a null pointer as a value will remove
|
||||
* the key from the info dictionary. Otherwise, a copy will be made of the string that is
|
||||
* passed in.
|
||||
*/
|
||||
QPDF_DLL
|
||||
void qpdf_set_info_key(qpdf_data qpdf, char const* key, char const* value);
|
||||
@ -420,21 +370,16 @@ extern "C" {
|
||||
|
||||
/* JSON WRITE FUNCTIONS */
|
||||
|
||||
/* This function serializes the PDF to JSON. This calls writeJSON
|
||||
* from the C++ API.
|
||||
/* This function serializes the PDF to JSON. This calls writeJSON from the C++ API.
|
||||
*
|
||||
* - version: the JSON version, currently must be 2
|
||||
* - fn: a function that will be called with blocks of JSON data;
|
||||
* will be called with data, a length, and the value of the
|
||||
* udata parameter to this function
|
||||
* - udata: will be passed as the third argument to fn with each
|
||||
* call; use this for your own tracking or pass a null pointer
|
||||
* if you don't need it
|
||||
* - For decode_level, json_stream_data, file_prefix, and
|
||||
* wanted_objects, see comments in QPDF.hh. For this API,
|
||||
* wanted_objects should be a null-terminated array of
|
||||
* null-terminated strings. Pass a null pointer if you want all
|
||||
* objects.
|
||||
* - fn: a function that will be called with blocks of JSON data; will be called with data, a
|
||||
* length, and the value of the udata parameter to this function
|
||||
* - udata: will be passed as the third argument to fn with each call; use this for your own
|
||||
* tracking or pass a null pointer if you don't need it
|
||||
* - For decode_level, json_stream_data, file_prefix, and wanted_objects, see comments in
|
||||
* QPDF.hh. For this API, wanted_objects should be a null-terminated array of null-terminated
|
||||
* strings. Pass a null pointer if you want all objects.
|
||||
*/
|
||||
|
||||
/* Function should return 0 on success. */
|
||||
@ -453,37 +398,29 @@ extern "C" {
|
||||
|
||||
/* WRITE FUNCTIONS */
|
||||
|
||||
/* Set up for writing. No writing is actually performed until the
|
||||
* call to qpdf_write().
|
||||
/* Set up for writing. No writing is actually performed until the call to qpdf_write().
|
||||
*/
|
||||
|
||||
/* Supply the name of the file to be written and initialize the
|
||||
* qpdf_data object to handle writing operations. This function
|
||||
* also attempts to create the file. The PDF data is not written
|
||||
* 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.
|
||||
/* Supply the name of the file to be written and initialize the qpdf_data object to handle
|
||||
* writing operations. This function also attempts to create the file. The PDF data is not
|
||||
* written 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.
|
||||
*/
|
||||
QPDF_DLL
|
||||
QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename);
|
||||
|
||||
/* Initialize for writing but indicate that the PDF file should be
|
||||
* written to memory. Call qpdf_get_buffer_length and
|
||||
* qpdf_get_buffer to retrieve the resulting buffer. The memory
|
||||
* containing the PDF file will be destroyed when qpdf_cleanup is
|
||||
* called.
|
||||
/* Initialize for writing but indicate that the PDF file should be written to memory. Call
|
||||
* qpdf_get_buffer_length and qpdf_get_buffer to retrieve the resulting buffer. The memory
|
||||
* containing the PDF file will be destroyed when qpdf_cleanup is called.
|
||||
*/
|
||||
QPDF_DLL
|
||||
QPDF_ERROR_CODE qpdf_init_write_memory(qpdf_data qpdf);
|
||||
|
||||
/* Retrieve the buffer used if the file was written to memory.
|
||||
* qpdf_get_buffer returns a null pointer if data was not written
|
||||
* to memory. The memory is freed when qpdf_cleanup is called or
|
||||
* if a subsequent call to qpdf_init_write or
|
||||
* qpdf_init_write_memory is called. */
|
||||
/* Retrieve the buffer used if the file was written to memory. qpdf_get_buffer returns a null
|
||||
* pointer if data was not written to memory. The memory is freed when qpdf_cleanup is called
|
||||
* or if a subsequent call to qpdf_init_write or qpdf_init_write_memory is called. */
|
||||
QPDF_DLL
|
||||
size_t qpdf_get_buffer_length(qpdf_data qpdf);
|
||||
QPDF_DLL
|
||||
@ -516,14 +453,14 @@ extern "C" {
|
||||
QPDF_DLL
|
||||
void qpdf_set_deterministic_ID(qpdf_data qpdf, QPDF_BOOL value);
|
||||
|
||||
/* Never use qpdf_set_static_ID except in test suites to suppress
|
||||
* generation of a random /ID. See also qpdf_set_deterministic_ID.
|
||||
/* Never use qpdf_set_static_ID except in test suites to suppress generation of a random /ID.
|
||||
* See also qpdf_set_deterministic_ID.
|
||||
*/
|
||||
QPDF_DLL
|
||||
void qpdf_set_static_ID(qpdf_data qpdf, QPDF_BOOL value);
|
||||
|
||||
/* Never use qpdf_set_static_aes_IV except in test suites to
|
||||
* create predictable AES encrypted output.
|
||||
/* Never use qpdf_set_static_aes_IV except in test suites to create predictable AES encrypted
|
||||
* output.
|
||||
*/
|
||||
QPDF_DLL
|
||||
void qpdf_set_static_aes_IV(qpdf_data qpdf, QPDF_BOOL value);
|
||||
@ -534,9 +471,8 @@ extern "C" {
|
||||
QPDF_DLL
|
||||
void qpdf_set_preserve_encryption(qpdf_data qpdf, QPDF_BOOL value);
|
||||
|
||||
/* The *_insecure functions are identical to the old versions but
|
||||
* have been renamed as a an alert to the caller that they are
|
||||
* insecure. See "Weak Cryptographic" in the manual for
|
||||
/* The *_insecure functions are identical to the old versions but have been renamed as a an
|
||||
* alert to the caller that they are insecure. See "Weak Cryptographic" in the manual for
|
||||
* details.
|
||||
*/
|
||||
QPDF_DLL
|
||||
@ -622,15 +558,12 @@ extern "C" {
|
||||
void
|
||||
qpdf_force_pdf_version_and_extension(qpdf_data qpdf, char const* version, int extension_level);
|
||||
|
||||
/* During write, your report_progress function will be called with
|
||||
* a value between 0 and 100 representing the approximate write
|
||||
* progress. The data object you pass to
|
||||
* qpdf_register_progress_reporter will be handed back to your
|
||||
* function. This function must be called after qpdf_init_write
|
||||
* (or qpdf_init_write_memory) and before qpdf_write. The
|
||||
* registered progress reporter applies only to a single write, so
|
||||
* you must call it again if you perform a subsequent write with a
|
||||
* new writer.
|
||||
/* During write, your report_progress function will be called with a value between 0 and 100
|
||||
* representing the approximate write progress. The data object you pass to
|
||||
* qpdf_register_progress_reporter will be handed back to your function. This function must be
|
||||
* called after qpdf_init_write (or qpdf_init_write_memory) and before qpdf_write. The
|
||||
* registered progress reporter applies only to a single write, so you must call it again if you
|
||||
* perform a subsequent write with a new writer.
|
||||
*/
|
||||
QPDF_DLL
|
||||
void qpdf_register_progress_reporter(
|
||||
@ -642,67 +575,51 @@ extern "C" {
|
||||
|
||||
/* Object handling.
|
||||
*
|
||||
* These functions take and return a qpdf_oh object handle, which
|
||||
* is just an unsigned integer. The value 0 is never returned, which
|
||||
* makes it usable as an uninitialized value. The handles returned by
|
||||
* these functions are guaranteed to be unique, i.e. two calls to
|
||||
* (the same of different) functions will return distinct handles
|
||||
* even when they refer to the same object.
|
||||
* These functions take and return a qpdf_oh object handle, which is just an unsigned integer.
|
||||
* The value 0 is never returned, which makes it usable as an uninitialized value. The handles
|
||||
* returned by these functions are guaranteed to be unique, i.e. two calls to (the same of
|
||||
* different) functions will return distinct handles even when they refer to the same object.
|
||||
*
|
||||
* Each function below, starting with qpdf_oh, corresponds to a
|
||||
* specific method of QPDFObjectHandler. For example,
|
||||
* qpdf_oh_is_bool corresponds to QPDFObjectHandle::isBool. If the
|
||||
* C++ method is overloaded, the C function's name will be
|
||||
* disambiguated. If the C++ method takes optional arguments, the C
|
||||
* function will have required arguments in those positions. For
|
||||
* details about the method, please see comments in
|
||||
* QPDFObjectHandle.hh. Comments here only explain things that are
|
||||
* specific to the "C" API.
|
||||
* Each function below, starting with qpdf_oh, corresponds to a specific method of
|
||||
* QPDFObjectHandler. For example, qpdf_oh_is_bool corresponds to QPDFObjectHandle::isBool. If
|
||||
* the C++ method is overloaded, the C function's name will be disambiguated. If the C++ method
|
||||
* takes optional arguments, the C function will have required arguments in those positions. For
|
||||
* details about the method, please see comments in QPDFObjectHandle.hh. Comments here only
|
||||
* explain things that are specific to the "C" API.
|
||||
*
|
||||
* Only a fraction of the methods of QPDFObjectHandle are
|
||||
* available here. Most of the basic methods for creating,
|
||||
* accessing, and modifying most types of objects are present.
|
||||
* Most of the higher-level functions are not implemented.
|
||||
* Functions for dealing with content streams as well as objects
|
||||
* that only exist in content streams (operators and inline
|
||||
* images) are mostly not provided.
|
||||
* Only a fraction of the methods of QPDFObjectHandle are available here. Most of the basic
|
||||
* methods for creating, accessing, and modifying most types of objects are present. Most of the
|
||||
* higher-level functions are not implemented. Functions for dealing with content streams as
|
||||
* well as objects that only exist in content streams (operators and inline images) are mostly
|
||||
* not provided.
|
||||
*
|
||||
* To refer to a specific QPDFObjectHandle, you need a pair
|
||||
* consisting of a qpdf_data and a qpdf_oh, which is just an index
|
||||
* into an internal table of objects. All memory allocated by any
|
||||
* of these functions is returned when qpdf_cleanup is called.
|
||||
* To refer to a specific QPDFObjectHandle, you need a pair consisting of a qpdf_data and a
|
||||
* qpdf_oh, which is just an index into an internal table of objects. All memory allocated by
|
||||
* any of these functions is returned when qpdf_cleanup is called.
|
||||
*
|
||||
* Regarding memory, the same rules apply as the above functions.
|
||||
* Specifically, if a function returns a char*, the memory is
|
||||
* managed by the library and, unless otherwise specified, is not
|
||||
* Regarding memory, the same rules apply as the above functions. Specifically, if a function
|
||||
* returns a char*, the memory is managed by the library and, unless otherwise specified, is not
|
||||
* expected to be valid after the next qpdf call.
|
||||
*
|
||||
* The qpdf_data object keeps a cache of handles returned by these
|
||||
* functions. Once you are finished referencing a handle, you can
|
||||
* optionally release it. Releasing handles is optional since they
|
||||
* will all get released by qpdf_cleanup, but it can help to
|
||||
* reduce the memory footprint of the qpdf_data object to release
|
||||
* them when you're done. Releasing a handle does not destroy the
|
||||
* object. All QPDFObjectHandle objects are deleted when they are
|
||||
* no longer referenced. Releasing an object handle simply
|
||||
* invalidates it. For example, if you create an object,
|
||||
* add it to an existing dictionary or array, and then release its
|
||||
* handle, the object is safely part of the dictionary or array.
|
||||
* Similarly, any other object handle refering to the object remains
|
||||
* valid. Explicitly releasing an object handle is essentially the
|
||||
* same as letting a QPDFObjectHandle go out of scope in the C++
|
||||
* API.
|
||||
* The qpdf_data object keeps a cache of handles returned by these functions. Once you are
|
||||
* finished referencing a handle, you can optionally release it. Releasing handles is optional
|
||||
* since they will all get released by qpdf_cleanup, but it can help to reduce the memory
|
||||
* footprint of the qpdf_data object to release them when you're done. Releasing a handle does
|
||||
* not destroy the object. All QPDFObjectHandle objects are deleted when they are no longer
|
||||
* referenced. Releasing an object handle simply invalidates it. For example, if you create an
|
||||
* object, add it to an existing dictionary or array, and then release its handle, the object is
|
||||
* safely part of the dictionary or array. Similarly, any other object handle refering to the
|
||||
* object remains valid. Explicitly releasing an object handle is essentially the same as
|
||||
* letting a QPDFObjectHandle go out of scope in the C++ API.
|
||||
*
|
||||
* Please see "ERROR HANDLING" above for details on how error
|
||||
* conditions are handled.
|
||||
* Please see "ERROR HANDLING" above for details on how error conditions are handled.
|
||||
*/
|
||||
|
||||
/* For examples of using this API, see examples/pdf-c-objects.c */
|
||||
|
||||
typedef unsigned int qpdf_oh;
|
||||
|
||||
/* Releasing objects -- see comments above. These functions have no
|
||||
* equivalent in the C++ API.
|
||||
/* Releasing objects -- see comments above. These functions have no equivalent in the C++ API.
|
||||
*/
|
||||
QPDF_DLL
|
||||
void qpdf_oh_release(qpdf_data qpdf, qpdf_oh oh);
|
||||
@ -727,13 +644,11 @@ extern "C" {
|
||||
QPDF_DLL
|
||||
void qpdf_replace_object(qpdf_data qpdf, int objid, int generation, qpdf_oh oh);
|
||||
|
||||
/* Wrappers around QPDFObjectHandle methods. Be sure to read
|
||||
* corresponding comments in QPDFObjectHandle.hh to understand
|
||||
* what each function does and what kinds of objects it applies
|
||||
* to. Note that names are to appear in a canonicalized form
|
||||
* starting with a leading slash and with all PDF escaping
|
||||
* resolved. See comments for getName() in QPDFObjectHandle.hh for
|
||||
* details.
|
||||
/* Wrappers around QPDFObjectHandle methods. Be sure to read corresponding comments in
|
||||
* QPDFObjectHandle.hh to understand what each function does and what kinds of objects it
|
||||
* applies to. Note that names are to appear in a canonicalized form starting with a leading
|
||||
* slash and with all PDF escaping resolved. See comments for getName() in QPDFObjectHandle.hh
|
||||
* for details.
|
||||
*/
|
||||
|
||||
QPDF_DLL
|
||||
@ -829,18 +744,14 @@ extern "C" {
|
||||
QPDF_BOOL
|
||||
qpdf_oh_get_value_as_name(qpdf_data qpdf, qpdf_oh oh, char const** value, size_t* length);
|
||||
|
||||
/* Return the length of the last string returned. This enables you
|
||||
* to retrieve the entire string for cases in which a char*
|
||||
* returned by one of the functions below points to a string with
|
||||
* embedded null characters. The function
|
||||
* qpdf_oh_get_binary_string_value takes a length pointer, which
|
||||
* can be useful if you are retrieving the value of a string that
|
||||
* is expected to contain binary data, such as a checksum or
|
||||
* document ID. It is always valid to call
|
||||
* qpdf_get_last_string_length, but it is usually not necessary as
|
||||
* C strings returned by the library are only expected to be able
|
||||
* to contain null characters if their values originate from PDF
|
||||
* strings in the input.
|
||||
/* Return the length of the last string returned. This enables you to retrieve the entire string
|
||||
* for cases in which a char* returned by one of the functions below points to a string with
|
||||
* embedded null characters. The function qpdf_oh_get_binary_string_value takes a length
|
||||
* pointer, which can be useful if you are retrieving the value of a string that is expected to
|
||||
* contain binary data, such as a checksum or document ID. It is always valid to call
|
||||
* qpdf_get_last_string_length, but it is usually not necessary as C strings returned by the
|
||||
* library are only expected to be able to contain null characters if their values originate
|
||||
* from PDF strings in the input.
|
||||
*/
|
||||
QPDF_DLL
|
||||
size_t qpdf_get_last_string_length(qpdf_data qpdf);
|
||||
@ -865,10 +776,9 @@ extern "C" {
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_get_array_item(qpdf_data qpdf, qpdf_oh oh, int n);
|
||||
|
||||
/* In all dictionary APIs, keys are specified/represented as
|
||||
* canonicalized name strings starting with / and with all PDF
|
||||
* escaping resolved. See comments for getName() in
|
||||
* QPDFObjectHandle for details.
|
||||
/* In all dictionary APIs, keys are specified/represented as canonicalized name strings starting
|
||||
* with / and with all PDF escaping resolved. See comments for getName() in QPDFObjectHandle for
|
||||
* details.
|
||||
*/
|
||||
|
||||
/* "C"-specific dictionary key iteration */
|
||||
@ -878,11 +788,9 @@ extern "C" {
|
||||
void qpdf_oh_begin_dict_key_iter(qpdf_data qpdf, qpdf_oh dict);
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_dict_more_keys(qpdf_data qpdf);
|
||||
/* The memory returned by qpdf_oh_dict_next_key is owned by
|
||||
* qpdf_data. It is good until the next call to
|
||||
* qpdf_oh_dict_next_key with the same qpdf_data object. Calling
|
||||
* the function again, even with a different dict, invalidates
|
||||
* previous return values.
|
||||
/* The memory returned by qpdf_oh_dict_next_key is owned by qpdf_data. It is good until the next
|
||||
* call to qpdf_oh_dict_next_key with the same qpdf_data object. Calling the function again,
|
||||
* even with a different dict, invalidates previous return values.
|
||||
*/
|
||||
QPDF_DLL
|
||||
char const* qpdf_oh_dict_next_key(qpdf_data qpdf);
|
||||
@ -918,8 +826,8 @@ extern "C" {
|
||||
qpdf_oh qpdf_oh_new_string(qpdf_data qpdf, char const* str);
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_new_unicode_string(qpdf_data qpdf, char const* utf8_str);
|
||||
/* Use qpdf_oh_new_binary_string for creating a string that may
|
||||
* contain atrbitary binary data including embedded null characters.
|
||||
/* Use qpdf_oh_new_binary_string for creating a string that may contain atrbitary binary data
|
||||
* including embedded null characters.
|
||||
*/
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_new_binary_string(qpdf_data qpdf, char const* str, size_t length);
|
||||
@ -930,11 +838,10 @@ extern "C" {
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_new_dictionary(qpdf_data qpdf);
|
||||
|
||||
/* Create a new stream. Use qpdf_oh_get_dict to get (and
|
||||
* subsequently modify) the stream dictionary if needed. See
|
||||
* comments in QPDFObjectHandle.hh for newStream() for additional
|
||||
* notes. You must call qpdf_oh_replace_stream_data to provide
|
||||
* data for the stream. See STREAM FUNCTIONS below.
|
||||
/* Create a new stream. Use qpdf_oh_get_dict to get (and subsequently modify) the stream
|
||||
* dictionary if needed. See comments in QPDFObjectHandle.hh for newStream() for additional
|
||||
* notes. You must call qpdf_oh_replace_stream_data to provide data for the stream. See STREAM
|
||||
* FUNCTIONS below.
|
||||
*/
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_new_stream(qpdf_data qpdf);
|
||||
@ -973,40 +880,33 @@ extern "C" {
|
||||
QPDF_DLL
|
||||
char const* qpdf_oh_unparse_binary(qpdf_data qpdf, qpdf_oh oh);
|
||||
|
||||
/* Note about foreign objects: the C API does not have enough
|
||||
* information in the value of a qpdf_oh to know what QPDF object
|
||||
* it belongs to. To uniquely specify a qpdf object handle from a
|
||||
* specific qpdf_data instance, you always pair the qpdf_oh with
|
||||
* the correct qpdf_data. Otherwise, you are likely to get
|
||||
* completely the wrong object if you are not lucky enough to get
|
||||
* an error about the object being invalid.
|
||||
/* Note about foreign objects: the C API does not have enough information in the value of a
|
||||
* qpdf_oh to know what QPDF object it belongs to. To uniquely specify a qpdf object handle from
|
||||
* a specific qpdf_data instance, you always pair the qpdf_oh with the correct qpdf_data.
|
||||
* Otherwise, you are likely to get completely the wrong object if you are not lucky enough to
|
||||
* get an error about the object being invalid.
|
||||
*/
|
||||
|
||||
/* Copy foreign object: the qpdf_oh returned belongs to `qpdf`,
|
||||
* while `foreign_oh` belongs to `other_qpdf`.
|
||||
/* Copy foreign object: the qpdf_oh returned belongs to `qpdf`, while `foreign_oh` belongs to
|
||||
* `other_qpdf`.
|
||||
*/
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_copy_foreign_object(qpdf_data qpdf, qpdf_data other_qpdf, qpdf_oh foreign_oh);
|
||||
|
||||
/* STREAM FUNCTIONS */
|
||||
|
||||
/* These functions provide basic access to streams and stream
|
||||
* data. They are not as comprehensive as what is in
|
||||
* QPDFObjectHandle, but they do allow for working with streams
|
||||
* and stream data as caller-managed memory.
|
||||
/* These functions provide basic access to streams and stream data. They are not as
|
||||
* comprehensive as what is in QPDFObjectHandle, but they do allow for working with streams and
|
||||
* stream data as caller-managed memory.
|
||||
*/
|
||||
|
||||
/* Get stream data as a buffer. The buffer is allocated with
|
||||
* malloc and must be freed by the caller. The size of the buffer
|
||||
* is stored in *len. The arguments are similar to those in
|
||||
* QPDFObjectHandle::pipeStreamData. To get raw stream data, pass
|
||||
* qpdf_dl_none as decode_level. Otherwise, filtering is attempted
|
||||
* and *filtered is set to indicate whether it was successful. If
|
||||
* *filtered is QPDF_FALSE, then raw, unfiltered stream data was
|
||||
* returned. You may pass a null pointer as filtered if you don't
|
||||
* care about the result. If you pass a null pointer as bufp (and
|
||||
* len), the value of filtered will be set to whether the stream
|
||||
* can be filterable.
|
||||
/* Get stream data as a buffer. The buffer is allocated with malloc and must be freed by the
|
||||
* caller. The size of the buffer is stored in *len. The arguments are similar to those in
|
||||
* QPDFObjectHandle::pipeStreamData. To get raw stream data, pass qpdf_dl_none as decode_level.
|
||||
* Otherwise, filtering is attempted and *filtered is set to indicate whether it was successful.
|
||||
* If *filtered is QPDF_FALSE, then raw, unfiltered stream data was returned. You may pass a
|
||||
* null pointer as filtered if you don't care about the result. If you pass a null pointer as
|
||||
* bufp (and len), the value of filtered will be set to whether the stream can be filterable.
|
||||
*/
|
||||
QPDF_DLL
|
||||
QPDF_ERROR_CODE qpdf_oh_get_stream_data(
|
||||
@ -1017,17 +917,16 @@ extern "C" {
|
||||
unsigned char** bufp,
|
||||
size_t* len);
|
||||
|
||||
/* This function returns the concatenation of all of a page's
|
||||
* content streams as a single, dynamically allocated buffer. As
|
||||
* with qpdf_oh_get_stream_data, the buffer is allocated with
|
||||
/* This function returns the concatenation of all of a page's content streams as a single,
|
||||
* dynamically allocated buffer. As with qpdf_oh_get_stream_data, the buffer is allocated with
|
||||
* malloc and must be freed by the caller.
|
||||
*/
|
||||
QPDF_DLL
|
||||
QPDF_ERROR_CODE qpdf_oh_get_page_content_data(
|
||||
qpdf_data qpdf, qpdf_oh page_oh, unsigned char** bufp, size_t* len);
|
||||
|
||||
/* The data pointed to by bufp will be copied by the library. It
|
||||
* does not need to remain valid after the call returns.
|
||||
/* The data pointed to by bufp will be copied by the library. It does not need to remain valid
|
||||
* after the call returns.
|
||||
*/
|
||||
QPDF_DLL
|
||||
void qpdf_oh_replace_stream_data(
|
||||
@ -1040,21 +939,18 @@ extern "C" {
|
||||
|
||||
/* PAGE FUNCTIONS */
|
||||
|
||||
/* The first time a page function is called, qpdf will traverse
|
||||
* the /Pages tree. Subsequent calls to retrieve the number of
|
||||
* pages or a specific page run in constant time as they are
|
||||
* accessing the pages cache. If you manipulate the page tree
|
||||
* outside of these functions, you should call
|
||||
* qpdf_update_all_pages_cache. See comments for getAllPages() and
|
||||
/* The first time a page function is called, qpdf will traverse the /Pages tree. Subsequent
|
||||
* calls to retrieve the number of pages or a specific page run in constant time as they are
|
||||
* accessing the pages cache. If you manipulate the page tree outside of these functions, you
|
||||
* should call qpdf_update_all_pages_cache. See comments for getAllPages() and
|
||||
* updateAllPagesCache() in QPDF.hh.
|
||||
*/
|
||||
|
||||
/* For each function, the corresponding method in QPDF.hh is
|
||||
* referenced. Please see comments in QPDF.hh for details.
|
||||
/* For each function, the corresponding method in QPDF.hh is referenced. Please see comments in
|
||||
* QPDF.hh for details.
|
||||
*/
|
||||
|
||||
/* calls getAllPages(). On error, returns -1 and sets error for
|
||||
* qpdf_get_error. */
|
||||
/* calls getAllPages(). On error, returns -1 and sets error for qpdf_get_error. */
|
||||
QPDF_DLL
|
||||
int qpdf_get_num_pages(qpdf_data qpdf);
|
||||
/* returns uninitialized object if out of range */
|
||||
@ -1065,9 +961,8 @@ extern "C" {
|
||||
QPDF_DLL
|
||||
QPDF_ERROR_CODE qpdf_update_all_pages_cache(qpdf_data qpdf);
|
||||
|
||||
/* findPage() -- return zero-based index. If page is not found,
|
||||
* return -1 and save the error to be retrieved with
|
||||
* qpdf_get_error.
|
||||
/* findPage() -- return zero-based index. If page is not found, return -1 and save the error to
|
||||
* be retrieved with qpdf_get_error.
|
||||
*/
|
||||
QPDF_DLL
|
||||
int qpdf_find_page_by_id(qpdf_data qpdf, int objid, int generation);
|
||||
@ -1078,10 +973,9 @@ extern "C" {
|
||||
QPDF_DLL
|
||||
QPDF_ERROR_CODE qpdf_push_inherited_attributes_to_page(qpdf_data qpdf);
|
||||
|
||||
/* Functions that add pages may add pages from other files. If
|
||||
* adding a page from the same file, newpage_qpdf and qpdf are the
|
||||
* same.
|
||||
/*/
|
||||
/* Functions that add pages may add pages from other files. If adding a page from the same file,
|
||||
newpage_qpdf and qpdf are the same.
|
||||
*/
|
||||
|
||||
/* addPage() */
|
||||
QPDF_DLL
|
||||
|
@ -2,33 +2,29 @@
|
||||
*
|
||||
* This file is part of qpdf.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*
|
||||
* Versions of qpdf prior to version 7 were released under the terms
|
||||
* of version 2.0 of the Artistic License. At your option, you may
|
||||
* continue to consider qpdf to be licensed under those terms. Please
|
||||
* see the manual for additional information.
|
||||
* Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
* License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
* Please see the manual for additional information.
|
||||
*/
|
||||
|
||||
#ifndef QPDFJOB_C_H
|
||||
#define QPDFJOB_C_H
|
||||
|
||||
/*
|
||||
* This file defines a basic "C" API for QPDFJob. See also qpdf-c.h,
|
||||
* which defines an API that exposes more of the library's API. This
|
||||
* API is primarily intended to make it simpler for programs in
|
||||
* languages other than C++ to incorporate functionality that could be
|
||||
* run directly from the command-line.
|
||||
* This file defines a basic "C" API for QPDFJob. See also qpdf-c.h, which defines an API that
|
||||
* exposes more of the library's API. This API is primarily intended to make it simpler for programs
|
||||
* in languages other than C++ to incorporate functionality that could be run directly from the
|
||||
* command-line.
|
||||
*/
|
||||
|
||||
#include <qpdf/DLL.h>
|
||||
@ -40,52 +36,46 @@
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This file provides a minimal wrapper around QPDFJob. See
|
||||
* examples/qpdfjob-c.c for an example of its use.
|
||||
* This file provides a minimal wrapper around QPDFJob. See examples/qpdfjob-c.c for an example of
|
||||
* its use.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* SHORT INTERFACE -- These functions are single calls that take
|
||||
* care of the whole life cycle of QPDFJob. They can be used for
|
||||
* one-shot operations where no additional configuration is
|
||||
/* SHORT INTERFACE -- These functions are single calls that take care of the whole life cycle of
|
||||
* QPDFJob. They can be used for one-shot operations where no additional configuration is
|
||||
* needed. See FULL INTERFACE below. */
|
||||
|
||||
/* This function does the equivalent of running the qpdf
|
||||
* command-line with the given arguments and returns the exit code
|
||||
* that qpdf would use. argv must be a null-terminated array of
|
||||
* null-terminated UTF8-encoded strings. If calling this from
|
||||
* wmain on Windows, use qpdfjob_run_from_wide_argv instead. Exit
|
||||
* code values are defined in Constants.h in the qpdf_exit_code_e
|
||||
* type.
|
||||
/* This function does the equivalent of running the qpdf command-line with the given arguments
|
||||
* and returns the exit code that qpdf would use. argv must be a null-terminated array of
|
||||
* null-terminated UTF8-encoded strings. If calling this from wmain on Windows, use
|
||||
* qpdfjob_run_from_wide_argv instead. Exit code values are defined in Constants.h in the
|
||||
* qpdf_exit_code_e type.
|
||||
*/
|
||||
QPDF_DLL
|
||||
int qpdfjob_run_from_argv(char const* const argv[]);
|
||||
|
||||
#ifndef QPDF_NO_WCHAR_T
|
||||
/* This function is the same as qpdfjob_run_from_argv except argv
|
||||
* is encoded with wide characters. This would be suitable for
|
||||
* calling from a Windows wmain function.
|
||||
/* This function is the same as qpdfjob_run_from_argv except argv is encoded with wide
|
||||
* characters. This would be suitable for calling from a Windows wmain function.
|
||||
*/
|
||||
QPDF_DLL
|
||||
int qpdfjob_run_from_wide_argv(wchar_t const* const argv[]);
|
||||
#endif /* QPDF_NO_WCHAR_T */
|
||||
|
||||
/* This function runs QPDFJob from a job JSON file. See the "QPDF
|
||||
* Job" section of the manual for details. The JSON string must be
|
||||
* UTF8-encoded. It returns the error code that qpdf would return
|
||||
* with the equivalent command-line invocation. Exit code values
|
||||
* are defined in Constants.h in the qpdf_exit_code_e type.
|
||||
/* This function runs QPDFJob from a job JSON file. See the "QPDF Job" section of the manual for
|
||||
* details. The JSON string must be UTF8-encoded. It returns the error code that qpdf would
|
||||
* return with the equivalent command-line invocation. Exit code values are defined in
|
||||
* Constants.h in the qpdf_exit_code_e type.
|
||||
*/
|
||||
QPDF_DLL
|
||||
int qpdfjob_run_from_json(char const* json);
|
||||
|
||||
/* FULL INTERFACE -- new in qpdf11. Similar to the qpdf-c.h API,
|
||||
* you must call qpdfjob_init to get a qpdfjob_handle and, when
|
||||
* done, call qpdfjob_cleanup to free resources. Remaining methods
|
||||
* take qpdfjob_handle as an argument. This interface requires
|
||||
* more calls but also offers greater flexibility.
|
||||
/* FULL INTERFACE -- new in qpdf11. Similar to the qpdf-c.h API, you must call qpdfjob_init to
|
||||
* get a qpdfjob_handle and, when done, call qpdfjob_cleanup to free resources. Remaining
|
||||
* methods take qpdfjob_handle as an argument. This interface requires more calls but also
|
||||
* offers greater flexibility.
|
||||
*/
|
||||
typedef struct _qpdfjob_handle* qpdfjob_handle;
|
||||
QPDF_DLL
|
||||
@ -94,11 +84,9 @@ extern "C" {
|
||||
QPDF_DLL
|
||||
void qpdfjob_cleanup(qpdfjob_handle* j);
|
||||
|
||||
/* Set or get the current logger. You need to call
|
||||
* qpdflogger_cleanup on the logger handles when you are done with
|
||||
* the handles. The underlying logger is cleaned up automatically
|
||||
* and persists if needed after the logger handle is destroyed.
|
||||
* See comments in qpdflogger-c.h for details.
|
||||
/* Set or get the current logger. You need to call qpdflogger_cleanup on the logger handles when
|
||||
* you are done with the handles. The underlying logger is cleaned up automatically and persists
|
||||
* if needed after the logger handle is destroyed. See comments in qpdflogger-c.h for details.
|
||||
*/
|
||||
|
||||
QPDF_DLL
|
||||
@ -106,62 +94,55 @@ extern "C" {
|
||||
QPDF_DLL
|
||||
qpdflogger_handle qpdfjob_get_logger(qpdfjob_handle j);
|
||||
|
||||
/* This function wraps QPDFJob::initializeFromArgv. The return
|
||||
* value is the same as qpdfjob_run. If this returns an error, it
|
||||
* is invalid to call any other functions this job handle.
|
||||
/* This function wraps QPDFJob::initializeFromArgv. The return value is the same as qpdfjob_run.
|
||||
* If this returns an error, it is invalid to call any other functions this job handle.
|
||||
*/
|
||||
QPDF_DLL
|
||||
int qpdfjob_initialize_from_argv(qpdfjob_handle j, char const* const argv[]);
|
||||
|
||||
#ifndef QPDF_NO_WCHAR_T
|
||||
/* This function is the same as qpdfjob_initialize_from_argv
|
||||
* except argv is encoded with wide characters. This would be
|
||||
* suitable for calling from a Windows wmain function.
|
||||
/* This function is the same as qpdfjob_initialize_from_argv except argv is encoded with wide
|
||||
* characters. This would be suitable for calling from a Windows wmain function.
|
||||
*/
|
||||
QPDF_DLL
|
||||
int qpdfjob_initialize_from_wide_argv(qpdfjob_handle j, wchar_t const* const argv[]);
|
||||
#endif /* QPDF_NO_WCHAR_T */
|
||||
|
||||
/* This function wraps QPDFJob::initializeFromJson. The return
|
||||
* value is the same as qpdfjob_run. If this returns an error, it
|
||||
* is invalid to call any other functions this job handle.
|
||||
/* This function wraps QPDFJob::initializeFromJson. The return value is the same as qpdfjob_run.
|
||||
* If this returns an error, it is invalid to call any other functions using this job handle.
|
||||
*/
|
||||
QPDF_DLL
|
||||
int qpdfjob_initialize_from_json(qpdfjob_handle j, char const* json);
|
||||
|
||||
/* This function wraps QPDFJob::run. It returns the error code
|
||||
* that qpdf would return with the equivalent command-line
|
||||
* invocation. Exit code values are defined in Constants.h in the
|
||||
/* This function wraps QPDFJob::run. It returns the error code that qpdf would return with the
|
||||
* equivalent command-line invocation. Exit code values are defined in Constants.h in the
|
||||
* qpdf_exit_code_e type.
|
||||
*/
|
||||
QPDF_DLL
|
||||
int qpdfjob_run(qpdfjob_handle j);
|
||||
|
||||
/* The following two functions allow a job to be run in two stages -
|
||||
* creation of a qpdf_data object and writing of the qpdf_data object. This
|
||||
* allows the qpdf_data object to be modified prior to writing it out. See
|
||||
* examples/qpdfjob-remove-annotations for a C++ illustration of its use.
|
||||
/* The following two functions allow a job to be run in two stages - creation of a qpdf_data
|
||||
* object and writing of the qpdf_data object. This allows the qpdf_data object to be modified
|
||||
* prior to writing it out. See examples/qpdfjob-remove-annotations for a C++ illustration of
|
||||
* its use.
|
||||
*
|
||||
* This function wraps QPDFJob::createQPDF. It runs the first stage of the
|
||||
* job. A nullptr is returned if the job did not produce any pdf file to be
|
||||
* written.
|
||||
* This function wraps QPDFJob::createQPDF. It runs the first stage of the job. A nullptr is
|
||||
* returned if the job did not produce any pdf file to be written.
|
||||
*/
|
||||
QPDF_DLL
|
||||
qpdf_data qpdfjob_create_qpdf(qpdfjob_handle j);
|
||||
|
||||
/* This function wraps QPDFJob::writeQPDF. It returns the error code that
|
||||
* qpdf would return with the equivalent command-line invocation. Exit code
|
||||
* values are defined in Constants.h in the qpdf_exit_code_e type. NOTE it
|
||||
* is the callers responsibility to clean up the resources associated
|
||||
* qpdf_data object by calling qpdf_cleanup after the call to
|
||||
/* This function wraps QPDFJob::writeQPDF. It returns the error code that qpdf would return with
|
||||
* the equivalent command-line invocation. Exit code values are defined in Constants.h in the
|
||||
* qpdf_exit_code_e type. NOTE it is the callers responsibility to clean up the resources
|
||||
* associated with the qpdf_data object by calling qpdf_cleanup after the call to
|
||||
* qpdfjob_write_qpdf.
|
||||
*/
|
||||
QPDF_DLL
|
||||
int qpdfjob_write_qpdf(qpdfjob_handle j, qpdf_data qpdf);
|
||||
|
||||
/* Allow specification of a custom progress reporter. The progress
|
||||
* reporter is only used if progress is otherwise requested (with
|
||||
* the --progress option or "progress": "" in the JSON).
|
||||
/* Allow specification of a custom progress reporter. The progress reporter is only used if
|
||||
* progress is otherwise requested (with the --progress option or "progress": "" in the JSON).
|
||||
*/
|
||||
QPDF_DLL
|
||||
void qpdfjob_register_progress_reporter(
|
||||
|
@ -2,30 +2,26 @@
|
||||
*
|
||||
* This file is part of qpdf.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*
|
||||
* Versions of qpdf prior to version 7 were released under the terms
|
||||
* of version 2.0 of the Artistic License. At your option, you may
|
||||
* continue to consider qpdf to be licensed under those terms. Please
|
||||
* see the manual for additional information.
|
||||
* Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
|
||||
* License. At your option, you may continue to consider qpdf to be licensed under those terms.
|
||||
* Please see the manual for additional information.
|
||||
*/
|
||||
|
||||
#ifndef QPDFLOGGER_H
|
||||
#define QPDFLOGGER_H
|
||||
|
||||
/*
|
||||
* This file provides a C API for QPDFLogger. See QPDFLogger.hh for
|
||||
* information about the logger and
|
||||
* This file provides a C API for QPDFLogger. See QPDFLogger.hh for information about the logger and
|
||||
* examples/qpdfjob-c-save-attachment.c for an example.
|
||||
*/
|
||||
|
||||
@ -36,26 +32,21 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* To operate on a logger, you need a handle to it. call
|
||||
* qpdflogger_default_logger to get a handle for the default
|
||||
* logger. There are functions in qpdf-c.h and qpdfjob-c.h that
|
||||
* also take or return logger handles. When you're done with the
|
||||
* logger handler, call qpdflogger_cleanup. This cleans up the
|
||||
* handle but leaves the underlying log object intact. (It uses a
|
||||
* shared pointer and will be cleaned up automatically when it is
|
||||
* no longer in use.) That means you can create a logger with
|
||||
* qpdflogger_create(), pass the logger handle to a function in
|
||||
* qpdf-c.h or qpdfjob-c.h, and then clean it up, subject to
|
||||
* constraints imposed by the other function.
|
||||
/* To operate on a logger, you need a handle to it. call qpdflogger_default_logger to get a
|
||||
* handle for the default logger. There are functions in qpdf-c.h and qpdfjob-c.h that also take
|
||||
* or return logger handles. When you're done with the logger handler, call qpdflogger_cleanup.
|
||||
* This cleans up the handle but leaves the underlying log object intact. (It uses a shared
|
||||
* pointer and will be cleaned up automatically when it is no longer in use.) That means you can
|
||||
* create a logger with qpdflogger_create(), pass the logger handle to a function in qpdf-c.h or
|
||||
* qpdfjob-c.h, and then clean it up, subject to constraints imposed by the other function.
|
||||
*/
|
||||
|
||||
typedef struct _qpdflogger_handle* qpdflogger_handle;
|
||||
QPDF_DLL
|
||||
qpdflogger_handle qpdflogger_default_logger();
|
||||
|
||||
/* Calling cleanup on the handle returned by qpdflogger_create
|
||||
* destroys the handle but not the underlying logger. See comments
|
||||
* above.
|
||||
/* Calling cleanup on the handle returned by qpdflogger_create destroys the handle but not the
|
||||
* underlying logger. See comments above.
|
||||
*/
|
||||
QPDF_DLL
|
||||
qpdflogger_handle qpdflogger_create();
|
||||
@ -84,8 +75,8 @@ extern "C" {
|
||||
void qpdflogger_set_error(
|
||||
qpdflogger_handle l, enum qpdf_log_dest_e dest, qpdf_log_fn_t fn, void* udata);
|
||||
|
||||
/* A non-zero value for only_if_not_set means that the save
|
||||
* pipeline will only be changed if it is not already set.
|
||||
/* A non-zero value for only_if_not_set means that the save pipeline will only be changed if it
|
||||
* is not already set.
|
||||
*/
|
||||
QPDF_DLL
|
||||
void qpdflogger_set_save(
|
||||
|
@ -11,8 +11,7 @@ ClosedFileInputSource::ClosedFileInputSource(char const* filename) :
|
||||
|
||||
ClosedFileInputSource::~ClosedFileInputSource()
|
||||
{
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in
|
||||
// README-maintainer
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer
|
||||
}
|
||||
|
||||
void
|
||||
@ -91,8 +90,7 @@ ClosedFileInputSource::unreadCh(char ch)
|
||||
{
|
||||
before();
|
||||
this->fis->unreadCh(ch);
|
||||
// Don't call after -- the file has to stay open after this
|
||||
// operation.
|
||||
// Don't call after -- the file has to stay open after this operation.
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -41,9 +41,8 @@ ContentNormalizer::handleToken(QPDFTokenizer::Token const& token)
|
||||
break;
|
||||
|
||||
case QPDFTokenizer::tt_string:
|
||||
// Replacing string and name tokens in this way normalizes
|
||||
// their representation as this will automatically handle
|
||||
// quoting of unprintable characters, etc.
|
||||
// Replacing string and name tokens in this way normalizes their representation as this will
|
||||
// automatically handle quoting of unprintable characters, etc.
|
||||
writeToken(QPDFTokenizer::Token(QPDFTokenizer::tt_string, token.getValue()));
|
||||
break;
|
||||
|
||||
|
@ -27,8 +27,7 @@ FileInputSource::FileInputSource(char const* description, FILE* filep, bool clos
|
||||
|
||||
FileInputSource::~FileInputSource()
|
||||
{
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in
|
||||
// README-maintainer
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer
|
||||
if (this->file && this->close_file) {
|
||||
fclose(this->file);
|
||||
}
|
||||
@ -68,8 +67,7 @@ FileInputSource::findAndSkipNextEOL()
|
||||
char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2;
|
||||
if (p) {
|
||||
result = cur_offset + (p - buf);
|
||||
// We found \r or \n. Keep reading until we get past
|
||||
// \r and \n characters.
|
||||
// We found \r or \n. Keep reading until we get past \r and \n characters.
|
||||
this->seek(result + 1, SEEK_SET);
|
||||
char ch;
|
||||
while (!done) {
|
||||
|
@ -20,12 +20,10 @@ InputSource::getLastOffset() const
|
||||
std::string
|
||||
InputSource::readLine(size_t max_line_length)
|
||||
{
|
||||
// Return at most max_line_length characters from the next line.
|
||||
// Lines are terminated by one or more \r or \n characters.
|
||||
// Consume the trailing newline characters but don't return them.
|
||||
// After this is called, the file will be positioned after a line
|
||||
// terminator or at the end of the file, and last_offset will
|
||||
// point to position the file had when this method was called.
|
||||
// Return at most max_line_length characters from the next line. Lines are terminated by one or
|
||||
// more \r or \n characters. Consume the trailing newline characters but don't return them.
|
||||
// After this is called, the file will be positioned after a line terminator or at the end of
|
||||
// the file, and last_offset will point to position the file had when this method was called.
|
||||
|
||||
qpdf_offset_t offset = this->tell();
|
||||
auto bp = std::make_unique<char[]>(max_line_length + 1);
|
||||
@ -45,22 +43,18 @@ InputSource::readLine(size_t max_line_length)
|
||||
bool
|
||||
InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len, Finder& finder)
|
||||
{
|
||||
// Basic approach: search for the first character of start_chars
|
||||
// starting from offset but not going past len (if len != 0). Once
|
||||
// the first character is found, see if it is the beginning of a
|
||||
// sequence of characters matching start_chars. If so, call
|
||||
// finder.check() to do caller-specific additional checks. If not,
|
||||
// keep searching.
|
||||
// Basic approach: search for the first character of start_chars starting from offset but not
|
||||
// going past len (if len != 0). Once the first character is found, see if it is the beginning
|
||||
// of a sequence of characters matching start_chars. If so, call finder.check() to do
|
||||
// caller-specific additional checks. If not, keep searching.
|
||||
|
||||
// This code is tricky and highly subject to off-by-one or other
|
||||
// edge case logic errors. See comments throughout that explain
|
||||
// how we're not missing any edge cases. There are also tests
|
||||
// specifically constructed to make sure we caught the edge cases
|
||||
// in testing.
|
||||
// This code is tricky and highly subject to off-by-one or other edge case logic errors. See
|
||||
// comments throughout that explain how we're not missing any edge cases. There are also tests
|
||||
// specifically constructed to make sure we caught the edge cases in testing.
|
||||
|
||||
char buf[1025]; // size known to input_source.cc in libtests
|
||||
// To enable us to guarantee null-termination, save an extra byte
|
||||
// so that buf[size] is valid memory.
|
||||
// To enable us to guarantee null-termination, save an extra byte so that buf[size] is valid
|
||||
// memory.
|
||||
size_t size = sizeof(buf) - 1;
|
||||
if ((strlen(start_chars) < 1) || (strlen(start_chars) > size)) {
|
||||
throw std::logic_error("InputSource::findSource called with"
|
||||
@ -71,19 +65,15 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len
|
||||
qpdf_offset_t buf_offset = offset;
|
||||
size_t bytes_read = 0;
|
||||
|
||||
// Guarantee that we return from this loop. Each time through, we
|
||||
// either return, advance p, or restart the loop with a condition
|
||||
// that will cause return on the next pass. Eventually we will
|
||||
// either be out of range or hit EOF, either of which forces us to
|
||||
// return.
|
||||
// Guarantee that we return from this loop. Each time through, we either return, advance p, or
|
||||
// restart the loop with a condition that will cause return on the next pass. Eventually we will
|
||||
// either be out of range or hit EOF, either of which forces us to return.
|
||||
while (true) {
|
||||
// Do we need to read more data? Pretend size = 5, buf starts
|
||||
// at 0, and start_chars has 3 characters. buf[5] is valid and
|
||||
// null. If p == 2, start_chars could be buf[2] through
|
||||
// buf[4], so p + strlen(start_chars) == buf + size is okay.
|
||||
// If p points to buf[size], since strlen(start_chars) is
|
||||
// always >= 1, this overflow test will be correct for that
|
||||
// case regardless of start_chars.
|
||||
// Do we need to read more data? Pretend size = 5, buf starts at 0, and start_chars has 3
|
||||
// characters. buf[5] is valid and null. If p == 2, start_chars could be buf[2] through
|
||||
// buf[4], so p + strlen(start_chars) == buf + size is okay. If p points to buf[size], since
|
||||
// strlen(start_chars) is always >= 1, this overflow test will be correct for that case
|
||||
// regardless of start_chars.
|
||||
if ((p == nullptr) || ((p + strlen(start_chars)) > (buf + bytes_read))) {
|
||||
if (p) {
|
||||
QTC::TC(
|
||||
@ -91,9 +81,8 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len
|
||||
buf_offset += (p - buf);
|
||||
}
|
||||
this->seek(buf_offset, SEEK_SET);
|
||||
// Read into buffer and zero out the rest of the buffer
|
||||
// including buf[size]. We allocated an extra byte so that
|
||||
// we could guarantee null termination as an extra
|
||||
// Read into buffer and zero out the rest of the buffer including buf[size]. We
|
||||
// allocated an extra byte so that we could guarantee null termination as an extra
|
||||
// protection against overrun when using string functions.
|
||||
bytes_read = this->read(buf, size);
|
||||
if (bytes_read < strlen(start_chars)) {
|
||||
@ -122,19 +111,16 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len
|
||||
}
|
||||
}
|
||||
if ((p + strlen(start_chars)) > (buf + bytes_read)) {
|
||||
// If there are not enough bytes left in the file for
|
||||
// start_chars, we will detect this on the next pass
|
||||
// as EOF and return.
|
||||
// If there are not enough bytes left in the file for start_chars, we will detect
|
||||
// this on the next pass as EOF and return.
|
||||
QTC::TC("libtests", "InputSource not enough bytes");
|
||||
continue;
|
||||
}
|
||||
|
||||
// See if p points to a sequence matching start_chars. We
|
||||
// already checked above to make sure we are not going to
|
||||
// overrun memory.
|
||||
// See if p points to a sequence matching start_chars. We already checked above to make
|
||||
// sure we are not going to overrun memory.
|
||||
if (strncmp(p, start_chars, strlen(start_chars)) == 0) {
|
||||
// Call finder.check() with the input source
|
||||
// positioned to the point of the match.
|
||||
// Call finder.check() with the input source positioned to the point of the match.
|
||||
this->seek(buf_offset + (p - buf), SEEK_SET);
|
||||
if (finder.check()) {
|
||||
return true;
|
||||
@ -144,8 +130,8 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len
|
||||
} else {
|
||||
QTC::TC("libtests", "InputSource first char matched but not string");
|
||||
}
|
||||
// This occurrence of the first character wasn't a match.
|
||||
// Skip over it and keep searching.
|
||||
// This occurrence of the first character wasn't a match. Skip over it and keep
|
||||
// searching.
|
||||
++p;
|
||||
} else {
|
||||
// Trigger reading the next block
|
||||
|
@ -21,9 +21,8 @@ long
|
||||
InsecureRandomDataProvider::random()
|
||||
{
|
||||
if (!this->seeded_random) {
|
||||
// Seed the random number generator with something simple, but
|
||||
// just to be interesting, don't use the unmodified current
|
||||
// time. It would be better if this were a more secure seed.
|
||||
// Seed the random number generator with something simple, but just to be interesting, don't
|
||||
// use the unmodified current time. It would be better if this were a more secure seed.
|
||||
auto seed = static_cast<unsigned int>(QUtil::get_current_time() ^ 0xcccc);
|
||||
#ifdef HAVE_RANDOM
|
||||
::srandom(seed);
|
||||
|
@ -133,12 +133,10 @@ JSONHandler::handle(std::string const& path, JSON j)
|
||||
}
|
||||
|
||||
if (!handled) {
|
||||
// It would be nice to include information about what type the
|
||||
// object was and what types were allowed, but we're relying
|
||||
// on schema validation to make sure input is properly
|
||||
// structured before calling the handlers. It would be
|
||||
// different if this code were trying to be part of a
|
||||
// general-purpose JSON package.
|
||||
// It would be nice to include information about what type the object was and what types
|
||||
// were allowed, but we're relying on schema validation to make sure input is properly
|
||||
// structured before calling the handlers. It would be different if this code were trying to
|
||||
// be part of a general-purpose JSON package.
|
||||
QTC::TC("libtests", "JSONHandler unhandled value");
|
||||
usage("JSON handler: value at " + path + " is not of expected type");
|
||||
}
|
||||
|
@ -78,8 +78,7 @@ MD5::encodeFile(char const* filename, qpdf_offset_t up_to_offset)
|
||||
}
|
||||
} while (len > 0);
|
||||
if (ferror(file)) {
|
||||
// Assume, perhaps incorrectly, that errno was set by the
|
||||
// underlying call to read....
|
||||
// Assume, perhaps incorrectly, that errno was set by the underlying call to read....
|
||||
(void)fclose(file);
|
||||
QUtil::throw_system_error(std::string("MD5: read error on ") + filename);
|
||||
}
|
||||
|
@ -36,23 +36,18 @@ NNTreeIterator::NNTreeIterator(NNTreeImpl& impl) :
|
||||
void
|
||||
NNTreeIterator::updateIValue(bool allow_invalid)
|
||||
{
|
||||
// ivalue should never be used inside the class since we return a
|
||||
// pointer/reference to it. Every bit of code that ever changes
|
||||
// what object the iterator points to should take care to call
|
||||
// updateIValue. Failure to do this means that any old references
|
||||
// to *iter will point to incorrect objects, though the next
|
||||
// dereference of the iterator will fix it. This isn't necessarily
|
||||
// catastrophic, but it would be confusing. The test suite
|
||||
// attempts to exercise various cases to ensure we don't introduce
|
||||
// that bug in the future, but sadly it's tricky to verify by
|
||||
// reasoning about the code that this constraint is always
|
||||
// satisfied. Whenever we update what the iterator points to, we
|
||||
// should call setItemNumber, which calls this. If we change what
|
||||
// the iterator in some other way, such as replacing a value or
|
||||
// removing an item and making the iterator point at a different
|
||||
// item in potentially the same position, we must call
|
||||
// updateIValue as well. These cases are handled, and for good
|
||||
// measure, we also call updateIValue in operator* and operator->.
|
||||
// ivalue should never be used inside the class since we return a pointer/reference to it. Every
|
||||
// bit of code that ever changes what object the iterator points to should take care to call
|
||||
// updateIValue. Failure to do this means that any old references to *iter will point to
|
||||
// incorrect objects, though the next dereference of the iterator will fix it. This isn't
|
||||
// necessarily catastrophic, but it would be confusing. The test suite attempts to exercise
|
||||
// various cases to ensure we don't introduce that bug in the future, but sadly it's tricky to
|
||||
// verify by reasoning about the code that this constraint is always satisfied. Whenever we
|
||||
// update what the iterator points to, we should call setItemNumber, which calls this. If we
|
||||
// change what the iterator points to in some other way, such as replacing a value or removing
|
||||
// an item and making the iterator point at a different item in potentially the same position,
|
||||
// we must call updateIValue as well. These cases are handled, and for good measure, we also
|
||||
// call updateIValue in operator* and operator->.
|
||||
|
||||
bool okay = false;
|
||||
if ((item_number >= 0) && this->node.isDictionary()) {
|
||||
@ -228,12 +223,11 @@ NNTreeIterator::resetLimits(QPDFObjectHandle node, std::list<PathElement>::itera
|
||||
void
|
||||
NNTreeIterator::split(QPDFObjectHandle to_split, std::list<PathElement>::iterator parent)
|
||||
{
|
||||
// Split some node along the path to the item pointed to by this
|
||||
// iterator, and adjust the iterator so it points to the same
|
||||
// item.
|
||||
// Split some node along the path to the item pointed to by this iterator, and adjust the
|
||||
// iterator so it points to the same item.
|
||||
|
||||
// In examples, for simplicity, /Nums is show to just contain
|
||||
// numbers instead of pairs. Imagine this tree:
|
||||
// In examples, for simplicity, /Nums is shown to just contain numbers instead of pairs. Imagine
|
||||
// this tree:
|
||||
//
|
||||
// root: << /Kids [ A B C D ] >>
|
||||
// A: << /Nums [ 1 2 3 4 ] >>
|
||||
@ -260,8 +254,7 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list<PathElement>::iterato
|
||||
throw std::logic_error("NNTreeIterator::split called an invalid iterator");
|
||||
}
|
||||
|
||||
// Find the array we actually need to split, which is either this
|
||||
// node's kids or items.
|
||||
// Find the array we actually need to split, which is either this node's kids or items.
|
||||
auto kids = to_split.getKey("/Kids");
|
||||
int nkids = kids.isArray() ? kids.getArrayNItems() : 0;
|
||||
auto items = to_split.getKey(impl.details.itemsKey());
|
||||
@ -294,30 +287,22 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list<PathElement>::iterato
|
||||
bool is_root = (parent == this->path.end());
|
||||
bool is_leaf = (nitems > 0);
|
||||
|
||||
// CURRENT STATE: tree is in original state; iterator is valid and
|
||||
// unchanged.
|
||||
// CURRENT STATE: tree is in original state; iterator is valid and unchanged.
|
||||
|
||||
if (is_root) {
|
||||
// What we want to do is to create a new node for the second
|
||||
// half of the items and put it in the parent's /Kids array
|
||||
// right after the element that points to the current to_split
|
||||
// node, but if we're splitting root, there is no parent, so
|
||||
// handle that first.
|
||||
// What we want to do is to create a new node for the second half of the items and put it in
|
||||
// the parent's /Kids array right after the element that points to the current to_split
|
||||
// node, but if we're splitting root, there is no parent, so handle that first.
|
||||
|
||||
// In the non-root case, parent points to the path element
|
||||
// whose /Kids contains the first half node, and the first
|
||||
// half node is to_split. If we are splitting the root, we
|
||||
// need to push everything down a level, but we want to keep
|
||||
// the actual root object the same so that indirect references
|
||||
// to it remain intact (and also in case it might be a direct
|
||||
// object, which it shouldn't be but that case probably exists
|
||||
// in the wild). To achieve this, we create a new node for the
|
||||
// first half and then replace /Kids in the root to contain
|
||||
// it. Then we adjust the path so that the first element is
|
||||
// root and the second element, if any, is the new first half.
|
||||
// In this way, we make the root case identical to the
|
||||
// non-root case so remaining logic can handle them in the
|
||||
// same way.
|
||||
// In the non-root case, parent points to the path element whose /Kids contains the first
|
||||
// half node, and the first half node is to_split. If we are splitting the root, we need to
|
||||
// push everything down a level, but we want to keep the actual root object the same so that
|
||||
// indirect references to it remain intact (and also in case it might be a direct object,
|
||||
// which it shouldn't be but that case probably exists in the wild). To achieve this, we
|
||||
// create a new node for the first half and then replace /Kids in the root to contain it.
|
||||
// Then we adjust the path so that the first element is root and the second element, if any,
|
||||
// is the new first half. In this way, we make the root case identical to the non-root case
|
||||
// so remaining logic can handle them in the same way.
|
||||
|
||||
auto first_node = impl.qpdf.makeIndirectObject(QPDFObjectHandle::newDictionary());
|
||||
first_node.replaceKey(key, first_half);
|
||||
@ -339,12 +324,11 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list<PathElement>::iterato
|
||||
to_split = first_node;
|
||||
}
|
||||
|
||||
// CURRENT STATE: parent is guaranteed to be defined, and we have
|
||||
// the invariants that parent[/Kids][kid_number] == to_split and
|
||||
// (++parent).node == to_split.
|
||||
// CURRENT STATE: parent is guaranteed to be defined, and we have the invariants that
|
||||
// parent[/Kids][kid_number] == to_split and (++parent).node == to_split.
|
||||
|
||||
// Create a second half array, and transfer the second half of the
|
||||
// items into the second half array.
|
||||
// Create a second half array, and transfer the second half of the items into the second half
|
||||
// array.
|
||||
QPDFObjectHandle second_half = QPDFObjectHandle::newArray();
|
||||
int start_idx = ((n / 2) & ~1);
|
||||
while (first_half.getArrayNItems() > start_idx) {
|
||||
@ -358,15 +342,13 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list<PathElement>::iterato
|
||||
second_node.replaceKey(key, second_half);
|
||||
resetLimits(second_node, parent);
|
||||
|
||||
// CURRENT STATE: half the items from the kids or items array in
|
||||
// the node being split have been moved into a new node. The new
|
||||
// node is not yet attached to the tree. The iterator may have a
|
||||
// CURRENT STATE: half the items from the kids or items array in the node being split have been
|
||||
// moved into a new node. The new node is not yet attached to the tree. The iterator may have a
|
||||
// path element or leaf node that is out of bounds.
|
||||
|
||||
// We need to adjust the parent to add the second node to /Kids
|
||||
// and, if needed, update kid_number to traverse through it. We
|
||||
// need to update to_split's path element, or the node if this is
|
||||
// a leaf, so that the kid/item number points to the right place.
|
||||
// We need to adjust the parent to add the second node to /Kids and, if needed, update
|
||||
// kid_number to traverse through it. We need to update to_split's path element, or the node if
|
||||
// this is a leaf, so that the kid/item number points to the right place.
|
||||
|
||||
auto parent_kids = parent->node.getKey("/Kids");
|
||||
parent_kids.insertItem(parent->kid_number + 1, second_node);
|
||||
@ -430,8 +412,7 @@ NNTreeIterator::insertAfter(QPDFObjectHandle key, QPDFObjectHandle value)
|
||||
void
|
||||
NNTreeIterator::remove()
|
||||
{
|
||||
// Remove this item, leaving the tree valid and this iterator
|
||||
// pointing to the next item.
|
||||
// Remove this item, leaving the tree valid and this iterator pointing to the next item.
|
||||
|
||||
if (!valid()) {
|
||||
throw std::logic_error("attempt made to remove an invalid iterator");
|
||||
@ -450,34 +431,32 @@ NNTreeIterator::remove()
|
||||
// There are still items left
|
||||
|
||||
if ((this->item_number == 0) || (this->item_number == nitems)) {
|
||||
// We removed either the first or last item of an items array
|
||||
// that remains non-empty, so we have to adjust limits.
|
||||
// We removed either the first or last item of an items array that remains non-empty, so
|
||||
// we have to adjust limits.
|
||||
QTC::TC("qpdf", "NNTree remove reset limits");
|
||||
resetLimits(this->node, lastPathElement());
|
||||
}
|
||||
|
||||
if (this->item_number == nitems) {
|
||||
// We removed the last item of a non-empty items array, so
|
||||
// advance to the successor of the previous item.
|
||||
// We removed the last item of a non-empty items array, so advance to the successor of
|
||||
// the previous item.
|
||||
QTC::TC("qpdf", "NNTree erased last item");
|
||||
this->item_number -= 2;
|
||||
increment(false);
|
||||
} else if (this->item_number < nitems) {
|
||||
// We don't have to do anything since the removed item's
|
||||
// successor now occupies its former location.
|
||||
// We don't have to do anything since the removed item's successor now occupies its
|
||||
// former location.
|
||||
QTC::TC("qpdf", "NNTree erased non-last item");
|
||||
updateIValue();
|
||||
} else {
|
||||
// We already checked to ensure this condition would not
|
||||
// happen.
|
||||
// We already checked to ensure this condition would not happen.
|
||||
throw std::logic_error("NNTreeIterator::remove: item_number > nitems after erase");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->path.empty()) {
|
||||
// Special case: if this is the root node, we can leave it
|
||||
// empty.
|
||||
// Special case: if this is the root node, we can leave it empty.
|
||||
QTC::TC("qpdf", "NNTree erased all items on leaf/root");
|
||||
setItemNumber(impl.oh, -1);
|
||||
return;
|
||||
@ -485,9 +464,8 @@ NNTreeIterator::remove()
|
||||
|
||||
QTC::TC("qpdf", "NNTree items is empty after remove");
|
||||
|
||||
// We removed the last item from this items array, so we need to
|
||||
// remove this node from the parent on up the tree. Then we need
|
||||
// to position ourselves at the removed item's successor.
|
||||
// We removed the last item from this items array, so we need to remove this node from the
|
||||
// parent on up the tree. Then we need to position ourselves at the removed item's successor.
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
auto element = lastPathElement();
|
||||
@ -503,8 +481,7 @@ NNTreeIterator::remove()
|
||||
resetLimits(element->node, parent);
|
||||
}
|
||||
if (element->kid_number == nkids) {
|
||||
// Move to the successor of the last child of the
|
||||
// previous kid.
|
||||
// Move to the successor of the last child of the previous kid.
|
||||
setItemNumber(QPDFObjectHandle(), -1);
|
||||
--element->kid_number;
|
||||
deepen(kids.getArrayItem(element->kid_number), false, true);
|
||||
@ -523,8 +500,7 @@ NNTreeIterator::remove()
|
||||
}
|
||||
done = true;
|
||||
} else if (parent == this->path.end()) {
|
||||
// We erased the very last item. Convert the root to an
|
||||
// empty items array.
|
||||
// We erased the very last item. Convert the root to an empty items array.
|
||||
QTC::TC("qpdf", "NNTree non-flat tree is empty after remove");
|
||||
element->node.removeKey("/Kids");
|
||||
element->node.replaceKey(impl.details.itemsKey(), QPDFObjectHandle::newArray());
|
||||
@ -608,9 +584,8 @@ NNTreeIterator::addPathElement(QPDFObjectHandle const& node, int kid_number)
|
||||
bool
|
||||
NNTreeIterator::deepen(QPDFObjectHandle node, bool first, bool allow_empty)
|
||||
{
|
||||
// Starting at this node, descend through the first or last kid
|
||||
// until we reach a node with items. If we succeed, return true;
|
||||
// otherwise return false and leave path alone.
|
||||
// Starting at this node, descend through the first or last kid until we reach a node with
|
||||
// items. If we succeed, return true; otherwise return false and leave path alone.
|
||||
|
||||
auto opath = this->path;
|
||||
bool failed = false;
|
||||
|
@ -98,9 +98,8 @@ Pl_AES_PDF::finish()
|
||||
flush(false);
|
||||
}
|
||||
if (!this->disable_padding) {
|
||||
// Pad as described in section 3.5.1 of version 1.7 of the PDF
|
||||
// specification, including providing an entire block of padding
|
||||
// if the input was a multiple of 16 bytes.
|
||||
// Pad as described in section 3.5.1 of version 1.7 of the PDF specification, including
|
||||
// providing an entire block of padding if the input was a multiple of 16 bytes.
|
||||
unsigned char pad = QIntC::to_uchar(this->buf_size - this->offset);
|
||||
memset(this->inbuf + this->offset, pad, pad);
|
||||
this->offset = this->buf_size;
|
||||
@ -108,11 +107,9 @@ Pl_AES_PDF::finish()
|
||||
}
|
||||
} else {
|
||||
if (this->offset != this->buf_size) {
|
||||
// This is never supposed to happen as the output is
|
||||
// always supposed to be padded. However, we have
|
||||
// encountered files for which the output is not a
|
||||
// multiple of the block size. In this case, pad with
|
||||
// zeroes and hope for the best.
|
||||
// This is never supposed to happen as the output is always supposed to be padded.
|
||||
// However, we have encountered files for which the output is not a multiple of the
|
||||
// block size. In this case, pad with zeroes and hope for the best.
|
||||
if (this->offset >= this->buf_size) {
|
||||
throw std::logic_error("buffer overflow in AES encryption"
|
||||
" pipeline");
|
||||
@ -156,19 +153,19 @@ Pl_AES_PDF::flush(bool strip_padding)
|
||||
bool return_after_init = false;
|
||||
if (this->cbc_mode) {
|
||||
if (encrypt) {
|
||||
// Set cbc_block to the initialization vector, and if
|
||||
// not zero, write it to the output stream.
|
||||
// Set cbc_block to the initialization vector, and if not zero, write it to the
|
||||
// output stream.
|
||||
initializeVector();
|
||||
if (!(this->use_zero_iv || this->use_specified_iv)) {
|
||||
getNext()->write(this->cbc_block, this->buf_size);
|
||||
}
|
||||
} else if (this->use_zero_iv || this->use_specified_iv) {
|
||||
// Initialize vector with zeroes; zero vector was not
|
||||
// written to the beginning of the input file.
|
||||
// Initialize vector with zeroes; zero vector was not written to the beginning of
|
||||
// the input file.
|
||||
initializeVector();
|
||||
} else {
|
||||
// Take the first block of input as the initialization
|
||||
// vector. There's nothing to write at this time.
|
||||
// Take the first block of input as the initialization vector. There's nothing to
|
||||
// write at this time.
|
||||
memcpy(this->cbc_block, this->inbuf, this->buf_size);
|
||||
this->offset = 0;
|
||||
return_after_init = true;
|
||||
|
@ -91,8 +91,7 @@ Pl_ASCII85Decoder::flush()
|
||||
}
|
||||
|
||||
QTC::TC("libtests", "Pl_ASCII85Decoder partial flush", (this->pos == 5) ? 0 : 1);
|
||||
// Reset before calling getNext()->write in case that throws an
|
||||
// exception.
|
||||
// Reset before calling getNext()->write in case that throws an exception.
|
||||
auto t = this->pos - 1;
|
||||
this->pos = 0;
|
||||
memset(this->inbuf, 117, 5);
|
||||
|
@ -79,8 +79,7 @@ Pl_ASCIIHexDecoder::flush()
|
||||
auto ch = static_cast<unsigned char>((b[0] << 4) + b[1]);
|
||||
|
||||
QTC::TC("libtests", "Pl_ASCIIHexDecoder partial flush", (this->pos == 2) ? 0 : 1);
|
||||
// Reset before calling getNext()->write in case that throws an
|
||||
// exception.
|
||||
// Reset before calling getNext()->write in case that throws an exception.
|
||||
this->pos = 0;
|
||||
this->inbuf[0] = '0';
|
||||
this->inbuf[1] = '0';
|
||||
|
@ -7,8 +7,7 @@ Pl_Concatenate::Pl_Concatenate(char const* identifier, Pipeline* next) :
|
||||
|
||||
Pl_Concatenate::~Pl_Concatenate()
|
||||
{
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in
|
||||
// README-maintainer
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -16,8 +16,7 @@ Pl_Count::Pl_Count(char const* identifier, Pipeline* next) :
|
||||
|
||||
Pl_Count::~Pl_Count()
|
||||
{
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in
|
||||
// README-maintainer
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -77,8 +77,7 @@ Pl_DCT::Pl_DCT(
|
||||
|
||||
Pl_DCT::~Pl_DCT()
|
||||
{
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in
|
||||
// README-maintainer
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer
|
||||
}
|
||||
|
||||
void
|
||||
@ -92,14 +91,12 @@ Pl_DCT::finish()
|
||||
{
|
||||
m->buf.finish();
|
||||
|
||||
// Using a std::shared_ptr<Buffer> here and passing it into compress
|
||||
// and decompress causes a memory leak with setjmp/longjmp. Just
|
||||
// use a pointer and delete it.
|
||||
// Using a std::shared_ptr<Buffer> here and passing it into compress and decompress causes a
|
||||
// memory leak with setjmp/longjmp. Just use a pointer and delete it.
|
||||
Buffer* b = m->buf.getBuffer();
|
||||
if (b->getSize() == 0) {
|
||||
// Special case: empty data will never succeed and probably
|
||||
// means we're calling finish a second time from an exception
|
||||
// handler.
|
||||
// Special case: empty data will never succeed and probably means we're calling finish a
|
||||
// second time from an exception handler.
|
||||
delete b;
|
||||
this->getNext()->finish();
|
||||
return;
|
||||
@ -114,8 +111,7 @@ Pl_DCT::finish()
|
||||
jerr.pub.error_exit = error_handler;
|
||||
|
||||
bool error = false;
|
||||
// The jpeg library is a "C" library, so we use setjmp and longjmp
|
||||
// for exception handling.
|
||||
// The jpeg library is a "C" library, so we use setjmp and longjmp for exception handling.
|
||||
if (setjmp(jerr.jmpbuf) == 0) {
|
||||
try {
|
||||
if (m->action == a_compress) {
|
||||
@ -124,9 +120,8 @@ Pl_DCT::finish()
|
||||
decompress(reinterpret_cast<void*>(&cinfo_decompress), b);
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
// Convert an exception back to a longjmp so we can ensure
|
||||
// that the right cleanup happens. This will get converted
|
||||
// back to an exception.
|
||||
// Convert an exception back to a longjmp so we can ensure that the right cleanup
|
||||
// happens. This will get converted back to an exception.
|
||||
jerr.msg = e.what();
|
||||
longjmp(jerr.jmpbuf, 1);
|
||||
}
|
||||
@ -205,9 +200,8 @@ init_buffer_source(j_decompress_ptr)
|
||||
static boolean
|
||||
fill_buffer_input_buffer(j_decompress_ptr)
|
||||
{
|
||||
// The whole JPEG data is expected to reside in the supplied memory
|
||||
// buffer, so any request for more data beyond the given buffer size
|
||||
// is treated as an error.
|
||||
// The whole JPEG data is expected to reside in the supplied memory buffer, so any request for
|
||||
// more data beyond the given buffer size is treated as an error.
|
||||
throw std::runtime_error("invalid jpeg data reading from buffer");
|
||||
return TRUE;
|
||||
}
|
||||
@ -216,8 +210,8 @@ static void
|
||||
skip_buffer_input_data(j_decompress_ptr cinfo, long num_bytes)
|
||||
{
|
||||
if (num_bytes < 0) {
|
||||
throw std::runtime_error("reading jpeg: jpeg library requested"
|
||||
" skipping a negative number of bytes");
|
||||
throw std::runtime_error(
|
||||
"reading jpeg: jpeg library requested skipping a negative number of bytes");
|
||||
}
|
||||
size_t to_skip = QIntC::to_size(num_bytes);
|
||||
if ((to_skip > 0) && (to_skip <= cinfo->src->bytes_in_buffer)) {
|
||||
|
@ -9,8 +9,7 @@ Pl_Discard::Pl_Discard() :
|
||||
|
||||
Pl_Discard::~Pl_Discard()
|
||||
{
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in
|
||||
// README-maintainer
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -16,16 +16,14 @@ Pl_Flate::Members::Members(size_t out_bufsize, action_e action) :
|
||||
zdata(nullptr)
|
||||
{
|
||||
this->outbuf = QUtil::make_shared_array<unsigned char>(out_bufsize);
|
||||
// Indirect through zdata to reach the z_stream so we don't have
|
||||
// to include zlib.h in Pl_Flate.hh. This means people using
|
||||
// shared library versions of qpdf don't have to have zlib
|
||||
// development files available, which particularly helps in a
|
||||
// Windows environment.
|
||||
// Indirect through zdata to reach the z_stream so we don't have to include zlib.h in
|
||||
// Pl_Flate.hh. This means people using shared library versions of qpdf don't have to have zlib
|
||||
// development files available, which particularly helps in a Windows environment.
|
||||
this->zdata = new z_stream;
|
||||
|
||||
if (out_bufsize > UINT_MAX) {
|
||||
throw std::runtime_error("Pl_Flate: zlib doesn't support buffer"
|
||||
" sizes larger than unsigned int");
|
||||
throw std::runtime_error(
|
||||
"Pl_Flate: zlib doesn't support buffer sizes larger than unsigned int");
|
||||
}
|
||||
|
||||
z_stream& zstream = *(static_cast<z_stream*>(this->zdata));
|
||||
@ -62,8 +60,7 @@ Pl_Flate::Pl_Flate(
|
||||
|
||||
Pl_Flate::~Pl_Flate()
|
||||
{
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in
|
||||
// README-maintainer
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer
|
||||
}
|
||||
|
||||
void
|
||||
@ -88,8 +85,7 @@ Pl_Flate::write(unsigned char const* data, size_t len)
|
||||
this->identifier + ": Pl_Flate: write() called after finish() called");
|
||||
}
|
||||
|
||||
// Write in chunks in case len is too big to fit in an int.
|
||||
// Assume int is at least 32 bits.
|
||||
// Write in chunks in case len is too big to fit in an int. Assume int is at least 32 bits.
|
||||
static size_t const max_bytes = 1 << 30;
|
||||
size_t bytes_left = len;
|
||||
unsigned char const* buf = data;
|
||||
@ -105,20 +101,18 @@ void
|
||||
Pl_Flate::handleData(unsigned char const* data, size_t len, int flush)
|
||||
{
|
||||
if (len > UINT_MAX) {
|
||||
throw std::runtime_error("Pl_Flate: zlib doesn't support data"
|
||||
" blocks larger than int");
|
||||
throw std::runtime_error("Pl_Flate: zlib doesn't support data blocks larger than int");
|
||||
}
|
||||
z_stream& zstream = *(static_cast<z_stream*>(m->zdata));
|
||||
// zlib is known not to modify the data pointed to by next_in but
|
||||
// doesn't declare the field value const unless compiled to do so.
|
||||
// zlib is known not to modify the data pointed to by next_in but doesn't declare the field
|
||||
// value const unless compiled to do so.
|
||||
zstream.next_in = const_cast<unsigned char*>(data);
|
||||
zstream.avail_in = QIntC::to_uint(len);
|
||||
|
||||
if (!m->initialized) {
|
||||
int err = Z_OK;
|
||||
|
||||
// deflateInit and inflateInit are macros that use old-style
|
||||
// casts.
|
||||
// deflateInit and inflateInit are macros that use old-style casts.
|
||||
#if ((defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406) || defined(__clang__))
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
@ -147,21 +141,18 @@ Pl_Flate::handleData(unsigned char const* data, size_t len, int flush)
|
||||
}
|
||||
if ((m->action == a_inflate) && (err != Z_OK) && zstream.msg &&
|
||||
(strcmp(zstream.msg, "incorrect data check") == 0)) {
|
||||
// Other PDF readers ignore this specific error. Combining
|
||||
// this with Z_SYNC_FLUSH enables qpdf to handle some
|
||||
// broken zlib streams without losing data.
|
||||
// Other PDF readers ignore this specific error. Combining this with Z_SYNC_FLUSH
|
||||
// enables qpdf to handle some broken zlib streams without losing data.
|
||||
err = Z_STREAM_END;
|
||||
}
|
||||
switch (err) {
|
||||
case Z_BUF_ERROR:
|
||||
// Probably shouldn't be able to happen, but possible as a
|
||||
// boundary condition: if the last call to inflate exactly
|
||||
// filled the output buffer, it's possible that the next
|
||||
// call to inflate could have nothing to do. There are PDF
|
||||
// files in the wild that have this error (including at
|
||||
// least one in qpdf's test suite). In some cases, we want
|
||||
// to know about this, because it indicates incorrect
|
||||
// compression, so call a callback if provided.
|
||||
// Probably shouldn't be able to happen, but possible as a boundary condition: if the
|
||||
// last call to inflate exactly filled the output buffer, it's possible that the next
|
||||
// call to inflate could have nothing to do. There are PDF files in the wild that have
|
||||
// this error (including at least one in qpdf's test suite). In some cases, we want to
|
||||
// know about this, because it indicates incorrect compression, so call a callback if
|
||||
// provided.
|
||||
this->warn("input stream is complete but output may still be valid", err);
|
||||
done = true;
|
||||
break;
|
||||
@ -173,9 +164,8 @@ Pl_Flate::handleData(unsigned char const* data, size_t len, int flush)
|
||||
case Z_OK:
|
||||
{
|
||||
if ((zstream.avail_in == 0) && (zstream.avail_out > 0)) {
|
||||
// There is nothing left to read, and there was
|
||||
// sufficient buffer space to write everything we
|
||||
// needed, so we're done for now.
|
||||
// There is nothing left to read, and there was sufficient buffer space to write
|
||||
// everything we needed, so we're done for now.
|
||||
done = true;
|
||||
}
|
||||
uLong ready = QIntC::to_ulong(m->out_bufsize - zstream.avail_out);
|
||||
|
@ -41,8 +41,7 @@ Pl_Function::Pl_Function(char const* identifier, Pipeline* next, writer_c_char_t
|
||||
|
||||
Pl_Function::~Pl_Function()
|
||||
{
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in
|
||||
// README-maintainer
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -149,9 +149,8 @@ Pl_LZWDecoder::handleCode(unsigned int code)
|
||||
this->eod = true;
|
||||
} else {
|
||||
if (this->last_code != 256) {
|
||||
// Add to the table from last time. New table entry would
|
||||
// be what we read last plus the first character of what
|
||||
// we're reading now.
|
||||
// Add to the table from last time. New table entry would be what we read last plus the
|
||||
// first character of what we're reading now.
|
||||
unsigned char next = '\0';
|
||||
unsigned int table_size = QIntC::to_uint(table.size());
|
||||
if (code < 256) {
|
||||
@ -162,10 +161,8 @@ Pl_LZWDecoder::handleCode(unsigned int code)
|
||||
if (idx > table_size) {
|
||||
throw std::runtime_error("LZWDecoder: bad code received");
|
||||
} else if (idx == table_size) {
|
||||
// The encoder would have just created this entry,
|
||||
// so the first character of this entry would have
|
||||
// been the same as the first character of the
|
||||
// last entry.
|
||||
// The encoder would have just created this entry, so the first character of
|
||||
// this entry would have been the same as the first character of the last entry.
|
||||
QTC::TC("libtests", "Pl_LZWDecoder last was table size");
|
||||
next = getFirstChar(this->last_code);
|
||||
} else {
|
||||
|
@ -19,8 +19,7 @@ Pl_MD5::write(unsigned char const* buf, size_t len)
|
||||
this->in_progress = true;
|
||||
}
|
||||
|
||||
// Write in chunks in case len is too big to fit in an int.
|
||||
// Assume int is at least 32 bits.
|
||||
// Write in chunks in case len is too big to fit in an int. Assume int is at least 32 bits.
|
||||
static size_t const max_bytes = 1 << 30;
|
||||
size_t bytes_left = len;
|
||||
unsigned char const* data = buf;
|
||||
|
@ -15,8 +15,7 @@ Pl_OStream::Pl_OStream(char const* identifier, std::ostream& os) :
|
||||
|
||||
Pl_OStream::~Pl_OStream()
|
||||
{
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in
|
||||
// README-maintainer
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -33,8 +33,8 @@ Pl_PNGFilter::Pl_PNGFilter(
|
||||
}
|
||||
if (!((bits_per_sample == 1) || (bits_per_sample == 2) || (bits_per_sample == 4) ||
|
||||
(bits_per_sample == 8) || (bits_per_sample == 16))) {
|
||||
throw std::runtime_error("PNGFilter created with invalid bits_per_sample not"
|
||||
" 1, 2, 4, 8, or 16");
|
||||
throw std::runtime_error(
|
||||
"PNGFilter created with invalid bits_per_sample not 1, 2, 4, 8, or 16");
|
||||
}
|
||||
this->bytes_per_pixel = ((bits_per_sample * samples_per_pixel) + 7) / 8;
|
||||
unsigned long long bpr = ((columns * bits_per_sample * samples_per_pixel) + 7) / 8;
|
||||
|
@ -23,8 +23,7 @@ Pl_QPDFTokenizer::Pl_QPDFTokenizer(
|
||||
|
||||
Pl_QPDFTokenizer::~Pl_QPDFTokenizer()
|
||||
{
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in
|
||||
// README-maintainer
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -18,8 +18,7 @@ Pl_RunLength::Pl_RunLength(char const* identifier, Pipeline* next, action_e acti
|
||||
|
||||
Pl_RunLength::~Pl_RunLength()
|
||||
{
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in
|
||||
// README-maintainer
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer
|
||||
}
|
||||
|
||||
void
|
||||
@ -135,10 +134,9 @@ Pl_RunLength::flush_encode()
|
||||
void
|
||||
Pl_RunLength::finish()
|
||||
{
|
||||
// When decoding, we might have read a length byte not followed by
|
||||
// data, which means the stream was terminated early, but we will
|
||||
// just ignore this case since this is the only sensible thing to
|
||||
// do.
|
||||
// When decoding, we might have read a length byte not followed by data, which means the stream
|
||||
// was terminated early, but we will just ignore this case since this is the only sensible thing
|
||||
// to do.
|
||||
if (m->action == a_encode) {
|
||||
flush_encode();
|
||||
unsigned char ch = 128;
|
||||
|
@ -20,8 +20,7 @@ Pl_SHA2::write(unsigned char const* buf, size_t len)
|
||||
this->in_progress = true;
|
||||
}
|
||||
|
||||
// Write in chunks in case len is too big to fit in an int.
|
||||
// Assume int is at least 32 bits.
|
||||
// Write in chunks in case len is too big to fit in an int. Assume int is at least 32 bits.
|
||||
static size_t const max_bytes = 1 << 30;
|
||||
size_t bytes_left = len;
|
||||
unsigned char const* data = buf;
|
||||
|
@ -19,8 +19,7 @@ Pl_StdioFile::Pl_StdioFile(char const* identifier, FILE* f) :
|
||||
|
||||
Pl_StdioFile::~Pl_StdioFile()
|
||||
{
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in
|
||||
// README-maintainer
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -15,8 +15,7 @@ Pl_String::Pl_String(char const* identifier, Pipeline* next, std::string& s) :
|
||||
|
||||
Pl_String::~Pl_String()
|
||||
{
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in
|
||||
// README-maintainer
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -106,9 +106,8 @@ namespace
|
||||
throwException()
|
||||
{
|
||||
throw std::logic_error("QPDF operation attempted on a QPDF object with no input "
|
||||
"source."
|
||||
" QPDF operations are invalid before processFile (or another"
|
||||
" process method) or after closeInputSource");
|
||||
"source. QPDF operations are invalid before processFile (or "
|
||||
"another process method) or after closeInputSource");
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
@ -54,13 +54,10 @@ QPDFAnnotationObjectHelper::getAppearanceStream(std::string const& which, std::s
|
||||
if (ap.isDictionary()) {
|
||||
QPDFObjectHandle ap_sub = ap.getKey(which);
|
||||
if (ap_sub.isStream()) {
|
||||
// According to the spec, Appearance State is supposed to
|
||||
// refer to a subkey of the appearance stream when /AP is
|
||||
// a dictionary, but files have been seen in the wild
|
||||
// where Appearance State is `/N` and `/AP` is a stream.
|
||||
// Therefore, if `which` points to a stream, disregard
|
||||
// state and just use the stream. See qpdf issue #949 for
|
||||
// details.
|
||||
// According to the spec, Appearance State is supposed to refer to a subkey of the
|
||||
// appearance stream when /AP is a dictionary, but files have been seen in the wild
|
||||
// where Appearance State is `/N` and `/AP` is a stream. Therefore, if `which` points to
|
||||
// a stream, disregard state and just use the stream. See qpdf issue #949 for details.
|
||||
QTC::TC("qpdf", "QPDFAnnotationObjectHelper AP stream");
|
||||
return ap_sub;
|
||||
}
|
||||
@ -85,84 +82,66 @@ QPDFAnnotationObjectHelper::getPageContentForAppearance(
|
||||
return "";
|
||||
}
|
||||
|
||||
// The appearance matrix computed by this method is the
|
||||
// transformation matrix that needs to be in effect when drawing
|
||||
// this annotation's appearance stream on the page. The algorithm
|
||||
// for computing the appearance matrix described in section 12.5.5
|
||||
// of the ISO-32000 PDF spec is similar but not identical to what
|
||||
// we are doing here.
|
||||
// The appearance matrix computed by this method is the transformation matrix that needs to be
|
||||
// in effect when drawing this annotation's appearance stream on the page. The algorithm for
|
||||
// computing the appearance matrix described in section 12.5.5 of the ISO-32000 PDF spec is
|
||||
// similar but not identical to what we are doing here.
|
||||
|
||||
// When rendering an appearance stream associated with an
|
||||
// annotation, there are four relevant components:
|
||||
// When rendering an appearance stream associated with an annotation, there are four relevant
|
||||
// components:
|
||||
//
|
||||
// * The appearance stream's bounding box (/BBox)
|
||||
// * The appearance stream's matrix (/Matrix)
|
||||
// * The annotation's rectangle (/Rect)
|
||||
// * In the case of form fields with the NoRotate flag, the
|
||||
// page's rotation
|
||||
// * In the case of form fields with the NoRotate flag, the page's rotation
|
||||
|
||||
// When rendering a form xobject in isolation, just drawn with a
|
||||
// /Do operator, there is no form field, so page rotation is not
|
||||
// relevant, and there is no annotation, so /Rect is not relevant,
|
||||
// so only /BBox and /Matrix are relevant. The effect of these are
|
||||
// as follows:
|
||||
// When rendering a form xobject in isolation, just drawn with a /Do operator, there is no form
|
||||
// field, so page rotation is not relevant, and there is no annotation, so /Rect is not
|
||||
// relevant, so only /BBox and /Matrix are relevant. The effect of these are as follows:
|
||||
|
||||
// * /BBox is treated as a clipping region
|
||||
// * /Matrix is applied as a transformation prior to rendering the
|
||||
// appearance stream.
|
||||
// * /Matrix is applied as a transformation prior to rendering the appearance stream.
|
||||
|
||||
// There is no relationship between /BBox and /Matrix in this
|
||||
// case.
|
||||
// There is no relationship between /BBox and /Matrix in this case.
|
||||
|
||||
// When rendering a form xobject in the context of an annotation,
|
||||
// things are a little different. In particular, a matrix is
|
||||
// established such that /BBox, when transformed by /Matrix, would
|
||||
// fit completely inside of /Rect. /BBox is no longer a clipping
|
||||
// region. To illustrate the difference, consider a /Matrix of
|
||||
// [2 0 0 2 0 0], which is scaling by a factor of two along both
|
||||
// axes. If the appearance stream drew a rectangle equal to /BBox,
|
||||
// in the case of the form xobject in isolation, this matrix would
|
||||
// cause only the lower-left quadrant of the rectangle to be
|
||||
// visible since the scaling would cause the rest of it to fall
|
||||
// outside of the clipping region. In the case of the form xobject
|
||||
// displayed in the context of an annotation, such a matrix would
|
||||
// have no effect at all because it would be applied to the
|
||||
// bounding box first, and then when the resulting enclosing
|
||||
// quadrilateral was transformed to fit into /Rect, the effect of
|
||||
// the scaling would be undone.
|
||||
// When rendering a form xobject in the context of an annotation, things are a little different.
|
||||
// In particular, a matrix is established such that /BBox, when transformed by /Matrix, would
|
||||
// fit completely inside of /Rect. /BBox is no longer a clipping region. To illustrate the
|
||||
// difference, consider a /Matrix of [2 0 0 2 0 0], which is scaling by a factor of two along
|
||||
// both axes. If the appearance stream drew a rectangle equal to /BBox, in the case of the form
|
||||
// xobject in isolation, this matrix would cause only the lower-left quadrant of the rectangle
|
||||
// to be visible since the scaling would cause the rest of it to fall outside of the clipping
|
||||
// region. In the case of the form xobject displayed in the context of an annotation, such a
|
||||
// matrix would have no effect at all because it would be applied to the bounding box first, and
|
||||
// then when the resulting enclosing quadrilateral was transformed to fit into /Rect, the effect
|
||||
// of the scaling would be undone.
|
||||
|
||||
// Our job is to create a transformation matrix that compensates
|
||||
// for these differences so that the appearance stream of an
|
||||
// annotation can be drawn as a regular form xobject.
|
||||
// Our job is to create a transformation matrix that compensates for these differences so that
|
||||
// the appearance stream of an annotation can be drawn as a regular form xobject.
|
||||
|
||||
// To do this, we perform the following steps, which overlap
|
||||
// significantly with the algorithm in 12.5.5:
|
||||
// To do this, we perform the following steps, which overlap significantly with the algorithm
|
||||
// in 12.5.5:
|
||||
|
||||
// 1. Transform the four corners of /BBox by applying /Matrix to
|
||||
// them, creating an arbitrarily transformed quadrilateral.
|
||||
// 1. Transform the four corners of /BBox by applying /Matrix to them, creating an arbitrarily
|
||||
// transformed quadrilateral.
|
||||
|
||||
// 2. Find the minimum upright rectangle that encompasses the
|
||||
// resulting quadrilateral. This is the "transformed appearance
|
||||
// box", T.
|
||||
// 2. Find the minimum upright rectangle that encompasses the resulting quadrilateral. This is
|
||||
// the "transformed appearance box", T.
|
||||
|
||||
// 3. Compute matrix A that maps the lower left and upper right
|
||||
// corners of T to the annotation's /Rect. This can be done by
|
||||
// scaling so that the sizes match and translating so that the
|
||||
// 3. Compute matrix A that maps the lower left and upper right corners of T to the annotation's
|
||||
// /Rect. This can be done by scaling so that the sizes match and translating so that the
|
||||
// scaled T exactly overlaps /Rect.
|
||||
|
||||
// If the annotation's /F flag has bit 4 set, this means that
|
||||
// annotation is to be rotated about its upper left corner to
|
||||
// counteract any rotation of the page so it remains upright. To
|
||||
// If the annotation's /F flag has bit 4 set, this means that annotation is to be rotated about
|
||||
// its upper left corner to counteract any rotation of the page so it remains upright. To
|
||||
// achieve this effect, we do the following extra steps:
|
||||
|
||||
// 1. Perform the rotation on /BBox box prior to transforming it
|
||||
// with /Matrix (by replacing matrix with concatenation of
|
||||
// matrix onto the rotation)
|
||||
// 1. Perform the rotation on /BBox box prior to transforming it with /Matrix (by replacing
|
||||
// matrix with concatenation of matrix onto the rotation)
|
||||
|
||||
// 2. Rotate the destination rectangle by the specified amount
|
||||
|
||||
// 3. Apply the rotation to A as computed above to get the final
|
||||
// appearance matrix.
|
||||
// 3. Apply the rotation to A as computed above to get the final appearance matrix.
|
||||
|
||||
QPDFObjectHandle rect_obj = this->oh.getKey("/Rect");
|
||||
QPDFObjectHandle as = getAppearanceStream("/N").getDict();
|
||||
@ -192,14 +171,12 @@ QPDFAnnotationObjectHelper::getPageContentForAppearance(
|
||||
QPDFObjectHandle::Rectangle rect = rect_obj.getArrayAsRectangle();
|
||||
bool do_rotate = (rotate && (flags & an_no_rotate));
|
||||
if (do_rotate) {
|
||||
// If the the annotation flags include the NoRotate bit and
|
||||
// the page is rotated, we have to rotate the annotation about
|
||||
// its upper left corner by the same amount in the opposite
|
||||
// direction so that it will remain upright in absolute
|
||||
// coordinates. Since the semantics of /Rotate for a page are
|
||||
// to rotate the page, while the effect of rotating using a
|
||||
// transformation matrix is to rotate the coordinate system,
|
||||
// the opposite directionality is explicit in the code.
|
||||
// If the the annotation flags include the NoRotate bit and the page is rotated, we have to
|
||||
// rotate the annotation about its upper left corner by the same amount in the opposite
|
||||
// direction so that it will remain upright in absolute coordinates. Since the semantics of
|
||||
// /Rotate for a page are to rotate the page, while the effect of rotating using a
|
||||
// transformation matrix is to rotate the coordinate system, the opposite directionality is
|
||||
// explicit in the code.
|
||||
QPDFMatrix mr;
|
||||
mr.rotatex90(rotate);
|
||||
mr.concat(matrix);
|
||||
|
@ -139,8 +139,8 @@ QPDFArgParser::addInvalidChoiceHandler(std::string const& arg, param_arg_handler
|
||||
auto i = m->option_table->find(arg);
|
||||
if (i == m->option_table->end()) {
|
||||
QTC::TC("libtests", "QPDFArgParser invalid choice handler to unknown");
|
||||
throw std::logic_error("QPDFArgParser: attempt to add invalid choice handler"
|
||||
" to unknown argument");
|
||||
throw std::logic_error(
|
||||
"QPDFArgParser: attempt to add invalid choice handler to unknown argument");
|
||||
}
|
||||
auto& oe = i->second;
|
||||
oe.invalid_choice_handler = handler;
|
||||
@ -231,9 +231,9 @@ QPDFArgParser::invalidHelpArg(std::string const& p)
|
||||
void
|
||||
QPDFArgParser::handleArgFileArguments()
|
||||
{
|
||||
// Support reading arguments from files. Create a new argv. Ensure
|
||||
// that argv itself as well as all its contents are automatically
|
||||
// deleted by using shared pointers to back the pointers in argv.
|
||||
// Support reading arguments from files. Create a new argv. Ensure that argv itself as well as
|
||||
// all its contents are automatically deleted by using shared pointers back to the pointers in
|
||||
// argv.
|
||||
m->new_argv.push_back(QUtil::make_shared_cstr(m->argv[0]));
|
||||
for (int i = 1; i < m->argc; ++i) {
|
||||
char const* argfile = nullptr;
|
||||
@ -264,12 +264,10 @@ QPDFArgParser::handleArgFileArguments()
|
||||
void
|
||||
QPDFArgParser::handleBashArguments()
|
||||
{
|
||||
// Do a minimal job of parsing bash_line into arguments. This
|
||||
// doesn't do everything the shell does (e.g. $(...), variable
|
||||
// expansion, arithmetic, globs, etc.), but it should be good
|
||||
// enough for purposes of handling completion. As we build up the
|
||||
// new argv, we can't use m->new_argv because this code has to
|
||||
// interoperate with @file arguments, so memory for both ways of
|
||||
// Do a minimal job of parsing bash_line into arguments. This doesn't do everything the shell
|
||||
// does (e.g. $(...), variable expansion, arithmetic, globs, etc.), but it should be good enough
|
||||
// for purposes of handling completion. As we build up the new argv, we can't use m->new_argv
|
||||
// because this code has to interoperate with @file arguments, so memory for both ways of
|
||||
// fabricating argv has to be protected.
|
||||
|
||||
bool last_was_backslash = false;
|
||||
@ -321,12 +319,11 @@ QPDFArgParser::handleBashArguments()
|
||||
}
|
||||
}
|
||||
if (m->bash_argv.empty()) {
|
||||
// This can't happen if properly invoked by bash, but ensure
|
||||
// we have a valid argv[0] regardless.
|
||||
// This can't happen if properly invoked by bash, but ensure we have a valid argv[0]
|
||||
// regardless.
|
||||
m->bash_argv.push_back(QUtil::make_shared_cstr(m->argv[0]));
|
||||
}
|
||||
// Explicitly discard any non-space-terminated word. The "current
|
||||
// word" is handled specially.
|
||||
// Explicitly discard any non-space-terminated word. The "current word" is handled specially.
|
||||
m->bash_argv_ph = QUtil::make_shared_array<char const*>(1 + m->bash_argv.size());
|
||||
for (size_t i = 0; i < m->bash_argv.size(); ++i) {
|
||||
m->bash_argv_ph.get()[i] = m->bash_argv.at(i).get();
|
||||
@ -367,12 +364,10 @@ QPDFArgParser::checkCompletion()
|
||||
{
|
||||
// See if we're being invoked from bash completion.
|
||||
std::string bash_point_env;
|
||||
// On Windows with mingw, there have been times when there appears
|
||||
// to be no way to distinguish between an empty environment
|
||||
// variable and an unset variable. There are also conditions under
|
||||
// which bash doesn't set COMP_LINE. Therefore, enter this logic
|
||||
// if either COMP_LINE or COMP_POINT are set. They will both be
|
||||
// set together under ordinary circumstances.
|
||||
// On Windows with mingw, there have been times when there appears to be no way to distinguish
|
||||
// between an empty environment variable and an unset variable. There are also conditions under
|
||||
// which bash doesn't set COMP_LINE. Therefore, enter this logic if either COMP_LINE or
|
||||
// COMP_POINT are set. They will both be set together under ordinary circumstances.
|
||||
bool got_line = QUtil::get_env("COMP_LINE", &m->bash_line);
|
||||
bool got_point = QUtil::get_env("COMP_POINT", &bash_point_env);
|
||||
if (got_line || got_point) {
|
||||
@ -385,15 +380,12 @@ QPDFArgParser::checkCompletion()
|
||||
if (p > m->bash_line.length()) {
|
||||
p = m->bash_line.length();
|
||||
}
|
||||
// Set bash_cur and bash_prev based on bash_line rather than
|
||||
// relying on argv. This enables us to use bashcompinit to get
|
||||
// completion in zsh too since bashcompinit sets COMP_LINE and
|
||||
// COMP_POINT but doesn't invoke the command with options like
|
||||
// bash does.
|
||||
// Set bash_cur and bash_prev based on bash_line rather than relying on argv. This enables
|
||||
// us to use bashcompinit to get completion in zsh too since bashcompinit sets COMP_LINE and
|
||||
// COMP_POINT but doesn't invoke the command with options like bash does.
|
||||
|
||||
// p is equal to length of the string. Walk backwards looking
|
||||
// for the first separator. bash_cur is everything after the
|
||||
// last separator, possibly empty.
|
||||
// p is equal to length of the string. Walk backwards looking for the first separator.
|
||||
// bash_cur is everything after the last separator, possibly empty.
|
||||
char sep(0);
|
||||
while (p > 0) {
|
||||
--p;
|
||||
@ -407,10 +399,9 @@ QPDFArgParser::checkCompletion()
|
||||
m->bash_cur = m->bash_line.substr(1 + p, std::string::npos);
|
||||
}
|
||||
if ((sep == ':') || (sep == '=')) {
|
||||
// Bash sets prev to the non-space separator if any.
|
||||
// Actually, if there are multiple separators in a row,
|
||||
// they are all included in prev, but that detail is not
|
||||
// important to us and not worth coding.
|
||||
// Bash sets prev to the non-space separator if any. Actually, if there are multiple
|
||||
// separators in a row, they are all included in prev, but that detail is not important
|
||||
// to us and not worth coding.
|
||||
m->bash_prev = m->bash_line.substr(p, 1);
|
||||
} else {
|
||||
// Go back to the last separator and set prev based on
|
||||
@ -429,8 +420,8 @@ QPDFArgParser::checkCompletion()
|
||||
m->bash_prev = m->bash_line.substr(0, p);
|
||||
}
|
||||
if (m->argc == 1) {
|
||||
// This is probably zsh using bashcompinit. There are a
|
||||
// few differences in the expected output.
|
||||
// This is probably zsh using bashcompinit. There are a few differences in the expected
|
||||
// output.
|
||||
m->zsh_completion = true;
|
||||
}
|
||||
handleBashArguments();
|
||||
@ -454,8 +445,7 @@ QPDFArgParser::parseArgs()
|
||||
std::string o_arg(arg);
|
||||
std::string arg_s(arg);
|
||||
if (strcmp(arg, "--") == 0) {
|
||||
// Special case for -- option, which is used to break out
|
||||
// of subparsers.
|
||||
// Special case for -- option, which is used to break out of subparsers.
|
||||
oep = m->option_table->find("--");
|
||||
end_option = true;
|
||||
if (oep == m->option_table->end()) {
|
||||
@ -471,11 +461,9 @@ QPDFArgParser::parseArgs()
|
||||
QTC::TC("libtests", "QPDFArgParser single dash");
|
||||
}
|
||||
|
||||
// Prevent --=something from being treated as an empty arg
|
||||
// by searching for = from after the first character. We
|
||||
// do this since the empty string in the option table is
|
||||
// for positional arguments. Besides, it doesn't make
|
||||
// sense to have an empty option.
|
||||
// Prevent --=something from being treated as an empty arg by searching for = from after
|
||||
// the first character. We do this since the empty string in the option table is for
|
||||
// positional arguments. Besides, it doesn't make sense to have an empty option.
|
||||
arg_s = arg;
|
||||
size_t equal_pos = std::string::npos;
|
||||
if (arg_s.length() > 0) {
|
||||
@ -489,8 +477,7 @@ QPDFArgParser::parseArgs()
|
||||
|
||||
if ((!m->bash_completion) && (m->argc == 2) && (m->cur_arg == 1) &&
|
||||
m->help_option_table.count(arg_s)) {
|
||||
// Handle help option, which is only valid as the sole
|
||||
// option.
|
||||
// Handle help option, which is only valid as the sole option.
|
||||
QTC::TC("libtests", "QPDFArgParser help option");
|
||||
oep = m->help_option_table.find(arg_s);
|
||||
help_option = true;
|
||||
@ -500,8 +487,7 @@ QPDFArgParser::parseArgs()
|
||||
oep = m->option_table->find(arg_s);
|
||||
}
|
||||
} else {
|
||||
// The empty string maps to the positional argument
|
||||
// handler.
|
||||
// The empty string maps to the positional argument handler.
|
||||
QTC::TC("libtests", "QPDFArgParser positional");
|
||||
oep = m->option_table->find("");
|
||||
parameter = arg;
|
||||
@ -522,8 +508,7 @@ QPDFArgParser::parseArgs()
|
||||
std::string message = "--" + arg_s + " must be given as --" + arg_s + "=";
|
||||
if (oe.invalid_choice_handler) {
|
||||
oe.invalid_choice_handler(parameter);
|
||||
// Method should call usage() or exit. Just in case it
|
||||
// doesn't...
|
||||
// Method should call usage() or exit. Just in case it doesn't...
|
||||
message += "option";
|
||||
} else if (!oe.choices.empty()) {
|
||||
QTC::TC("libtests", "QPDFArgParser required choices");
|
||||
@ -609,8 +594,8 @@ QPDFArgParser::addOptionsToCompletions(option_table_t& option_table)
|
||||
std::string base = "--" + arg;
|
||||
if (oe.param_arg_handler) {
|
||||
if (m->zsh_completion) {
|
||||
// zsh doesn't treat = as a word separator, so add all
|
||||
// the options so we don't get a space after the =.
|
||||
// zsh doesn't treat = as a word separator, so add all the options so we don't get a
|
||||
// space after the =.
|
||||
addChoicesToCompletions(option_table, arg, base + "=");
|
||||
}
|
||||
m->completions.insert(base + "=");
|
||||
|
@ -92,8 +92,7 @@ QPDFCryptoProvider::setDefaultProvider_internal(std::string const& name)
|
||||
{
|
||||
if (!m->providers.count(name)) {
|
||||
throw std::logic_error(
|
||||
"QPDFCryptoProvider: request to set default"
|
||||
" provider to unknown implementation \"" +
|
||||
"QPDFCryptoProvider: request to set default provider to unknown implementation \"" +
|
||||
name + "\"");
|
||||
}
|
||||
m->default_provider = name;
|
||||
|
@ -233,9 +233,8 @@ QPDFCrypto_gnutls::rijndael_process(unsigned char* in_data, unsigned char* out_d
|
||||
this->cipher_ctx, in_data, rijndael_buf_size, out_data, rijndael_buf_size);
|
||||
}
|
||||
|
||||
// Gnutls doesn't support AES in ECB (non-CBC) mode, but the
|
||||
// result is the same as if you just reset the cbc block to all
|
||||
// zeroes each time. We jump through a few hoops here to make this
|
||||
// Gnutls doesn't support AES in ECB (non-CBC) mode, but the result is the same as if you just
|
||||
// reset the cbc block to all zeroes each time. We jump through a few hoops here to make this
|
||||
// work.
|
||||
if (!this->cbc_mode) {
|
||||
static unsigned char zeroes[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
@ -83,8 +83,8 @@ static void
|
||||
check_openssl(int status)
|
||||
{
|
||||
if (status != 1) {
|
||||
// OpenSSL creates a "queue" of errors; copy the first (innermost)
|
||||
// error to the exception message.
|
||||
// OpenSSL creates a "queue" of errors; copy the first (innermost) error to the exception
|
||||
// message.
|
||||
char buf[256] = "";
|
||||
ERR_error_string_n(ERR_get_error(), buf, sizeof(buf));
|
||||
std::string what = "OpenSSL error: ";
|
||||
|
@ -2,6 +2,5 @@
|
||||
|
||||
QPDFDocumentHelper::~QPDFDocumentHelper()
|
||||
{
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in
|
||||
// README-maintainer
|
||||
// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer
|
||||
}
|
||||
|
@ -134,8 +134,8 @@ QPDFEFStreamObjectHelper::newFromStream(QPDFObjectHandle stream)
|
||||
QPDFEFStreamObjectHelper result(stream);
|
||||
stream.getDict().replaceKey("/Type", QPDFObjectHandle::newName("/EmbeddedFile"));
|
||||
Pl_Discard discard;
|
||||
// The PDF spec specifies use of MD5 here and notes that it is not
|
||||
// to be used for security. MD5 is known to be insecure.
|
||||
// The PDF spec specifies use of MD5 here and notes that it is not to be used for security. MD5
|
||||
// is known to be insecure.
|
||||
Pl_MD5 md5("EF md5", &discard);
|
||||
Pl_Count count("EF size", &md5);
|
||||
if (!stream.pipeStreamData(&count, nullptr, 0, qpdf_dl_all)) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user