Commit 3c5700c255f4603b5df9c6d183d13dd71a083cc3
1 parent
6e6a73d2
Code tidy - reflow comments and strings
Showing
135 changed files
with
2378 additions
and
3380 deletions
examples/pdf-attach-file.cc
| @@ -8,11 +8,10 @@ | @@ -8,11 +8,10 @@ | ||
| 8 | #include <iostream> | 8 | #include <iostream> |
| 9 | 9 | ||
| 10 | // | 10 | // |
| 11 | -// This example attaches a file to an input file, adds a page to the | ||
| 12 | -// beginning of the file that includes a file attachment annotation, | ||
| 13 | -// and writes the result to an output file. It also illustrates a | ||
| 14 | -// number of new API calls that were added in qpdf 10.2 as well as | ||
| 15 | -// the use of the qpdf literal syntax introduced in qpdf 10.6. | 11 | +// This example attaches a file to an input file, adds a page to the beginning of the file that |
| 12 | +// includes a file attachment annotation, and writes the result to an output file. It also | ||
| 13 | +// illustrates a number of new API calls that were added in qpdf 10.2 as well as the use of the qpdf | ||
| 14 | +// literal syntax introduced in qpdf 10.6. | ||
| 16 | // | 15 | // |
| 17 | 16 | ||
| 18 | static char const* whoami = nullptr; | 17 | static char const* whoami = nullptr; |
| @@ -43,8 +42,8 @@ process( | @@ -43,8 +42,8 @@ process( | ||
| 43 | QPDF q; | 42 | QPDF q; |
| 44 | q.processFile(infilename, password); | 43 | q.processFile(infilename, password); |
| 45 | 44 | ||
| 46 | - // Create an indirect object for the built-in Helvetica font. This | ||
| 47 | - // uses the qpdf literal syntax introduced in qpdf 10.6. | 45 | + // Create an indirect object for the built-in Helvetica font. This uses the qpdf literal syntax |
| 46 | + // introduced in qpdf 10.6. | ||
| 48 | auto f1 = q.makeIndirectObject( | 47 | auto f1 = q.makeIndirectObject( |
| 49 | // force line-break | 48 | // force line-break |
| 50 | "<<" | 49 | "<<" |
| @@ -55,9 +54,8 @@ process( | @@ -55,9 +54,8 @@ process( | ||
| 55 | " /Encoding /WinAnsiEncoding" | 54 | " /Encoding /WinAnsiEncoding" |
| 56 | ">>"_qpdf); | 55 | ">>"_qpdf); |
| 57 | 56 | ||
| 58 | - // Create a resources dictionary with fonts. This uses the new | ||
| 59 | - // parse introduced in qpdf 10.2 that takes a QPDF* and allows | ||
| 60 | - // indirect object references. | 57 | + // Create a resources dictionary with fonts. This uses the new parse introduced in qpdf 10.2 |
| 58 | + // that takes a QPDF* and allows indirect object references. | ||
| 61 | auto resources = q.makeIndirectObject( | 59 | auto resources = q.makeIndirectObject( |
| 62 | // line-break | 60 | // line-break |
| 63 | QPDFObjectHandle::parse( | 61 | QPDFObjectHandle::parse( |
| @@ -97,8 +95,8 @@ process( | @@ -97,8 +95,8 @@ process( | ||
| 97 | "S\n"); | 95 | "S\n"); |
| 98 | auto apdict = ap.getDict(); | 96 | auto apdict = ap.getDict(); |
| 99 | 97 | ||
| 100 | - // The following four lines demonstrate the use of the qpdf literal syntax | ||
| 101 | - // introduced in qpdf 10.6. They could have been written as: | 98 | + // The following four lines demonstrate the use of the qpdf literal syntax introduced in |
| 99 | + // qpdf 10.6. They could have been written as: | ||
| 102 | // apdict.replaceKey("/Resources", QPDFObjectHandle::newDictionary()); | 100 | // apdict.replaceKey("/Resources", QPDFObjectHandle::newDictionary()); |
| 103 | // apdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject")); | 101 | // apdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject")); |
| 104 | // apdict.replaceKey("/Subtype", QPDFObjectHandle::newName("/Form")); | 102 | // apdict.replaceKey("/Subtype", QPDFObjectHandle::newName("/Form")); |
examples/pdf-bookmarks.cc
| @@ -8,9 +8,9 @@ | @@ -8,9 +8,9 @@ | ||
| 8 | #include <cstring> | 8 | #include <cstring> |
| 9 | #include <iostream> | 9 | #include <iostream> |
| 10 | 10 | ||
| 11 | -// This program demonstrates extraction of bookmarks using the qpdf | ||
| 12 | -// outlines API. Note that all the information shown by this program | ||
| 13 | -// can also be obtained from a PDF file using qpdf's --json option. | 11 | +// This program demonstrates extraction of bookmarks using the qpdf outlines API. Note that all the |
| 12 | +// information shown by this program can also be obtained from a PDF file using qpdf's --json | ||
| 13 | +// option. | ||
| 14 | // | 14 | // |
| 15 | // Ignore calls to QTC::TC - they are for qpdf CI testing only. | 15 | // Ignore calls to QTC::TC - they are for qpdf CI testing only. |
| 16 | 16 | ||
| @@ -118,11 +118,10 @@ show_bookmark_details(QPDFOutlineObjectHelper outline, std::vector<int> numbers) | @@ -118,11 +118,10 @@ show_bookmark_details(QPDFOutlineObjectHelper outline, std::vector<int> numbers) | ||
| 118 | void | 118 | void |
| 119 | extract_bookmarks(std::vector<QPDFOutlineObjectHelper> outlines, std::vector<int>& numbers) | 119 | extract_bookmarks(std::vector<QPDFOutlineObjectHelper> outlines, std::vector<int>& numbers) |
| 120 | { | 120 | { |
| 121 | - // For style == st_numbers, numbers.at(n) contains the numerical | ||
| 122 | - // label for the outline, so we count up from 1. | ||
| 123 | - // For style == st_lines, numbers.at(n) == 0 indicates the last | ||
| 124 | - // outline at level n, and we don't otherwise care what the value | ||
| 125 | - // is, so we count up to zero. | 121 | + // For style == st_numbers, numbers.at(n) contains the numerical label for the outline, so we |
| 122 | + // count up from 1. | ||
| 123 | + // For style == st_lines, numbers.at(n) == 0 indicates the last outline at level n, and we don't | ||
| 124 | + // otherwise care what the value is, so we count up to zero. | ||
| 126 | numbers.push_back((style == st_lines) ? -QIntC::to_int(outlines.size()) : 0); | 125 | numbers.push_back((style == st_lines) ? -QIntC::to_int(outlines.size()) : 0); |
| 127 | for (auto& outline: outlines) { | 126 | for (auto& outline: outlines) { |
| 128 | ++(numbers.back()); | 127 | ++(numbers.back()); |
examples/pdf-c-objects.c
| 1 | -/* | ||
| 2 | - * This is an example program to demonstrate use of object handle | ||
| 3 | - * functions in the C API. | ||
| 4 | - */ | 1 | +/* This is an example program to demonstrate use of object handle functions in the C API. */ |
| 5 | 2 | ||
| 6 | #include <qpdf/qpdf-c.h> | 3 | #include <qpdf/qpdf-c.h> |
| 7 | #include <stdio.h> | 4 | #include <stdio.h> |
| @@ -20,8 +17,7 @@ usage() | @@ -20,8 +17,7 @@ usage() | ||
| 20 | QPDF_BOOL | 17 | QPDF_BOOL |
| 21 | modify_file(qpdf_data qpdf) | 18 | modify_file(qpdf_data qpdf) |
| 22 | { | 19 | { |
| 23 | - /* This small example performs the following operation on the | ||
| 24 | - * document catalog (a.k.a. root): | 20 | + /* This small example performs the following operation on the document catalog (a.k.a. root): |
| 25 | * - Remove PageLayout | 21 | * - Remove PageLayout |
| 26 | * - Remove OpenAction | 22 | * - Remove OpenAction |
| 27 | * - If there are outlines, set PageMode to UseOutlines; otherwise, | 23 | * - If there are outlines, set PageMode to UseOutlines; otherwise, |
| @@ -72,8 +68,7 @@ main(int argc, char* argv[]) | @@ -72,8 +68,7 @@ main(int argc, char* argv[]) | ||
| 72 | 68 | ||
| 73 | if (((qpdf_read(qpdf, infile, password) & QPDF_ERRORS) == 0) && modify_file(qpdf) && | 69 | if (((qpdf_read(qpdf, infile, password) & QPDF_ERRORS) == 0) && modify_file(qpdf) && |
| 74 | ((qpdf_init_write(qpdf, outfile) & QPDF_ERRORS) == 0)) { | 70 | ((qpdf_init_write(qpdf, outfile) & QPDF_ERRORS) == 0)) { |
| 75 | - /* Use static ID for testing only. For production, a | ||
| 76 | - * non-static ID is used. See also | 71 | + /* Use static ID for testing only. For production, a non-static ID is used. See also |
| 77 | * qpdf_set_deterministic_ID. */ | 72 | * qpdf_set_deterministic_ID. */ |
| 78 | qpdf_set_static_ID(qpdf, QPDF_TRUE); /* for testing only */ | 73 | qpdf_set_static_ID(qpdf, QPDF_TRUE); /* for testing only */ |
| 79 | qpdf_write(qpdf); | 74 | qpdf_write(qpdf); |
examples/pdf-count-strings.cc
| 1 | // | 1 | // |
| 2 | -// This example illustrates the use of QPDFObjectHandle::TokenFilter | ||
| 3 | -// with filterContents. See also pdf-filter-tokens.cc for an example | ||
| 4 | -// that uses QPDFObjectHandle::TokenFilter with addContentTokenFilter. | 2 | +// This example illustrates the use of QPDFObjectHandle::TokenFilter with filterContents. See also |
| 3 | +// pdf-filter-tokens.cc for an example that uses QPDFObjectHandle::TokenFilter with | ||
| 4 | +// addContentTokenFilter. | ||
| 5 | // | 5 | // |
| 6 | 6 | ||
| 7 | #include <cstdlib> | 7 | #include <cstdlib> |
| @@ -46,16 +46,15 @@ StringCounter::handleToken(QPDFTokenizer::Token const& token) | @@ -46,16 +46,15 @@ StringCounter::handleToken(QPDFTokenizer::Token const& token) | ||
| 46 | if (token.getType() == QPDFTokenizer::tt_string) { | 46 | if (token.getType() == QPDFTokenizer::tt_string) { |
| 47 | ++this->count; | 47 | ++this->count; |
| 48 | } | 48 | } |
| 49 | - // Preserve input verbatim by passing each token to any specified | ||
| 50 | - // downstream filter. | 49 | + // Preserve input verbatim by passing each token to any specified downstream filter. |
| 51 | writeToken(token); | 50 | writeToken(token); |
| 52 | } | 51 | } |
| 53 | 52 | ||
| 54 | void | 53 | void |
| 55 | StringCounter::handleEOF() | 54 | StringCounter::handleEOF() |
| 56 | { | 55 | { |
| 57 | - // Write a comment at the end of the stream just to show how we | ||
| 58 | - // can enhance the output if we want. | 56 | + // Write a comment at the end of the stream just to show how we can enhance the output if we |
| 57 | + // want. | ||
| 59 | write("\n% strings found: "); | 58 | write("\n% strings found: "); |
| 60 | write(std::to_string(this->count)); | 59 | write(std::to_string(this->count)); |
| 61 | } | 60 | } |
| @@ -82,10 +81,9 @@ main(int argc, char* argv[]) | @@ -82,10 +81,9 @@ main(int argc, char* argv[]) | ||
| 82 | int pageno = 0; | 81 | int pageno = 0; |
| 83 | for (auto& page: QPDFPageDocumentHelper(pdf).getAllPages()) { | 82 | for (auto& page: QPDFPageDocumentHelper(pdf).getAllPages()) { |
| 84 | ++pageno; | 83 | ++pageno; |
| 85 | - // Pass the contents of a page through our string counter. | ||
| 86 | - // If it's an even page, capture the output. This | ||
| 87 | - // illustrates that you may capture any output generated | ||
| 88 | - // by the filter, or you may ignore it. | 84 | + // Pass the contents of a page through our string counter. If it's an even page, capture |
| 85 | + // the output. This illustrates that you may capture any output generated by the filter, | ||
| 86 | + // or you may ignore it. | ||
| 89 | StringCounter counter; | 87 | StringCounter counter; |
| 90 | if (pageno % 2) { | 88 | if (pageno % 2) { |
| 91 | // Ignore output for odd pages. | 89 | // Ignore output for odd pages. |
examples/pdf-create.cc
| 1 | // | 1 | // |
| 2 | -// This is an example of creating a PDF file from scratch. It | ||
| 3 | -// illustrates use of several QPDF operations for creating objects and | ||
| 4 | -// streams. It also serves as an illustration of how to use | 2 | +// This is an example of creating a PDF file from scratch. It illustrates use of several QPDF |
| 3 | +// operations for creating objects and streams. It also serves as an illustration of how to use | ||
| 5 | // StreamDataProvider with different types of filters. | 4 | // StreamDataProvider with different types of filters. |
| 6 | // | 5 | // |
| 7 | 6 | ||
| @@ -20,8 +19,8 @@ | @@ -20,8 +19,8 @@ | ||
| 20 | 19 | ||
| 21 | static char const* whoami = nullptr; | 20 | static char const* whoami = nullptr; |
| 22 | 21 | ||
| 23 | -// This is a simple StreamDataProvider that writes image data for an | ||
| 24 | -// orange square of the given width and height. | 22 | +// This is a simple StreamDataProvider that writes image data for an orange square of the given |
| 23 | +// width and height. | ||
| 25 | class ImageProvider: public QPDFObjectHandle::StreamDataProvider | 24 | class ImageProvider: public QPDFObjectHandle::StreamDataProvider |
| 26 | { | 25 | { |
| 27 | public: | 26 | public: |
| @@ -130,8 +129,7 @@ usage() | @@ -130,8 +129,7 @@ usage() | ||
| 130 | static QPDFObjectHandle | 129 | static QPDFObjectHandle |
| 131 | createPageContents(QPDF& pdf, std::string const& text) | 130 | createPageContents(QPDF& pdf, std::string const& text) |
| 132 | { | 131 | { |
| 133 | - // Create a stream that displays our image and the given text in | ||
| 134 | - // our font. | 132 | + // Create a stream that displays our image and the given text in our font. |
| 135 | std::string contents = "BT /F1 24 Tf 72 320 Td (" + text + | 133 | std::string contents = "BT /F1 24 Tf 72 320 Td (" + text + |
| 136 | ") Tj ET\n" | 134 | ") Tj ET\n" |
| 137 | "q 244 0 0 144 184 100 cm /Im1 Do Q\n"; | 135 | "q 244 0 0 144 184 100 cm /Im1 Do Q\n"; |
| @@ -159,11 +157,9 @@ add_page( | @@ -159,11 +157,9 @@ add_page( | ||
| 159 | { | 157 | { |
| 160 | QPDF& pdf(dh.getQPDF()); | 158 | QPDF& pdf(dh.getQPDF()); |
| 161 | 159 | ||
| 162 | - // Create a stream to encode our image. QPDFWriter will fill in | ||
| 163 | - // the length and will respect our filters based on stream data | ||
| 164 | - // mode. Since we are not specifying, QPDFWriter will compress | ||
| 165 | - // with /FlateDecode if we don't provide any other form of | ||
| 166 | - // compression. | 160 | + // Create a stream to encode our image. QPDFWriter will fill in the length and will respect our |
| 161 | + // filters based on stream data mode. Since we are not specifying, QPDFWriter will compress with | ||
| 162 | + // /FlateDecode if we don't provide any other form of compression. | ||
| 167 | auto* p = new ImageProvider(color_space, filter); | 163 | auto* p = new ImageProvider(color_space, filter); |
| 168 | std::shared_ptr<QPDFObjectHandle::StreamDataProvider> provider(p); | 164 | std::shared_ptr<QPDFObjectHandle::StreamDataProvider> provider(p); |
| 169 | size_t width = p->getWidth(); | 165 | size_t width = p->getWidth(); |
| @@ -219,20 +215,17 @@ check( | @@ -219,20 +215,17 @@ check( | ||
| 219 | std::vector<std::string> const& color_spaces, | 215 | std::vector<std::string> const& color_spaces, |
| 220 | std::vector<std::string> const& filters) | 216 | std::vector<std::string> const& filters) |
| 221 | { | 217 | { |
| 222 | - // Each stream is compressed the way it is supposed to be. We will | ||
| 223 | - // add additional tests in qpdf.test to exercise QPDFWriter more | ||
| 224 | - // fully. In this case, we want to make sure that we actually have | ||
| 225 | - // RunLengthDecode and DCTDecode where we are supposed to and | ||
| 226 | - // FlateDecode where we provided no filters. | 218 | + // Each stream is compressed the way it is supposed to be. We will add additional tests in |
| 219 | + // qpdf.test to exercise QPDFWriter more fully. In this case, we want to make sure that we | ||
| 220 | + // actually have RunLengthDecode and DCTDecode where we are supposed to and FlateDecode where we | ||
| 221 | + // provided no filters. | ||
| 227 | 222 | ||
| 228 | - // Each image is correct. For non-lossy image compression, the | ||
| 229 | - // uncompressed image data should exactly match what ImageProvider | ||
| 230 | - // provided. For the DCTDecode data, allow for some fuzz to handle | ||
| 231 | - // jpeg compression as well as its variance on different systems. | 223 | + // Each image is correct. For non-lossy image compression, the uncompressed image data should |
| 224 | + // exactly match what ImageProvider provided. For the DCTDecode data, allow for some fuzz to | ||
| 225 | + // handle jpeg compression as well as its variance on different systems. | ||
| 232 | 226 | ||
| 233 | - // These tests should use QPDFObjectHandle's stream data retrieval | ||
| 234 | - // methods, but don't try to fully exercise them here. That is | ||
| 235 | - // done elsewhere. | 227 | + // These tests should use QPDFObjectHandle's stream data retrieval methods, but don't try to |
| 228 | + // fully exercise them here. That is done elsewhere. | ||
| 236 | 229 | ||
| 237 | size_t n_color_spaces = color_spaces.size(); | 230 | size_t n_color_spaces = color_spaces.size(); |
| 238 | size_t n_filters = filters.size(); | 231 | size_t n_filters = filters.size(); |
| @@ -254,8 +247,8 @@ check( | @@ -254,8 +247,8 @@ check( | ||
| 254 | // Check filter and color space. | 247 | // Check filter and color space. |
| 255 | std::string desired_color_space = color_spaces[(pageno - 1) / n_color_spaces]; | 248 | std::string desired_color_space = color_spaces[(pageno - 1) / n_color_spaces]; |
| 256 | std::string desired_filter = filters[(pageno - 1) % n_filters]; | 249 | std::string desired_filter = filters[(pageno - 1) % n_filters]; |
| 257 | - // In the default mode, QPDFWriter will compress with | ||
| 258 | - // /FlateDecode if no filters are provided. | 250 | + // In the default mode, QPDFWriter will compress with /FlateDecode if no filters are |
| 251 | + // provided. | ||
| 259 | if (desired_filter == "null") { | 252 | if (desired_filter == "null") { |
| 260 | desired_filter = "/FlateDecode"; | 253 | desired_filter = "/FlateDecode"; |
| 261 | } | 254 | } |
| @@ -288,11 +281,9 @@ check( | @@ -288,11 +281,9 @@ check( | ||
| 288 | std::cout << "page " << pageno << ": image data length mismatch" << std::endl; | 281 | std::cout << "page " << pageno << ": image data length mismatch" << std::endl; |
| 289 | this_errors = errors = true; | 282 | this_errors = errors = true; |
| 290 | } else { | 283 | } else { |
| 291 | - // Compare bytes. For JPEG, allow a certain number of | ||
| 292 | - // the bytes to be off desired by more than a given | ||
| 293 | - // tolerance. Any of the samples may be a little off | ||
| 294 | - // because of lossy compression, and around sharp | ||
| 295 | - // edges, things can be quite off. For non-lossy | 284 | + // Compare bytes. For JPEG, allow a certain number of the bytes to be off desired by |
| 285 | + // more than a given tolerance. Any of the samples may be a little off because of | ||
| 286 | + // lossy compression, and around sharp edges, things can be quite off. For non-lossy | ||
| 296 | // compression, do not allow any tolerance. | 287 | // compression, do not allow any tolerance. |
| 297 | unsigned char const* actual_bytes = actual_data->getBuffer(); | 288 | unsigned char const* actual_bytes = actual_data->getBuffer(); |
| 298 | unsigned char const* desired_bytes = desired_data->getBuffer(); | 289 | unsigned char const* desired_bytes = desired_data->getBuffer(); |
| @@ -332,8 +323,7 @@ create_pdf(char const* filename) | @@ -332,8 +323,7 @@ create_pdf(char const* filename) | ||
| 332 | // Start with an empty PDF that has no pages or non-required objects. | 323 | // Start with an empty PDF that has no pages or non-required objects. |
| 333 | pdf.emptyPDF(); | 324 | pdf.emptyPDF(); |
| 334 | 325 | ||
| 335 | - // Add an indirect object to contain a font descriptor for the | ||
| 336 | - // built-in Helvetica font. | 326 | + // Add an indirect object to contain a font descriptor for the built-in Helvetica font. |
| 337 | QPDFObjectHandle font = pdf.makeIndirectObject( | 327 | QPDFObjectHandle font = pdf.makeIndirectObject( |
| 338 | // line-break | 328 | // line-break |
| 339 | "<<" | 329 | "<<" |
| @@ -362,8 +352,7 @@ create_pdf(char const* filename) | @@ -362,8 +352,7 @@ create_pdf(char const* filename) | ||
| 362 | QPDFWriter w(pdf, filename); | 352 | QPDFWriter w(pdf, filename); |
| 363 | w.write(); | 353 | w.write(); |
| 364 | 354 | ||
| 365 | - // For test suite, verify that everything is the way it is | ||
| 366 | - // supposed to be. | 355 | + // For test suite, verify that everything is the way it is supposed to be. |
| 367 | check(filename, color_spaces, filters); | 356 | check(filename, color_spaces, filters); |
| 368 | } | 357 | } |
| 369 | 358 |
examples/pdf-custom-filter.cc
| @@ -8,43 +8,35 @@ | @@ -8,43 +8,35 @@ | ||
| 8 | #include <iostream> | 8 | #include <iostream> |
| 9 | #include <memory> | 9 | #include <memory> |
| 10 | 10 | ||
| 11 | -// This example shows you everything you need to know to implement a | ||
| 12 | -// custom stream filter for encoding and decoding as well as a stream | ||
| 13 | -// data provider that modifies the stream's dictionary. This example | ||
| 14 | -// uses the pattern of having the stream data provider class use a | ||
| 15 | -// second QPDF instance with copies of streams from the original QPDF | ||
| 16 | -// so that the stream data provider can access the original stream | ||
| 17 | -// data. This is implemented very efficiently inside the qpdf library as | ||
| 18 | -// the second QPDF instance knows how to read the stream data from the | ||
| 19 | -// original input file, so no extra copies of the original stream data | ||
| 20 | -// are made. | ||
| 21 | - | ||
| 22 | -// This example creates an imaginary filter called /XORDecode. There | ||
| 23 | -// is no such filter in PDF, so the streams created by the example | ||
| 24 | -// would not be usable by any PDF reader. However, the techniques here | ||
| 25 | -// would work if you were going to implement support for a filter that | ||
| 26 | -// qpdf does not support natively. For example, using the techniques | ||
| 27 | -// shown here, it would be possible to create an application that | ||
| 28 | -// downsampled or re-encoded images or that re-compressed streams | ||
| 29 | -// using a more efficient "deflate" implementation than zlib. | ||
| 30 | - | ||
| 31 | -// Comments appear throughout the code describing each piece of code | ||
| 32 | -// and its purpose. You can read the file top to bottom, or you can | ||
| 33 | -// start with main() and follow the flow. | ||
| 34 | - | ||
| 35 | -// Please also see the test suite, qtest/custom-filter.test, which | ||
| 36 | -// contains additional comments describing how to observe the results | ||
| 37 | -// of running this example on test files that are specifically crafted | ||
| 38 | -// for it. | 11 | +// This example shows you everything you need to know to implement a custom stream filter for |
| 12 | +// encoding and decoding as well as a stream data provider that modifies the stream's dictionary. | ||
| 13 | +// This example uses the pattern of having the stream data provider class use a second QPDF instance | ||
| 14 | +// with copies of streams from the original QPDF so that the stream data provider can access the | ||
| 15 | +// original stream data. This is implemented very efficiently inside the qpdf library as the second | ||
| 16 | +// QPDF instance knows how to read the stream data from the original input file, so no extra copies | ||
| 17 | +// of the original stream data are made. | ||
| 18 | + | ||
| 19 | +// This example creates an imaginary filter called /XORDecode. There is no such filter in PDF, so | ||
| 20 | +// the streams created by the example would not be usable by any PDF reader. However, the techniques | ||
| 21 | +// here would work if you were going to implement support for a filter that qpdf does not support | ||
| 22 | +// natively. For example, using the techniques shown here, it would be possible to create an | ||
| 23 | +// application that downsampled or re-encoded images or that re-compressed streams using a more | ||
| 24 | +// efficient "deflate" implementation than zlib. | ||
| 25 | + | ||
| 26 | +// Comments appear throughout the code describing each piece of code and its purpose. You can read | ||
| 27 | +// the file top to bottom, or you can start with main() and follow the flow. | ||
| 28 | + | ||
| 29 | +// Please also see the test suite, qtest/custom-filter.test, which contains additional comments | ||
| 30 | +// describing how to observe the results of running this example on test files that are specifically | ||
| 31 | +// crafted for it. | ||
| 39 | 32 | ||
| 40 | static char const* whoami = nullptr; | 33 | static char const* whoami = nullptr; |
| 41 | 34 | ||
| 42 | class Pl_XOR: public Pipeline | 35 | class Pl_XOR: public Pipeline |
| 43 | { | 36 | { |
| 44 | - // This class implements a Pipeline for the made-up XOR decoder. | ||
| 45 | - // It is initialized with a single-byte "key" and just XORs each | ||
| 46 | - // byte with that key. This makes it reversible, so there is no | ||
| 47 | - // distinction between encoding and decoding. | 37 | + // This class implements a Pipeline for the made-up XOR decoder. It is initialized with a |
| 38 | + // single-byte "key" and just XORs each byte with that key. This makes it reversible, so there | ||
| 39 | + // is no distinction between encoding and decoding. | ||
| 48 | 40 | ||
| 49 | public: | 41 | public: |
| 50 | Pl_XOR(char const* identifier, Pipeline* next, unsigned char key); | 42 | Pl_XOR(char const* identifier, Pipeline* next, unsigned char key); |
| @@ -79,17 +71,14 @@ Pl_XOR::finish() | @@ -79,17 +71,14 @@ Pl_XOR::finish() | ||
| 79 | 71 | ||
| 80 | class SF_XORDecode: public QPDFStreamFilter | 72 | class SF_XORDecode: public QPDFStreamFilter |
| 81 | { | 73 | { |
| 82 | - // This class implements a QPDFStreamFilter that knows how to | ||
| 83 | - // validate and interpret decode parameters (/DecodeParms) for the | ||
| 84 | - // made-up /XORDecode stream filter. Since this is not a real | ||
| 85 | - // stream filter, no actual PDF reader would know how to interpret | ||
| 86 | - // it. This is just to illustrate how to create a stream filter. | ||
| 87 | - // In main(), we call QPDF::registerStreamFilter to tell the | ||
| 88 | - // library about the filter. See comments in QPDFStreamFilter.hh | ||
| 89 | - // for details on how to implement the methods. For purposes of | ||
| 90 | - // example, we are calling this a "specialized" compression | ||
| 91 | - // filter, which just means QPDF assumes that it should not | ||
| 92 | - // "uncompress" the stream by default. | 74 | + // This class implements a QPDFStreamFilter that knows how to validate and interpret decode |
| 75 | + // parameters (/DecodeParms) for the made-up /XORDecode stream filter. Since this is not a real | ||
| 76 | + // stream filter, no actual PDF reader would know how to interpret it. This is just to | ||
| 77 | + // illustrate how to create a stream filter. In main(), we call QPDF::registerStreamFilter to | ||
| 78 | + // tell the library about the filter. See comments in QPDFStreamFilter.hh for details on how to | ||
| 79 | + // implement the methods. For purposes of example, we are calling this a "specialized" | ||
| 80 | + // compression filter, which just means QPDF assumes that it should not "uncompress" the stream | ||
| 81 | + // by default. | ||
| 93 | public: | 82 | public: |
| 94 | ~SF_XORDecode() override = default; | 83 | ~SF_XORDecode() override = default; |
| 95 | bool setDecodeParms(QPDFObjectHandle decode_parms) override; | 84 | bool setDecodeParms(QPDFObjectHandle decode_parms) override; |
| @@ -98,33 +87,28 @@ class SF_XORDecode: public QPDFStreamFilter | @@ -98,33 +87,28 @@ class SF_XORDecode: public QPDFStreamFilter | ||
| 98 | 87 | ||
| 99 | private: | 88 | private: |
| 100 | unsigned char key; | 89 | unsigned char key; |
| 101 | - // It is the responsibility of the QPDFStreamFilter implementation | ||
| 102 | - // to ensure that the pipeline returned by getDecodePipeline() is | ||
| 103 | - // deleted when the class is deleted. The easiest way to do this | ||
| 104 | - // is to stash the pipeline in a std::shared_ptr, which enables us | ||
| 105 | - // to use the default destructor implementation. | 90 | + // It is the responsibility of the QPDFStreamFilter implementation to ensure that the pipeline |
| 91 | + // returned by getDecodePipeline() is deleted when the class is deleted. The easiest way to do | ||
| 92 | + // this is to stash the pipeline in a std::shared_ptr, which enables us to use the default | ||
| 93 | + // destructor implementation. | ||
| 106 | std::shared_ptr<Pl_XOR> pipeline; | 94 | std::shared_ptr<Pl_XOR> pipeline; |
| 107 | }; | 95 | }; |
| 108 | 96 | ||
| 109 | bool | 97 | bool |
| 110 | SF_XORDecode::setDecodeParms(QPDFObjectHandle decode_parms) | 98 | SF_XORDecode::setDecodeParms(QPDFObjectHandle decode_parms) |
| 111 | { | 99 | { |
| 112 | - // For purposes of example, we store the key in a separate stream. | ||
| 113 | - // We could just as well store the key directly in /DecodeParms, | ||
| 114 | - // but this example uses a stream to illustrate how one might do | ||
| 115 | - // that. For example, if implementing /JBIG2Decode, one would need | ||
| 116 | - // to handle the /JBIG2Globals key, which points to a stream. See | ||
| 117 | - // comments in SF_XORDecode::registerStream for additional notes | ||
| 118 | - // on this. | 100 | + // For purposes of example, we store the key in a separate stream. We could just as well store |
| 101 | + // the key directly in /DecodeParms, but this example uses a stream to illustrate how one might | ||
| 102 | + // do that. For example, if implementing /JBIG2Decode, one would need to handle the | ||
| 103 | + // /JBIG2Globals key, which points to a stream. See comments in SF_XORDecode::registerStream for | ||
| 104 | + // additional notes on this. | ||
| 119 | try { | 105 | try { |
| 120 | - // Expect /DecodeParms to be a dictionary with a /KeyStream | ||
| 121 | - // key that points to a one-byte stream whose single byte is | ||
| 122 | - // the key. If we are successful at retrieving the key, return | ||
| 123 | - // true, indicating that we are able to process with the given | ||
| 124 | - // decode parameters. Under any other circumstances, return | ||
| 125 | - // false. For other examples of QPDFStreamFilter | ||
| 126 | - // implementations, look at the classes whose names start with | ||
| 127 | - // SF_ in the qpdf library implementation. | 106 | + // Expect /DecodeParms to be a dictionary with a /KeyStream key that points to a one-byte |
| 107 | + // stream whose single byte is the key. If we are successful at retrieving the key, return | ||
| 108 | + // true, indicating that we are able to process with the given decode parameters. Under any | ||
| 109 | + // other circumstances, return false. For other examples of QPDFStreamFilter | ||
| 110 | + // implementations, look at the classes whose names start with SF_ in the qpdf library | ||
| 111 | + // implementation. | ||
| 128 | auto buf = decode_parms.getKey("/KeyStream").getStreamData(); | 112 | auto buf = decode_parms.getKey("/KeyStream").getStreamData(); |
| 129 | if (buf->getSize() != 1) { | 113 | if (buf->getSize() != 1) { |
| 130 | return false; | 114 | return false; |
| @@ -140,14 +124,12 @@ SF_XORDecode::setDecodeParms(QPDFObjectHandle decode_parms) | @@ -140,14 +124,12 @@ SF_XORDecode::setDecodeParms(QPDFObjectHandle decode_parms) | ||
| 140 | Pipeline* | 124 | Pipeline* |
| 141 | SF_XORDecode::getDecodePipeline(Pipeline* next) | 125 | SF_XORDecode::getDecodePipeline(Pipeline* next) |
| 142 | { | 126 | { |
| 143 | - // Return a pipeline that the qpdf library should pass the stream | ||
| 144 | - // data through. The pipeline should receive encoded data and pass | ||
| 145 | - // decoded data to "next". getDecodePipeline() can always count on | ||
| 146 | - // setDecodeParms() having been called first. The setDecodeParms() | ||
| 147 | - // method should store any parameters needed by the pipeline. To | ||
| 148 | - // ensure that the pipeline we return disappears when the class | ||
| 149 | - // disappears, stash it in a std::shared_ptr<Pl_XOR> and retrieve | ||
| 150 | - // the raw pointer from there. | 127 | + // Return a pipeline that the qpdf library should pass the stream data through. The pipeline |
| 128 | + // should receive encoded data and pass decoded data to "next". getDecodePipeline() can always | ||
| 129 | + // count on setDecodeParms() having been called first. The setDecodeParms() method should store | ||
| 130 | + // any parameters needed by the pipeline. To ensure that the pipeline we return disappears when | ||
| 131 | + // the class disappears, stash it in a std::shared_ptr<Pl_XOR> and retrieve the raw pointer from | ||
| 132 | + // there. | ||
| 151 | this->pipeline = std::make_shared<Pl_XOR>("xor", next, this->key); | 133 | this->pipeline = std::make_shared<Pl_XOR>("xor", next, this->key); |
| 152 | return this->pipeline.get(); | 134 | return this->pipeline.get(); |
| 153 | } | 135 | } |
| @@ -155,46 +137,37 @@ SF_XORDecode::getDecodePipeline(Pipeline* next) | @@ -155,46 +137,37 @@ SF_XORDecode::getDecodePipeline(Pipeline* next) | ||
| 155 | bool | 137 | bool |
| 156 | SF_XORDecode::isSpecializedCompression() | 138 | SF_XORDecode::isSpecializedCompression() |
| 157 | { | 139 | { |
| 158 | - // The default implementation of QPDFStreamFilter would return | ||
| 159 | - // false, so if you want a specialized or lossy compression | ||
| 160 | - // filter, override one of the methods as described in | 140 | + // The default implementation of QPDFStreamFilter would return false, so if you want a |
| 141 | + // specialized or lossy compression filter, override one of the methods as described in | ||
| 161 | // QPDFStreamFilter.hh. | 142 | // QPDFStreamFilter.hh. |
| 162 | return true; | 143 | return true; |
| 163 | } | 144 | } |
| 164 | 145 | ||
| 165 | class StreamReplacer: public QPDFObjectHandle::StreamDataProvider | 146 | class StreamReplacer: public QPDFObjectHandle::StreamDataProvider |
| 166 | { | 147 | { |
| 167 | - // This class implements a StreamDataProvider that, under specific | ||
| 168 | - // conditions, replaces the stream data with data encoded with the | ||
| 169 | - // made-up /XORDecode filter. | 148 | + // This class implements a StreamDataProvider that, under specific conditions, replaces the |
| 149 | + // stream data with data encoded with the made-up /XORDecode filter. | ||
| 170 | 150 | ||
| 171 | // The flow for this class is as follows: | 151 | // The flow for this class is as follows: |
| 172 | // | 152 | // |
| 173 | - // * The main application iterates through streams that should be | ||
| 174 | - // replaced and calls registerStream. registerStream in turn | ||
| 175 | - // calls maybeReplace passing nullptr to pipeline and the | ||
| 176 | - // address of a valid QPDFObjectHandle to dict_updates. The | ||
| 177 | - // stream passed in for this call is the stream for the original | ||
| 178 | - // QPDF object. It has not yet been altered, so we have access | ||
| 179 | - // to its original dictionary and data. As described in the | ||
| 180 | - // method, the method when called in this way makes a | ||
| 181 | - // determination as to whether the stream should be replaced. If | ||
| 182 | - // so, registerStream makes whatever changes are required. We | ||
| 183 | - // have to do this now because we can't modify the stream during | ||
| 184 | - // the writing process. | 153 | + // * The main application iterates through streams that should be replaced and calls |
| 154 | + // registerStream. registerStream in turn calls maybeReplace passing nullptr to pipeline and | ||
| 155 | + // the address of a valid QPDFObjectHandle to dict_updates. The stream passed in for this call | ||
| 156 | + // is the stream for the original QPDF object. It has not yet been altered, so we have access | ||
| 157 | + // to its original dictionary and data. As described in the method, the method when called in | ||
| 158 | + // this way makes a determination as to whether the stream should be replaced. If so, | ||
| 159 | + // registerStream makes whatever changes are required. We have to do this now because we can't | ||
| 160 | + // modify the stream during the writing process. | ||
| 185 | // | 161 | // |
| 186 | - // * provideStreamData(), which is called by QPDFWriter during the | ||
| 187 | - // write process, actually writes the modified stream data. It | ||
| 188 | - // calls maybeReplace again, but this time it passes a valid | ||
| 189 | - // pipeline and passes nullptr to dict_updates. In this mode, | ||
| 190 | - // the stream dictionary has already been altered, and the | ||
| 191 | - // original stream data is no longer directly accessible. Trying | ||
| 192 | - // to retrieve the stream data would cause an infinite loop because | ||
| 193 | - // it would just end up calling provideStreamData again. This is | ||
| 194 | - // why maybeReplace uses a stashed copy of the original stream. | ||
| 195 | - | ||
| 196 | - // Additional explanation can be found in the method | ||
| 197 | - // implementations. | 162 | + // * provideStreamData(), which is called by QPDFWriter during the write process, actually |
| 163 | + // writes the modified stream data. It calls maybeReplace again, but this time it passes a | ||
| 164 | + // valid pipeline and passes nullptr to dict_updates. In this mode, the stream dictionary has | ||
| 165 | + // already been altered, and the original stream data is no longer directly accessible. Trying | ||
| 166 | + // to retrieve the stream data would cause an infinite loop because it would just end up | ||
| 167 | + // calling provideStreamData again. This is why maybeReplace uses a stashed copy of the | ||
| 168 | + // original stream. | ||
| 169 | + | ||
| 170 | + // Additional explanation can be found in the method implementations. | ||
| 198 | 171 | ||
| 199 | public: | 172 | public: |
| 200 | StreamReplacer(QPDF* pdf); | 173 | StreamReplacer(QPDF* pdf); |
| @@ -211,17 +184,16 @@ class StreamReplacer: public QPDFObjectHandle::StreamDataProvider | @@ -211,17 +184,16 @@ class StreamReplacer: public QPDFObjectHandle::StreamDataProvider | ||
| 211 | Pipeline* pipeline, | 184 | Pipeline* pipeline, |
| 212 | QPDFObjectHandle* dict_updates); | 185 | QPDFObjectHandle* dict_updates); |
| 213 | 186 | ||
| 214 | - // Hang onto a reference to the QPDF object containing the streams | ||
| 215 | - // we are replacing. We need this to create a new stream. | 187 | + // Hang onto a reference to the QPDF object containing the streams we are replacing. We need |
| 188 | + // this to create a new stream. | ||
| 216 | QPDF* pdf; | 189 | QPDF* pdf; |
| 217 | 190 | ||
| 218 | - // Map the object/generation in original file to the copied stream | ||
| 219 | - // in "other". We use this to retrieve the original data. | 191 | + // Map the object/generation in original file to the copied stream in "other". We use this to |
| 192 | + // retrieve the original data. | ||
| 220 | std::map<QPDFObjGen, QPDFObjectHandle> copied_streams; | 193 | std::map<QPDFObjGen, QPDFObjectHandle> copied_streams; |
| 221 | 194 | ||
| 222 | - // Each stream gets is own "key" for the XOR filter. We use a | ||
| 223 | - // single instance of StreamReplacer for all streams, so stash all | ||
| 224 | - // the keys here. | 195 | + // Each stream gets is own "key" for the XOR filter. We use a single instance of StreamReplacer |
| 196 | + // for all streams, so stash all the keys here. | ||
| 225 | std::map<QPDFObjGen, unsigned char> keys; | 197 | std::map<QPDFObjGen, unsigned char> keys; |
| 226 | }; | 198 | }; |
| 227 | 199 | ||
| @@ -237,49 +209,38 @@ StreamReplacer::maybeReplace( | @@ -237,49 +209,38 @@ StreamReplacer::maybeReplace( | ||
| 237 | Pipeline* pipeline, | 209 | Pipeline* pipeline, |
| 238 | QPDFObjectHandle* dict_updates) | 210 | QPDFObjectHandle* dict_updates) |
| 239 | { | 211 | { |
| 240 | - // As described in the class comments, this method is called | ||
| 241 | - // twice. Before writing has started pipeline is nullptr, and | ||
| 242 | - // dict_updates is provided. In this mode, we figure out whether | ||
| 243 | - // we should replace the stream and, if so, take care of the | ||
| 244 | - // necessary setup. When we are actually ready to supply the data, | ||
| 245 | - // this method is called again with pipeline populated and | ||
| 246 | - // dict_updates as a nullptr. In this mode, we are not allowed to | ||
| 247 | - // change anything, since writing is already in progress. We | ||
| 248 | - // must simply provide the stream data. | ||
| 249 | - | ||
| 250 | - // The return value indicates whether or not we should replace the | ||
| 251 | - // stream. If the first call returns false, there will be no | ||
| 252 | - // second call. If the second call returns false, something went | ||
| 253 | - // wrong since the method should always make the same decision for | ||
| 254 | - // a given stream. | ||
| 255 | - | ||
| 256 | - // For this example, all the determination logic could have | ||
| 257 | - // appeared inside the if (dict_updates) block rather than being | ||
| 258 | - // duplicated, but in some cases, there may be a reason to | ||
| 259 | - // duplicate things. For example, if you wanted to write code that | ||
| 260 | - // re-encoded an image if the new encoding was more efficient, | ||
| 261 | - // you'd have to actually try it out. Then you would either have | ||
| 262 | - // to cache the result somewhere or just repeat the calculations, | ||
| 263 | - // depending on space/time constraints, etc. | ||
| 264 | - | ||
| 265 | - // In our contrived example, we are replacing the data for all | ||
| 266 | - // streams that have /DoXOR = true in the stream dictionary. If | ||
| 267 | - // this were a more realistic application, our criteria would be | ||
| 268 | - // more sensible. For example, an image downsampler might choose | ||
| 269 | - // to replace a stream that represented an image with a high pixel | ||
| 270 | - // density. | 212 | + // As described in the class comments, this method is called twice. Before writing has started |
| 213 | + // pipeline is nullptr, and dict_updates is provided. In this mode, we figure out whether we | ||
| 214 | + // should replace the stream and, if so, take care of the necessary setup. When we are actually | ||
| 215 | + // ready to supply the data, this method is called again with pipeline populated and | ||
| 216 | + // dict_updates as a nullptr. In this mode, we are not allowed to change anything, since writing | ||
| 217 | + // is already in progress. We must simply provide the stream data. | ||
| 218 | + | ||
| 219 | + // The return value indicates whether or not we should replace the stream. If the first call | ||
| 220 | + // returns false, there will be no second call. If the second call returns false, something went | ||
| 221 | + // wrong since the method should always make the same decision for a given stream. | ||
| 222 | + | ||
| 223 | + // For this example, all the determination logic could have appeared inside the if | ||
| 224 | + // (dict_updates) block rather than being duplicated, but in some cases, there may be a reason | ||
| 225 | + // to duplicate things. For example, if you wanted to write code that re-encoded an image if the | ||
| 226 | + // new encoding was more efficient, you'd have to actually try it out. Then you would either | ||
| 227 | + // have to cache the result somewhere or just repeat the calculations, depending on space/time | ||
| 228 | + // constraints, etc. | ||
| 229 | + | ||
| 230 | + // In our contrived example, we are replacing the data for all streams that have /DoXOR = true | ||
| 231 | + // in the stream dictionary. If this were a more realistic application, our criteria would be | ||
| 232 | + // more sensible. For example, an image downsampler might choose to replace a stream that | ||
| 233 | + // represented an image with a high pixel density. | ||
| 271 | auto dict = stream.getDict(); | 234 | auto dict = stream.getDict(); |
| 272 | auto mark = dict.getKey("/DoXOR"); | 235 | auto mark = dict.getKey("/DoXOR"); |
| 273 | if (!(mark.isBool() && mark.getBoolValue())) { | 236 | if (!(mark.isBool() && mark.getBoolValue())) { |
| 274 | return false; | 237 | return false; |
| 275 | } | 238 | } |
| 276 | 239 | ||
| 277 | - // We can't replace the stream data if we can't get the original | ||
| 278 | - // stream data for any reason. A more realistic application may | ||
| 279 | - // actually look at the data here as well, or it may be able to | ||
| 280 | - // make all its decisions from the stream dictionary. However, | ||
| 281 | - // it's a good idea to make sure we can retrieve the filtered data | ||
| 282 | - // if we are going to need it later. | 240 | + // We can't replace the stream data if we can't get the original stream data for any reason. A |
| 241 | + // more realistic application may actually look at the data here as well, or it may be able to | ||
| 242 | + // make all its decisions from the stream dictionary. However, it's a good idea to make sure we | ||
| 243 | + // can retrieve the filtered data if we are going to need it later. | ||
| 283 | std::shared_ptr<Buffer> out; | 244 | std::shared_ptr<Buffer> out; |
| 284 | try { | 245 | try { |
| 285 | out = stream.getStreamData(); | 246 | out = stream.getStreamData(); |
| @@ -288,19 +249,15 @@ StreamReplacer::maybeReplace( | @@ -288,19 +249,15 @@ StreamReplacer::maybeReplace( | ||
| 288 | } | 249 | } |
| 289 | 250 | ||
| 290 | if (dict_updates) { | 251 | if (dict_updates) { |
| 291 | - // It's not safe to make any modifications to any objects | ||
| 292 | - // during the writing process since the updated objects may | ||
| 293 | - // have already been written. In this mode, when dict_updates | ||
| 294 | - // is provided, we have not started writing. Store the | ||
| 295 | - // modifications we intend to make to the stream dictionary | ||
| 296 | - // here. We're just storing /OrigLength for purposes of | ||
| 297 | - // example. Again, a realistic application would make other | ||
| 298 | - // changes. For example, an image resampler might change the | ||
| 299 | - // dimensions or other properties of the image. | 252 | + // It's not safe to make any modifications to any objects during the writing process since |
| 253 | + // the updated objects may have already been written. In this mode, when dict_updates is | ||
| 254 | + // provided, we have not started writing. Store the modifications we intend to make to the | ||
| 255 | + // stream dictionary here. We're just storing /OrigLength for purposes of example. Again, a | ||
| 256 | + // realistic application would make other changes. For example, an image resampler might | ||
| 257 | + // change the dimensions or other properties of the image. | ||
| 300 | dict_updates->replaceKey( | 258 | dict_updates->replaceKey( |
| 301 | "/OrigLength", QPDFObjectHandle::newInteger(QIntC::to_longlong(out->getSize()))); | 259 | "/OrigLength", QPDFObjectHandle::newInteger(QIntC::to_longlong(out->getSize()))); |
| 302 | - // We are also storing the "key" that we will access when | ||
| 303 | - // writing the data. | 260 | + // We are also storing the "key" that we will access when writing the data. |
| 304 | this->keys[og] = QIntC::to_uchar((og.getObj() * QIntC::to_int(out->getSize())) & 0xff); | 261 | this->keys[og] = QIntC::to_uchar((og.getObj() * QIntC::to_int(out->getSize())) & 0xff); |
| 305 | } | 262 | } |
| 306 | 263 | ||
| @@ -319,21 +276,18 @@ StreamReplacer::registerStream( | @@ -319,21 +276,18 @@ StreamReplacer::registerStream( | ||
| 319 | { | 276 | { |
| 320 | QPDFObjGen og(stream.getObjGen()); | 277 | QPDFObjGen og(stream.getObjGen()); |
| 321 | 278 | ||
| 322 | - // We don't need to process a stream more than once. In this | ||
| 323 | - // example, we are just iterating through objects, but if we were | ||
| 324 | - // doing something like iterating through images on pages, we | 279 | + // We don't need to process a stream more than once. In this example, we are just iterating |
| 280 | + // through objects, but if we were doing something like iterating through images on pages, we | ||
| 325 | // might realistically encounter the same stream more than once. | 281 | // might realistically encounter the same stream more than once. |
| 326 | if (this->copied_streams.count(og) > 0) { | 282 | if (this->copied_streams.count(og) > 0) { |
| 327 | return; | 283 | return; |
| 328 | } | 284 | } |
| 329 | - // Store something in copied_streams so that we don't | ||
| 330 | - // double-process even in the negative case. This gets replaced | ||
| 331 | - // later if needed. | 285 | + // Store something in copied_streams so that we don't double-process even in the negative case. |
| 286 | + // This gets replaced later if needed. | ||
| 332 | this->copied_streams[og] = QPDFObjectHandle::newNull(); | 287 | this->copied_streams[og] = QPDFObjectHandle::newNull(); |
| 333 | 288 | ||
| 334 | - // Call maybeReplace with dict_updates. In this mode, it | ||
| 335 | - // determines whether we should replace the stream data and, if | ||
| 336 | - // so, supplies dictionary updates we should make. | 289 | + // Call maybeReplace with dict_updates. In this mode, it determines whether we should replace |
| 290 | + // the stream data and, if so, supplies dictionary updates we should make. | ||
| 337 | bool should_replace = false; | 291 | bool should_replace = false; |
| 338 | QPDFObjectHandle dict_updates = QPDFObjectHandle::newDictionary(); | 292 | QPDFObjectHandle dict_updates = QPDFObjectHandle::newDictionary(); |
| 339 | try { | 293 | try { |
| @@ -343,9 +297,8 @@ StreamReplacer::registerStream( | @@ -343,9 +297,8 @@ StreamReplacer::registerStream( | ||
| 343 | } | 297 | } |
| 344 | 298 | ||
| 345 | if (should_replace) { | 299 | if (should_replace) { |
| 346 | - // Copy the stream so we can get to the original data from the | ||
| 347 | - // stream data provider. This doesn't actually copy any data, | ||
| 348 | - // but the copy retains the original stream data after the | 300 | + // Copy the stream so we can get to the original data from the stream data provider. This |
| 301 | + // doesn't actually copy any data, but the copy retains the original stream data after the | ||
| 349 | // original one is modified. | 302 | // original one is modified. |
| 350 | this->copied_streams[og] = stream.copyStream(); | 303 | this->copied_streams[og] = stream.copyStream(); |
| 351 | // Update the stream dictionary with any changes. | 304 | // Update the stream dictionary with any changes. |
| @@ -353,20 +306,17 @@ StreamReplacer::registerStream( | @@ -353,20 +306,17 @@ StreamReplacer::registerStream( | ||
| 353 | for (auto const& k: dict_updates.getKeys()) { | 306 | for (auto const& k: dict_updates.getKeys()) { |
| 354 | dict.replaceKey(k, dict_updates.getKey(k)); | 307 | dict.replaceKey(k, dict_updates.getKey(k)); |
| 355 | } | 308 | } |
| 356 | - // Create the key stream that will be referenced from | ||
| 357 | - // /DecodeParms. We have to do this now since you can't modify | ||
| 358 | - // or create objects during write. | 309 | + // Create the key stream that will be referenced from /DecodeParms. We have to do this now |
| 310 | + // since you can't modify or create objects during write. | ||
| 359 | char p[1] = {static_cast<char>(this->keys[og])}; | 311 | char p[1] = {static_cast<char>(this->keys[og])}; |
| 360 | std::string p_str(p, 1); | 312 | std::string p_str(p, 1); |
| 361 | QPDFObjectHandle dp_stream = this->pdf->newStream(p_str); | 313 | QPDFObjectHandle dp_stream = this->pdf->newStream(p_str); |
| 362 | - // Create /DecodeParms as expected by our fictitious | ||
| 363 | - // /XORDecode filter. | 314 | + // Create /DecodeParms as expected by our fictitious /XORDecode filter. |
| 364 | QPDFObjectHandle decode_parms = | 315 | QPDFObjectHandle decode_parms = |
| 365 | QPDFObjectHandle::newDictionary({{"/KeyStream", dp_stream}}); | 316 | QPDFObjectHandle::newDictionary({{"/KeyStream", dp_stream}}); |
| 366 | stream.replaceStreamData(self, QPDFObjectHandle::newName("/XORDecode"), decode_parms); | 317 | stream.replaceStreamData(self, QPDFObjectHandle::newName("/XORDecode"), decode_parms); |
| 367 | - // Further, if /ProtectXOR = true, we disable filtering on write | ||
| 368 | - // so that QPDFWriter will not decode the stream even though we | ||
| 369 | - // have registered a stream filter for /XORDecode. | 318 | + // Further, if /ProtectXOR = true, we disable filtering on write so that QPDFWriter will not |
| 319 | + // decode the stream even though we have registered a stream filter for /XORDecode. | ||
| 370 | auto protect = dict.getKey("/ProtectXOR"); | 320 | auto protect = dict.getKey("/ProtectXOR"); |
| 371 | if (protect.isBool() && protect.getBoolValue()) { | 321 | if (protect.isBool() && protect.getBoolValue()) { |
| 372 | stream.setFilterOnWrite(false); | 322 | stream.setFilterOnWrite(false); |
| @@ -378,14 +328,12 @@ void | @@ -378,14 +328,12 @@ void | ||
| 378 | StreamReplacer::provideStreamData(QPDFObjGen const& og, Pipeline* pipeline) | 328 | StreamReplacer::provideStreamData(QPDFObjGen const& og, Pipeline* pipeline) |
| 379 | { | 329 | { |
| 380 | QPDFObjectHandle orig = this->copied_streams[og]; | 330 | QPDFObjectHandle orig = this->copied_streams[og]; |
| 381 | - // call maybeReplace again, this time with the pipeline and no | ||
| 382 | - // dict_updates. In this mode, maybeReplace doesn't make any | ||
| 383 | - // changes. We have to hand it the original stream data, which we | 331 | + // call maybeReplace again, this time with the pipeline and no dict_updates. In this mode, |
| 332 | + // maybeReplace doesn't make any changes. We have to hand it the original stream data, which we | ||
| 384 | // get from copied_streams. | 333 | // get from copied_streams. |
| 385 | if (!maybeReplace(og, orig, pipeline, nullptr)) { | 334 | if (!maybeReplace(og, orig, pipeline, nullptr)) { |
| 386 | - // Since this only gets called for streams we already | ||
| 387 | - // determined we are replacing, a false return would indicate | ||
| 388 | - // a logic error. | 335 | + // Since this only gets called for streams we already determined we are replacing, a false |
| 336 | + // return would indicate a logic error. | ||
| 389 | throw std::logic_error("should_replace return false in provideStreamData"); | 337 | throw std::logic_error("should_replace return false in provideStreamData"); |
| 390 | } | 338 | } |
| 391 | } | 339 | } |
| @@ -396,17 +344,15 @@ process(char const* infilename, char const* outfilename, bool decode_specialized | @@ -396,17 +344,15 @@ process(char const* infilename, char const* outfilename, bool decode_specialized | ||
| 396 | QPDF qpdf; | 344 | QPDF qpdf; |
| 397 | qpdf.processFile(infilename); | 345 | qpdf.processFile(infilename); |
| 398 | 346 | ||
| 399 | - // Create a single StreamReplacer instance. The interface requires | ||
| 400 | - // a std::shared_ptr in various places, so allocate a StreamReplacer | ||
| 401 | - // and stash it in a std::shared_ptr. | 347 | + // Create a single StreamReplacer instance. The interface requires a std::shared_ptr in various |
| 348 | + // places, so allocate a StreamReplacer and stash it in a std::shared_ptr. | ||
| 402 | auto* replacer = new StreamReplacer(&qpdf); | 349 | auto* replacer = new StreamReplacer(&qpdf); |
| 403 | std::shared_ptr<QPDFObjectHandle::StreamDataProvider> p(replacer); | 350 | std::shared_ptr<QPDFObjectHandle::StreamDataProvider> p(replacer); |
| 404 | 351 | ||
| 405 | for (auto& o: qpdf.getAllObjects()) { | 352 | for (auto& o: qpdf.getAllObjects()) { |
| 406 | if (o.isStream()) { | 353 | if (o.isStream()) { |
| 407 | - // Call registerStream for every stream. Only ones that | ||
| 408 | - // registerStream decides to replace will actually be | ||
| 409 | - // replaced. | 354 | + // Call registerStream for every stream. Only ones that registerStream decides to |
| 355 | + // replace will actually be replaced. | ||
| 410 | replacer->registerStream(o, p); | 356 | replacer->registerStream(o, p); |
| 411 | } | 357 | } |
| 412 | } | 358 | } |
| @@ -454,9 +400,8 @@ main(int argc, char* argv[]) | @@ -454,9 +400,8 @@ main(int argc, char* argv[]) | ||
| 454 | } | 400 | } |
| 455 | 401 | ||
| 456 | try { | 402 | try { |
| 457 | - // Register our fictitious filter. This enables QPDFWriter to | ||
| 458 | - // decode our streams. This is not a real filter, so no real | ||
| 459 | - // PDF reading application would be able to interpret it. This | 403 | + // Register our fictitious filter. This enables QPDFWriter to decode our streams. This is |
| 404 | + // not a real filter, so no real PDF reading application would be able to interpret it. This | ||
| 460 | // is just for illustrative purposes. | 405 | // is just for illustrative purposes. |
| 461 | QPDF::registerStreamFilter("/XORDecode", [] { return std::make_shared<SF_XORDecode>(); }); | 406 | QPDF::registerStreamFilter("/XORDecode", [] { return std::make_shared<SF_XORDecode>(); }); |
| 462 | // Do the actual processing. | 407 | // Do the actual processing. |
examples/pdf-double-page-size.cc
| @@ -14,18 +14,16 @@ void | @@ -14,18 +14,16 @@ void | ||
| 14 | usage() | 14 | usage() |
| 15 | { | 15 | { |
| 16 | std::cerr << "Usage: " << whoami << " infile.pdf outfile.pdf [in-password]" << std::endl | 16 | std::cerr << "Usage: " << whoami << " infile.pdf outfile.pdf [in-password]" << std::endl |
| 17 | - << "Double size of all pages in infile.pdf;" | ||
| 18 | - << " write output to outfile.pdf" << std::endl; | 17 | + << "Double size of all pages in infile.pdf; write output to outfile.pdf" << std::endl; |
| 19 | exit(2); | 18 | exit(2); |
| 20 | } | 19 | } |
| 21 | 20 | ||
| 22 | -// If there is a box of name box_name, replace it with a new box whose | ||
| 23 | -// elements are double the values of the original box. | 21 | +// If there is a box of name box_name, replace it with a new box whose elements are double the |
| 22 | +// values of the original box. | ||
| 24 | static void | 23 | static void |
| 25 | doubleBoxSize(QPDFPageObjectHelper& page, char const* box_name) | 24 | doubleBoxSize(QPDFPageObjectHelper& page, char const* box_name) |
| 26 | { | 25 | { |
| 27 | - // We need to use getAttribute rather than getKey as some boxes could | ||
| 28 | - // be inherited. | 26 | + // We need to use getAttribute rather than getKey as some boxes could be inherited. |
| 29 | auto box = page.getAttribute(box_name, true); | 27 | auto box = page.getAttribute(box_name, true); |
| 30 | if (box.isNull()) { | 28 | if (box.isNull()) { |
| 31 | return; | 29 | return; |
examples/pdf-filter-tokens.cc
| 1 | // | 1 | // |
| 2 | -// This example illustrates the use of QPDFObjectHandle::TokenFilter | ||
| 3 | -// with addContentTokenFilter. Please see comments inline for details. | ||
| 4 | -// See also pdf-count-strings.cc for a use of | 2 | +// This example illustrates the use of QPDFObjectHandle::TokenFilter with addContentTokenFilter. |
| 3 | +// Please see comments inline for details. See also pdf-count-strings.cc for a use of | ||
| 5 | // QPDFObjectHandle::TokenFilter with filterContents. | 4 | // QPDFObjectHandle::TokenFilter with filterContents. |
| 6 | // | 5 | // |
| 7 | 6 | ||
| @@ -26,9 +25,8 @@ usage() | @@ -26,9 +25,8 @@ usage() | ||
| 26 | exit(2); | 25 | exit(2); |
| 27 | } | 26 | } |
| 28 | 27 | ||
| 29 | -// The StringReverser class is a trivial example of using a token | ||
| 30 | -// filter. This class only overrides the pure virtual handleToken | ||
| 31 | -// function and preserves the default handleEOF function. | 28 | +// The StringReverser class is a trivial example of using a token filter. This class only overrides |
| 29 | +// the pure virtual handleToken function and preserves the default handleEOF function. | ||
| 32 | class StringReverser: public QPDFObjectHandle::TokenFilter | 30 | class StringReverser: public QPDFObjectHandle::TokenFilter |
| 33 | { | 31 | { |
| 34 | public: | 32 | public: |
| @@ -39,15 +37,12 @@ class StringReverser: public QPDFObjectHandle::TokenFilter | @@ -39,15 +37,12 @@ class StringReverser: public QPDFObjectHandle::TokenFilter | ||
| 39 | void | 37 | void |
| 40 | StringReverser::handleToken(QPDFTokenizer::Token const& token) | 38 | StringReverser::handleToken(QPDFTokenizer::Token const& token) |
| 41 | { | 39 | { |
| 42 | - // For string tokens, reverse the characters. For other tokens, | ||
| 43 | - // just pass them through. Notice that we construct a new string | ||
| 44 | - // token and write that, thus allowing the library to handle any | ||
| 45 | - // subtleties about properly encoding unprintable characters. This | ||
| 46 | - // function doesn't handle multibyte characters at all. It's not | ||
| 47 | - // intended to be an example of the correct way to reverse | ||
| 48 | - // strings. It's just intended to give a simple example of a | ||
| 49 | - // pretty minimal filter and to show an example of writing a | ||
| 50 | - // constructed token. | 40 | + // For string tokens, reverse the characters. For other tokens, just pass them through. Notice |
| 41 | + // that we construct a new string token and write that, thus allowing the library to handle any | ||
| 42 | + // subtleties about properly encoding unprintable characters. This function doesn't handle | ||
| 43 | + // multibyte characters at all. It's not intended to be an example of the correct way to reverse | ||
| 44 | + // strings. It's just intended to give a simple example of a pretty minimal filter and to show | ||
| 45 | + // an example of writing a constructed token. | ||
| 51 | if (token.getType() == QPDFTokenizer::tt_string) { | 46 | if (token.getType() == QPDFTokenizer::tt_string) { |
| 52 | std::string value = token.getValue(); | 47 | std::string value = token.getValue(); |
| 53 | std::reverse(value.begin(), value.end()); | 48 | std::reverse(value.begin(), value.end()); |
| @@ -57,9 +52,8 @@ StringReverser::handleToken(QPDFTokenizer::Token const& token) | @@ -57,9 +52,8 @@ StringReverser::handleToken(QPDFTokenizer::Token const& token) | ||
| 57 | } | 52 | } |
| 58 | } | 53 | } |
| 59 | 54 | ||
| 60 | -// The ColorToGray filter finds all "rg" operators in the content | ||
| 61 | -// stream and replaces them with "g" operators, thus mapping color to | ||
| 62 | -// grayscale. Note that it only applies to content streams, not | 55 | +// The ColorToGray filter finds all "rg" operators in the content stream and replaces them with "g" |
| 56 | +// operators, thus mapping color to grayscale. Note that it only applies to content streams, not | ||
| 63 | // images, so this will not replace color images with grayscale | 57 | // images, so this will not replace color images with grayscale |
| 64 | // images. | 58 | // images. |
| 65 | class ColorToGray: public QPDFObjectHandle::TokenFilter | 59 | class ColorToGray: public QPDFObjectHandle::TokenFilter |
| @@ -99,29 +93,23 @@ ColorToGray::numericValue(QPDFTokenizer::Token const& token) | @@ -99,29 +93,23 @@ ColorToGray::numericValue(QPDFTokenizer::Token const& token) | ||
| 99 | void | 93 | void |
| 100 | ColorToGray::handleToken(QPDFTokenizer::Token const& token) | 94 | ColorToGray::handleToken(QPDFTokenizer::Token const& token) |
| 101 | { | 95 | { |
| 102 | - // Track the number of non-ignorable tokens we've seen. If we see | ||
| 103 | - // an "rg" following three numbers, convert it to a grayscale | ||
| 104 | - // value. Keep writing tokens to the output as we can. | ||
| 105 | - | ||
| 106 | - // There are several things to notice here. We keep two stacks: | ||
| 107 | - // one of "meaningful" tokens, and one of all tokens. This way we | ||
| 108 | - // can preserve whitespace or comments that we encounter in the | ||
| 109 | - // stream and there preserve layout. As we receive tokens, we keep | ||
| 110 | - // the last four meaningful tokens. If we see three numbers | ||
| 111 | - // followed by rg, we use the three numbers to calculate a gray | ||
| 112 | - // value that is perceptually similar to the color value and then | ||
| 113 | - // write the "g" operator to the output, discarding any spaces or | ||
| 114 | - // comments encountered embedded in the "rg" operator. | ||
| 115 | - | ||
| 116 | - // The stack and all_stack members are updated in such a way that | ||
| 117 | - // they always contain exactly the same non-ignorable tokens. The | ||
| 118 | - // stack member contains the tokens that would be left if you | 96 | + // Track the number of non-ignorable tokens we've seen. If we see an "rg" following three |
| 97 | + // numbers, convert it to a grayscale value. Keep writing tokens to the output as we can. | ||
| 98 | + | ||
| 99 | + // There are several things to notice here. We keep two stacks: one of "meaningful" tokens, and | ||
| 100 | + // one of all tokens. This way we can preserve whitespace or comments that we encounter in the | ||
| 101 | + // stream and there preserve layout. As we receive tokens, we keep the last four meaningful | ||
| 102 | + // tokens. If we see three numbers followed by rg, we use the three numbers to calculate a gray | ||
| 103 | + // value that is perceptually similar to the color value and then write the "g" operator to the | ||
| 104 | + // output, discarding any spaces or comments encountered embedded in the "rg" operator. | ||
| 105 | + | ||
| 106 | + // The stack and all_stack members are updated in such a way that they always contain exactly | ||
| 107 | + // the same non-ignorable tokens. The stack member contains the tokens that would be left if you | ||
| 119 | // removed all space and comment tokens from all_stack. | 108 | // removed all space and comment tokens from all_stack. |
| 120 | 109 | ||
| 121 | - // On each new token, flush out any space or comment tokens. Store | ||
| 122 | - // the incoming token. If we just got an rg preceded by the right | ||
| 123 | - // kinds of operands, replace the command. Flush any additional | ||
| 124 | - // accumulated tokens to keep the stack only four tokens deep. | 110 | + // On each new token, flush out any space or comment tokens. Store the incoming token. If we |
| 111 | + // just got an rg preceded by the right kinds of operands, replace the command. Flush any | ||
| 112 | + // additional accumulated tokens to keep the stack only four tokens deep. | ||
| 125 | 113 | ||
| 126 | while ((!this->all_stack.empty()) && isIgnorable(this->all_stack.at(0).getType())) { | 114 | while ((!this->all_stack.empty()) && isIgnorable(this->all_stack.at(0).getType())) { |
| 127 | writeToken(this->all_stack.at(0)); | 115 | writeToken(this->all_stack.at(0)); |
| @@ -182,11 +170,9 @@ main(int argc, char* argv[]) | @@ -182,11 +170,9 @@ main(int argc, char* argv[]) | ||
| 182 | QPDF pdf; | 170 | QPDF pdf; |
| 183 | pdf.processFile(infilename); | 171 | pdf.processFile(infilename); |
| 184 | for (auto& page: QPDFPageDocumentHelper(pdf).getAllPages()) { | 172 | for (auto& page: QPDFPageDocumentHelper(pdf).getAllPages()) { |
| 185 | - // Attach two token filters to each page of this file. | ||
| 186 | - // When the file is written, or when the pages' contents | ||
| 187 | - // are retrieved in any other way, the filters will be | ||
| 188 | - // applied. See comments on the filters for additional | ||
| 189 | - // details. | 173 | + // Attach two token filters to each page of this file. When the file is written, or when |
| 174 | + // the pages' contents are retrieved in any other way, the filters will be applied. See | ||
| 175 | + // comments on the filters for additional details. | ||
| 190 | page.addContentTokenFilter( | 176 | page.addContentTokenFilter( |
| 191 | std::shared_ptr<QPDFObjectHandle::TokenFilter>(new StringReverser)); | 177 | std::shared_ptr<QPDFObjectHandle::TokenFilter>(new StringReverser)); |
| 192 | page.addContentTokenFilter( | 178 | page.addContentTokenFilter( |
examples/pdf-invert-images.cc
| @@ -20,15 +20,12 @@ usage() | @@ -20,15 +20,12 @@ usage() | ||
| 20 | exit(2); | 20 | exit(2); |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | -// Derive a class from StreamDataProvider to provide updated stream | ||
| 24 | -// data. The main purpose of using this object is to avoid having to | ||
| 25 | -// allocate memory up front for the objects. We want to replace the | ||
| 26 | -// stream data with a function of the original stream data. In order | ||
| 27 | -// to do this without actually holding all the images in memory, we | ||
| 28 | -// create copies of the streams. Copying the streams doesn't actually | ||
| 29 | -// copy the data. Internally, the qpdf library is holding onto the | ||
| 30 | -// location of the original stream data, which makes it possible for | ||
| 31 | -// the StreamDataProvider to access it when it needs it. | 23 | +// Derive a class from StreamDataProvider to provide updated stream data. The main purpose of using |
| 24 | +// this object is to avoid having to allocate memory up front for the objects. We want to replace | ||
| 25 | +// the stream data with a function of the original stream data. In order to do this without actually | ||
| 26 | +// holding all the images in memory, we create copies of the streams. Copying the streams doesn't | ||
| 27 | +// actually copy the data. Internally, the qpdf library is holding onto the location of the original | ||
| 28 | +// stream data, which makes it possible for the StreamDataProvider to access it when it needs it. | ||
| 32 | class ImageInverter: public QPDFObjectHandle::StreamDataProvider | 29 | class ImageInverter: public QPDFObjectHandle::StreamDataProvider |
| 33 | { | 30 | { |
| 34 | public: | 31 | public: |
| @@ -46,42 +43,35 @@ void | @@ -46,42 +43,35 @@ void | ||
| 46 | ImageInverter::registerImage( | 43 | ImageInverter::registerImage( |
| 47 | QPDFObjectHandle image, std::shared_ptr<QPDFObjectHandle::StreamDataProvider> self) | 44 | QPDFObjectHandle image, std::shared_ptr<QPDFObjectHandle::StreamDataProvider> self) |
| 48 | { | 45 | { |
| 49 | - // replaceStreamData requires a pointer holder to the stream data | ||
| 50 | - // provider, but there's no way for us to generate one ourselves, | ||
| 51 | - // so we have to have it handed to us. Don't be tempted to have | ||
| 52 | - // the class contain a std::shared_ptr to itself as a member. Doing | ||
| 53 | - // this will prevent the class from ever being deleted since the | ||
| 54 | - // reference count will never drop to zero (and std::shared_ptr | ||
| 55 | - // doesn't have weak references). | 46 | + // replaceStreamData requires a pointer holder to the stream data provider, but there's no way |
| 47 | + // for us to generate one ourselves, so we have to have it handed to us. Don't be tempted to | ||
| 48 | + // have the class contain a std::shared_ptr to itself as a member. Doing this will prevent the | ||
| 49 | + // class from ever being deleted since the reference count will never drop to zero (and | ||
| 50 | + // std::shared_ptr doesn't have weak references). | ||
| 56 | 51 | ||
| 57 | QPDFObjGen og(image.getObjGen()); | 52 | QPDFObjGen og(image.getObjGen()); |
| 58 | - // Store information about the images based on the object and | ||
| 59 | - // generation number. Recall that a single image object may be | ||
| 60 | - // used more than once, so no need to update the same stream | ||
| 61 | - // multiple times. | 53 | + // Store information about the images based on the object and generation number. Recall that a |
| 54 | + // single image object may be used more than once, so no need to update the same stream multiple | ||
| 55 | + // times. | ||
| 62 | if (this->copied_images.count(og) > 0) { | 56 | if (this->copied_images.count(og) > 0) { |
| 63 | return; | 57 | return; |
| 64 | } | 58 | } |
| 65 | this->copied_images[og] = image.copyStream(); | 59 | this->copied_images[og] = image.copyStream(); |
| 66 | 60 | ||
| 67 | - // Register our stream data provider for this stream. Future calls | ||
| 68 | - // to getStreamData or pipeStreamData will use the new | ||
| 69 | - // information. Provide null for both filter and decode | ||
| 70 | - // parameters. Note that this does not mean the image data will be | ||
| 71 | - // uncompressed when we write the file. By default, QPDFWriter | ||
| 72 | - // will use /FlateDecode for anything that is uncompressed or | ||
| 73 | - // filterable in the input QPDF object, so we don't have to deal | ||
| 74 | - // with it explicitly here. We could explicitly use /DCTDecode and | ||
| 75 | - // write through a DCT filter if we wanted. | 61 | + // Register our stream data provider for this stream. Future calls to getStreamData or |
| 62 | + // pipeStreamData will use the new information. Provide null for both filter and decode | ||
| 63 | + // parameters. Note that this does not mean the image data will be uncompressed when we write | ||
| 64 | + // the file. By default, QPDFWriter will use /FlateDecode for anything that is uncompressed or | ||
| 65 | + // filterable in the input QPDF object, so we don't have to deal with it explicitly here. We | ||
| 66 | + // could explicitly use /DCTDecode and write through a DCT filter if we wanted. | ||
| 76 | image.replaceStreamData(self, QPDFObjectHandle::newNull(), QPDFObjectHandle::newNull()); | 67 | image.replaceStreamData(self, QPDFObjectHandle::newNull(), QPDFObjectHandle::newNull()); |
| 77 | } | 68 | } |
| 78 | 69 | ||
| 79 | void | 70 | void |
| 80 | ImageInverter::provideStreamData(QPDFObjGen const& og, Pipeline* pipeline) | 71 | ImageInverter::provideStreamData(QPDFObjGen const& og, Pipeline* pipeline) |
| 81 | { | 72 | { |
| 82 | - // Use the object and generation number supplied to look up the | ||
| 83 | - // image data. Then invert the image data and write the inverted | ||
| 84 | - // data to the pipeline. | 73 | + // Use the object and generation number supplied to look up the image data. Then invert the |
| 74 | + // image data and write the inverted data to the pipeline. | ||
| 85 | std::shared_ptr<Buffer> data = this->copied_images[og].getStreamData(qpdf_dl_all); | 75 | std::shared_ptr<Buffer> data = this->copied_images[og].getStreamData(qpdf_dl_all); |
| 86 | size_t size = data->getSize(); | 76 | size_t size = data->getSize(); |
| 87 | unsigned char* buf = data->getBuffer(); | 77 | unsigned char* buf = data->getBuffer(); |
| @@ -130,11 +120,9 @@ main(int argc, char* argv[]) | @@ -130,11 +120,9 @@ main(int argc, char* argv[]) | ||
| 130 | QPDFObjectHandle color_space = image_dict.getKey("/ColorSpace"); | 120 | QPDFObjectHandle color_space = image_dict.getKey("/ColorSpace"); |
| 131 | QPDFObjectHandle bits_per_component = image_dict.getKey("/BitsPerComponent"); | 121 | QPDFObjectHandle bits_per_component = image_dict.getKey("/BitsPerComponent"); |
| 132 | 122 | ||
| 133 | - // For our example, we can only work with images 8-bit | ||
| 134 | - // grayscale images that we can fully decode. Use | ||
| 135 | - // pipeStreamData with a null pipeline to determine | ||
| 136 | - // whether the image is filterable. Directly inspect | ||
| 137 | - // keys to determine the image type. | 123 | + // For our example, we can only work with images 8-bit grayscale images that we can |
| 124 | + // fully decode. Use pipeStreamData with a null pipeline to determine whether the | ||
| 125 | + // image is filterable. Directly inspect keys to determine the image type. | ||
| 138 | if (image.pipeStreamData(nullptr, qpdf_ef_compress, qpdf_dl_all) && | 126 | if (image.pipeStreamData(nullptr, qpdf_ef_compress, qpdf_dl_all) && |
| 139 | color_space.isNameAndEquals("/DeviceGray") && bits_per_component.isInteger() && | 127 | color_space.isNameAndEquals("/DeviceGray") && bits_per_component.isInteger() && |
| 140 | (bits_per_component.getIntValue() == 8)) { | 128 | (bits_per_component.getIntValue() == 8)) { |
| @@ -146,8 +134,7 @@ main(int argc, char* argv[]) | @@ -146,8 +134,7 @@ main(int argc, char* argv[]) | ||
| 146 | // Write out a new file | 134 | // Write out a new file |
| 147 | QPDFWriter w(qpdf, outfilename); | 135 | QPDFWriter w(qpdf, outfilename); |
| 148 | if (static_id) { | 136 | if (static_id) { |
| 149 | - // For the test suite, uncompress streams and use static | ||
| 150 | - // IDs. | 137 | + // For the test suite, uncompress streams and use static IDs. |
| 151 | w.setStaticID(true); // for testing only | 138 | w.setStaticID(true); // for testing only |
| 152 | } | 139 | } |
| 153 | w.write(); | 140 | w.write(); |
examples/pdf-linearize.c
| @@ -51,8 +51,7 @@ main(int argc, char* argv[]) | @@ -51,8 +51,7 @@ main(int argc, char* argv[]) | ||
| 51 | 51 | ||
| 52 | if (((qpdf_read(qpdf, infile, password) & QPDF_ERRORS) == 0) && | 52 | if (((qpdf_read(qpdf, infile, password) & QPDF_ERRORS) == 0) && |
| 53 | ((qpdf_init_write(qpdf, outfile) & QPDF_ERRORS) == 0)) { | 53 | ((qpdf_init_write(qpdf, outfile) & QPDF_ERRORS) == 0)) { |
| 54 | - /* Use static ID for testing only. For production, a | ||
| 55 | - * non-static ID is used. See also | 54 | + /* Use static ID for testing only. For production, a non-static ID is used. See also |
| 56 | * qpdf_set_deterministic_ID. */ | 55 | * qpdf_set_deterministic_ID. */ |
| 57 | qpdf_set_static_ID(qpdf, QPDF_TRUE); /* for testing only */ | 56 | qpdf_set_static_ID(qpdf, QPDF_TRUE); /* for testing only */ |
| 58 | qpdf_set_linearization(qpdf, QPDF_TRUE); | 57 | qpdf_set_linearization(qpdf, QPDF_TRUE); |
examples/pdf-name-number-tree.cc
| @@ -29,24 +29,19 @@ main(int argc, char* argv[]) | @@ -29,24 +29,19 @@ main(int argc, char* argv[]) | ||
| 29 | QPDF qpdf; | 29 | QPDF qpdf; |
| 30 | qpdf.emptyPDF(); | 30 | qpdf.emptyPDF(); |
| 31 | 31 | ||
| 32 | - // This example doesn't do anything particularly useful other than | ||
| 33 | - // just illustrate how to use the APIs for name and number trees. | ||
| 34 | - // It also demonstrates use of the iterators for dictionaries and | ||
| 35 | - // arrays introduced at the same time with qpdf 10.2. | ||
| 36 | - | ||
| 37 | - // To use this example, compile it and run it. Study the output | ||
| 38 | - // and compare it to what you expect. When done, look at the | ||
| 39 | - // generated output file in a text editor to inspect the structure | ||
| 40 | - // of the trees as left in the file. | ||
| 41 | - | ||
| 42 | - // We're just going to create some name and number trees, hang | ||
| 43 | - // them off the document catalog (root), and write an empty PDF to | ||
| 44 | - // a file. The PDF will have no pages and won't be viewable, but | ||
| 45 | - // you can look at it in a text editor to see the resulting | ||
| 46 | - // structure of the PDF. | ||
| 47 | - | ||
| 48 | - // Create a dictionary off the root where we will hang our name | ||
| 49 | - // and number tree. | 32 | + // This example doesn't do anything particularly useful other than just illustrate how to use |
| 33 | + // the APIs for name and number trees. It also demonstrates use of the iterators for | ||
| 34 | + // dictionaries and arrays introduced at the same time with qpdf 10.2. | ||
| 35 | + | ||
| 36 | + // To use this example, compile it and run it. Study the output and compare it to what you | ||
| 37 | + // expect. When done, look at the generated output file in a text editor to inspect the | ||
| 38 | + // structure of the trees as left in the file. | ||
| 39 | + | ||
| 40 | + // We're just going to create some name and number trees, hang them off the document catalog | ||
| 41 | + // (root), and write an empty PDF to a file. The PDF will have no pages and won't be viewable, | ||
| 42 | + // but you can look at it in a text editor to see the resulting structure of the PDF. | ||
| 43 | + | ||
| 44 | + // Create a dictionary off the root where we will hang our name and number tree. | ||
| 50 | auto root = qpdf.getRoot(); | 45 | auto root = qpdf.getRoot(); |
| 51 | auto example = QPDFObjectHandle::newDictionary(); | 46 | auto example = QPDFObjectHandle::newDictionary(); |
| 52 | root.replaceKey("/Example", example); | 47 | root.replaceKey("/Example", example); |
| @@ -75,8 +70,8 @@ main(int argc, char* argv[]) | @@ -75,8 +70,8 @@ main(int argc, char* argv[]) | ||
| 75 | std::cout << " " << i.first << " -> " << i.second.unparse() << std::endl; | 70 | std::cout << " " << i.first << " -> " << i.second.unparse() << std::endl; |
| 76 | } | 71 | } |
| 77 | 72 | ||
| 78 | - // This is a small tree, so everything will be at the root. We can | ||
| 79 | - // look at it using dictionary and array iterators. | 73 | + // This is a small tree, so everything will be at the root. We can look at it using dictionary |
| 74 | + // and array iterators. | ||
| 80 | std::cout << "Keys in name tree object:" << std::endl; | 75 | std::cout << "Keys in name tree object:" << std::endl; |
| 81 | QPDFObjectHandle names; | 76 | QPDFObjectHandle names; |
| 82 | for (auto const& i: name_tree_oh.ditems()) { | 77 | for (auto const& i: name_tree_oh.ditems()) { |
| @@ -121,15 +116,12 @@ main(int argc, char* argv[]) | @@ -121,15 +116,12 @@ main(int argc, char* argv[]) | ||
| 121 | << std::endl; | 116 | << std::endl; |
| 122 | std::cout << "Has K?: " << name_tree.hasName("K") << std::endl; | 117 | std::cout << "Has K?: " << name_tree.hasName("K") << std::endl; |
| 123 | 118 | ||
| 124 | - // Illustrate some more advanced usage using number trees. These | ||
| 125 | - // calls work for name trees too. | 119 | + // Illustrate some more advanced usage using number trees. These calls work for name trees too. |
| 126 | 120 | ||
| 127 | - // The safe way to populate a tree is to call insert repeatedly as | ||
| 128 | - // above, but if you know you are definitely inserting items in | ||
| 129 | - // order, it is more efficient to insert them using insertAfter, | ||
| 130 | - // which avoids doing a binary search through the tree for each | ||
| 131 | - // insertion. Note that if you don't insert items in order using | ||
| 132 | - // this method, you will create an invalid tree. | 121 | + // The safe way to populate a tree is to call insert repeatedly as above, but if you know you |
| 122 | + // are definitely inserting items in order, it is more efficient to insert them using | ||
| 123 | + // insertAfter, which avoids doing a binary search through the tree for each insertion. Note | ||
| 124 | + // that if you don't insert items in order using this method, you will create an invalid tree. | ||
| 133 | auto number_tree = QPDFNumberTreeObjectHelper::newEmpty(qpdf); | 125 | auto number_tree = QPDFNumberTreeObjectHelper::newEmpty(qpdf); |
| 134 | auto number_tree_oh = number_tree.getObjectHandle(); | 126 | auto number_tree_oh = number_tree.getObjectHandle(); |
| 135 | example.replaceKey("/NumberTree", number_tree_oh); | 127 | example.replaceKey("/NumberTree", number_tree_oh); |
| @@ -149,9 +141,8 @@ main(int argc, char* argv[]) | @@ -149,9 +141,8 @@ main(int argc, char* argv[]) | ||
| 149 | ++n; | 141 | ++n; |
| 150 | } | 142 | } |
| 151 | 143 | ||
| 152 | - // When you remove an item with an iterator, the iterator | ||
| 153 | - // advances. This makes it possible to filter while iterating. | ||
| 154 | - // Remove all items that are multiples of 5. | 144 | + // When you remove an item with an iterator, the iterator advances. This makes it possible to |
| 145 | + // filter while iterating. Remove all items that are multiples of 5. | ||
| 155 | iter2 = number_tree.begin(); | 146 | iter2 = number_tree.begin(); |
| 156 | while (iter2 != number_tree.end()) { | 147 | while (iter2 != number_tree.end()) { |
| 157 | if (iter2->first % 5 == 0) { | 148 | if (iter2->first % 5 == 0) { |
examples/pdf-overlay-page.cc
| @@ -6,10 +6,9 @@ | @@ -6,10 +6,9 @@ | ||
| 6 | #include <cstdlib> | 6 | #include <cstdlib> |
| 7 | #include <iostream> | 7 | #include <iostream> |
| 8 | 8 | ||
| 9 | -// This program demonstrates use of form XObjects to overlay a page | ||
| 10 | -// from one file onto all pages of another file. The qpdf program's | ||
| 11 | -// --overlay and --underlay options provide a more general version of | ||
| 12 | -// this capability. | 9 | +// This program demonstrates use of form XObjects to overlay a page from one file onto all pages of |
| 10 | +// another file. The qpdf program's --overlay and --underlay options provide a more general version | ||
| 11 | +// of this capability. | ||
| 13 | 12 | ||
| 14 | static char const* whoami = nullptr; | 13 | static char const* whoami = nullptr; |
| 15 | 14 | ||
| @@ -44,24 +43,21 @@ stamp_page(char const* infile, char const* stampfile, char const* outfile) | @@ -44,24 +43,21 @@ stamp_page(char const* infile, char const* stampfile, char const* outfile) | ||
| 44 | int min_suffix = 1; | 43 | int min_suffix = 1; |
| 45 | std::string name = resources.getUniqueResourceName("/Fx", min_suffix); | 44 | std::string name = resources.getUniqueResourceName("/Fx", min_suffix); |
| 46 | 45 | ||
| 47 | - // Generate content to place the form XObject centered within | ||
| 48 | - // destination page's trim box. | 46 | + // Generate content to place the form XObject centered within destination page's trim box. |
| 49 | QPDFMatrix m; | 47 | QPDFMatrix m; |
| 50 | std::string content = | 48 | std::string content = |
| 51 | ph.placeFormXObject(stamp_fo, name, ph.getTrimBox().getArrayAsRectangle(), m); | 49 | ph.placeFormXObject(stamp_fo, name, ph.getTrimBox().getArrayAsRectangle(), m); |
| 52 | if (!content.empty()) { | 50 | if (!content.empty()) { |
| 53 | - // Append the content to the page's content. Surround the | ||
| 54 | - // original content with q...Q to the new content from the | ||
| 55 | - // page's original content. | 51 | + // Append the content to the page's content. Surround the original content with q...Q to |
| 52 | + // the new content from the page's original content. | ||
| 56 | resources.mergeResources("<< /XObject << >> >>"_qpdf); | 53 | resources.mergeResources("<< /XObject << >> >>"_qpdf); |
| 57 | resources.getKey("/XObject").replaceKey(name, stamp_fo); | 54 | resources.getKey("/XObject").replaceKey(name, stamp_fo); |
| 58 | ph.addPageContents(inpdf.newStream("q\n"), true); | 55 | ph.addPageContents(inpdf.newStream("q\n"), true); |
| 59 | ph.addPageContents(inpdf.newStream("\nQ\n" + content), false); | 56 | ph.addPageContents(inpdf.newStream("\nQ\n" + content), false); |
| 60 | } | 57 | } |
| 61 | - // Copy the annotations and form fields from the original page | ||
| 62 | - // to the new page. For more efficiency when copying multiple | ||
| 63 | - // pages, we can create a QPDFAcroFormDocumentHelper and pass | ||
| 64 | - // it in. See comments in QPDFPageObjectHelper.hh for details. | 58 | + // Copy the annotations and form fields from the original page to the new page. For more |
| 59 | + // efficiency when copying multiple pages, we can create a QPDFAcroFormDocumentHelper and | ||
| 60 | + // pass it in. See comments in QPDFPageObjectHelper.hh for details. | ||
| 65 | ph.copyAnnotations(stamp_page_1, m); | 61 | ph.copyAnnotations(stamp_page_1, m); |
| 66 | } | 62 | } |
| 67 | 63 |
examples/pdf-parse-content.cc
| @@ -13,8 +13,8 @@ void | @@ -13,8 +13,8 @@ void | ||
| 13 | usage() | 13 | usage() |
| 14 | { | 14 | { |
| 15 | std::cerr << "Usage: " << whoami << " filename page-number" << std::endl | 15 | std::cerr << "Usage: " << whoami << " filename page-number" << std::endl |
| 16 | - << "Prints a dump of the objects in the content streams" | ||
| 17 | - << " of the given page." << std::endl | 16 | + << "Prints a dump of the objects in the content streams of the given page." |
| 17 | + << std::endl | ||
| 18 | << "Pages are numbered from 1." << std::endl; | 18 | << "Pages are numbered from 1." << std::endl; |
| 19 | exit(2); | 19 | exit(2); |
| 20 | } | 20 | } |
examples/pdf-set-form-values.cc
| @@ -29,41 +29,33 @@ main(int argc, char* argv[]) | @@ -29,41 +29,33 @@ main(int argc, char* argv[]) | ||
| 29 | char const* outfilename = argv[2]; | 29 | char const* outfilename = argv[2]; |
| 30 | char const* value = argv[3]; | 30 | char const* value = argv[3]; |
| 31 | 31 | ||
| 32 | - // This is a contrived example that just goes through a file page | ||
| 33 | - // by page and sets the value of any text fields it finds to a | ||
| 34 | - // fixed value as given on the command line. The purpose here is | ||
| 35 | - // to illustrate use of the helper classes around interactive | ||
| 36 | - // forms. | 32 | + // This is a contrived example that just goes through a file page by page and sets the value of |
| 33 | + // any text fields it finds to a fixed value as given on the command line. The purpose here is | ||
| 34 | + // to illustrate use of the helper classes around interactive forms. | ||
| 37 | 35 | ||
| 38 | try { | 36 | try { |
| 39 | QPDF qpdf; | 37 | QPDF qpdf; |
| 40 | qpdf.processFile(infilename); | 38 | qpdf.processFile(infilename); |
| 41 | 39 | ||
| 42 | - // We will iterate through form fields by starting at the page | ||
| 43 | - // level and looking at each field for each page. We could | ||
| 44 | - // also called QPDFAcroFormDocumentHelper::getFormFields to | ||
| 45 | - // iterate at the field level, but doing it as below | ||
| 46 | - // illustrates how we can map from annotations to fields. | 40 | + // We will iterate through form fields by starting at the page level and looking at each |
| 41 | + // field for each page. We could also called QPDFAcroFormDocumentHelper::getFormFields to | ||
| 42 | + // iterate at the field level, but doing it as below illustrates how we can map from | ||
| 43 | + // annotations to fields. | ||
| 47 | 44 | ||
| 48 | QPDFAcroFormDocumentHelper afdh(qpdf); | 45 | QPDFAcroFormDocumentHelper afdh(qpdf); |
| 49 | for (auto const& page: QPDFPageDocumentHelper(qpdf).getAllPages()) { | 46 | for (auto const& page: QPDFPageDocumentHelper(qpdf).getAllPages()) { |
| 50 | - // Get all widget annotations for each page. Widget | ||
| 51 | - // annotations are the ones that contain the details of | ||
| 52 | - // what's in a form field. | 47 | + // Get all widget annotations for each page. Widget annotations are the ones that |
| 48 | + // contain the details of what's in a form field. | ||
| 53 | for (auto& annot: afdh.getWidgetAnnotationsForPage(page)) { | 49 | for (auto& annot: afdh.getWidgetAnnotationsForPage(page)) { |
| 54 | - // For each annotation, find its associated field. If | ||
| 55 | - // it's a text field, set its value. | 50 | + // For each annotation, find its associated field. If it's a text field, set its |
| 51 | + // value. | ||
| 56 | QPDFFormFieldObjectHelper ffh = afdh.getFieldForAnnotation(annot); | 52 | QPDFFormFieldObjectHelper ffh = afdh.getFieldForAnnotation(annot); |
| 57 | if (ffh.getFieldType() == "/Tx") { | 53 | if (ffh.getFieldType() == "/Tx") { |
| 58 | - // Set the value. Passing false as the second | ||
| 59 | - // value prevents qpdf from setting | ||
| 60 | - // /NeedAppearances to true (but will not turn it | ||
| 61 | - // off if it's already on), so we call | ||
| 62 | - // generateAppearance after setting the value. You | ||
| 63 | - // may or may not want to do this depending on | ||
| 64 | - // whether the appearance streams generated by | ||
| 65 | - // qpdf are good enough for your purposes. For | ||
| 66 | - // additional details, please see comments in | 54 | + // Set the value. Passing false as the second value prevents qpdf from setting |
| 55 | + // /NeedAppearances to true (but will not turn it off if it's already on), so we | ||
| 56 | + // call generateAppearance after setting the value. You may or may not want to | ||
| 57 | + // do this depending on whether the appearance streams generated by qpdf are | ||
| 58 | + // good enough for your purposes. For additional details, please see comments in | ||
| 67 | // QPDFFormFieldObjectHelper.hh for this method. | 59 | // QPDFFormFieldObjectHelper.hh for this method. |
| 68 | ffh.setV(value, false); | 60 | ffh.setV(value, false); |
| 69 | ffh.generateAppearance(annot); | 61 | ffh.generateAppearance(annot); |
examples/pdf-split-pages.cc
| 1 | // | 1 | // |
| 2 | -// This is a stand-alone example of splitting a PDF into individual | ||
| 3 | -// pages. It does essentially the same thing that qpdf --split-pages | ||
| 4 | -// does. | 2 | +// This is a stand-alone example of splitting a PDF into individual pages. It does essentially the |
| 3 | +// same thing that qpdf --split-pages does. | ||
| 5 | // | 4 | // |
| 6 | 5 | ||
| 7 | #include <qpdf/QIntC.hh> | 6 | #include <qpdf/QIntC.hh> |
| @@ -32,8 +31,7 @@ process(char const* whoami, char const* infile, std::string outprefix) | @@ -32,8 +31,7 @@ process(char const* whoami, char const* infile, std::string outprefix) | ||
| 32 | QPDFPageDocumentHelper(outpdf).addPage(page, false); | 31 | QPDFPageDocumentHelper(outpdf).addPage(page, false); |
| 33 | QPDFWriter outpdfw(outpdf, outfile.c_str()); | 32 | QPDFWriter outpdfw(outpdf, outfile.c_str()); |
| 34 | if (static_id) { | 33 | if (static_id) { |
| 35 | - // For the test suite, uncompress streams and use static | ||
| 36 | - // IDs. | 34 | + // For the test suite, uncompress streams and use static IDs. |
| 37 | outpdfw.setStaticID(true); // for testing only | 35 | outpdfw.setStaticID(true); // for testing only |
| 38 | outpdfw.setStreamDataMode(qpdf_s_uncompress); | 36 | outpdfw.setStreamDataMode(qpdf_s_uncompress); |
| 39 | } | 37 | } |
examples/qpdf-job.cc
| @@ -3,8 +3,7 @@ | @@ -3,8 +3,7 @@ | ||
| 3 | 3 | ||
| 4 | #include <iostream> | 4 | #include <iostream> |
| 5 | 5 | ||
| 6 | -// This program is a simple demonstration of different ways to use the | ||
| 7 | -// QPDFJob API. | 6 | +// This program is a simple demonstration of different ways to use the QPDFJob API. |
| 8 | 7 | ||
| 9 | static char const* whoami = nullptr; | 8 | static char const* whoami = nullptr; |
| 10 | 9 | ||
| @@ -28,10 +27,9 @@ main(int argc, char* argv[]) | @@ -28,10 +27,9 @@ main(int argc, char* argv[]) | ||
| 28 | usage(); | 27 | usage(); |
| 29 | } | 28 | } |
| 30 | 29 | ||
| 31 | - // The examples below all catch std::exception. Note that | ||
| 32 | - // QPDFUsage can be caught separately to report on errors in using | ||
| 33 | - // the API itself. For CLI, this is command-line usage. For JSON | ||
| 34 | - // or the API, it would be errors from the equivalent invocation. | 30 | + // The examples below all catch std::exception. Note that QPDFUsage can be caught separately to |
| 31 | + // report on errors in using the API itself. For CLI, this is command-line usage. For JSON or | ||
| 32 | + // the API, it would be errors from the equivalent invocation. | ||
| 35 | 33 | ||
| 36 | // Note that staticId is used for testing only. | 34 | // Note that staticId is used for testing only. |
| 37 | 35 |
examples/qpdfjob-c-save-attachment.c
| @@ -6,10 +6,9 @@ | @@ -6,10 +6,9 @@ | ||
| 6 | #include <stdlib.h> | 6 | #include <stdlib.h> |
| 7 | #include <string.h> | 7 | #include <string.h> |
| 8 | 8 | ||
| 9 | -// This example demonstrates how we can redirect where saved output | ||
| 10 | -// goes by calling the default logger's setSave method before running | ||
| 11 | -// something with QPDFJob. See qpdfjob-c-save-attachment.c for an | ||
| 12 | -// implementation that uses the C API. | 9 | +// This example demonstrates how we can redirect where saved output goes by calling the default |
| 10 | +// logger's setSave method before running something with QPDFJob. See qpdfjob-c-save-attachment.c | ||
| 11 | +// for an implementation that uses the C API. | ||
| 13 | 12 | ||
| 14 | static int | 13 | static int |
| 15 | save_to_file(char const* data, size_t len, void* udata) | 14 | save_to_file(char const* data, size_t len, void* udata) |
| @@ -79,9 +78,8 @@ main(int argc, char* argv[]) | @@ -79,9 +78,8 @@ main(int argc, char* argv[]) | ||
| 79 | }; | 78 | }; |
| 80 | outfile = do_fopen(outfilename); | 79 | outfile = do_fopen(outfilename); |
| 81 | 80 | ||
| 82 | - /* Use qpdflogger_set_save with a callback function to redirect | ||
| 83 | - * saved data. You can use other qpdf logger functions to capture | ||
| 84 | - * informational output, warnings, and errors. | 81 | + /* Use qpdflogger_set_save with a callback function to redirect saved data. You can use other |
| 82 | + * qpdf logger functions to capture informational output, warnings, and errors. | ||
| 85 | */ | 83 | */ |
| 86 | qpdflogger_set_save(l, qpdf_log_dest_custom, save_to_file, (void*)outfile, 0); | 84 | qpdflogger_set_save(l, qpdf_log_dest_custom, save_to_file, (void*)outfile, 0); |
| 87 | qpdflogger_cleanup(&l); | 85 | qpdflogger_cleanup(&l); |
examples/qpdfjob-c.c
| 1 | -/* | ||
| 2 | - * This is an example program to linearize a PDF file using the C | ||
| 3 | - * QPDFJob API. | ||
| 4 | - */ | 1 | +/* This is an example program to linearize a PDF file using the C QPDFJob API. */ |
| 5 | 2 | ||
| 6 | #include <qpdf/qpdfjob-c.h> | 3 | #include <qpdf/qpdfjob-c.h> |
| 7 | #include <stdio.h> | 4 | #include <stdio.h> |
| @@ -48,14 +45,12 @@ main(int argc, char* argv[]) | @@ -48,14 +45,12 @@ main(int argc, char* argv[]) | ||
| 48 | new_argv[4] = "--static-id"; /* for testing only */ | 45 | new_argv[4] = "--static-id"; /* for testing only */ |
| 49 | new_argv[5] = NULL; | 46 | new_argv[5] = NULL; |
| 50 | 47 | ||
| 51 | - /* See qpdf-job.cc for a C++ example of using the json interface. | ||
| 52 | - * To use that from C just like the argv one, call | ||
| 53 | - * qpdfjob_run_from_json instead and pass the json string as a | ||
| 54 | - * single char const* argument. | 48 | + /* See qpdf-job.cc for a C++ example of using the json interface. To use that from C just like |
| 49 | + * the argv one, call qpdfjob_run_from_json instead and pass the json string as a single char | ||
| 50 | + * const* argument. | ||
| 55 | * | 51 | * |
| 56 | - * See qpdfjob-c-save-attachment.c for an example of using the | ||
| 57 | - * full form of the qpdfjob interface with init and cleanup | ||
| 58 | - * functions. | 52 | + * See qpdfjob-c-save-attachment.c for an example of using the full form of the qpdfjob |
| 53 | + * interface with init and cleanup functions. | ||
| 59 | */ | 54 | */ |
| 60 | r = qpdfjob_run_from_argv(new_argv); | 55 | r = qpdfjob_run_from_argv(new_argv); |
| 61 | return r; | 56 | return r; |
examples/qpdfjob-remove-annotations.cc
| @@ -6,10 +6,9 @@ | @@ -6,10 +6,9 @@ | ||
| 6 | #include <cstdlib> | 6 | #include <cstdlib> |
| 7 | #include <iostream> | 7 | #include <iostream> |
| 8 | 8 | ||
| 9 | -// This example demonstrates how we can use the QPDFJob createQPDF and writeQPDF | ||
| 10 | -// methods to add custom transformations to the output produced by QPDFJob runs. | ||
| 11 | -// The example is a full copy of the qpdf program modified to allways remove all | ||
| 12 | -// annotations from the final output. | 9 | +// This example demonstrates how we can use the QPDFJob createQPDF and writeQPDF methods to add |
| 10 | +// custom transformations to the output produced by QPDFJob runs. The example is a full copy of the | ||
| 11 | +// qpdf program modified to allways remove all annotations from the final output. | ||
| 13 | 12 | ||
| 14 | static char const* whoami = nullptr; | 13 | static char const* whoami = nullptr; |
| 15 | 14 |
examples/qpdfjob-save-attachment.cc
| @@ -3,10 +3,9 @@ | @@ -3,10 +3,9 @@ | ||
| 3 | #include <qpdf/QPDFLogger.hh> | 3 | #include <qpdf/QPDFLogger.hh> |
| 4 | #include <qpdf/QUtil.hh> | 4 | #include <qpdf/QUtil.hh> |
| 5 | 5 | ||
| 6 | -// This example demonstrates how we can redirect where saved output | ||
| 7 | -// goes by calling the default logger's setSave method before running | ||
| 8 | -// something with QPDFJob. See qpdfjob-c-save-attachment.c for an | ||
| 9 | -// implementation that uses the C API. | 6 | +// This example demonstrates how we can redirect where saved output goes by calling the default |
| 7 | +// logger's setSave method before running something with QPDFJob. See qpdfjob-c-save-attachment.c | ||
| 8 | +// for an implementation that uses the C API. | ||
| 10 | 9 | ||
| 11 | int | 10 | int |
| 12 | main(int argc, char* argv[]) | 11 | main(int argc, char* argv[]) |
include/qpdf/BufferInputSource.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDF_BUFFERINPUTSOURCE_HH | 19 | #ifndef QPDF_BUFFERINPUTSOURCE_HH |
| 23 | #define QPDF_BUFFERINPUTSOURCE_HH | 20 | #define QPDF_BUFFERINPUTSOURCE_HH |
| @@ -28,8 +25,8 @@ | @@ -28,8 +25,8 @@ | ||
| 28 | class QPDF_DLL_CLASS BufferInputSource: public InputSource | 25 | class QPDF_DLL_CLASS BufferInputSource: public InputSource |
| 29 | { | 26 | { |
| 30 | public: | 27 | public: |
| 31 | - // If own_memory is true, BufferInputSource will delete the buffer | ||
| 32 | - // when finished with it. Otherwise, the caller owns the memory. | 28 | + // If own_memory is true, BufferInputSource will delete the buffer when finished with it. |
| 29 | + // Otherwise, the caller owns the memory. | ||
| 33 | QPDF_DLL | 30 | QPDF_DLL |
| 34 | BufferInputSource(std::string const& description, Buffer* buf, bool own_memory = false); | 31 | BufferInputSource(std::string const& description, Buffer* buf, bool own_memory = false); |
| 35 | QPDF_DLL | 32 | QPDF_DLL |
include/qpdf/ClosedFileInputSource.hh
| @@ -2,31 +2,27 @@ | @@ -2,31 +2,27 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDF_CLOSEDFILEINPUTSOURCE_HH | 19 | #ifndef QPDF_CLOSEDFILEINPUTSOURCE_HH |
| 23 | #define QPDF_CLOSEDFILEINPUTSOURCE_HH | 20 | #define QPDF_CLOSEDFILEINPUTSOURCE_HH |
| 24 | 21 | ||
| 25 | -// This is an input source that reads from files, like | ||
| 26 | -// FileInputSource, except that it opens and close the file | ||
| 27 | -// surrounding every operation. This decreases efficiency, but it allows | ||
| 28 | -// many more of these to exist at once than the maximum number of open | ||
| 29 | -// file descriptors. This is used for merging large numbers of files. | 22 | +// This is an input source that reads from files, like FileInputSource, except that it opens and |
| 23 | +// close the file surrounding every operation. This decreases efficiency, but it allows many more of | ||
| 24 | +// these to exist at once than the maximum number of open file descriptors. This is used for merging | ||
| 25 | +// large numbers of files. | ||
| 30 | 26 | ||
| 31 | #include <qpdf/InputSource.hh> | 27 | #include <qpdf/InputSource.hh> |
| 32 | #include <qpdf/PointerHolder.hh> // unused -- remove in qpdf 12 (see #785) | 28 | #include <qpdf/PointerHolder.hh> // unused -- remove in qpdf 12 (see #785) |
| @@ -57,10 +53,9 @@ class QPDF_DLL_CLASS ClosedFileInputSource: public InputSource | @@ -57,10 +53,9 @@ class QPDF_DLL_CLASS ClosedFileInputSource: public InputSource | ||
| 57 | QPDF_DLL | 53 | QPDF_DLL |
| 58 | virtual void unreadCh(char ch); | 54 | virtual void unreadCh(char ch); |
| 59 | 55 | ||
| 60 | - // The file stays open between calls to stayOpen(true) and | ||
| 61 | - // stayOpen(false). You can use this to surround multiple | ||
| 62 | - // operations on a single ClosedFileInputSource to reduce the | ||
| 63 | - // overhead of a separate open/close on each call. | 56 | + // The file stays open between calls to stayOpen(true) and stayOpen(false). You can use this to |
| 57 | + // surround multiple operations on a single ClosedFileInputSource to reduce the overhead of a | ||
| 58 | + // separate open/close on each call. | ||
| 64 | QPDF_DLL | 59 | QPDF_DLL |
| 65 | void stayOpen(bool); | 60 | void stayOpen(bool); |
| 66 | 61 |
include/qpdf/FileInputSource.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDF_FILEINPUTSOURCE_HH | 19 | #ifndef QPDF_FILEINPUTSOURCE_HH |
| 23 | #define QPDF_FILEINPUTSOURCE_HH | 20 | #define QPDF_FILEINPUTSOURCE_HH |
include/qpdf/InputSource.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDF_INPUTSOURCE_HH | 19 | #ifndef QPDF_INPUTSOURCE_HH |
| 23 | #define QPDF_INPUTSOURCE_HH | 20 | #define QPDF_INPUTSOURCE_HH |
| @@ -30,9 +27,8 @@ | @@ -30,9 +27,8 @@ | ||
| 30 | #include <memory> | 27 | #include <memory> |
| 31 | #include <string> | 28 | #include <string> |
| 32 | 29 | ||
| 33 | -// Remember to use QPDF_DLL_CLASS on anything derived from InputSource | ||
| 34 | -// so it will work with dynamic_cast across the shared object | ||
| 35 | -// boundary. | 30 | +// Remember to use QPDF_DLL_CLASS on anything derived from InputSource so it will work with |
| 31 | +// dynamic_cast across the shared object boundary. | ||
| 36 | class QPDF_DLL_CLASS InputSource | 32 | class QPDF_DLL_CLASS InputSource |
| 37 | { | 33 | { |
| 38 | public: | 34 | public: |
| @@ -61,12 +57,10 @@ class QPDF_DLL_CLASS InputSource | @@ -61,12 +57,10 @@ class QPDF_DLL_CLASS InputSource | ||
| 61 | QPDF_DLL | 57 | QPDF_DLL |
| 62 | std::string readLine(size_t max_line_length); | 58 | std::string readLine(size_t max_line_length); |
| 63 | 59 | ||
| 64 | - // Find first or last occurrence of a sequence of characters | ||
| 65 | - // starting within the range defined by offset and len such that, | ||
| 66 | - // when the input source is positioned at the beginning of that | ||
| 67 | - // sequence, finder.check() returns true. If len is 0, the search | ||
| 68 | - // proceeds until EOF. If a qualifying pattern is found, these | ||
| 69 | - // methods return true and leave the input source positioned | 60 | + // Find first or last occurrence of a sequence of characters starting within the range defined |
| 61 | + // by offset and len such that, when the input source is positioned at the beginning of that | ||
| 62 | + // sequence, finder.check() returns true. If len is 0, the search proceeds until EOF. If a | ||
| 63 | + // qualifying pattern is found, these methods return true and leave the input source positioned | ||
| 70 | // wherever check() left it at the end of the matching pattern. | 64 | // wherever check() left it at the end of the matching pattern. |
| 71 | QPDF_DLL | 65 | QPDF_DLL |
| 72 | bool findFirst(char const* start_chars, qpdf_offset_t offset, size_t len, Finder& finder); | 66 | bool findFirst(char const* start_chars, qpdf_offset_t offset, size_t len, Finder& finder); |
| @@ -80,11 +74,9 @@ class QPDF_DLL_CLASS InputSource | @@ -80,11 +74,9 @@ class QPDF_DLL_CLASS InputSource | ||
| 80 | virtual void rewind() = 0; | 74 | virtual void rewind() = 0; |
| 81 | virtual size_t read(char* buffer, size_t length) = 0; | 75 | virtual size_t read(char* buffer, size_t length) = 0; |
| 82 | 76 | ||
| 83 | - // Note: you can only unread the character you just read. The | ||
| 84 | - // specific character is ignored by some implementations, and the | ||
| 85 | - // implementation doesn't check this. Use of unreadCh is | ||
| 86 | - // semantically equivalent to seek(-1, SEEK_CUR) but is much more | ||
| 87 | - // efficient. | 77 | + // Note: you can only unread the character you just read. The specific character is ignored by |
| 78 | + // some implementations, and the implementation doesn't check this. Use of unreadCh is | ||
| 79 | + // semantically equivalent to seek(-1, SEEK_CUR) but is much more efficient. | ||
| 88 | virtual void unreadCh(char ch) = 0; | 80 | virtual void unreadCh(char ch) = 0; |
| 89 | 81 | ||
| 90 | // The following methods are for use by QPDFTokenizer | 82 | // The following methods are for use by QPDFTokenizer |
| @@ -149,9 +141,8 @@ InputSource::fastTell() | @@ -149,9 +141,8 @@ InputSource::fastTell() | ||
| 149 | inline bool | 141 | inline bool |
| 150 | InputSource::fastRead(char& ch) | 142 | InputSource::fastRead(char& ch) |
| 151 | { | 143 | { |
| 152 | - // Before calling fastRead, fastTell must be called to prepare the buffer. | ||
| 153 | - // Once reading is complete, fastUnread must be called to set the correct | ||
| 154 | - // file position. | 144 | + // Before calling fastRead, fastTell must be called to prepare the buffer. Once reading is |
| 145 | + // complete, fastUnread must be called to set the correct file position. | ||
| 155 | if (this->buf_idx < this->buf_len) { | 146 | if (this->buf_idx < this->buf_len) { |
| 156 | ch = this->buffer[this->buf_idx]; | 147 | ch = this->buffer[this->buf_idx]; |
| 157 | ++(this->buf_idx); | 148 | ++(this->buf_idx); |
include/qpdf/PDFVersion.hh
| @@ -2,26 +2,22 @@ | @@ -2,26 +2,22 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | -// This class implements a simple writer for saving QPDF objects to | ||
| 23 | -// new PDF files. See comments through the header file for additional | ||
| 24 | -// details. | 19 | +// This class implements a simple writer for saving QPDF objects to new PDF files. See comments |
| 20 | +// through the header file for additional details. | ||
| 25 | 21 | ||
| 26 | #ifndef PDFVERSION_HH | 22 | #ifndef PDFVERSION_HH |
| 27 | #define PDFVERSION_HH | 23 | #define PDFVERSION_HH |
| @@ -32,10 +28,9 @@ | @@ -32,10 +28,9 @@ | ||
| 32 | class PDFVersion | 28 | class PDFVersion |
| 33 | { | 29 | { |
| 34 | public: | 30 | public: |
| 35 | - // Represent a PDF version. PDF versions are typically | ||
| 36 | - // major.minor, but PDF 1.7 has several extension levels as the | ||
| 37 | - // ISO 32000 spec was in progress. This class helps with | ||
| 38 | - // comparison of versions. | 31 | + // Represent a PDF version. PDF versions are typically major.minor, but PDF 1.7 has several |
| 32 | + // extension levels as the ISO 32000 spec was in progress. This class helps with comparison of | ||
| 33 | + // versions. | ||
| 39 | QPDF_DLL | 34 | QPDF_DLL |
| 40 | PDFVersion(); | 35 | PDFVersion(); |
| 41 | QPDF_DLL | 36 | QPDF_DLL |
| @@ -49,13 +44,12 @@ class PDFVersion | @@ -49,13 +44,12 @@ class PDFVersion | ||
| 49 | QPDF_DLL | 44 | QPDF_DLL |
| 50 | bool operator==(PDFVersion const& rhs) const; | 45 | bool operator==(PDFVersion const& rhs) const; |
| 51 | 46 | ||
| 52 | - // Replace this version with the other one if the other one is | ||
| 53 | - // greater. | 47 | + // Replace this version with the other one if the other one is greater. |
| 54 | QPDF_DLL | 48 | QPDF_DLL |
| 55 | void updateIfGreater(PDFVersion const& other); | 49 | void updateIfGreater(PDFVersion const& other); |
| 56 | 50 | ||
| 57 | - // Initialize a string and integer suitable for passing to | ||
| 58 | - // QPDFWriter::setMinimumPDFVersion or QPDFWriter::forcePDFVersion. | 51 | + // Initialize a string and integer suitable for passing to QPDFWriter::setMinimumPDFVersion or |
| 52 | + // QPDFWriter::forcePDFVersion. | ||
| 59 | QPDF_DLL | 53 | QPDF_DLL |
| 60 | void getVersion(std::string& version, int& extension_level) const; | 54 | void getVersion(std::string& version, int& extension_level) const; |
| 61 | 55 |
include/qpdf/Pipeline.hh
| @@ -26,8 +26,7 @@ | @@ -26,8 +26,7 @@ | ||
| 26 | // | 26 | // |
| 27 | // The client is required to call finish() before destroying a Pipeline in order to avoid loss of | 27 | // The client is required to call finish() before destroying a Pipeline in order to avoid loss of |
| 28 | // data. A Pipeline class should not throw an exception in the destructor if this hasn't been done | 28 | // data. A Pipeline class should not throw an exception in the destructor if this hasn't been done |
| 29 | -// though since doing so causes too much trouble when deleting | ||
| 30 | -// pipelines during error conditions. | 29 | +// though since doing so causes too much trouble when deleting pipelines during error conditions. |
| 31 | // | 30 | // |
| 32 | // Some pipelines are reusable (i.e., you can call write() after calling finish() and can call | 31 | // Some pipelines are reusable (i.e., you can call write() after calling finish() and can call |
| 33 | // finish() multiple times) while others are not. It is up to the caller to use a pipeline | 32 | // finish() multiple times) while others are not. It is up to the caller to use a pipeline |
include/qpdf/Pl_Buffer.hh
| @@ -47,8 +47,8 @@ class QPDF_DLL_CLASS Pl_Buffer: public Pipeline | @@ -47,8 +47,8 @@ class QPDF_DLL_CLASS Pl_Buffer: public Pipeline | ||
| 47 | void finish() override; | 47 | void finish() override; |
| 48 | 48 | ||
| 49 | // Each call to getBuffer() resets this object -- see notes above. | 49 | // Each call to getBuffer() resets this object -- see notes above. |
| 50 | - // The caller is responsible for deleting the returned Buffer | ||
| 51 | - // object. See also getBufferSharedPointer() and getMallocBuffer(). | 50 | + // The caller is responsible for deleting the returned Buffer object. See also |
| 51 | + // getBufferSharedPointer() and getMallocBuffer(). | ||
| 52 | QPDF_DLL | 52 | QPDF_DLL |
| 53 | Buffer* getBuffer(); | 53 | Buffer* getBuffer(); |
| 54 | 54 |
include/qpdf/Pl_Concatenate.hh
| @@ -2,31 +2,27 @@ | @@ -2,31 +2,27 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef PL_CONCATENATE_HH | 19 | #ifndef PL_CONCATENATE_HH |
| 23 | #define PL_CONCATENATE_HH | 20 | #define PL_CONCATENATE_HH |
| 24 | 21 | ||
| 25 | -// This pipeline will drop all regular finished calls rather than | ||
| 26 | -// passing them onto next. To finish downstream streams, call | ||
| 27 | -// manualFinish. This makes it possible to pipe multiple streams | ||
| 28 | -// (e.g. with QPDFObjectHandle::pipeStreamData) to a downstream like | ||
| 29 | -// Pl_Flate that can't handle multiple calls to finish(). | 22 | +// This pipeline will drop all regular finished calls rather than passing them onto next. To finish |
| 23 | +// downstream streams, call manualFinish. This makes it possible to pipe multiple streams (e.g. | ||
| 24 | +// with QPDFObjectHandle::pipeStreamData) to a downstream like Pl_Flate that can't handle multiple | ||
| 25 | +// calls to finish(). | ||
| 30 | 26 | ||
| 31 | #include <qpdf/Pipeline.hh> | 27 | #include <qpdf/Pipeline.hh> |
| 32 | 28 | ||
| @@ -44,8 +40,7 @@ class QPDF_DLL_CLASS Pl_Concatenate: public Pipeline | @@ -44,8 +40,7 @@ class QPDF_DLL_CLASS Pl_Concatenate: public Pipeline | ||
| 44 | QPDF_DLL | 40 | QPDF_DLL |
| 45 | virtual void finish(); | 41 | virtual void finish(); |
| 46 | 42 | ||
| 47 | - // At the very end, call manualFinish to actually finish the rest of | ||
| 48 | - // the pipeline. | 43 | + // At the very end, call manualFinish to actually finish the rest of the pipeline. |
| 49 | QPDF_DLL | 44 | QPDF_DLL |
| 50 | void manualFinish(); | 45 | void manualFinish(); |
| 51 | 46 |
include/qpdf/Pl_Count.hh
| @@ -2,28 +2,24 @@ | @@ -2,28 +2,24 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef PL_COUNT_HH | 19 | #ifndef PL_COUNT_HH |
| 23 | #define PL_COUNT_HH | 20 | #define PL_COUNT_HH |
| 24 | 21 | ||
| 25 | -// This pipeline is reusable; i.e., it is safe to call write() after | ||
| 26 | -// calling finish(). | 22 | +// This pipeline is reusable; i.e., it is safe to call write() after calling finish(). |
| 27 | 23 | ||
| 28 | #include <qpdf/Pipeline.hh> | 24 | #include <qpdf/Pipeline.hh> |
| 29 | #include <qpdf/Types.h> | 25 | #include <qpdf/Types.h> |
| @@ -42,8 +38,8 @@ class QPDF_DLL_CLASS Pl_Count: public Pipeline | @@ -42,8 +38,8 @@ class QPDF_DLL_CLASS Pl_Count: public Pipeline | ||
| 42 | // Returns the number of bytes written | 38 | // Returns the number of bytes written |
| 43 | QPDF_DLL | 39 | QPDF_DLL |
| 44 | qpdf_offset_t getCount() const; | 40 | qpdf_offset_t getCount() const; |
| 45 | - // Returns the last character written, or '\0' if no characters | ||
| 46 | - // have been written (in which case getCount() returns 0) | 41 | + // Returns the last character written, or '\0' if no characters have been written (in which case |
| 42 | + // getCount() returns 0) | ||
| 47 | QPDF_DLL | 43 | QPDF_DLL |
| 48 | unsigned char getLastChar() const; | 44 | unsigned char getLastChar() const; |
| 49 | 45 | ||
| @@ -60,8 +56,7 @@ class QPDF_DLL_CLASS Pl_Count: public Pipeline | @@ -60,8 +56,7 @@ class QPDF_DLL_CLASS Pl_Count: public Pipeline | ||
| 60 | Members(); | 56 | Members(); |
| 61 | Members(Members const&) = delete; | 57 | Members(Members const&) = delete; |
| 62 | 58 | ||
| 63 | - // Must be qpdf_offset_t, not size_t, to handle writing more than | ||
| 64 | - // size_t can handle. | 59 | + // Must be qpdf_offset_t, not size_t, to handle writing more than size_t can handle. |
| 65 | qpdf_offset_t count; | 60 | qpdf_offset_t count; |
| 66 | unsigned char last_char; | 61 | unsigned char last_char; |
| 67 | }; | 62 | }; |
include/qpdf/Pl_DCT.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef PL_DCT_HH | 19 | #ifndef PL_DCT_HH |
| 23 | #define PL_DCT_HH | 20 | #define PL_DCT_HH |
| @@ -27,8 +24,7 @@ | @@ -27,8 +24,7 @@ | ||
| 27 | #include <qpdf/Pl_Buffer.hh> | 24 | #include <qpdf/Pl_Buffer.hh> |
| 28 | #include <cstddef> | 25 | #include <cstddef> |
| 29 | 26 | ||
| 30 | -// jpeglib.h must be included after cstddef or else it messes up the | ||
| 31 | -// definition of size_t. | 27 | +// jpeglib.h must be included after cstddef or else it messes up the definition of size_t. |
| 32 | #include <jpeglib.h> | 28 | #include <jpeglib.h> |
| 33 | 29 | ||
| 34 | class QPDF_DLL_CLASS Pl_DCT: public Pipeline | 30 | class QPDF_DLL_CLASS Pl_DCT: public Pipeline |
include/qpdf/Pl_Discard.hh
| @@ -2,31 +2,26 @@ | @@ -2,31 +2,26 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef PL_DISCARD_HH | 19 | #ifndef PL_DISCARD_HH |
| 23 | #define PL_DISCARD_HH | 20 | #define PL_DISCARD_HH |
| 24 | 21 | ||
| 25 | -// This pipeline discards its output. It is an end-of-line pipeline | ||
| 26 | -// (with no next). | 22 | +// This pipeline discards its output. It is an end-of-line pipeline (with no next). |
| 27 | 23 | ||
| 28 | -// This pipeline is reusable; i.e., it is safe to call write() after | ||
| 29 | -// calling finish(). | 24 | +// This pipeline is reusable; i.e., it is safe to call write() after calling finish(). |
| 30 | 25 | ||
| 31 | #include <qpdf/Pipeline.hh> | 26 | #include <qpdf/Pipeline.hh> |
| 32 | 27 |
include/qpdf/Pl_Function.hh
| @@ -2,38 +2,33 @@ | @@ -2,38 +2,33 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef PL_FUNCTION_HH | 19 | #ifndef PL_FUNCTION_HH |
| 23 | #define PL_FUNCTION_HH | 20 | #define PL_FUNCTION_HH |
| 24 | 21 | ||
| 25 | -// This pipeline calls an arbitrary function with whatever data is | ||
| 26 | -// passed to it. This pipeline can be reused. | 22 | +// This pipeline calls an arbitrary function with whatever data is passed to it. This pipeline can |
| 23 | +// be reused. | ||
| 27 | // | 24 | // |
| 28 | -// For this pipeline, "next" may be null. If a next pointer is | ||
| 29 | -// provided, this pipeline will also pass the data through to it and | ||
| 30 | -// will forward finish() to it. | 25 | +// For this pipeline, "next" may be null. If a next pointer is provided, this pipeline will also |
| 26 | +// pass the data through to it and will forward finish() to it. | ||
| 31 | // | 27 | // |
| 32 | -// It is okay to not call finish() on this pipeline if it has no | ||
| 33 | -// "next". | 28 | +// It is okay to not call finish() on this pipeline if it has no "next". |
| 34 | // | 29 | // |
| 35 | -// It is okay to keep calling write() after a previous write throws an | ||
| 36 | -// exception as long as the delegated function allows it. | 30 | +// It is okay to keep calling write() after a previous write throws an exception as long as the |
| 31 | +// delegated function allows it. | ||
| 37 | 32 | ||
| 38 | #include <qpdf/Pipeline.hh> | 33 | #include <qpdf/Pipeline.hh> |
| 39 | 34 | ||
| @@ -48,10 +43,9 @@ class QPDF_DLL_CLASS Pl_Function: public Pipeline | @@ -48,10 +43,9 @@ class QPDF_DLL_CLASS Pl_Function: public Pipeline | ||
| 48 | QPDF_DLL | 43 | QPDF_DLL |
| 49 | Pl_Function(char const* identifier, Pipeline* next, writer_t fn); | 44 | Pl_Function(char const* identifier, Pipeline* next, writer_t fn); |
| 50 | 45 | ||
| 51 | - // The supplied C-style function is called every time write is | ||
| 52 | - // called. The udata option is passed into the function with each | ||
| 53 | - // call. If the function returns a non-zero value, a runtime error | ||
| 54 | - // is thrown. | 46 | + // The supplied C-style function is called every time write is called. The udata option is |
| 47 | + // passed into the function with each call. If the function returns a non-zero value, a runtime | ||
| 48 | + // error is thrown. | ||
| 55 | typedef int (*writer_c_t)(unsigned char const*, size_t, void*); | 49 | typedef int (*writer_c_t)(unsigned char const*, size_t, void*); |
| 56 | QPDF_DLL | 50 | QPDF_DLL |
| 57 | Pl_Function(char const* identifier, Pipeline* next, writer_c_t fn, void* udata); | 51 | Pl_Function(char const* identifier, Pipeline* next, writer_c_t fn, void* udata); |
include/qpdf/Pl_OStream.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | // End-of-line pipeline that simply writes its data to a stdio FILE* object. | 19 | // End-of-line pipeline that simply writes its data to a stdio FILE* object. |
| 23 | 20 | ||
| @@ -35,8 +32,7 @@ | @@ -35,8 +32,7 @@ | ||
| 35 | class QPDF_DLL_CLASS Pl_OStream: public Pipeline | 32 | class QPDF_DLL_CLASS Pl_OStream: public Pipeline |
| 36 | { | 33 | { |
| 37 | public: | 34 | public: |
| 38 | - // os is externally maintained; this class just writes to and | ||
| 39 | - // flushes it. It does not close it. | 35 | + // os is externally maintained; this class just writes to and flushes it. It does not close it. |
| 40 | QPDF_DLL | 36 | QPDF_DLL |
| 41 | Pl_OStream(char const* identifier, std::ostream& os); | 37 | Pl_OStream(char const* identifier, std::ostream& os); |
| 42 | QPDF_DLL | 38 | QPDF_DLL |
include/qpdf/Pl_QPDFTokenizer.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef PL_QPDFTOKENIZER_HH | 19 | #ifndef PL_QPDFTOKENIZER_HH |
| 23 | #define PL_QPDFTOKENIZER_HH | 20 | #define PL_QPDFTOKENIZER_HH |
| @@ -31,22 +28,19 @@ | @@ -31,22 +28,19 @@ | ||
| 31 | 28 | ||
| 32 | #include <memory> | 29 | #include <memory> |
| 33 | 30 | ||
| 34 | -// Tokenize the incoming text using QPDFTokenizer and pass the tokens | ||
| 35 | -// in turn to a QPDFObjectHandle::TokenFilter object. All bytes of | ||
| 36 | -// incoming content will be included in exactly one token and passed | ||
| 37 | -// downstream. | 31 | +// Tokenize the incoming text using QPDFTokenizer and pass the tokens in turn to a |
| 32 | +// QPDFObjectHandle::TokenFilter object. All bytes of incoming content will be included in exactly | ||
| 33 | +// one token and passed downstream. | ||
| 38 | 34 | ||
| 39 | -// This is a very low-level interface for working with token filters. | ||
| 40 | -// Most code will want to use QPDFObjectHandle::filterPageContents or | ||
| 41 | -// QPDFObjectHandle::addTokenFilter. See QPDFObjectHandle.hh for | ||
| 42 | -// details. | 35 | +// This is a very low-level interface for working with token filters. Most code will want to use |
| 36 | +// QPDFObjectHandle::filterPageContents or QPDFObjectHandle::addTokenFilter. See QPDFObjectHandle.hh | ||
| 37 | +// for details. | ||
| 43 | 38 | ||
| 44 | class QPDF_DLL_CLASS Pl_QPDFTokenizer: public Pipeline | 39 | class QPDF_DLL_CLASS Pl_QPDFTokenizer: public Pipeline |
| 45 | { | 40 | { |
| 46 | public: | 41 | public: |
| 47 | - // Whatever pipeline is provided as "next" will be set as the | ||
| 48 | - // pipeline that the token filter writes to. If next is not | ||
| 49 | - // provided, any output written by the filter will be discarded. | 42 | + // Whatever pipeline is provided as "next" will be set as the pipeline that the token filter |
| 43 | + // writes to. If next is not provided, any output written by the filter will be discarded. | ||
| 50 | QPDF_DLL | 44 | QPDF_DLL |
| 51 | Pl_QPDFTokenizer( | 45 | Pl_QPDFTokenizer( |
| 52 | char const* identifier, QPDFObjectHandle::TokenFilter* filter, Pipeline* next = nullptr); | 46 | char const* identifier, QPDFObjectHandle::TokenFilter* filter, Pipeline* next = nullptr); |
include/qpdf/Pl_RunLength.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef PL_RUNLENGTH_HH | 19 | #ifndef PL_RUNLENGTH_HH |
| 23 | #define PL_RUNLENGTH_HH | 20 | #define PL_RUNLENGTH_HH |
include/qpdf/Pl_StdioFile.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | // End-of-line pipeline that simply writes its data to a stdio FILE* object. | 19 | // End-of-line pipeline that simply writes its data to a stdio FILE* object. |
| 23 | 20 | ||
| @@ -35,8 +32,7 @@ | @@ -35,8 +32,7 @@ | ||
| 35 | class QPDF_DLL_CLASS Pl_StdioFile: public Pipeline | 32 | class QPDF_DLL_CLASS Pl_StdioFile: public Pipeline |
| 36 | { | 33 | { |
| 37 | public: | 34 | public: |
| 38 | - // f is externally maintained; this class just writes to and | ||
| 39 | - // flushes it. It does not close it. | 35 | + // f is externally maintained; this class just writes to and flushes it. It does not close it. |
| 40 | QPDF_DLL | 36 | QPDF_DLL |
| 41 | Pl_StdioFile(char const* identifier, FILE* f); | 37 | Pl_StdioFile(char const* identifier, FILE* f); |
| 42 | QPDF_DLL | 38 | QPDF_DLL |
include/qpdf/Pl_String.hh
| @@ -2,39 +2,34 @@ | @@ -2,39 +2,34 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef PL_STRING_HH | 19 | #ifndef PL_STRING_HH |
| 23 | #define PL_STRING_HH | 20 | #define PL_STRING_HH |
| 24 | 21 | ||
| 25 | -// This pipeline accumulates the data passed to it into a std::string, | ||
| 26 | -// a reference to which is passed in at construction. Each subsequent | ||
| 27 | -// use of this pipeline appends to the data accumulated so far. | 22 | +// This pipeline accumulates the data passed to it into a std::string, a reference to which is |
| 23 | +// passed in at construction. Each subsequent use of this pipeline appends to the data accumulated | ||
| 24 | +// so far. | ||
| 28 | // | 25 | // |
| 29 | -// For this pipeline, "next" may be null. If a next pointer is | ||
| 30 | -// provided, this pipeline will also pass the data through to it and | ||
| 31 | -// will forward finish() to it. | 26 | +// For this pipeline, "next" may be null. If a next pointer is provided, this pipeline will also |
| 27 | +// pass the data through to it and will forward finish() to it. | ||
| 32 | // | 28 | // |
| 33 | -// It is okay to not call finish() on this pipeline if it has no | ||
| 34 | -// "next". This makes it easy to stick this in front of another | ||
| 35 | -// pipeline to capture data that is written to the other pipeline | ||
| 36 | -// without interfering with when finish is called on the other | ||
| 37 | -// pipeline and without having to put a Pl_Concatenate after it. | 29 | +// It is okay to not call finish() on this pipeline if it has no "next". This makes it easy to stick |
| 30 | +// this in front of another pipeline to capture data that is written to the other pipeline without | ||
| 31 | +// interfering with when finish is called on the other pipeline and without having to put a | ||
| 32 | +// Pl_Concatenate after it. | ||
| 38 | 33 | ||
| 39 | #include <qpdf/Pipeline.hh> | 34 | #include <qpdf/Pipeline.hh> |
| 40 | 35 |
include/qpdf/QPDF.hh
| @@ -68,7 +68,7 @@ class QPDF | @@ -68,7 +68,7 @@ class QPDF | ||
| 68 | // read until they are needed. A QPDF object may be associated with only one file in its | 68 | // read until they are needed. A QPDF object may be associated with only one file in its |
| 69 | // lifetime. This method must be called before any methods that potentially ask for information | 69 | // lifetime. This method must be called before any methods that potentially ask for information |
| 70 | // about the PDF file are called. Prior to calling this, the only methods that are allowed are | 70 | // about the PDF file are called. Prior to calling this, the only methods that are allowed are |
| 71 | - // those that set parameters. If the input file is not encrypted,either a null password or an | 71 | + // those that set parameters. If the input file is not encrypted, either a null password or an |
| 72 | // empty password can be used. If the file is encrypted, either the user password or the owner | 72 | // empty password can be used. If the file is encrypted, either the user password or the owner |
| 73 | // password may be supplied. The method setPasswordIsHexKey may be called prior to calling this | 73 | // password may be supplied. The method setPasswordIsHexKey may be called prior to calling this |
| 74 | // method or any of the other process methods to force the password to be interpreted as a raw | 74 | // method or any of the other process methods to force the password to be interpreted as a raw |
include/qpdf/QPDFAnnotationObjectHelper.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFANNOTATIONOBJECTHELPER_HH | 19 | #ifndef QPDFANNOTATIONOBJECTHELPER_HH |
| 23 | #define QPDFANNOTATIONOBJECTHELPER_HH | 20 | #define QPDFANNOTATIONOBJECTHELPER_HH |
| @@ -35,19 +32,16 @@ class QPDFAnnotationObjectHelper: public QPDFObjectHelper | @@ -35,19 +32,16 @@ class QPDFAnnotationObjectHelper: public QPDFObjectHelper | ||
| 35 | QPDF_DLL | 32 | QPDF_DLL |
| 36 | virtual ~QPDFAnnotationObjectHelper() = default; | 33 | virtual ~QPDFAnnotationObjectHelper() = default; |
| 37 | 34 | ||
| 38 | - // This class provides helper methods for annotations. More | ||
| 39 | - // functionality will likely be added in the future. | 35 | + // This class provides helper methods for annotations. More functionality will likely be added |
| 36 | + // in the future. | ||
| 40 | 37 | ||
| 41 | - // Some functionality for annotations is also implemented in | ||
| 42 | - // QPDFAcroFormDocumentHelper and QPDFFormFieldObjectHelper. In | ||
| 43 | - // some cases, functions defined there work for other annotations | ||
| 44 | - // besides widget annotations, but they are implemented with form | ||
| 45 | - // fields so that they can properly handle form fields when | ||
| 46 | - // needed. | 38 | + // Some functionality for annotations is also implemented in QPDFAcroFormDocumentHelper and |
| 39 | + // QPDFFormFieldObjectHelper. In some cases, functions defined there work for other annotations | ||
| 40 | + // besides widget annotations, but they are implemented with form fields so that they can | ||
| 41 | + // properly handle form fields when needed. | ||
| 47 | 42 | ||
| 48 | - // Return the subtype of the annotation as a string (e.g. | ||
| 49 | - // "/Widget"). Returns the empty string if the subtype (which is | ||
| 50 | - // required by the spec) is missing. | 43 | + // Return the subtype of the annotation as a string (e.g. "/Widget"). Returns the empty string |
| 44 | + // if the subtype (which is required by the spec) is missing. | ||
| 51 | QPDF_DLL | 45 | QPDF_DLL |
| 52 | std::string getSubtype(); | 46 | std::string getSubtype(); |
| 53 | 47 | ||
| @@ -57,39 +51,32 @@ class QPDFAnnotationObjectHelper: public QPDFObjectHelper | @@ -57,39 +51,32 @@ class QPDFAnnotationObjectHelper: public QPDFObjectHelper | ||
| 57 | QPDF_DLL | 51 | QPDF_DLL |
| 58 | QPDFObjectHandle getAppearanceDictionary(); | 52 | QPDFObjectHandle getAppearanceDictionary(); |
| 59 | 53 | ||
| 60 | - // Return the appearance state as given in "/AS", or the empty | ||
| 61 | - // string if none is given. | 54 | + // Return the appearance state as given in "/AS", or the empty string if none is given. |
| 62 | QPDF_DLL | 55 | QPDF_DLL |
| 63 | std::string getAppearanceState(); | 56 | std::string getAppearanceState(); |
| 64 | 57 | ||
| 65 | - // Return flags from "/F". The value is a logical or of | ||
| 66 | - // pdf_annotation_flag_e as defined in qpdf/Constants.h. | 58 | + // Return flags from "/F". The value is a logical or of pdf_annotation_flag_e as defined in |
| 59 | + // qpdf/Constants.h. | ||
| 67 | QPDF_DLL | 60 | QPDF_DLL |
| 68 | int getFlags(); | 61 | int getFlags(); |
| 69 | 62 | ||
| 70 | - // Return a specific stream. "which" may be one of "/N", "/R", or | ||
| 71 | - // "/D" to indicate the normal, rollover, or down appearance | ||
| 72 | - // stream. (Any value may be passed to "which"; if an appearance | ||
| 73 | - // stream of that name exists, it will be returned.) If the value | ||
| 74 | - // associated with "which" in the appearance dictionary is a | ||
| 75 | - // subdictionary, an appearance state may be specified to select | ||
| 76 | - // which appearance stream is desired. If not specified, the | ||
| 77 | - // appearance state in "/AS" will used. | 63 | + // Return a specific stream. "which" may be one of "/N", "/R", or "/D" to indicate the normal, |
| 64 | + // rollover, or down appearance stream. (Any value may be passed to "which"; if an appearance | ||
| 65 | + // stream of that name exists, it will be returned.) If the value associated with "which" in the | ||
| 66 | + // appearance dictionary is a subdictionary, an appearance state may be specified to select | ||
| 67 | + // which appearance stream is desired. If not specified, the appearance state in "/AS" will | ||
| 68 | + // used. | ||
| 78 | QPDF_DLL | 69 | QPDF_DLL |
| 79 | QPDFObjectHandle getAppearanceStream(std::string const& which, std::string const& state = ""); | 70 | QPDFObjectHandle getAppearanceStream(std::string const& which, std::string const& state = ""); |
| 80 | 71 | ||
| 81 | - // Generate text suitable for addition to the containing page's | ||
| 82 | - // content stream that draws this annotation's appearance stream | ||
| 83 | - // as a form XObject. The value "name" is the resource name that | ||
| 84 | - // will be used to refer to the form xobject. The value "rotate" | ||
| 85 | - // should be set to the page's /Rotate value or 0 if none. The | ||
| 86 | - // values of required_flags and forbidden_flags are constructed by | ||
| 87 | - // logically "or"ing annotation flags of type | ||
| 88 | - // pdf_annotation_flag_e defined in qpdf/Constants.h. Content will | ||
| 89 | - // be returned only if all required_flags are set and no | ||
| 90 | - // forbidden_flags are set. For example, including an_no_view in | ||
| 91 | - // forbidden_flags could be useful for creating an on-screen view, | ||
| 92 | - // and including an_print to required_flags could be useful if | 72 | + // Generate text suitable for addition to the containing page's content stream that draws this |
| 73 | + // annotation's appearance stream as a form XObject. The value "name" is the resource name that | ||
| 74 | + // will be used to refer to the form xobject. The value "rotate" should be set to the page's | ||
| 75 | + // /Rotate value or 0 if none. The values of required_flags and forbidden_flags are constructed | ||
| 76 | + // by logically "or"ing annotation flags of type pdf_annotation_flag_e defined in | ||
| 77 | + // qpdf/Constants.h. Content will be returned only if all required_flags are set and no | ||
| 78 | + // forbidden_flags are set. For example, including an_no_view in forbidden_flags could be useful | ||
| 79 | + // for creating an on-screen view, and including an_print to required_flags could be useful if | ||
| 93 | // preparing to print. | 80 | // preparing to print. |
| 94 | QPDF_DLL | 81 | QPDF_DLL |
| 95 | std::string getPageContentForAppearance( | 82 | std::string getPageContentForAppearance( |
include/qpdf/QPDFCryptoProvider.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFCRYPTOPROVIDER_HH | 19 | #ifndef QPDFCRYPTOPROVIDER_HH |
| 23 | #define QPDFCRYPTOPROVIDER_HH | 20 | #define QPDFCRYPTOPROVIDER_HH |
| @@ -30,35 +27,30 @@ | @@ -30,35 +27,30 @@ | ||
| 30 | #include <set> | 27 | #include <set> |
| 31 | #include <string> | 28 | #include <string> |
| 32 | 29 | ||
| 33 | -// This class is part of qpdf's pluggable crypto provider support. | ||
| 34 | -// Most users won't need to know or care about this class, but you can | ||
| 35 | -// use it if you want to supply your own crypto implementation. See | ||
| 36 | -// also comments in QPDFCryptoImpl.hh. | 30 | +// This class is part of qpdf's pluggable crypto provider support. Most users won't need to know or |
| 31 | +// care about this class, but you can use it if you want to supply your own crypto implementation. | ||
| 32 | +// See also comments in QPDFCryptoImpl.hh. | ||
| 37 | 33 | ||
| 38 | class QPDFCryptoProvider | 34 | class QPDFCryptoProvider |
| 39 | { | 35 | { |
| 40 | public: | 36 | public: |
| 41 | - // Methods for getting and registering crypto implementations. | ||
| 42 | - // These methods are not thread-safe. | 37 | + // Methods for getting and registering crypto implementations. These methods are not |
| 38 | + // thread-safe. | ||
| 43 | 39 | ||
| 44 | - // Return an instance of a crypto provider using the default | ||
| 45 | - // implementation. | 40 | + // Return an instance of a crypto provider using the default implementation. |
| 46 | QPDF_DLL | 41 | QPDF_DLL |
| 47 | static std::shared_ptr<QPDFCryptoImpl> getImpl(); | 42 | static std::shared_ptr<QPDFCryptoImpl> getImpl(); |
| 48 | 43 | ||
| 49 | - // Return an instance of the crypto provider registered using the | ||
| 50 | - // given name. | 44 | + // Return an instance of the crypto provider registered using the given name. |
| 51 | QPDF_DLL | 45 | QPDF_DLL |
| 52 | static std::shared_ptr<QPDFCryptoImpl> getImpl(std::string const& name); | 46 | static std::shared_ptr<QPDFCryptoImpl> getImpl(std::string const& name); |
| 53 | 47 | ||
| 54 | - // Register the given type (T) as a crypto implementation. T must | ||
| 55 | - // be derived from QPDFCryptoImpl and must have a constructor that | ||
| 56 | - // takes no arguments. | 48 | + // Register the given type (T) as a crypto implementation. T must be derived from QPDFCryptoImpl |
| 49 | + // and must have a constructor that takes no arguments. | ||
| 57 | template <typename T> | 50 | template <typename T> |
| 58 | QPDF_DLL static void registerImpl(std::string const& name); | 51 | QPDF_DLL static void registerImpl(std::string const& name); |
| 59 | 52 | ||
| 60 | - // Set the crypto provider registered with the given name as the | ||
| 61 | - // default crypto implementation. | 53 | + // Set the crypto provider registered with the given name as the default crypto implementation. |
| 62 | QPDF_DLL | 54 | QPDF_DLL |
| 63 | static void setDefaultProvider(std::string const& name); | 55 | static void setDefaultProvider(std::string const& name); |
| 64 | 56 |
include/qpdf/QPDFDocumentHelper.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFDOCUMENTHELPER_HH | 19 | #ifndef QPDFDOCUMENTHELPER_HH |
| 23 | #define QPDFDOCUMENTHELPER_HH | 20 | #define QPDFDOCUMENTHELPER_HH |
| @@ -25,16 +22,13 @@ | @@ -25,16 +22,13 @@ | ||
| 25 | #include <qpdf/DLL.h> | 22 | #include <qpdf/DLL.h> |
| 26 | #include <qpdf/QPDF.hh> | 23 | #include <qpdf/QPDF.hh> |
| 27 | 24 | ||
| 28 | -// This is a base class for QPDF Document Helper classes. Document | ||
| 29 | -// helpers are classes that provide a convenient, higher-level API for | ||
| 30 | -// accessing document-level structures with a PDF file. Document | ||
| 31 | -// helpers are always initialized with a reference to a QPDF object, | ||
| 32 | -// and the object can always be retrieved. The intention is that you | ||
| 33 | -// may freely intermix use of document helpers with the underlying | ||
| 34 | -// QPDF object unless there is a specific comment in a specific helper | ||
| 35 | -// method that says otherwise. The pattern of using helper objects was | ||
| 36 | -// introduced to allow creation of higher level helper functions | ||
| 37 | -// without polluting the public interface of QPDF. | 25 | +// This is a base class for QPDF Document Helper classes. Document helpers are classes that provide |
| 26 | +// a convenient, higher-level API for accessing document-level structures with a PDF file. Document | ||
| 27 | +// helpers are always initialized with a reference to a QPDF object, and the object can always be | ||
| 28 | +// retrieved. The intention is that you may freely intermix use of document helpers with the | ||
| 29 | +// underlying QPDF object unless there is a specific comment in a specific helper method that says | ||
| 30 | +// otherwise. The pattern of using helper objects was introduced to allow creation of higher level | ||
| 31 | +// helper functions without polluting the public interface of QPDF. | ||
| 38 | 32 | ||
| 39 | class QPDF_DLL_CLASS QPDFDocumentHelper | 33 | class QPDF_DLL_CLASS QPDFDocumentHelper |
| 40 | { | 34 | { |
include/qpdf/QPDFEFStreamObjectHelper.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFEFSTREAMOBJECTHELPER_HH | 19 | #ifndef QPDFEFSTREAMOBJECTHELPER_HH |
| 23 | #define QPDFEFSTREAMOBJECTHELPER_HH | 20 | #define QPDFEFSTREAMOBJECTHELPER_HH |
| @@ -29,9 +26,8 @@ | @@ -29,9 +26,8 @@ | ||
| 29 | #include <qpdf/QPDFObjectHandle.hh> | 26 | #include <qpdf/QPDFObjectHandle.hh> |
| 30 | #include <functional> | 27 | #include <functional> |
| 31 | 28 | ||
| 32 | -// This class provides a higher level interface around Embedded File | ||
| 33 | -// Streams, which are discussed in section 7.11.4 of the ISO-32000 PDF | ||
| 34 | -// specification. | 29 | +// This class provides a higher level interface around Embedded File Streams, which are discussed in |
| 30 | +// section 7.11.4 of the ISO-32000 PDF specification. | ||
| 35 | 31 | ||
| 36 | class QPDFEFStreamObjectHelper: public QPDFObjectHelper | 32 | class QPDFEFStreamObjectHelper: public QPDFObjectHelper |
| 37 | { | 33 | { |
| @@ -41,11 +37,10 @@ class QPDFEFStreamObjectHelper: public QPDFObjectHelper | @@ -41,11 +37,10 @@ class QPDFEFStreamObjectHelper: public QPDFObjectHelper | ||
| 41 | QPDF_DLL | 37 | QPDF_DLL |
| 42 | virtual ~QPDFEFStreamObjectHelper() = default; | 38 | virtual ~QPDFEFStreamObjectHelper() = default; |
| 43 | 39 | ||
| 44 | - // Date parameters are strings that conform to the PDF spec for | ||
| 45 | - // date/time strings, which is "D:yyyymmddhhmmss<z>" where <z> is | ||
| 46 | - // either "Z" for UTC or "-hh'mm'" or "+hh'mm'" for timezone | ||
| 47 | - // offset. Examples: "D:20210207161528-05'00'", | ||
| 48 | - // "D:20210207211528Z". See QUtil::qpdf_time_to_pdf_time. | 40 | + // Date parameters are strings that conform to the PDF spec for date/time strings, which is |
| 41 | + // "D:yyyymmddhhmmss<z>" where <z> is either "Z" for UTC or "-hh'mm'" or "+hh'mm'" for timezone | ||
| 42 | + // offset. Examples: "D:20210207161528-05'00'", "D:20210207211528Z". See | ||
| 43 | + // QUtil::qpdf_time_to_pdf_time. | ||
| 49 | 44 | ||
| 50 | QPDF_DLL | 45 | QPDF_DLL |
| 51 | std::string getCreationDate(); | 46 | std::string getCreationDate(); |
| @@ -57,32 +52,27 @@ class QPDFEFStreamObjectHelper: public QPDFObjectHelper | @@ -57,32 +52,27 @@ class QPDFEFStreamObjectHelper: public QPDFObjectHelper | ||
| 57 | // Subtype is a mime type such as "text/plain" | 52 | // Subtype is a mime type such as "text/plain" |
| 58 | QPDF_DLL | 53 | QPDF_DLL |
| 59 | std::string getSubtype(); | 54 | std::string getSubtype(); |
| 60 | - // Return the checksum as stored in the object as a binary string. | ||
| 61 | - // This does not check consistency with the data. If not present, | ||
| 62 | - // return an empty string. The PDF spec specifies this as an MD5 | ||
| 63 | - // checksum and notes that it is not to be used for security | ||
| 64 | - // purposes since MD5 is known not to be secure. | 55 | + // Return the checksum as stored in the object as a binary string. This does not check |
| 56 | + // consistency with the data. If not present, return an empty string. The PDF spec specifies | ||
| 57 | + // this as an MD5 checksum and notes that it is not to be used for security purposes since MD5 | ||
| 58 | + // is known not to be secure. | ||
| 65 | QPDF_DLL | 59 | QPDF_DLL |
| 66 | std::string getChecksum(); | 60 | std::string getChecksum(); |
| 67 | 61 | ||
| 68 | - // Setters return a reference to this object so that they can be | ||
| 69 | - // used as fluent interfaces, e.g. | 62 | + // Setters return a reference to this object so that they can be used as fluent interfaces, e.g. |
| 70 | // efsoh.setCreationDate(x).setModDate(y); | 63 | // efsoh.setCreationDate(x).setModDate(y); |
| 71 | 64 | ||
| 72 | - // Create a new embedded file stream with the given stream data, | ||
| 73 | - // which can be provided in any of several ways. To get the new | ||
| 74 | - // object back, call getObjectHandle() on the returned object. The | ||
| 75 | - // checksum and size are computed automatically and stored. Other | ||
| 76 | - // parameters may be supplied using setters defined below. | 65 | + // Create a new embedded file stream with the given stream data, which can be provided in any of |
| 66 | + // several ways. To get the new object back, call getObjectHandle() on the returned object. The | ||
| 67 | + // checksum and size are computed automatically and stored. Other parameters may be supplied | ||
| 68 | + // using setters defined below. | ||
| 77 | QPDF_DLL | 69 | QPDF_DLL |
| 78 | static QPDFEFStreamObjectHelper createEFStream(QPDF& qpdf, std::shared_ptr<Buffer> data); | 70 | static QPDFEFStreamObjectHelper createEFStream(QPDF& qpdf, std::shared_ptr<Buffer> data); |
| 79 | QPDF_DLL | 71 | QPDF_DLL |
| 80 | static QPDFEFStreamObjectHelper createEFStream(QPDF& qpdf, std::string const& data); | 72 | static QPDFEFStreamObjectHelper createEFStream(QPDF& qpdf, std::string const& data); |
| 81 | - // The provider function must write the data to the given | ||
| 82 | - // pipeline. The function may be called multiple times by the qpdf | ||
| 83 | - // library. You can pass QUtil::file_provider(filename) as the | ||
| 84 | - // provider to have the qpdf library provide the contents of | ||
| 85 | - // filename as a binary. | 73 | + // The provider function must write the data to the given pipeline. The function may be called |
| 74 | + // multiple times by the qpdf library. You can pass QUtil::file_provider(filename) as the | ||
| 75 | + // provider to have the qpdf library provide the contents of filename as a binary. | ||
| 86 | QPDF_DLL | 76 | QPDF_DLL |
| 87 | static QPDFEFStreamObjectHelper | 77 | static QPDFEFStreamObjectHelper |
| 88 | createEFStream(QPDF& qpdf, std::function<void(Pipeline*)> provider); | 78 | createEFStream(QPDF& qpdf, std::function<void(Pipeline*)> provider); |
| @@ -93,8 +83,7 @@ class QPDFEFStreamObjectHelper: public QPDFObjectHelper | @@ -93,8 +83,7 @@ class QPDFEFStreamObjectHelper: public QPDFObjectHelper | ||
| 93 | QPDF_DLL | 83 | QPDF_DLL |
| 94 | QPDFEFStreamObjectHelper& setModDate(std::string const&); | 84 | QPDFEFStreamObjectHelper& setModDate(std::string const&); |
| 95 | 85 | ||
| 96 | - // Set subtype as a mime-type, e.g. "text/plain" or | ||
| 97 | - // "application/pdf". | 86 | + // Set subtype as a mime-type, e.g. "text/plain" or "application/pdf". |
| 98 | QPDF_DLL | 87 | QPDF_DLL |
| 99 | QPDFEFStreamObjectHelper& setSubtype(std::string const&); | 88 | QPDFEFStreamObjectHelper& setSubtype(std::string const&); |
| 100 | 89 |
include/qpdf/QPDFEmbeddedFileDocumentHelper.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFEMBEDDEDFILEDOCUMENTHELPER_HH | 19 | #ifndef QPDFEMBEDDEDFILEDOCUMENTHELPER_HH |
| 23 | #define QPDFEMBEDDEDFILEDOCUMENTHELPER_HH | 20 | #define QPDFEMBEDDEDFILEDOCUMENTHELPER_HH |
| @@ -32,9 +29,9 @@ | @@ -32,9 +29,9 @@ | ||
| 32 | #include <map> | 29 | #include <map> |
| 33 | #include <memory> | 30 | #include <memory> |
| 34 | 31 | ||
| 35 | -// This class provides a higher level interface around document-level | ||
| 36 | -// file attachments, also known as embedded files. These are discussed | ||
| 37 | -// in sections 7.7.4 and 7.11 of the ISO-32000 PDF specification. | 32 | +// This class provides a higher level interface around document-level file attachments, also known |
| 33 | +// as embedded files. These are discussed in sections 7.7.4 and 7.11 of the ISO-32000 PDF | ||
| 34 | +// specification. | ||
| 38 | 35 | ||
| 39 | class QPDFEmbeddedFileDocumentHelper: public QPDFDocumentHelper | 36 | class QPDFEmbeddedFileDocumentHelper: public QPDFDocumentHelper |
| 40 | { | 37 | { |
| @@ -50,8 +47,8 @@ class QPDFEmbeddedFileDocumentHelper: public QPDFDocumentHelper | @@ -50,8 +47,8 @@ class QPDFEmbeddedFileDocumentHelper: public QPDFDocumentHelper | ||
| 50 | QPDF_DLL | 47 | QPDF_DLL |
| 51 | std::map<std::string, std::shared_ptr<QPDFFileSpecObjectHelper>> getEmbeddedFiles(); | 48 | std::map<std::string, std::shared_ptr<QPDFFileSpecObjectHelper>> getEmbeddedFiles(); |
| 52 | 49 | ||
| 53 | - // If an embedded file with the given name exists, return a | ||
| 54 | - // (shared) pointer to it. Otherwise, return nullptr. | 50 | + // If an embedded file with the given name exists, return a (shared) pointer to it. Otherwise, |
| 51 | + // return nullptr. | ||
| 55 | QPDF_DLL | 52 | QPDF_DLL |
| 56 | std::shared_ptr<QPDFFileSpecObjectHelper> getEmbeddedFile(std::string const& name); | 53 | std::shared_ptr<QPDFFileSpecObjectHelper> getEmbeddedFile(std::string const& name); |
| 57 | 54 | ||
| @@ -59,14 +56,11 @@ class QPDFEmbeddedFileDocumentHelper: public QPDFDocumentHelper | @@ -59,14 +56,11 @@ class QPDFEmbeddedFileDocumentHelper: public QPDFDocumentHelper | ||
| 59 | QPDF_DLL | 56 | QPDF_DLL |
| 60 | void replaceEmbeddedFile(std::string const& name, QPDFFileSpecObjectHelper const&); | 57 | void replaceEmbeddedFile(std::string const& name, QPDFFileSpecObjectHelper const&); |
| 61 | 58 | ||
| 62 | - // Remove an embedded file if present. Return value is true if the | ||
| 63 | - // file was present and was removed. This method not only removes | ||
| 64 | - // the embedded file from the embedded files name tree but also | ||
| 65 | - // nulls out the file specification dictionary. This means that | ||
| 66 | - // any references to this file from file attachment annotations | ||
| 67 | - // will also stop working. This is the best way to make the | ||
| 68 | - // attachment actually disappear from the file and not just from | ||
| 69 | - // the list of attachments. | 59 | + // Remove an embedded file if present. Return value is true if the file was present and was |
| 60 | + // removed. This method not only removes the embedded file from the embedded files name tree but | ||
| 61 | + // also nulls out the file specification dictionary. This means that any references to this file | ||
| 62 | + // from file attachment annotations will also stop working. This is the best way to make the | ||
| 63 | + // attachment actually disappear from the file and not just from the list of attachments. | ||
| 70 | QPDF_DLL | 64 | QPDF_DLL |
| 71 | bool removeEmbeddedFile(std::string const& name); | 65 | bool removeEmbeddedFile(std::string const& name); |
| 72 | 66 |
include/qpdf/QPDFFileSpecObjectHelper.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFFILESPECOBJECTHELPER_HH | 19 | #ifndef QPDFFILESPECOBJECTHELPER_HH |
| 23 | #define QPDFFILESPECOBJECTHELPER_HH | 20 | #define QPDFFILESPECOBJECTHELPER_HH |
| @@ -29,9 +26,8 @@ | @@ -29,9 +26,8 @@ | ||
| 29 | #include <qpdf/QPDFEFStreamObjectHelper.hh> | 26 | #include <qpdf/QPDFEFStreamObjectHelper.hh> |
| 30 | #include <qpdf/QPDFObjectHandle.hh> | 27 | #include <qpdf/QPDFObjectHandle.hh> |
| 31 | 28 | ||
| 32 | -// This class provides a higher level interface around File | ||
| 33 | -// Specification dictionaries, which are discussed in section 7.11 of | ||
| 34 | -// the ISO-32000 PDF specification. | 29 | +// This class provides a higher level interface around File Specification dictionaries, which are |
| 30 | +// discussed in section 7.11 of the ISO-32000 PDF specification. | ||
| 35 | 31 | ||
| 36 | class QPDFFileSpecObjectHelper: public QPDFObjectHelper | 32 | class QPDFFileSpecObjectHelper: public QPDFObjectHelper |
| 37 | { | 33 | { |
| @@ -44,45 +40,38 @@ class QPDFFileSpecObjectHelper: public QPDFObjectHelper | @@ -44,45 +40,38 @@ class QPDFFileSpecObjectHelper: public QPDFObjectHelper | ||
| 44 | QPDF_DLL | 40 | QPDF_DLL |
| 45 | std::string getDescription(); | 41 | std::string getDescription(); |
| 46 | 42 | ||
| 47 | - // Get the main filename for this file specification. In priority | ||
| 48 | - // order, check /UF, /F, /Unix, /DOS, /Mac. | 43 | + // Get the main filename for this file specification. In priority order, check /UF, /F, /Unix, |
| 44 | + // /DOS, /Mac. | ||
| 49 | QPDF_DLL | 45 | QPDF_DLL |
| 50 | std::string getFilename(); | 46 | std::string getFilename(); |
| 51 | 47 | ||
| 52 | - // Return any of /UF, /F, /Unix, /DOS, /Mac filename keys that may | ||
| 53 | - // be present in the object. | 48 | + // Return any of /UF, /F, /Unix, /DOS, /Mac filename keys that may be present in the object. |
| 54 | QPDF_DLL | 49 | QPDF_DLL |
| 55 | std::map<std::string, std::string> getFilenames(); | 50 | std::map<std::string, std::string> getFilenames(); |
| 56 | 51 | ||
| 57 | - // Get the requested embedded file stream for this file | ||
| 58 | - // specification. If key is empty, In priority order, check /UF, | ||
| 59 | - // /F, /Unix, /DOS, /Mac. Returns a null object if not found. If | ||
| 60 | - // this is an actual embedded file stream, its data is the content | ||
| 61 | - // of the attachment. You can also use | ||
| 62 | - // QPDFEFStreamObjectHelper for higher level access to | ||
| 63 | - // the parameters. | 52 | + // Get the requested embedded file stream for this file specification. If key is empty, In |
| 53 | + // priority order, check /UF, /F, /Unix, /DOS, /Mac. Returns a null object if not found. If this | ||
| 54 | + // is an actual embedded file stream, its data is the content of the attachment. You can also | ||
| 55 | + // use QPDFEFStreamObjectHelper for higher level access to the parameters. | ||
| 64 | QPDF_DLL | 56 | QPDF_DLL |
| 65 | QPDFObjectHandle getEmbeddedFileStream(std::string const& key = ""); | 57 | QPDFObjectHandle getEmbeddedFileStream(std::string const& key = ""); |
| 66 | 58 | ||
| 67 | - // Return the /EF key of the file spec, which is a map from file | ||
| 68 | - // name key to embedded file stream. | 59 | + // Return the /EF key of the file spec, which is a map from file name key to embedded file |
| 60 | + // stream. | ||
| 69 | QPDF_DLL | 61 | QPDF_DLL |
| 70 | QPDFObjectHandle getEmbeddedFileStreams(); | 62 | QPDFObjectHandle getEmbeddedFileStreams(); |
| 71 | 63 | ||
| 72 | - // Setters return a reference to this object so that they can be | ||
| 73 | - // used as fluent interfaces, e.g. | 64 | + // Setters return a reference to this object so that they can be used as fluent interfaces, e.g. |
| 74 | // fsoh.setDescription(x).setFilename(y); | 65 | // fsoh.setDescription(x).setFilename(y); |
| 75 | 66 | ||
| 76 | - // Create a new filespec as an indirect object with the given | ||
| 77 | - // filename, and attach the contents of the specified file as data | ||
| 78 | - // in an embedded file stream. | 67 | + // Create a new filespec as an indirect object with the given filename, and attach the contents |
| 68 | + // of the specified file as data in an embedded file stream. | ||
| 79 | QPDF_DLL | 69 | QPDF_DLL |
| 80 | static QPDFFileSpecObjectHelper | 70 | static QPDFFileSpecObjectHelper |
| 81 | createFileSpec(QPDF& qpdf, std::string const& filename, std::string const& fullpath); | 71 | createFileSpec(QPDF& qpdf, std::string const& filename, std::string const& fullpath); |
| 82 | 72 | ||
| 83 | - // Create a new filespec as an indirect object with the given | ||
| 84 | - // unicode filename and embedded file stream. The file name will | ||
| 85 | - // be used as both /UF and /F. If you need to override, call | 73 | + // Create a new filespec as an indirect object with the given unicode filename and embedded file |
| 74 | + // stream. The file name will be used as both /UF and /F. If you need to override, call | ||
| 86 | // setFilename. | 75 | // setFilename. |
| 87 | QPDF_DLL | 76 | QPDF_DLL |
| 88 | static QPDFFileSpecObjectHelper | 77 | static QPDFFileSpecObjectHelper |
| @@ -90,11 +79,9 @@ class QPDFFileSpecObjectHelper: public QPDFObjectHelper | @@ -90,11 +79,9 @@ class QPDFFileSpecObjectHelper: public QPDFObjectHelper | ||
| 90 | 79 | ||
| 91 | QPDF_DLL | 80 | QPDF_DLL |
| 92 | QPDFFileSpecObjectHelper& setDescription(std::string const&); | 81 | QPDFFileSpecObjectHelper& setDescription(std::string const&); |
| 93 | - // setFilename sets /UF to unicode_name. If compat_name is empty, | ||
| 94 | - // it is also set to unicode_name. unicode_name should be a UTF-8 | ||
| 95 | - // encoded string. compat_name is converted to a string | ||
| 96 | - // QPDFObjectHandle literally, preserving whatever encoding it | ||
| 97 | - // might happen to have. | 82 | + // setFilename sets /UF to unicode_name. If compat_name is empty, it is also set to |
| 83 | + // unicode_name. unicode_name should be a UTF-8 encoded string. compat_name is converted to a | ||
| 84 | + // string QPDFObjectHandle literally, preserving whatever encoding it might happen to have. | ||
| 98 | QPDF_DLL | 85 | QPDF_DLL |
| 99 | QPDFFileSpecObjectHelper& | 86 | QPDFFileSpecObjectHelper& |
| 100 | setFilename(std::string const& unicode_name, std::string const& compat_name = ""); | 87 | setFilename(std::string const& unicode_name, std::string const& compat_name = ""); |
include/qpdf/QPDFLogger.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFLOGGER_HH | 19 | #ifndef QPDFLOGGER_HH |
| 23 | #define QPDFLOGGER_HH | 20 | #define QPDFLOGGER_HH |
| @@ -33,18 +30,14 @@ class QPDFLogger | @@ -33,18 +30,14 @@ class QPDFLogger | ||
| 33 | QPDF_DLL | 30 | QPDF_DLL |
| 34 | static std::shared_ptr<QPDFLogger> create(); | 31 | static std::shared_ptr<QPDFLogger> create(); |
| 35 | 32 | ||
| 36 | - // Return the default logger. In general, you should use the | ||
| 37 | - // default logger. You can also create your own loggers and use | ||
| 38 | - // them QPDF and QPDFJob objects, but there are few reasons to do | ||
| 39 | - // so. One reason may if you are using multiple QPDF or QPDFJob | ||
| 40 | - // objects in different threads and want to capture output and | ||
| 41 | - // errors to different streams. (Note that a single QPDF or | ||
| 42 | - // QPDFJob can't be safely used from multiple threads, but it is | ||
| 43 | - // safe to use separate QPDF and QPDFJob objects on separate | ||
| 44 | - // threads.) Another possible reason would be if you are writing | ||
| 45 | - // an application that uses the qpdf library directly and qpdf is | ||
| 46 | - // also used by a downstream library or if you are using qpdf from | ||
| 47 | - // a library and don't want to interfere with potential uses of | 33 | + // Return the default logger. In general, you should use the default logger. You can also create |
| 34 | + // your own loggers and use them QPDF and QPDFJob objects, but there are few reasons to do so. | ||
| 35 | + // One reason may if you are using multiple QPDF or QPDFJob objects in different threads and | ||
| 36 | + // want to capture output and errors to different streams. (Note that a single QPDF or QPDFJob | ||
| 37 | + // can't be safely used from multiple threads, but it is safe to use separate QPDF and QPDFJob | ||
| 38 | + // objects on separate threads.) Another possible reason would be if you are writing an | ||
| 39 | + // application that uses the qpdf library directly and qpdf is also used by a downstream library | ||
| 40 | + // or if you are using qpdf from a library and don't want to interfere with potential uses of | ||
| 48 | // qpdf by other libraries or applications. | 41 | // qpdf by other libraries or applications. |
| 49 | QPDF_DLL | 42 | QPDF_DLL |
| 50 | static std::shared_ptr<QPDFLogger> defaultLogger(); | 43 | static std::shared_ptr<QPDFLogger> defaultLogger(); |
| @@ -56,50 +49,40 @@ class QPDFLogger | @@ -56,50 +49,40 @@ class QPDFLogger | ||
| 56 | // error -- standard error | 49 | // error -- standard error |
| 57 | // save -- undefined unless set | 50 | // save -- undefined unless set |
| 58 | // | 51 | // |
| 59 | - // "info" is used for diagnostic messages, verbose messages, and | ||
| 60 | - // progress messages. "warn" is used for warnings. "error" is used | ||
| 61 | - // for errors. "save" is used for saving output -- see below. | 52 | + // "info" is used for diagnostic messages, verbose messages, and progress messages. "warn" is |
| 53 | + // used for warnings. "error" is used for errors. "save" is used for saving output -- see below. | ||
| 62 | // | 54 | // |
| 63 | - // On deletion, finish() is called for the standard output and | ||
| 64 | - // standard error pipelines, which flushes output. If you supply | ||
| 65 | - // any custom pipelines, you must call finish() on them yourself. | ||
| 66 | - // Note that calling finish is not needed for string, stdio, or | ||
| 67 | - // ostream pipelines. | 55 | + // On deletion, finish() is called for the standard output and standard error pipelines, which |
| 56 | + // flushes output. If you supply any custom pipelines, you must call finish() on them yourself. | ||
| 57 | + // Note that calling finish is not needed for string, stdio, or ostream pipelines. | ||
| 68 | // | 58 | // |
| 69 | // NOTES ABOUT THE SAVE PIPELINE | 59 | // NOTES ABOUT THE SAVE PIPELINE |
| 70 | // | 60 | // |
| 71 | - // The save pipeline is used by QPDFJob when some kind of binary | ||
| 72 | - // output is being saved. This includes saving attachments and | ||
| 73 | - // stream data and also includes when the output file is standard | ||
| 74 | - // output. If you want to grab that output, you can call setSave. | ||
| 75 | - // See examples/qpdfjob-save-attachment.cc and | ||
| 76 | - // examples/qpdfjob-c-save-attachment.c. | 61 | + // The save pipeline is used by QPDFJob when some kind of binary output is being saved. This |
| 62 | + // includes saving attachments and stream data and also includes when the output file is | ||
| 63 | + // standard output. If you want to grab that output, you can call setSave. See | ||
| 64 | + // examples/qpdfjob-save-attachment.cc and examples/qpdfjob-c-save-attachment.c. | ||
| 77 | // | 65 | // |
| 78 | - // You should never set the save pipeline to the same destination | ||
| 79 | - // as something else. Doing so will corrupt your save output. If | ||
| 80 | - // you want to save to standard output, use the method | ||
| 81 | - // saveToStandardOutput(). In addition to setting the save | ||
| 82 | - // pipeline, that does the following extra things: | 66 | + // You should never set the save pipeline to the same destination as something else. Doing so |
| 67 | + // will corrupt your save output. If you want to save to standard output, use the method | ||
| 68 | + // saveToStandardOutput(). In addition to setting the save pipeline, that does the following | ||
| 69 | + // extra things: | ||
| 83 | // | 70 | // |
| 84 | // * If standard output has been used, a logic error is thrown | 71 | // * If standard output has been used, a logic error is thrown |
| 85 | - // * If info is set to standard output at the time of the set save | ||
| 86 | - // call, it is switched to standard error. | 72 | + // * If info is set to standard output at the time of the set save call, it is switched to |
| 73 | + // standard error. | ||
| 87 | // | 74 | // |
| 88 | - // This is not a guarantee. You can still mess this up in ways | ||
| 89 | - // that are not checked. Here are a few examples: | 75 | + // This is not a guarantee. You can still mess this up in ways that are not checked. Here are a |
| 76 | + // few examples: | ||
| 90 | // | 77 | // |
| 91 | - // * Don't set any pipeline to standard output *after* passing it | ||
| 92 | - // to setSave() | ||
| 93 | - // * Don't use a separate mechanism to write stdout/stderr other | ||
| 94 | - // than QPDFLogger::standardOutput() | ||
| 95 | - // * Don't set anything to the same custom pipeline that save is | ||
| 96 | - // set to. | 78 | + // * Don't set any pipeline to standard output *after* passing it to setSave() |
| 79 | + // * Don't use a separate mechanism to write stdout/stderr other than | ||
| 80 | + // QPDFLogger::standardOutput() | ||
| 81 | + // * Don't set anything to the same custom pipeline that save is set to. | ||
| 97 | // | 82 | // |
| 98 | - // Just be sure that if you change pipelines around, you should | ||
| 99 | - // avoid having the save pipeline also be used for any other | ||
| 100 | - // purpose. The special case for saving to standard output allows | ||
| 101 | - // you to call saveToStandardOutput() early without having to | ||
| 102 | - // worry about the info pipeline. | 83 | + // Just be sure that if you change pipelines around, you should avoid having the save pipeline |
| 84 | + // also be used for any other purpose. The special case for saving to standard output allows you | ||
| 85 | + // to call saveToStandardOutput() early without having to worry about the info pipeline. | ||
| 103 | 86 | ||
| 104 | QPDF_DLL | 87 | QPDF_DLL |
| 105 | void info(char const*); | 88 | void info(char const*); |
| @@ -145,9 +128,8 @@ class QPDFLogger | @@ -145,9 +128,8 @@ class QPDFLogger | ||
| 145 | QPDF_DLL | 128 | QPDF_DLL |
| 146 | void saveToStandardOutput(bool only_if_not_set); | 129 | void saveToStandardOutput(bool only_if_not_set); |
| 147 | 130 | ||
| 148 | - // Shortcut for logic to reset output to new output/error streams. | ||
| 149 | - // out_stream is used for info, err_stream is used for error, and | ||
| 150 | - // warning is cleared so that it follows error. | 131 | + // Shortcut for logic to reset output to new output/error streams. out_stream is used for info, |
| 132 | + // err_stream is used for error, and warning is cleared so that it follows error. | ||
| 151 | QPDF_DLL | 133 | QPDF_DLL |
| 152 | void setOutputStreams(std::ostream* out_stream, std::ostream* err_stream); | 134 | void setOutputStreams(std::ostream* out_stream, std::ostream* err_stream); |
| 153 | 135 |
include/qpdf/QPDFMatrix.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFMATRIX_HH | 19 | #ifndef QPDFMATRIX_HH |
| 23 | #define QPDFMATRIX_HH | 20 | #define QPDFMATRIX_HH |
| @@ -26,8 +23,7 @@ | @@ -26,8 +23,7 @@ | ||
| 26 | #include <qpdf/QPDFObjectHandle.hh> | 23 | #include <qpdf/QPDFObjectHandle.hh> |
| 27 | #include <string> | 24 | #include <string> |
| 28 | 25 | ||
| 29 | -// This class represents a PDF transformation matrix using a tuple | ||
| 30 | -// such that | 26 | +// This class represents a PDF transformation matrix using a tuple such that |
| 31 | // | 27 | // |
| 32 | // โ โ | 28 | // โ โ |
| 33 | // โ a b 0 โ | 29 | // โ a b 0 โ |
| @@ -45,8 +41,7 @@ class QPDFMatrix | @@ -45,8 +41,7 @@ class QPDFMatrix | ||
| 45 | QPDF_DLL | 41 | QPDF_DLL |
| 46 | QPDFMatrix(QPDFObjectHandle::Matrix const&); | 42 | QPDFMatrix(QPDFObjectHandle::Matrix const&); |
| 47 | 43 | ||
| 48 | - // Returns the six values separated by spaces as real numbers with | ||
| 49 | - // trimmed zeroes. | 44 | + // Returns the six values separated by spaces as real numbers with trimmed zeroes. |
| 50 | QPDF_DLL | 45 | QPDF_DLL |
| 51 | std::string unparse() const; | 46 | std::string unparse() const; |
| 52 | 47 | ||
| @@ -75,14 +70,12 @@ class QPDFMatrix | @@ -75,14 +70,12 @@ class QPDFMatrix | ||
| 75 | QPDF_DLL | 70 | QPDF_DLL |
| 76 | void transform(double x, double y, double& xp, double& yp) const; | 71 | void transform(double x, double y, double& xp, double& yp) const; |
| 77 | 72 | ||
| 78 | - // Transform a rectangle by creating a new rectangle that tightly | ||
| 79 | - // bounds the polygon resulting from transforming the four | ||
| 80 | - // corners. | 73 | + // Transform a rectangle by creating a new rectangle that tightly bounds the polygon resulting |
| 74 | + // from transforming the four corners. | ||
| 81 | QPDF_DLL | 75 | QPDF_DLL |
| 82 | QPDFObjectHandle::Rectangle transformRectangle(QPDFObjectHandle::Rectangle r) const; | 76 | QPDFObjectHandle::Rectangle transformRectangle(QPDFObjectHandle::Rectangle r) const; |
| 83 | 77 | ||
| 84 | - // operator== tests for exact equality, not considering deltas for | ||
| 85 | - // floating point. | 78 | + // operator== tests for exact equality, not considering deltas for floating point. |
| 86 | QPDF_DLL | 79 | QPDF_DLL |
| 87 | bool operator==(QPDFMatrix const& rhs) const; | 80 | bool operator==(QPDFMatrix const& rhs) const; |
| 88 | QPDF_DLL | 81 | QPDF_DLL |
include/qpdf/QPDFNameTreeObjectHelper.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFNAMETREEOBJECTHELPER_HH | 19 | #ifndef QPDFNAMETREEOBJECTHELPER_HH |
| 23 | #define QPDFNAMETREEOBJECTHELPER_HH | 20 | #define QPDFNAMETREEOBJECTHELPER_HH |
| @@ -30,13 +27,11 @@ | @@ -30,13 +27,11 @@ | ||
| 30 | 27 | ||
| 31 | #include <qpdf/DLL.h> | 28 | #include <qpdf/DLL.h> |
| 32 | 29 | ||
| 33 | -// This is an object helper for name trees. See section 7.9.6 in the | ||
| 34 | -// PDF spec (ISO 32000) for a description of name trees. When looking | ||
| 35 | -// up items in the name tree, use UTF-8 strings. All names are | ||
| 36 | -// normalized for lookup purposes. | 30 | +// This is an object helper for name trees. See section 7.9.6 in the PDF spec (ISO 32000) for a |
| 31 | +// description of name trees. When looking up items in the name tree, use UTF-8 strings. All names | ||
| 32 | +// are normalized for lookup purposes. | ||
| 37 | 33 | ||
| 38 | -// See examples/pdf-name-number-tree.cc for a demonstration of using | ||
| 39 | -// QPDFNameTreeObjectHelper. | 34 | +// See examples/pdf-name-number-tree.cc for a demonstration of using QPDFNameTreeObjectHelper. |
| 40 | 35 | ||
| 41 | class NNTreeImpl; | 36 | class NNTreeImpl; |
| 42 | class NNTreeIterator; | 37 | class NNTreeIterator; |
| @@ -45,8 +40,8 @@ class NNTreeDetails; | @@ -45,8 +40,8 @@ class NNTreeDetails; | ||
| 45 | class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper | 40 | class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper |
| 46 | { | 41 | { |
| 47 | public: | 42 | public: |
| 48 | - // The qpdf object is required so that this class can issue | ||
| 49 | - // warnings, attempt repairs, and add indirect objects. | 43 | + // The qpdf object is required so that this class can issue warnings, attempt repairs, and add |
| 44 | + // indirect objects. | ||
| 50 | QPDF_DLL | 45 | QPDF_DLL |
| 51 | QPDFNameTreeObjectHelper(QPDFObjectHandle, QPDF&, bool auto_repair = true); | 46 | QPDFNameTreeObjectHelper(QPDFObjectHandle, QPDF&, bool auto_repair = true); |
| 52 | 47 | ||
| @@ -57,13 +52,11 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper | @@ -57,13 +52,11 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper | ||
| 57 | QPDF_DLL | 52 | QPDF_DLL |
| 58 | virtual ~QPDFNameTreeObjectHelper(); | 53 | virtual ~QPDFNameTreeObjectHelper(); |
| 59 | 54 | ||
| 60 | - // Return whether the number tree has an explicit entry for this | ||
| 61 | - // number. | 55 | + // Return whether the number tree has an explicit entry for this number. |
| 62 | QPDF_DLL | 56 | QPDF_DLL |
| 63 | bool hasName(std::string const& utf8); | 57 | bool hasName(std::string const& utf8); |
| 64 | 58 | ||
| 65 | - // Find an object by name. If found, returns true and initializes | ||
| 66 | - // oh. See also find(). | 59 | + // Find an object by name. If found, returns true and initializes oh. See also find(). |
| 67 | QPDF_DLL | 60 | QPDF_DLL |
| 68 | bool findObject(std::string const& utf8, QPDFObjectHandle& oh); | 61 | bool findObject(std::string const& utf8, QPDFObjectHandle& oh); |
| 69 | 62 | ||
| @@ -115,21 +108,17 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper | @@ -115,21 +108,17 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper | ||
| 115 | return !operator==(other); | 108 | return !operator==(other); |
| 116 | } | 109 | } |
| 117 | 110 | ||
| 118 | - // DANGER: this method can create inconsistent trees if not | ||
| 119 | - // used properly! Insert a new item immediately after the | ||
| 120 | - // current iterator and increment so that it points to the new | ||
| 121 | - // item. If the current iterator is end(), insert at the | ||
| 122 | - // beginning. This method does not check for proper ordering, | ||
| 123 | - // so if you use it, you must ensure that the item you are | ||
| 124 | - // inserting belongs where you are putting it. The reason for | ||
| 125 | - // this method is that it is more efficient than insert() and | ||
| 126 | - // can be used safely when you are creating a new tree and | ||
| 127 | - // inserting items in sorted order. | 111 | + // DANGER: this method can create inconsistent trees if not used properly! Insert a new item |
| 112 | + // immediately after the current iterator and increment so that it points to the new item. | ||
| 113 | + // If the current iterator is end(), insert at the beginning. This method does not check for | ||
| 114 | + // proper ordering, so if you use it, you must ensure that the item you are inserting | ||
| 115 | + // belongs where you are putting it. The reason for this method is that it is more efficient | ||
| 116 | + // than insert() and can be used safely when you are creating a new tree and inserting items | ||
| 117 | + // in sorted order. | ||
| 128 | QPDF_DLL | 118 | QPDF_DLL |
| 129 | void insertAfter(std::string const& key, QPDFObjectHandle value); | 119 | void insertAfter(std::string const& key, QPDFObjectHandle value); |
| 130 | 120 | ||
| 131 | - // Remove the current item and advance the iterator to the | ||
| 132 | - // next item. | 121 | + // Remove the current item and advance the iterator to the next item. |
| 133 | QPDF_DLL | 122 | QPDF_DLL |
| 134 | void remove(); | 123 | void remove(); |
| 135 | 124 | ||
| @@ -141,10 +130,9 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper | @@ -141,10 +130,9 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper | ||
| 141 | value_type ivalue; | 130 | value_type ivalue; |
| 142 | }; | 131 | }; |
| 143 | 132 | ||
| 144 | - // The iterator looks like map iterator, so i.first is a string | ||
| 145 | - // and i.second is a QPDFObjectHandle. Incrementing end() brings | ||
| 146 | - // you to the first item. Decrementing end() brings you to the | ||
| 147 | - // last item. | 133 | + // The iterator looks like map iterator, so i.first is a string and i.second is a |
| 134 | + // QPDFObjectHandle. Incrementing end() brings you to the first item. Decrementing end() brings | ||
| 135 | + // you to the last item. | ||
| 148 | QPDF_DLL | 136 | QPDF_DLL |
| 149 | iterator begin() const; | 137 | iterator begin() const; |
| 150 | QPDF_DLL | 138 | QPDF_DLL |
| @@ -153,8 +141,8 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper | @@ -153,8 +141,8 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper | ||
| 153 | QPDF_DLL | 141 | QPDF_DLL |
| 154 | iterator last() const; | 142 | iterator last() const; |
| 155 | 143 | ||
| 156 | - // Find the entry with the given key. If return_prev_if_not_found | ||
| 157 | - // is true and the item is not found, return the next lower item. | 144 | + // Find the entry with the given key. If return_prev_if_not_found is true and the item is not |
| 145 | + // found, return the next lower item. | ||
| 158 | QPDF_DLL | 146 | QPDF_DLL |
| 159 | iterator find(std::string const& key, bool return_prev_if_not_found = false); | 147 | iterator find(std::string const& key, bool return_prev_if_not_found = false); |
| 160 | 148 | ||
| @@ -162,20 +150,18 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper | @@ -162,20 +150,18 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper | ||
| 162 | QPDF_DLL | 150 | QPDF_DLL |
| 163 | iterator insert(std::string const& key, QPDFObjectHandle value); | 151 | iterator insert(std::string const& key, QPDFObjectHandle value); |
| 164 | 152 | ||
| 165 | - // Remove an item. Return true if the item was found and removed; | ||
| 166 | - // otherwise return false. If value is not null, initialize it to | ||
| 167 | - // the value that was removed. | 153 | + // Remove an item. Return true if the item was found and removed; otherwise return false. If |
| 154 | + // value is not null, initialize it to the value that was removed. | ||
| 168 | QPDF_DLL | 155 | QPDF_DLL |
| 169 | bool remove(std::string const& key, QPDFObjectHandle* value = nullptr); | 156 | bool remove(std::string const& key, QPDFObjectHandle* value = nullptr); |
| 170 | 157 | ||
| 171 | - // Return the contents of the name tree as a map. Note that name | ||
| 172 | - // trees may be very large, so this may use a lot of RAM. It is | ||
| 173 | - // more efficient to use QPDFNameTreeObjectHelper's iterator. | 158 | + // Return the contents of the name tree as a map. Note that name trees may be very large, so |
| 159 | + // this may use a lot of RAM. It is more efficient to use QPDFNameTreeObjectHelper's iterator. | ||
| 174 | QPDF_DLL | 160 | QPDF_DLL |
| 175 | std::map<std::string, QPDFObjectHandle> getAsMap() const; | 161 | std::map<std::string, QPDFObjectHandle> getAsMap() const; |
| 176 | 162 | ||
| 177 | - // Split a node if the number of items exceeds this value. There's | ||
| 178 | - // no real reason to ever set this except for testing. | 163 | + // Split a node if the number of items exceeds this value. There's no real reason to ever set |
| 164 | + // this except for testing. | ||
| 179 | QPDF_DLL | 165 | QPDF_DLL |
| 180 | void setSplitThreshold(int); | 166 | void setSplitThreshold(int); |
| 181 | 167 |
include/qpdf/QPDFNumberTreeObjectHelper.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFNUMBERTREEOBJECTHELPER_HH | 19 | #ifndef QPDFNUMBERTREEOBJECTHELPER_HH |
| 23 | #define QPDFNUMBERTREEOBJECTHELPER_HH | 20 | #define QPDFNUMBERTREEOBJECTHELPER_HH |
| @@ -29,11 +26,10 @@ | @@ -29,11 +26,10 @@ | ||
| 29 | 26 | ||
| 30 | #include <qpdf/DLL.h> | 27 | #include <qpdf/DLL.h> |
| 31 | 28 | ||
| 32 | -// This is an object helper for number trees. See section 7.9.7 in the | ||
| 33 | -// PDF spec (ISO 32000) for a description of number trees. | 29 | +// This is an object helper for number trees. See section 7.9.7 in the PDF spec (ISO 32000) for a |
| 30 | +// description of number trees. | ||
| 34 | 31 | ||
| 35 | -// See examples/pdf-name-number-tree.cc for a demonstration of using | ||
| 36 | -// QPDFNumberTreeObjectHelper. | 32 | +// See examples/pdf-name-number-tree.cc for a demonstration of using QPDFNumberTreeObjectHelper. |
| 37 | 33 | ||
| 38 | class NNTreeImpl; | 34 | class NNTreeImpl; |
| 39 | class NNTreeIterator; | 35 | class NNTreeIterator; |
| @@ -42,8 +38,8 @@ class NNTreeDetails; | @@ -42,8 +38,8 @@ class NNTreeDetails; | ||
| 42 | class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper | 38 | class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper |
| 43 | { | 39 | { |
| 44 | public: | 40 | public: |
| 45 | - // The qpdf object is required so that this class can issue | ||
| 46 | - // warnings, attempt repairs, and add indirect objects. | 41 | + // The qpdf object is required so that this class can issue warnings, attempt repairs, and add |
| 42 | + // indirect objects. | ||
| 47 | QPDF_DLL | 43 | QPDF_DLL |
| 48 | QPDFNumberTreeObjectHelper(QPDFObjectHandle, QPDF&, bool auto_repair = true); | 44 | QPDFNumberTreeObjectHelper(QPDFObjectHandle, QPDF&, bool auto_repair = true); |
| 49 | 45 | ||
| @@ -62,24 +58,20 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper | @@ -62,24 +58,20 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper | ||
| 62 | QPDF_DLL | 58 | QPDF_DLL |
| 63 | numtree_number getMax(); | 59 | numtree_number getMax(); |
| 64 | 60 | ||
| 65 | - // Return whether the number tree has an explicit entry for this | ||
| 66 | - // number. | 61 | + // Return whether the number tree has an explicit entry for this number. |
| 67 | QPDF_DLL | 62 | QPDF_DLL |
| 68 | bool hasIndex(numtree_number idx); | 63 | bool hasIndex(numtree_number idx); |
| 69 | 64 | ||
| 70 | - // Find an object with a specific index. If found, returns true | ||
| 71 | - // and initializes oh. See also find(). | 65 | + // Find an object with a specific index. If found, returns true and initializes oh. See also |
| 66 | + // find(). | ||
| 72 | QPDF_DLL | 67 | QPDF_DLL |
| 73 | bool findObject(numtree_number idx, QPDFObjectHandle& oh); | 68 | bool findObject(numtree_number idx, QPDFObjectHandle& oh); |
| 74 | - // Find the object at the index or, if not found, the object whose | ||
| 75 | - // index is the highest index less than the requested index. If | ||
| 76 | - // the requested index is less than the minimum, return false. | ||
| 77 | - // Otherwise, return true, initialize oh to the object, and set | ||
| 78 | - // offset to the difference between the requested index and the | ||
| 79 | - // actual index. For example, if a number tree has values for 3 | ||
| 80 | - // and 6 and idx is 5, this method would return true, initialize | ||
| 81 | - // oh to the value with index 3, and set offset to 2 (5 - 3). See | ||
| 82 | - // also find(). | 69 | + // Find the object at the index or, if not found, the object whose index is the highest index |
| 70 | + // less than the requested index. If the requested index is less than the minimum, return false. | ||
| 71 | + // Otherwise, return true, initialize oh to the object, and set offset to the difference between | ||
| 72 | + // the requested index and the actual index. For example, if a number tree has values for 3 and | ||
| 73 | + // 6 and idx is 5, this method would return true, initialize oh to the value with index 3, and | ||
| 74 | + // set offset to 2 (5 - 3). See also find(). | ||
| 83 | QPDF_DLL | 75 | QPDF_DLL |
| 84 | bool findObjectAtOrBelow(numtree_number idx, QPDFObjectHandle& oh, numtree_number& offset); | 76 | bool findObjectAtOrBelow(numtree_number idx, QPDFObjectHandle& oh, numtree_number& offset); |
| 85 | 77 | ||
| @@ -131,21 +123,17 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper | @@ -131,21 +123,17 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper | ||
| 131 | return !operator==(other); | 123 | return !operator==(other); |
| 132 | } | 124 | } |
| 133 | 125 | ||
| 134 | - // DANGER: this method can create inconsistent trees if not | ||
| 135 | - // used properly! Insert a new item immediately after the | ||
| 136 | - // current iterator and increment so that it points to the new | ||
| 137 | - // item. If the current iterator is end(), insert at the | ||
| 138 | - // beginning. This method does not check for proper ordering, | ||
| 139 | - // so if you use it, you must ensure that the item you are | ||
| 140 | - // inserting belongs where you are putting it. The reason for | ||
| 141 | - // this method is that it is more efficient than insert() and | ||
| 142 | - // can be used safely when you are creating a new tree and | ||
| 143 | - // inserting items in sorted order. | 126 | + // DANGER: this method can create inconsistent trees if not used properly! Insert a new item |
| 127 | + // immediately after the current iterator and increment so that it points to the new item. | ||
| 128 | + // If the current iterator is end(), insert at the beginning. This method does not check for | ||
| 129 | + // proper ordering, so if you use it, you must ensure that the item you are inserting | ||
| 130 | + // belongs where you are putting it. The reason for this method is that it is more efficient | ||
| 131 | + // than insert() and can be used safely when you are creating a new tree and inserting items | ||
| 132 | + // in sorted order. | ||
| 144 | QPDF_DLL | 133 | QPDF_DLL |
| 145 | void insertAfter(numtree_number key, QPDFObjectHandle value); | 134 | void insertAfter(numtree_number key, QPDFObjectHandle value); |
| 146 | 135 | ||
| 147 | - // Remove the current item and advance the iterator to the | ||
| 148 | - // next item. | 136 | + // Remove the current item and advance the iterator to the next item. |
| 149 | QPDF_DLL | 137 | QPDF_DLL |
| 150 | void remove(); | 138 | void remove(); |
| 151 | 139 | ||
| @@ -157,10 +145,9 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper | @@ -157,10 +145,9 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper | ||
| 157 | value_type ivalue; | 145 | value_type ivalue; |
| 158 | }; | 146 | }; |
| 159 | 147 | ||
| 160 | - // The iterator looks like map iterator, so i.first is a string | ||
| 161 | - // and i.second is a QPDFObjectHandle. Incrementing end() brings | ||
| 162 | - // you to the first item. Decrementing end() brings you to the | ||
| 163 | - // last item. | 148 | + // The iterator looks like map iterator, so i.first is a string and i.second is a |
| 149 | + // QPDFObjectHandle. Incrementing end() brings you to the first item. Decrementing end() brings | ||
| 150 | + // you to the last item. | ||
| 164 | QPDF_DLL | 151 | QPDF_DLL |
| 165 | iterator begin() const; | 152 | iterator begin() const; |
| 166 | QPDF_DLL | 153 | QPDF_DLL |
| @@ -169,8 +156,8 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper | @@ -169,8 +156,8 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper | ||
| 169 | QPDF_DLL | 156 | QPDF_DLL |
| 170 | iterator last() const; | 157 | iterator last() const; |
| 171 | 158 | ||
| 172 | - // Find the entry with the given key. If return_prev_if_not_found | ||
| 173 | - // is true and the item is not found, return the next lower item. | 159 | + // Find the entry with the given key. If return_prev_if_not_found is true and the item is not |
| 160 | + // found, return the next lower item. | ||
| 174 | QPDF_DLL | 161 | QPDF_DLL |
| 175 | iterator find(numtree_number key, bool return_prev_if_not_found = false); | 162 | iterator find(numtree_number key, bool return_prev_if_not_found = false); |
| 176 | 163 | ||
| @@ -178,22 +165,19 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper | @@ -178,22 +165,19 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper | ||
| 178 | QPDF_DLL | 165 | QPDF_DLL |
| 179 | iterator insert(numtree_number key, QPDFObjectHandle value); | 166 | iterator insert(numtree_number key, QPDFObjectHandle value); |
| 180 | 167 | ||
| 181 | - // Remove an item. Return true if the item was found and removed; | ||
| 182 | - // otherwise return false. If value is not null, initialize it to | ||
| 183 | - // the value that was removed. | 168 | + // Remove an item. Return true if the item was found and removed; otherwise return false. If |
| 169 | + // value is not null, initialize it to the value that was removed. | ||
| 184 | QPDF_DLL | 170 | QPDF_DLL |
| 185 | bool remove(numtree_number key, QPDFObjectHandle* value = nullptr); | 171 | bool remove(numtree_number key, QPDFObjectHandle* value = nullptr); |
| 186 | 172 | ||
| 187 | - // Return the contents of the number tree as a map. Note that | ||
| 188 | - // number trees may be very large, so this may use a lot of RAM. | ||
| 189 | - // It is more efficient to use QPDFNumberTreeObjectHelper's | ||
| 190 | - // iterator. | 173 | + // Return the contents of the number tree as a map. Note that number trees may be very large, so |
| 174 | + // this may use a lot of RAM. It is more efficient to use QPDFNumberTreeObjectHelper's iterator. | ||
| 191 | typedef std::map<numtree_number, QPDFObjectHandle> idx_map; | 175 | typedef std::map<numtree_number, QPDFObjectHandle> idx_map; |
| 192 | QPDF_DLL | 176 | QPDF_DLL |
| 193 | idx_map getAsMap() const; | 177 | idx_map getAsMap() const; |
| 194 | 178 | ||
| 195 | - // Split a node if the number of items exceeds this value. There's | ||
| 196 | - // no real reason to ever set this except for testing. | 179 | + // Split a node if the number of items exceeds this value. There's no real reason to ever set |
| 180 | + // this except for testing. | ||
| 197 | QPDF_DLL | 181 | QPDF_DLL |
| 198 | void setSplitThreshold(int); | 182 | void setSplitThreshold(int); |
| 199 | 183 |
include/qpdf/QPDFObjGen.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFOBJGEN_HH | 19 | #ifndef QPDFOBJGEN_HH |
| 23 | #define QPDFOBJGEN_HH | 20 | #define QPDFOBJGEN_HH |
| @@ -29,8 +26,8 @@ | @@ -29,8 +26,8 @@ | ||
| 29 | class QPDFObjectHandle; | 26 | class QPDFObjectHandle; |
| 30 | class QPDFObjectHelper; | 27 | class QPDFObjectHelper; |
| 31 | 28 | ||
| 32 | -// This class represents an object ID and generation pair. It is | ||
| 33 | -// suitable to use as a key in a map or set. | 29 | +// This class represents an object ID and generation pair. It is suitable to use as a key in a map |
| 30 | +// or set. | ||
| 34 | 31 | ||
| 35 | class QPDFObjGen | 32 | class QPDFObjGen |
| 36 | { | 33 | { |
| @@ -91,13 +88,11 @@ class QPDFObjGen | @@ -91,13 +88,11 @@ class QPDFObjGen | ||
| 91 | 88 | ||
| 92 | // Convenience class for loop detection when processing objects. | 89 | // Convenience class for loop detection when processing objects. |
| 93 | // | 90 | // |
| 94 | - // The class adds 'add' methods to a std::set<QPDFObjGen> which allows | ||
| 95 | - // to test whether an QPDFObjGen is present in the set and to insert it in | ||
| 96 | - // a single operation. The 'add' method is overloaded to take a QPDFObjGen, | ||
| 97 | - // QPDFObjectHandle or an QPDFObjectHelper as parameter. | 91 | + // The class adds 'add' methods to a std::set<QPDFObjGen> which allows to test whether an |
| 92 | + // QPDFObjGen is present in the set and to insert it in a single operation. The 'add' method is | ||
| 93 | + // overloaded to take a QPDFObjGen, QPDFObjectHandle or an QPDFObjectHelper as parameter. | ||
| 98 | // | 94 | // |
| 99 | - // The erase method is modified to ignore requests to erase | ||
| 100 | - // QPDFObjGen(0, 0). | 95 | + // The erase method is modified to ignore requests to erase QPDFObjGen(0, 0). |
| 101 | // | 96 | // |
| 102 | // Usage example: | 97 | // Usage example: |
| 103 | // | 98 | // |
| @@ -112,8 +107,8 @@ class QPDFObjGen | @@ -112,8 +107,8 @@ class QPDFObjGen | ||
| 112 | class QPDF_DLL_CLASS set: public std::set<QPDFObjGen> | 107 | class QPDF_DLL_CLASS set: public std::set<QPDFObjGen> |
| 113 | { | 108 | { |
| 114 | public: | 109 | public: |
| 115 | - // Add 'og' to the set. Return false if 'og' is already present in | ||
| 116 | - // the set. Attempts to insert QPDFObjGen(0, 0) are ignored. | 110 | + // Add 'og' to the set. Return false if 'og' is already present in the set. Attempts to |
| 111 | + // insert QPDFObjGen(0, 0) are ignored. | ||
| 117 | QPDF_DLL | 112 | QPDF_DLL |
| 118 | bool | 113 | bool |
| 119 | add(QPDFObjGen og) | 114 | add(QPDFObjGen og) |
| @@ -150,9 +145,8 @@ class QPDFObjGen | @@ -150,9 +145,8 @@ class QPDFObjGen | ||
| 150 | }; | 145 | }; |
| 151 | 146 | ||
| 152 | private: | 147 | private: |
| 153 | - // This class does not use the Members pattern to avoid a memory | ||
| 154 | - // allocation for every one of these. A lot of these get created | ||
| 155 | - // and destroyed. | 148 | + // This class does not use the Members pattern to avoid a memory allocation for every one of |
| 149 | + // these. A lot of these get created and destroyed. | ||
| 156 | int obj{0}; | 150 | int obj{0}; |
| 157 | int gen{0}; | 151 | int gen{0}; |
| 158 | }; | 152 | }; |
include/qpdf/QPDFObjectHelper.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFOBJECTHELPER_HH | 19 | #ifndef QPDFOBJECTHELPER_HH |
| 23 | #define QPDFOBJECTHELPER_HH | 20 | #define QPDFOBJECTHELPER_HH |
| @@ -26,16 +23,13 @@ | @@ -26,16 +23,13 @@ | ||
| 26 | 23 | ||
| 27 | #include <qpdf/QPDFObjectHandle.hh> | 24 | #include <qpdf/QPDFObjectHandle.hh> |
| 28 | 25 | ||
| 29 | -// This is a base class for QPDF Object Helper classes. Object helpers | ||
| 30 | -// are classes that provide a convenient, higher-level API for working | ||
| 31 | -// with specific types of QPDF objects. Object helpers are always | ||
| 32 | -// initialized with a QPDFObjectHandle, and the underlying object | ||
| 33 | -// handle can always be retrieved. The intention is that you may | ||
| 34 | -// freely intermix use of document helpers with the underlying QPDF | ||
| 35 | -// objects unless there is a specific comment in a specific helper | ||
| 36 | -// method that says otherwise. The pattern of using helper objects was | ||
| 37 | -// introduced to allow creation of higher level helper functions | ||
| 38 | -// without polluting the public interface of QPDFObjectHandle. | 26 | +// This is a base class for QPDF Object Helper classes. Object helpers are classes that provide a |
| 27 | +// convenient, higher-level API for working with specific types of QPDF objects. Object helpers are | ||
| 28 | +// always initialized with a QPDFObjectHandle, and the underlying object handle can always be | ||
| 29 | +// retrieved. The intention is that you may freely intermix use of document helpers with the | ||
| 30 | +// underlying QPDF objects unless there is a specific comment in a specific helper method that says | ||
| 31 | +// otherwise. The pattern of using helper objects was introduced to allow creation of higher level | ||
| 32 | +// helper functions without polluting the public interface of QPDFObjectHandle. | ||
| 39 | 33 | ||
| 40 | class QPDF_DLL_CLASS QPDFObjectHelper | 34 | class QPDF_DLL_CLASS QPDFObjectHelper |
| 41 | { | 35 | { |
include/qpdf/QPDFOutlineDocumentHelper.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFOUTLINEDOCUMENTHELPER_HH | 19 | #ifndef QPDFOUTLINEDOCUMENTHELPER_HH |
| 23 | #define QPDFOUTLINEDOCUMENTHELPER_HH | 20 | #define QPDFOUTLINEDOCUMENTHELPER_HH |
| @@ -33,11 +30,10 @@ | @@ -33,11 +30,10 @@ | ||
| 33 | 30 | ||
| 34 | #include <qpdf/DLL.h> | 31 | #include <qpdf/DLL.h> |
| 35 | 32 | ||
| 36 | -// This is a document helper for outlines, also known as bookmarks. | ||
| 37 | -// Outlines are discussed in section 12.3.3 of the PDF spec | ||
| 38 | -// (ISO-32000). With the help of QPDFOutlineObjectHelper, the outlines | ||
| 39 | -// tree is traversed, and a bidirectional map is made between pages | ||
| 40 | -// and outlines. See also QPDFOutlineObjectHelper. | 33 | +// This is a document helper for outlines, also known as bookmarks. Outlines are discussed in |
| 34 | +// section 12.3.3 of the PDF spec (ISO-32000). With the help of QPDFOutlineObjectHelper, the | ||
| 35 | +// outlines tree is traversed, and a bidirectional map is made between pages and outlines. See also | ||
| 36 | +// QPDFOutlineObjectHelper. | ||
| 41 | 37 | ||
| 42 | class QPDFOutlineDocumentHelper: public QPDFDocumentHelper | 38 | class QPDFOutlineDocumentHelper: public QPDFDocumentHelper |
| 43 | { | 39 | { |
| @@ -53,15 +49,13 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper | @@ -53,15 +49,13 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper | ||
| 53 | QPDF_DLL | 49 | QPDF_DLL |
| 54 | std::vector<QPDFOutlineObjectHelper> getTopLevelOutlines(); | 50 | std::vector<QPDFOutlineObjectHelper> getTopLevelOutlines(); |
| 55 | 51 | ||
| 56 | - // If the name is a name object, look it up in the /Dests key of | ||
| 57 | - // the document catalog. If the name is a string, look it up in | ||
| 58 | - // the name tree pointed to by the /Dests key of the names | 52 | + // If the name is a name object, look it up in the /Dests key of the document catalog. If the |
| 53 | + // name is a string, look it up in the name tree pointed to by the /Dests key of the names | ||
| 59 | // dictionary. | 54 | // dictionary. |
| 60 | QPDF_DLL | 55 | QPDF_DLL |
| 61 | QPDFObjectHandle resolveNamedDest(QPDFObjectHandle name); | 56 | QPDFObjectHandle resolveNamedDest(QPDFObjectHandle name); |
| 62 | 57 | ||
| 63 | - // Return a list outlines that are known to target the specified | ||
| 64 | - // page | 58 | + // Return a list outlines that are known to target the specified page |
| 65 | QPDF_DLL | 59 | QPDF_DLL |
| 66 | std::vector<QPDFOutlineObjectHelper> getOutlinesForPage(QPDFObjGen const&); | 60 | std::vector<QPDFOutlineObjectHelper> getOutlinesForPage(QPDFObjGen const&); |
| 67 | 61 |
include/qpdf/QPDFOutlineObjectHelper.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFOUTLINEOBJECTHELPER_HH | 19 | #ifndef QPDFOUTLINEOBJECTHELPER_HH |
| 23 | #define QPDFOUTLINEOBJECTHELPER_HH | 20 | #define QPDFOUTLINEOBJECTHELPER_HH |
| @@ -30,9 +27,8 @@ class QPDFOutlineDocumentHelper; | @@ -30,9 +27,8 @@ class QPDFOutlineDocumentHelper; | ||
| 30 | 27 | ||
| 31 | #include <qpdf/DLL.h> | 28 | #include <qpdf/DLL.h> |
| 32 | 29 | ||
| 33 | -// This is an object helper for outline items. Outlines, also known as | ||
| 34 | -// bookmarks, are described in section 12.3.3 of the PDF spec | ||
| 35 | -// (ISO-32000). See comments below for details. | 30 | +// This is an object helper for outline items. Outlines, also known as bookmarks, are described in |
| 31 | +// section 12.3.3 of the PDF spec (ISO-32000). See comments below for details. | ||
| 36 | 32 | ||
| 37 | class QPDFOutlineObjectHelper: public QPDFObjectHelper | 33 | class QPDFOutlineObjectHelper: public QPDFObjectHelper |
| 38 | { | 34 | { |
| @@ -40,16 +36,15 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper | @@ -40,16 +36,15 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper | ||
| 40 | QPDF_DLL | 36 | QPDF_DLL |
| 41 | virtual ~QPDFOutlineObjectHelper() | 37 | virtual ~QPDFOutlineObjectHelper() |
| 42 | { | 38 | { |
| 43 | - // This must be cleared explicitly to avoid circular references | ||
| 44 | - // that prevent cleanup of pointer holders. | 39 | + // This must be cleared explicitly to avoid circular references that prevent cleanup of |
| 40 | + // pointer holders. | ||
| 45 | m->parent = nullptr; | 41 | m->parent = nullptr; |
| 46 | } | 42 | } |
| 47 | 43 | ||
| 48 | - // All constructors are private. You can only create one of these | ||
| 49 | - // using QPDFOutlineDocumentHelper. | 44 | + // All constructors are private. You can only create one of these using |
| 45 | + // QPDFOutlineDocumentHelper. | ||
| 50 | 46 | ||
| 51 | - // Return parent pointer. Returns a null pointer if this is a | ||
| 52 | - // top-level outline. | 47 | + // Return parent pointer. Returns a null pointer if this is a top-level outline. |
| 53 | QPDF_DLL | 48 | QPDF_DLL |
| 54 | std::shared_ptr<QPDFOutlineObjectHelper> getParent(); | 49 | std::shared_ptr<QPDFOutlineObjectHelper> getParent(); |
| 55 | 50 | ||
| @@ -57,29 +52,25 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper | @@ -57,29 +52,25 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper | ||
| 57 | QPDF_DLL | 52 | QPDF_DLL |
| 58 | std::vector<QPDFOutlineObjectHelper> getKids(); | 53 | std::vector<QPDFOutlineObjectHelper> getKids(); |
| 59 | 54 | ||
| 60 | - // Return the destination, regardless of whether it is named or | ||
| 61 | - // explicit and whether it is directly provided or in a GoTo | ||
| 62 | - // action. Returns a null object if the destination can't be | ||
| 63 | - // determined. Named destinations can be resolved using the older | ||
| 64 | - // root /Dest dictionary or the current names tree. | 55 | + // Return the destination, regardless of whether it is named or explicit and whether it is |
| 56 | + // directly provided or in a GoTo action. Returns a null object if the destination can't be | ||
| 57 | + // determined. Named destinations can be resolved using the older root /Dest dictionary or the | ||
| 58 | + // current names tree. | ||
| 65 | QPDF_DLL | 59 | QPDF_DLL |
| 66 | QPDFObjectHandle getDest(); | 60 | QPDFObjectHandle getDest(); |
| 67 | 61 | ||
| 68 | - // Return the page that the outline points to. Returns a null | ||
| 69 | - // object if the destination page can't be determined. | 62 | + // Return the page that the outline points to. Returns a null object if the destination page |
| 63 | + // can't be determined. | ||
| 70 | QPDF_DLL | 64 | QPDF_DLL |
| 71 | QPDFObjectHandle getDestPage(); | 65 | QPDFObjectHandle getDestPage(); |
| 72 | 66 | ||
| 73 | - // Returns the value of /Count as present in the object, or 0 if | ||
| 74 | - // not present. If count is positive, the outline is open. If | ||
| 75 | - // negative, it is closed. Either way, the absolute value is the | ||
| 76 | - // number descendant items that would be visible if this were | ||
| 77 | - // open. | 67 | + // Returns the value of /Count as present in the object, or 0 if not present. If count is |
| 68 | + // positive, the outline is open. If negative, it is closed. Either way, the absolute value is | ||
| 69 | + // the number descendant items that would be visible if this were open. | ||
| 78 | QPDF_DLL | 70 | QPDF_DLL |
| 79 | int getCount(); | 71 | int getCount(); |
| 80 | 72 | ||
| 81 | - // Returns the title as a UTF-8 string. Returns the empty string | ||
| 82 | - // if there is no title. | 73 | + // Returns the title as a UTF-8 string. Returns the empty string if there is no title. |
| 83 | QPDF_DLL | 74 | QPDF_DLL |
| 84 | std::string getTitle(); | 75 | std::string getTitle(); |
| 85 | 76 |
include/qpdf/QPDFPageDocumentHelper.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFPAGEDOCUMENTHELPER_HH | 19 | #ifndef QPDFPAGEDOCUMENTHELPER_HH |
| 23 | #define QPDFPAGEDOCUMENTHELPER_HH | 20 | #define QPDFPAGEDOCUMENTHELPER_HH |
| @@ -42,67 +39,53 @@ class QPDFPageDocumentHelper: public QPDFDocumentHelper | @@ -42,67 +39,53 @@ class QPDFPageDocumentHelper: public QPDFDocumentHelper | ||
| 42 | QPDF_DLL | 39 | QPDF_DLL |
| 43 | virtual ~QPDFPageDocumentHelper() = default; | 40 | virtual ~QPDFPageDocumentHelper() = default; |
| 44 | 41 | ||
| 45 | - // Traverse page tree, and return all /Page objects wrapped in | ||
| 46 | - // QPDFPageObjectHelper objects. Unlike with | ||
| 47 | - // QPDF::getAllPages, the vector of pages returned by | ||
| 48 | - // this call is not affected by additions or removals of pages. If | ||
| 49 | - // you manipulate pages, you will have to call this again to get a | ||
| 50 | - // new copy. Please see comments in QPDF.hh for getAllPages() for | ||
| 51 | - // additional details. | 42 | + // Traverse page tree, and return all /Page objects wrapped in QPDFPageObjectHelper objects. |
| 43 | + // Unlike with QPDF::getAllPages, the vector of pages returned by this call is not affected by | ||
| 44 | + // additions or removals of pages. If you manipulate pages, you will have to call this again to | ||
| 45 | + // get a new copy. Please see comments in QPDF.hh for getAllPages() for additional details. | ||
| 52 | QPDF_DLL | 46 | QPDF_DLL |
| 53 | std::vector<QPDFPageObjectHelper> getAllPages(); | 47 | std::vector<QPDFPageObjectHelper> getAllPages(); |
| 54 | 48 | ||
| 55 | - // The PDF /Pages tree allows inherited values. Working with the | ||
| 56 | - // pages of a pdf is much easier when the inheritance is resolved | ||
| 57 | - // by explicitly setting the values in each /Page. | 49 | + // The PDF /Pages tree allows inherited values. Working with the pages of a pdf is much easier |
| 50 | + // when the inheritance is resolved by explicitly setting the values in each /Page. | ||
| 58 | QPDF_DLL | 51 | QPDF_DLL |
| 59 | void pushInheritedAttributesToPage(); | 52 | void pushInheritedAttributesToPage(); |
| 60 | 53 | ||
| 61 | - // This calls QPDFPageObjectHelper::removeUnreferencedResources | ||
| 62 | - // for every page in the document. See comments in | ||
| 63 | - // QPDFPageObjectHelper.hh for details. | 54 | + // This calls QPDFPageObjectHelper::removeUnreferencedResources for every page in the document. |
| 55 | + // See comments in QPDFPageObjectHelper.hh for details. | ||
| 64 | QPDF_DLL | 56 | QPDF_DLL |
| 65 | void removeUnreferencedResources(); | 57 | void removeUnreferencedResources(); |
| 66 | 58 | ||
| 67 | - // Add new page at the beginning or the end of the current pdf. | ||
| 68 | - // The newpage parameter may be either a direct object, an | ||
| 69 | - // indirect object from this QPDF, or an indirect object from | ||
| 70 | - // another QPDF. If it is a direct object, it will be made | ||
| 71 | - // indirect. If it is an indirect object from another QPDF, this | ||
| 72 | - // method will call pushInheritedAttributesToPage on the other | ||
| 73 | - // file and then copy the page to this QPDF using the same | ||
| 74 | - // underlying code as copyForeignObject. At this stage, if the | ||
| 75 | - // indirect object is already in the pages tree, a shallow copy is | ||
| 76 | - // made to avoid adding the same page more than once. In version | ||
| 77 | - // 10.3.1 and earlier, adding a page that already existed would | ||
| 78 | - // throw an exception and could cause qpdf to crash on subsequent | ||
| 79 | - // page insertions in some cases. Note that this means that, in | ||
| 80 | - // some cases, the page actually added won't be exactly the same | ||
| 81 | - // object as the one passed in. If you want to do subsequent | 59 | + // Add new page at the beginning or the end of the current pdf. The newpage parameter may be |
| 60 | + // either a direct object, an indirect object from this QPDF, or an indirect object from another | ||
| 61 | + // QPDF. If it is a direct object, it will be made indirect. If it is an indirect object from | ||
| 62 | + // another QPDF, this method will call pushInheritedAttributesToPage on the other file and then | ||
| 63 | + // copy the page to this QPDF using the same underlying code as copyForeignObject. At this | ||
| 64 | + // stage, if the indirect object is already in the pages tree, a shallow copy is made to avoid | ||
| 65 | + // adding the same page more than once. In version 10.3.1 and earlier, adding a page that | ||
| 66 | + // already existed would throw an exception and could cause qpdf to crash on subsequent page | ||
| 67 | + // insertions in some cases. Note that this means that, in some cases, the page actually added | ||
| 68 | + // won't be exactly the same object as the one passed in. If you want to do subsequent | ||
| 82 | // modification on the page, you should retrieve it again. | 69 | // modification on the page, you should retrieve it again. |
| 83 | // | 70 | // |
| 84 | - // Note that you can call copyForeignObject directly to copy a | ||
| 85 | - // page from a different file, but the resulting object will not | ||
| 86 | - // be a page in the new file. You could do this, for example, to | ||
| 87 | - // convert a page into a form XObject, though for that, you're | ||
| 88 | - // better off using QPDFPageObjectHelper::getFormXObjectForPage. | 71 | + // Note that you can call copyForeignObject directly to copy a page from a different file, but |
| 72 | + // the resulting object will not be a page in the new file. You could do this, for example, to | ||
| 73 | + // convert a page into a form XObject, though for that, you're better off using | ||
| 74 | + // QPDFPageObjectHelper::getFormXObjectForPage. | ||
| 89 | // | 75 | // |
| 90 | - // This method does not have any specific awareness of annotations | ||
| 91 | - // or form fields, so if you just add a page without thinking | ||
| 92 | - // about it, you might end up with two pages that share form | ||
| 93 | - // fields or annotations. While the page may look fine, it will | ||
| 94 | - // probably not function properly with regard to interactive | ||
| 95 | - // features. To work around this, you should called | ||
| 96 | - // QPDFAcroFormDocumentHelper::fixCopiedAnnotations. A future | ||
| 97 | - // version of qpdf will likely provide a higher-level interface | ||
| 98 | - // for copying pages around that will handle document-level | 76 | + // This method does not have any specific awareness of annotations or form fields, so if you |
| 77 | + // just add a page without thinking about it, you might end up with two pages that share form | ||
| 78 | + // fields or annotations. While the page may look fine, it will probably not function properly | ||
| 79 | + // with regard to interactive features. To work around this, you should called | ||
| 80 | + // QPDFAcroFormDocumentHelper::fixCopiedAnnotations. A future version of qpdf will likely | ||
| 81 | + // provide a higher-level interface for copying pages around that will handle document-level | ||
| 99 | // constructs in a less error-prone fashion. | 82 | // constructs in a less error-prone fashion. |
| 100 | 83 | ||
| 101 | QPDF_DLL | 84 | QPDF_DLL |
| 102 | void addPage(QPDFPageObjectHelper newpage, bool first); | 85 | void addPage(QPDFPageObjectHelper newpage, bool first); |
| 103 | 86 | ||
| 104 | - // Add new page before or after refpage. See comments for addPage | ||
| 105 | - // for details about what newpage should be. | 87 | + // Add new page before or after refpage. See comments for addPage for details about what newpage |
| 88 | + // should be. | ||
| 106 | QPDF_DLL | 89 | QPDF_DLL |
| 107 | void addPageAt(QPDFPageObjectHelper newpage, bool before, QPDFPageObjectHelper refpage); | 90 | void addPageAt(QPDFPageObjectHelper newpage, bool before, QPDFPageObjectHelper refpage); |
| 108 | 91 | ||
| @@ -110,17 +93,13 @@ class QPDFPageDocumentHelper: public QPDFDocumentHelper | @@ -110,17 +93,13 @@ class QPDFPageDocumentHelper: public QPDFDocumentHelper | ||
| 110 | QPDF_DLL | 93 | QPDF_DLL |
| 111 | void removePage(QPDFPageObjectHelper page); | 94 | void removePage(QPDFPageObjectHelper page); |
| 112 | 95 | ||
| 113 | - // For every annotation, integrate the annotation's appearance | ||
| 114 | - // stream into the containing page's content streams, merge the | ||
| 115 | - // annotation's resources with the page's resources, and remove | ||
| 116 | - // the annotation from the page. Handles widget annotations | ||
| 117 | - // associated with interactive form fields as a special case, | ||
| 118 | - // including removing the /AcroForm key from the document catalog. | ||
| 119 | - // The values passed to required_flags and forbidden_flags are | ||
| 120 | - // passed along to | ||
| 121 | - // QPDFAnnotationObjectHelper::getPageContentForAppearance. See | ||
| 122 | - // comments there in QPDFAnnotationObjectHelper.hh for meanings of | ||
| 123 | - // those flags. | 96 | + // For every annotation, integrate the annotation's appearance stream into the containing page's |
| 97 | + // content streams, merge the annotation's resources with the page's resources, and remove the | ||
| 98 | + // annotation from the page. Handles widget annotations associated with interactive form fields | ||
| 99 | + // as a special case, including removing the /AcroForm key from the document catalog. The values | ||
| 100 | + // passed to required_flags and forbidden_flags are passed along to | ||
| 101 | + // QPDFAnnotationObjectHelper::getPageContentForAppearance. See comments there in | ||
| 102 | + // QPDFAnnotationObjectHelper.hh for meanings of those flags. | ||
| 124 | QPDF_DLL | 103 | QPDF_DLL |
| 125 | void flattenAnnotations(int required_flags = 0, int forbidden_flags = an_invisible | an_hidden); | 104 | void flattenAnnotations(int required_flags = 0, int forbidden_flags = an_invisible | an_hidden); |
| 126 | 105 |
include/qpdf/QPDFPageLabelDocumentHelper.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFPAGELABELDOCUMENTHELPER_HH | 19 | #ifndef QPDFPAGELABELDOCUMENTHELPER_HH |
| 23 | #define QPDFPAGELABELDOCUMENTHELPER_HH | 20 | #define QPDFPAGELABELDOCUMENTHELPER_HH |
| @@ -30,18 +27,15 @@ | @@ -30,18 +27,15 @@ | ||
| 30 | 27 | ||
| 31 | #include <qpdf/DLL.h> | 28 | #include <qpdf/DLL.h> |
| 32 | 29 | ||
| 33 | -// Page labels are discussed in the PDF spec (ISO-32000) in section | ||
| 34 | -// 12.4.2. | 30 | +// Page labels are discussed in the PDF spec (ISO-32000) in section 12.4.2. |
| 35 | // | 31 | // |
| 36 | -// Page labels are implemented as a number tree. Each key is a page | ||
| 37 | -// index, numbered from 0. The values are dictionaries with the | ||
| 38 | -// following keys, all optional: | 32 | +// Page labels are implemented as a number tree. Each key is a page index, numbered from 0. The |
| 33 | +// values are dictionaries with the following keys, all optional: | ||
| 39 | // | 34 | // |
| 40 | // * /Type: if present, must be /PageLabel | 35 | // * /Type: if present, must be /PageLabel |
| 41 | -// * /S: one of /D, /R, /r, /A, or /a for decimal, upper-case and | ||
| 42 | -// lower-case Roman numeral, or upper-case and lower-case alphabetic | ||
| 43 | -// * /P: if present, a fixed prefix string that is prepended to each | ||
| 44 | -// page number | 36 | +// * /S: one of /D, /R, /r, /A, or /a for decimal, upper-case and lower-case Roman numeral, or |
| 37 | +// upper-case and lower-case alphabetic | ||
| 38 | +// * /P: if present, a fixed prefix string that is prepended to each page number | ||
| 45 | // * /St: the starting number, or 1 if not specified | 39 | // * /St: the starting number, or 1 if not specified |
| 46 | 40 | ||
| 47 | class QPDFPageLabelDocumentHelper: public QPDFDocumentHelper | 41 | class QPDFPageLabelDocumentHelper: public QPDFDocumentHelper |
| @@ -55,25 +49,20 @@ class QPDFPageLabelDocumentHelper: public QPDFDocumentHelper | @@ -55,25 +49,20 @@ class QPDFPageLabelDocumentHelper: public QPDFDocumentHelper | ||
| 55 | QPDF_DLL | 49 | QPDF_DLL |
| 56 | bool hasPageLabels(); | 50 | bool hasPageLabels(); |
| 57 | 51 | ||
| 58 | - // Return a page label dictionary representing the page label for | ||
| 59 | - // the given page. The page does not need to appear explicitly in | ||
| 60 | - // the page label dictionary. This method will adjust /St as | 52 | + // Return a page label dictionary representing the page label for the given page. The page does |
| 53 | + // not need to appear explicitly in the page label dictionary. This method will adjust /St as | ||
| 61 | // needed to produce a label that is suitable for the page. | 54 | // needed to produce a label that is suitable for the page. |
| 62 | QPDF_DLL | 55 | QPDF_DLL |
| 63 | QPDFObjectHandle getLabelForPage(long long page_idx); | 56 | QPDFObjectHandle getLabelForPage(long long page_idx); |
| 64 | 57 | ||
| 65 | - // Append to the incoming vector a list of objects suitable for | ||
| 66 | - // inclusion in a /PageLabels dictionary's /Nums field. start_idx | ||
| 67 | - // and end_idx are the indexes to the starting and ending pages | ||
| 68 | - // (inclusive) in the original file, and new_start_idx is the | ||
| 69 | - // index to the first page in the new file. For example, if pages | ||
| 70 | - // 10 through 12 of one file are being copied to a new file as | ||
| 71 | - // pages 6 through 8, you would call getLabelsForPageRange(10, 12, | ||
| 72 | - // 6), which would return as many entries as are required to add | ||
| 73 | - // to the new file's PageLabels. This method fabricates a suitable | ||
| 74 | - // entry even if the original document has no page labels. This | ||
| 75 | - // behavior facilitates using this function to incrementally build | ||
| 76 | - // up a page labels tree when merging files. | 58 | + // Append to the incoming vector a list of objects suitable for inclusion in a /PageLabels |
| 59 | + // dictionary's /Nums field. start_idx and end_idx are the indexes to the starting and ending | ||
| 60 | + // pages (inclusive) in the original file, and new_start_idx is the index to the first page in | ||
| 61 | + // the new file. For example, if pages 10 through 12 of one file are being copied to a new file | ||
| 62 | + // as pages 6 through 8, you would call getLabelsForPageRange(10, 12, 6), which would return as | ||
| 63 | + // many entries as are required to add to the new file's PageLabels. This method fabricates a | ||
| 64 | + // suitable entry even if the original document has no page labels. This behavior facilitates | ||
| 65 | + // using this function to incrementally build up a page labels tree when merging files. | ||
| 77 | QPDF_DLL | 66 | QPDF_DLL |
| 78 | void getLabelsForPageRange( | 67 | void getLabelsForPageRange( |
| 79 | long long start_idx, | 68 | long long start_idx, |
include/qpdf/QPDFStreamFilter.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFSTREAMFILTER_HH | 19 | #ifndef QPDFSTREAMFILTER_HH |
| 23 | #define QPDFSTREAMFILTER_HH | 20 | #define QPDFSTREAMFILTER_HH |
| @@ -35,36 +32,29 @@ class QPDF_DLL_CLASS QPDFStreamFilter | @@ -35,36 +32,29 @@ class QPDF_DLL_CLASS QPDFStreamFilter | ||
| 35 | QPDF_DLL | 32 | QPDF_DLL |
| 36 | virtual ~QPDFStreamFilter() = default; | 33 | virtual ~QPDFStreamFilter() = default; |
| 37 | 34 | ||
| 38 | - // A QPDFStreamFilter class must implement, at a minimum, | ||
| 39 | - // setDecodeParms() and getDecodePipeline(). QPDF will always call | ||
| 40 | - // setDecodeParms() before calling getDecodePipeline(). It is | ||
| 41 | - // expected that you will store any needed information from | ||
| 42 | - // decode_parms (or the decode_parms object itself) in your | ||
| 43 | - // instance so that it can be used to construct the decode | ||
| 44 | - // pipeline. | 35 | + // A QPDFStreamFilter class must implement, at a minimum, setDecodeParms() and |
| 36 | + // getDecodePipeline(). QPDF will always call setDecodeParms() before calling | ||
| 37 | + // getDecodePipeline(). It is expected that you will store any needed information from | ||
| 38 | + // decode_parms (or the decode_parms object itself) in your instance so that it can be used to | ||
| 39 | + // construct the decode pipeline. | ||
| 45 | 40 | ||
| 46 | - // Return a boolean indicating whether your filter can proceed | ||
| 47 | - // with the given /DecodeParms. The default implementation accepts | ||
| 48 | - // a null object and rejects everything else. | 41 | + // Return a boolean indicating whether your filter can proceed with the given /DecodeParms. The |
| 42 | + // default implementation accepts a null object and rejects everything else. | ||
| 49 | QPDF_DLL | 43 | QPDF_DLL |
| 50 | virtual bool setDecodeParms(QPDFObjectHandle decode_parms); | 44 | virtual bool setDecodeParms(QPDFObjectHandle decode_parms); |
| 51 | 45 | ||
| 52 | - // Return a pipeline that will decode data encoded with your | ||
| 53 | - // filter. Your implementation must ensure that the pipeline is | ||
| 54 | - // deleted when the instance of your class is destroyed. | 46 | + // Return a pipeline that will decode data encoded with your filter. Your implementation must |
| 47 | + // ensure that the pipeline is deleted when the instance of your class is destroyed. | ||
| 55 | QPDF_DLL | 48 | QPDF_DLL |
| 56 | virtual Pipeline* getDecodePipeline(Pipeline* next) = 0; | 49 | virtual Pipeline* getDecodePipeline(Pipeline* next) = 0; |
| 57 | 50 | ||
| 58 | - // If your filter implements "specialized" compression or lossy | ||
| 59 | - // compression, override one or both of these methods. The default | ||
| 60 | - // implementations return false. See comments in QPDFWriter for | ||
| 61 | - // details. QPDF defines specialized compression as non-lossy | ||
| 62 | - // compression not intended for general-purpose data. qpdf, by | ||
| 63 | - // default, doesn't mess with streams that are compressed with | ||
| 64 | - // specialized compression, the idea being that the decision to | ||
| 65 | - // use that compression scheme would fall outside of what | ||
| 66 | - // QPDFWriter would know anything about, so any attempt to decode | ||
| 67 | - // and re-encode would probably be undesirable. | 51 | + // If your filter implements "specialized" compression or lossy compression, override one or |
| 52 | + // both of these methods. The default implementations return false. See comments in QPDFWriter | ||
| 53 | + // for details. QPDF defines specialized compression as non-lossy compression not intended for | ||
| 54 | + // general-purpose data. qpdf, by default, doesn't mess with streams that are compressed with | ||
| 55 | + // specialized compression, the idea being that the decision to use that compression scheme | ||
| 56 | + // would fall outside of what QPDFWriter would know anything about, so any attempt to decode and | ||
| 57 | + // re-encode would probably be undesirable. | ||
| 68 | QPDF_DLL | 58 | QPDF_DLL |
| 69 | virtual bool isSpecializedCompression(); | 59 | virtual bool isSpecializedCompression(); |
| 70 | QPDF_DLL | 60 | QPDF_DLL |
include/qpdf/QPDFSystemError.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFSYSTEMERROR_HH | 19 | #ifndef QPDFSYSTEMERROR_HH |
| 23 | #define QPDFSYSTEMERROR_HH | 20 | #define QPDFSYSTEMERROR_HH |
| @@ -37,9 +34,8 @@ class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error | @@ -37,9 +34,8 @@ class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error | ||
| 37 | QPDF_DLL | 34 | QPDF_DLL |
| 38 | virtual ~QPDFSystemError() noexcept = default; | 35 | virtual ~QPDFSystemError() noexcept = default; |
| 39 | 36 | ||
| 40 | - // To get a complete error string, call what(), provided by | ||
| 41 | - // std::exception. The accessors below return the original values | ||
| 42 | - // used to create the exception. | 37 | + // To get a complete error string, call what(), provided by std::exception. The accessors below |
| 38 | + // return the original values used to create the exception. | ||
| 43 | 39 | ||
| 44 | QPDF_DLL | 40 | QPDF_DLL |
| 45 | std::string const& getDescription() const; | 41 | std::string const& getDescription() const; |
| @@ -50,8 +46,8 @@ class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error | @@ -50,8 +46,8 @@ class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error | ||
| 50 | QPDF_DLL_PRIVATE | 46 | QPDF_DLL_PRIVATE |
| 51 | static std::string createWhat(std::string const& description, int system_errno); | 47 | static std::string createWhat(std::string const& description, int system_errno); |
| 52 | 48 | ||
| 53 | - // This class does not use the Members pattern to avoid needless | ||
| 54 | - // memory allocations during exception handling. | 49 | + // This class does not use the Members pattern to avoid needless memory allocations during |
| 50 | + // exception handling. | ||
| 55 | 51 | ||
| 56 | std::string description; | 52 | std::string description; |
| 57 | int system_errno; | 53 | int system_errno; |
include/qpdf/QPDFUsage.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFUSAGE_HH | 19 | #ifndef QPDFUSAGE_HH |
| 23 | #define QPDFUSAGE_HH | 20 | #define QPDFUSAGE_HH |
include/qpdf/QPDFWriter.hh
| @@ -2,26 +2,22 @@ | @@ -2,26 +2,22 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | -// This class implements a simple writer for saving QPDF objects to | ||
| 23 | -// new PDF files. See comments through the header file for additional | ||
| 24 | -// details. | 19 | +// This class implements a simple writer for saving QPDF objects to new PDF files. See comments |
| 20 | +// through the header file for additional details. | ||
| 25 | 21 | ||
| 26 | #ifndef QPDFWRITER_HH | 22 | #ifndef QPDFWRITER_HH |
| 27 | #define QPDFWRITER_HH | 23 | #define QPDFWRITER_HH |
| @@ -57,21 +53,19 @@ class Pl_MD5; | @@ -57,21 +53,19 @@ class Pl_MD5; | ||
| 57 | class QPDFWriter | 53 | class QPDFWriter |
| 58 | { | 54 | { |
| 59 | public: | 55 | public: |
| 60 | - // Construct a QPDFWriter object without specifying output. You | ||
| 61 | - // must call one of the output setting routines defined below. | 56 | + // Construct a QPDFWriter object without specifying output. You must call one of the output |
| 57 | + // setting routines defined below. | ||
| 62 | QPDF_DLL | 58 | QPDF_DLL |
| 63 | QPDFWriter(QPDF& pdf); | 59 | QPDFWriter(QPDF& pdf); |
| 64 | 60 | ||
| 65 | - // Create a QPDFWriter object that writes its output to a file or | ||
| 66 | - // to stdout. This is equivalent to using the previous | ||
| 67 | - // constructor and then calling setOutputFilename(). See | 61 | + // Create a QPDFWriter object that writes its output to a file or to stdout. This is equivalent |
| 62 | + // to using the previous constructor and then calling setOutputFilename(). See | ||
| 68 | // setOutputFilename() for details. | 63 | // setOutputFilename() for details. |
| 69 | QPDF_DLL | 64 | QPDF_DLL |
| 70 | QPDFWriter(QPDF& pdf, char const* filename); | 65 | QPDFWriter(QPDF& pdf, char const* filename); |
| 71 | 66 | ||
| 72 | - // Create a QPDFWriter object that writes its output to an already | ||
| 73 | - // open FILE*. This is equivalent to calling the first | ||
| 74 | - // constructor and then calling setOutputFile(). See | 67 | + // Create a QPDFWriter object that writes its output to an already open FILE*. This is |
| 68 | + // equivalent to calling the first constructor and then calling setOutputFile(). See | ||
| 75 | // setOutputFile() for details. | 69 | // setOutputFile() for details. |
| 76 | QPDF_DLL | 70 | QPDF_DLL |
| 77 | QPDFWriter(QPDF& pdf, char const* description, FILE* file, bool close_file); | 71 | QPDFWriter(QPDF& pdf, char const* description, FILE* file, bool close_file); |
| @@ -85,15 +79,13 @@ class QPDFWriter | @@ -85,15 +79,13 @@ class QPDFWriter | ||
| 85 | QPDF_DLL | 79 | QPDF_DLL |
| 86 | virtual ~ProgressReporter(); | 80 | virtual ~ProgressReporter(); |
| 87 | 81 | ||
| 88 | - // This method is called with a value from 0 to 100 to | ||
| 89 | - // indicate approximate progress through the write process. | ||
| 90 | - // See registerProgressReporter. | 82 | + // This method is called with a value from 0 to 100 to indicate approximate progress through |
| 83 | + // the write process. See registerProgressReporter. | ||
| 91 | virtual void reportProgress(int) = 0; | 84 | virtual void reportProgress(int) = 0; |
| 92 | }; | 85 | }; |
| 93 | 86 | ||
| 94 | - // This is a progress reporter that takes a function. It is used | ||
| 95 | - // by the C APIs, but it is available if you want to just register | ||
| 96 | - // a C function as a handler. | 87 | + // This is a progress reporter that takes a function. It is used by the C APIs, but it is |
| 88 | + // available if you want to just register a C function as a handler. | ||
| 97 | class QPDF_DLL_CLASS FunctionProgressReporter: public ProgressReporter | 89 | class QPDF_DLL_CLASS FunctionProgressReporter: public ProgressReporter |
| 98 | { | 90 | { |
| 99 | public: | 91 | public: |
| @@ -108,39 +100,31 @@ class QPDFWriter | @@ -108,39 +100,31 @@ class QPDFWriter | ||
| 108 | std::function<void(int)> handler; | 100 | std::function<void(int)> handler; |
| 109 | }; | 101 | }; |
| 110 | 102 | ||
| 111 | - // Setting Output. Output may be set only one time. If you don't | ||
| 112 | - // use the filename version of the QPDFWriter constructor, you | ||
| 113 | - // must call exactly one of these methods. | 103 | + // Setting Output. Output may be set only one time. If you don't use the filename version of |
| 104 | + // the QPDFWriter constructor, you must call exactly one of these methods. | ||
| 114 | 105 | ||
| 115 | - // Passing null as filename means write to stdout. QPDFWriter | ||
| 116 | - // will create a zero-length output file upon construction. If | ||
| 117 | - // write fails, the empty or partially written file will not be | ||
| 118 | - // deleted. This is by design: sometimes the partial file may be | ||
| 119 | - // useful for tracking down problems. If your application doesn't | ||
| 120 | - // want the partially written file to be left behind, you should | ||
| 121 | - // delete it the eventual call to write fails. | 106 | + // Passing null as filename means write to stdout. QPDFWriter will create a zero-length output |
| 107 | + // file upon construction. If write fails, the empty or partially written file will not be | ||
| 108 | + // deleted. This is by design: sometimes the partial file may be useful for tracking down | ||
| 109 | + // problems. If your application doesn't want the partially written file to be left behind, you | ||
| 110 | + // should delete it the eventual call to write fails. | ||
| 122 | QPDF_DLL | 111 | QPDF_DLL |
| 123 | void setOutputFilename(char const* filename); | 112 | void setOutputFilename(char const* filename); |
| 124 | 113 | ||
| 125 | - // Write to the given FILE*, which must be opened by the caller. | ||
| 126 | - // If close_file is true, QPDFWriter will close the file. | ||
| 127 | - // Otherwise, the caller must close the file. The file does not | ||
| 128 | - // need to be seekable; it will be written to in a single pass. | ||
| 129 | - // It must be open in binary mode. | 114 | + // Write to the given FILE*, which must be opened by the caller. If close_file is true, |
| 115 | + // QPDFWriter will close the file. Otherwise, the caller must close the file. The file does not | ||
| 116 | + // need to be seekable; it will be written to in a single pass. It must be open in binary mode. | ||
| 130 | QPDF_DLL | 117 | QPDF_DLL |
| 131 | void setOutputFile(char const* description, FILE* file, bool close_file); | 118 | void setOutputFile(char const* description, FILE* file, bool close_file); |
| 132 | 119 | ||
| 133 | - // Indicate that QPDFWriter should create a memory buffer to | ||
| 134 | - // contain the final PDF file. Obtain the memory by calling | ||
| 135 | - // getBuffer(). | 120 | + // Indicate that QPDFWriter should create a memory buffer to contain the final PDF file. Obtain |
| 121 | + // the memory by calling getBuffer(). | ||
| 136 | QPDF_DLL | 122 | QPDF_DLL |
| 137 | void setOutputMemory(); | 123 | void setOutputMemory(); |
| 138 | 124 | ||
| 139 | - // Return the buffer object containing the PDF file. If | ||
| 140 | - // setOutputMemory() has been called, this method may be called | ||
| 141 | - // exactly one time after write() has returned. The caller is | ||
| 142 | - // responsible for deleting the buffer when done. See also | ||
| 143 | - // getBufferSharedPointer(). | 125 | + // Return the buffer object containing the PDF file. If setOutputMemory() has been called, this |
| 126 | + // method may be called exactly one time after write() has returned. The caller is responsible | ||
| 127 | + // for deleting the buffer when done. See also getBufferSharedPointer(). | ||
| 144 | QPDF_DLL | 128 | QPDF_DLL |
| 145 | Buffer* getBuffer(); | 129 | Buffer* getBuffer(); |
| 146 | 130 | ||
| @@ -148,33 +132,27 @@ class QPDFWriter | @@ -148,33 +132,27 @@ class QPDFWriter | ||
| 148 | QPDF_DLL | 132 | QPDF_DLL |
| 149 | std::shared_ptr<Buffer> getBufferSharedPointer(); | 133 | std::shared_ptr<Buffer> getBufferSharedPointer(); |
| 150 | 134 | ||
| 151 | - // Supply your own pipeline object. Output will be written to | ||
| 152 | - // this pipeline, and QPDFWriter will call finish() on the | ||
| 153 | - // pipeline. It is the caller's responsibility to manage the | ||
| 154 | - // memory for the pipeline. The pipeline is never deleted by | ||
| 155 | - // QPDFWriter, which makes it possible for you to call additional | ||
| 156 | - // methods on the pipeline after the writing is finished. | 135 | + // Supply your own pipeline object. Output will be written to this pipeline, and QPDFWriter |
| 136 | + // will call finish() on the pipeline. It is the caller's responsibility to manage the memory | ||
| 137 | + // for the pipeline. The pipeline is never deleted by QPDFWriter, which makes it possible for | ||
| 138 | + // you to call additional methods on the pipeline after the writing is finished. | ||
| 157 | QPDF_DLL | 139 | QPDF_DLL |
| 158 | void setOutputPipeline(Pipeline*); | 140 | void setOutputPipeline(Pipeline*); |
| 159 | 141 | ||
| 160 | // Setting Parameters | 142 | // Setting Parameters |
| 161 | 143 | ||
| 162 | - // Set the value of object stream mode. In disable mode, we never | ||
| 163 | - // generate any object streams. In preserve mode, we preserve | ||
| 164 | - // object stream structure from the original file. In generate | ||
| 165 | - // mode, we generate our own object streams. In all cases, we | ||
| 166 | - // generate a conventional cross-reference table if there are no | ||
| 167 | - // object streams and a cross-reference stream if there are object | ||
| 168 | - // streams. The default is o_preserve. | 144 | + // Set the value of object stream mode. In disable mode, we never generate any object streams. |
| 145 | + // In preserve mode, we preserve object stream structure from the original file. In generate | ||
| 146 | + // mode, we generate our own object streams. In all cases, we generate a conventional | ||
| 147 | + // cross-reference table if there are no object streams and a cross-reference stream if there | ||
| 148 | + // are object streams. The default is o_preserve. | ||
| 169 | QPDF_DLL | 149 | QPDF_DLL |
| 170 | void setObjectStreamMode(qpdf_object_stream_e); | 150 | void setObjectStreamMode(qpdf_object_stream_e); |
| 171 | 151 | ||
| 172 | - // Set value of stream data mode. This is an older interface. | ||
| 173 | - // Instead of using this, prefer setCompressStreams() and | ||
| 174 | - // setDecodeLevel(). This method is retained for compatibility, | ||
| 175 | - // but it does not cover the full range of available | ||
| 176 | - // configurations. The mapping between this and the new methods is | ||
| 177 | - // as follows: | 152 | + // Set value of stream data mode. This is an older interface. Instead of using this, prefer |
| 153 | + // setCompressStreams() and setDecodeLevel(). This method is retained for compatibility, but it | ||
| 154 | + // does not cover the full range of available configurations. The mapping between this and the | ||
| 155 | + // new methods is as follows: | ||
| 178 | // | 156 | // |
| 179 | // qpdf_s_uncompress: | 157 | // qpdf_s_uncompress: |
| 180 | // setCompressStreams(false) | 158 | // setCompressStreams(false) |
| @@ -190,205 +168,161 @@ class QPDFWriter | @@ -190,205 +168,161 @@ class QPDFWriter | ||
| 190 | QPDF_DLL | 168 | QPDF_DLL |
| 191 | void setStreamDataMode(qpdf_stream_data_e); | 169 | void setStreamDataMode(qpdf_stream_data_e); |
| 192 | 170 | ||
| 193 | - // If true, compress any uncompressed streams when writing them. | ||
| 194 | - // Metadata streams are a special case and are not compressed even | ||
| 195 | - // if this is true. This is true by default for QPDFWriter. If you | ||
| 196 | - // want QPDFWriter to leave uncompressed streams uncompressed, | ||
| 197 | - // pass false to this method. | 171 | + // If true, compress any uncompressed streams when writing them. Metadata streams are a special |
| 172 | + // case and are not compressed even if this is true. This is true by default for QPDFWriter. If | ||
| 173 | + // you want QPDFWriter to leave uncompressed streams uncompressed, pass false to this method. | ||
| 198 | QPDF_DLL | 174 | QPDF_DLL |
| 199 | void setCompressStreams(bool); | 175 | void setCompressStreams(bool); |
| 200 | 176 | ||
| 201 | - // When QPDFWriter encounters streams, this parameter controls the | ||
| 202 | - // behavior with respect to attempting to apply any filters to the | ||
| 203 | - // streams when copying to the output. The decode levels are as | ||
| 204 | - // follows: | 177 | + // When QPDFWriter encounters streams, this parameter controls the behavior with respect to |
| 178 | + // attempting to apply any filters to the streams when copying to the output. The decode levels | ||
| 179 | + // are as follows: | ||
| 205 | // | 180 | // |
| 206 | - // qpdf_dl_none: Do not attempt to apply any filters. Streams | ||
| 207 | - // remain as they appear in the original file. Note that | ||
| 208 | - // uncompressed streams may still be compressed on output. You can | 181 | + // qpdf_dl_none: Do not attempt to apply any filters. Streams remain as they appear in the |
| 182 | + // original file. Note that uncompressed streams may still be compressed on output. You can | ||
| 209 | // disable that by calling setCompressStreams(false). | 183 | // disable that by calling setCompressStreams(false). |
| 210 | // | 184 | // |
| 211 | - // qpdf_dl_generalized: This is the default. QPDFWriter will apply | ||
| 212 | - // LZWDecode, ASCII85Decode, ASCIIHexDecode, and FlateDecode | ||
| 213 | - // filters on the input. When combined with | ||
| 214 | - // setCompressStreams(true), which the default, the effect of this | ||
| 215 | - // is that streams filtered with these older and less efficient | ||
| 216 | - // filters will be recompressed with the Flate filter. By default, | ||
| 217 | - // as a special case, if a stream is already compressed with | ||
| 218 | - // FlateDecode and setCompressStreams is enabled, the original | ||
| 219 | - // compressed data will be preserved. This behavior can be | ||
| 220 | - // overridden by calling setRecompressFlate(true). | 185 | + // qpdf_dl_generalized: This is the default. QPDFWriter will apply LZWDecode, ASCII85Decode, |
| 186 | + // ASCIIHexDecode, and FlateDecode filters on the input. When combined with | ||
| 187 | + // setCompressStreams(true), which the default, the effect of this is that streams filtered with | ||
| 188 | + // these older and less efficient filters will be recompressed with the Flate filter. By | ||
| 189 | + // default, as a special case, if a stream is already compressed with FlateDecode and | ||
| 190 | + // setCompressStreams is enabled, the original compressed data will be preserved. This behavior | ||
| 191 | + // can be overridden by calling setRecompressFlate(true). | ||
| 221 | // | 192 | // |
| 222 | - // qpdf_dl_specialized: In addition to uncompressing the | ||
| 223 | - // generalized compression formats, supported non-lossy | ||
| 224 | - // compression will also be decoded. At present, this includes | ||
| 225 | - // the RunLengthDecode filter. | 193 | + // qpdf_dl_specialized: In addition to uncompressing the generalized compression formats, |
| 194 | + // supported non-lossy compression will also be decoded. At present, this includes the | ||
| 195 | + // RunLengthDecode filter. | ||
| 226 | // | 196 | // |
| 227 | - // qpdf_dl_all: In addition to generalized and non-lossy | ||
| 228 | - // specialized filters, supported lossy compression filters will | ||
| 229 | - // be applied. At present, this includes DCTDecode (JPEG) | ||
| 230 | - // compression. Note that compressing the resulting data with | ||
| 231 | - // DCTDecode again will accumulate loss, so avoid multiple | ||
| 232 | - // compression and decompression cycles. This is mostly useful for | ||
| 233 | - // retrieving image data. | 197 | + // qpdf_dl_all: In addition to generalized and non-lossy specialized filters, supported lossy |
| 198 | + // compression filters will be applied. At present, this includes DCTDecode (JPEG) compression. | ||
| 199 | + // Note that compressing the resulting data with DCTDecode again will accumulate loss, so avoid | ||
| 200 | + // multiple compression and decompression cycles. This is mostly useful for retrieving image | ||
| 201 | + // data. | ||
| 234 | QPDF_DLL | 202 | QPDF_DLL |
| 235 | void setDecodeLevel(qpdf_stream_decode_level_e); | 203 | void setDecodeLevel(qpdf_stream_decode_level_e); |
| 236 | 204 | ||
| 237 | - // By default, when both the input and output contents of a stream | ||
| 238 | - // are compressed with Flate, qpdf does not uncompress and | ||
| 239 | - // recompress the stream. Passing true here causes it to do so. | ||
| 240 | - // This can be useful if recompressing all streams with a higher | ||
| 241 | - // compression level, which can be set by calling the static | ||
| 242 | - // method Pl_Flate::setCompressionLevel. | 205 | + // By default, when both the input and output contents of a stream are compressed with Flate, |
| 206 | + // qpdf does not uncompress and recompress the stream. Passing true here causes it to do so. | ||
| 207 | + // This can be useful if recompressing all streams with a higher compression level, which can be | ||
| 208 | + // set by calling the static method Pl_Flate::setCompressionLevel. | ||
| 243 | QPDF_DLL | 209 | QPDF_DLL |
| 244 | void setRecompressFlate(bool); | 210 | void setRecompressFlate(bool); |
| 245 | 211 | ||
| 246 | - // Set value of content stream normalization. The default is | ||
| 247 | - // "false". If true, we attempt to normalize newlines inside of | ||
| 248 | - // content streams. Some constructs such as inline images may | ||
| 249 | - // thwart our efforts. There may be some cases where this can | ||
| 250 | - // damage the content stream. This flag should be used only for | ||
| 251 | - // debugging and experimenting with PDF content streams. Never | ||
| 252 | - // use it for production files. | 212 | + // Set value of content stream normalization. The default is "false". If true, we attempt to |
| 213 | + // normalize newlines inside of content streams. Some constructs such as inline images may | ||
| 214 | + // thwart our efforts. There may be some cases where this can damage the content stream. This | ||
| 215 | + // flag should be used only for debugging and experimenting with PDF content streams. Never use | ||
| 216 | + // it for production files. | ||
| 253 | QPDF_DLL | 217 | QPDF_DLL |
| 254 | void setContentNormalization(bool); | 218 | void setContentNormalization(bool); |
| 255 | 219 | ||
| 256 | - // Set QDF mode. QDF mode causes special "pretty printing" of | ||
| 257 | - // PDF objects, adds comments for easier perusing of files. | ||
| 258 | - // Resulting PDF files can be edited in a text editor and then run | ||
| 259 | - // through fix-qdf to update cross reference tables and stream | ||
| 260 | - // lengths. | 220 | + // Set QDF mode. QDF mode causes special "pretty printing" of PDF objects, adds comments for |
| 221 | + // easier perusing of files. Resulting PDF files can be edited in a text editor and then run | ||
| 222 | + // through fix-qdf to update cross reference tables and stream lengths. | ||
| 261 | QPDF_DLL | 223 | QPDF_DLL |
| 262 | void setQDFMode(bool); | 224 | void setQDFMode(bool); |
| 263 | 225 | ||
| 264 | - // Preserve unreferenced objects. The default behavior is to | ||
| 265 | - // discard any object that is not visited during a traversal of | ||
| 266 | - // the object structure from the trailer. | 226 | + // Preserve unreferenced objects. The default behavior is to discard any object that is not |
| 227 | + // visited during a traversal of the object structure from the trailer. | ||
| 267 | QPDF_DLL | 228 | QPDF_DLL |
| 268 | void setPreserveUnreferencedObjects(bool); | 229 | void setPreserveUnreferencedObjects(bool); |
| 269 | 230 | ||
| 270 | - // Always write a newline before the endstream keyword. This helps | ||
| 271 | - // with PDF/A compliance, though it is not sufficient for it. | 231 | + // Always write a newline before the endstream keyword. This helps with PDF/A compliance, though |
| 232 | + // it is not sufficient for it. | ||
| 272 | QPDF_DLL | 233 | QPDF_DLL |
| 273 | void setNewlineBeforeEndstream(bool); | 234 | void setNewlineBeforeEndstream(bool); |
| 274 | 235 | ||
| 275 | - // Set the minimum PDF version. If the PDF version of the input | ||
| 276 | - // file (or previously set minimum version) is less than the | ||
| 277 | - // version passed to this method, the PDF version of the output | ||
| 278 | - // file will be set to this value. If the original PDF file's | ||
| 279 | - // version or previously set minimum version is already this | ||
| 280 | - // version or later, the original file's version will be used. | ||
| 281 | - // QPDFWriter automatically sets the minimum version to 1.4 when | ||
| 282 | - // R3 encryption parameters are used, and to 1.5 when object | ||
| 283 | - // streams are used. | 236 | + // Set the minimum PDF version. If the PDF version of the input file (or previously set minimum |
| 237 | + // version) is less than the version passed to this method, the PDF version of the output file | ||
| 238 | + // will be set to this value. If the original PDF file's version or previously set minimum | ||
| 239 | + // version is already this version or later, the original file's version will be used. | ||
| 240 | + // QPDFWriter automatically sets the minimum version to 1.4 when R3 encryption parameters are | ||
| 241 | + // used, and to 1.5 when object streams are used. | ||
| 284 | QPDF_DLL | 242 | QPDF_DLL |
| 285 | void setMinimumPDFVersion(std::string const&, int extension_level = 0); | 243 | void setMinimumPDFVersion(std::string const&, int extension_level = 0); |
| 286 | QPDF_DLL | 244 | QPDF_DLL |
| 287 | void setMinimumPDFVersion(PDFVersion const&); | 245 | void setMinimumPDFVersion(PDFVersion const&); |
| 288 | 246 | ||
| 289 | - // Force the PDF version of the output file to be a given version. | ||
| 290 | - // Use of this function may create PDF files that will not work | ||
| 291 | - // properly with older PDF viewers. When a PDF version is set | ||
| 292 | - // using this function, qpdf will use this version even if the | ||
| 293 | - // file contains features that are not supported in that version | ||
| 294 | - // of PDF. In other words, you should only use this function if | ||
| 295 | - // you are sure the PDF file in question has no features of newer | ||
| 296 | - // versions of PDF or if you are willing to create files that old | ||
| 297 | - // viewers may try to open but not be able to properly interpret. | ||
| 298 | - // If any encryption has been applied to the document either | ||
| 299 | - // explicitly or by preserving the encryption of the source | ||
| 300 | - // document, forcing the PDF version to a value too low to support | ||
| 301 | - // that type of encryption will explicitly disable decryption. | ||
| 302 | - // Additionally, forcing to a version below 1.5 will disable | ||
| 303 | - // object streams. | 247 | + // Force the PDF version of the output file to be a given version. Use of this function may |
| 248 | + // create PDF files that will not work properly with older PDF viewers. When a PDF version is | ||
| 249 | + // set using this function, qpdf will use this version even if the file contains features that | ||
| 250 | + // are not supported in that version of PDF. In other words, you should only use this function | ||
| 251 | + // if you are sure the PDF file in question has no features of newer versions of PDF or if you | ||
| 252 | + // are willing to create files that old viewers may try to open but not be able to properly | ||
| 253 | + // interpret. If any encryption has been applied to the document either explicitly or by | ||
| 254 | + // preserving the encryption of the source document, forcing the PDF version to a value too low | ||
| 255 | + // to support that type of encryption will explicitly disable decryption. Additionally, forcing | ||
| 256 | + // to a version below 1.5 will disable object streams. | ||
| 304 | QPDF_DLL | 257 | QPDF_DLL |
| 305 | void forcePDFVersion(std::string const&, int extension_level = 0); | 258 | void forcePDFVersion(std::string const&, int extension_level = 0); |
| 306 | 259 | ||
| 307 | - // Provide additional text to insert in the PDF file somewhere | ||
| 308 | - // near the beginning of the file. This can be used to add | ||
| 309 | - // comments to the beginning of a PDF file, for example, if those | ||
| 310 | - // comments are to be consumed by some other application. No | ||
| 311 | - // checks are performed to ensure that the text inserted here is | ||
| 312 | - // valid PDF. If you want to insert multiline comments, you will | ||
| 313 | - // need to include \n in the string yourself and start each line | ||
| 314 | - // with %. An extra newline will be appended if one is not | ||
| 315 | - // already present at the end of your text. | 260 | + // Provide additional text to insert in the PDF file somewhere near the beginning of the file. |
| 261 | + // This can be used to add comments to the beginning of a PDF file, for example, if those | ||
| 262 | + // comments are to be consumed by some other application. No checks are performed to ensure | ||
| 263 | + // that the text inserted here is valid PDF. If you want to insert multiline comments, you will | ||
| 264 | + // need to include \n in the string yourself and start each line with %. An extra newline will | ||
| 265 | + // be appended if one is not already present at the end of your text. | ||
| 316 | QPDF_DLL | 266 | QPDF_DLL |
| 317 | void setExtraHeaderText(std::string const&); | 267 | void setExtraHeaderText(std::string const&); |
| 318 | 268 | ||
| 319 | - // Causes a deterministic /ID value to be generated. When this is | ||
| 320 | - // set, the current time and output file name are not used as part | ||
| 321 | - // of /ID generation. Instead, a digest of all significant parts | ||
| 322 | - // of the output file's contents is included in the /ID | ||
| 323 | - // calculation. Use of a deterministic /ID can be handy when it is | ||
| 324 | - // desirable for a repeat of the same qpdf operation on the same | ||
| 325 | - // inputs being written to the same outputs with the same | ||
| 326 | - // parameters to generate exactly the same results. This feature | ||
| 327 | - // is incompatible with encrypted files because, for encrypted | ||
| 328 | - // files, the /ID is generated before any part of the file is | ||
| 329 | - // written since it is an input to the encryption process. | 269 | + // Causes a deterministic /ID value to be generated. When this is set, the current time and |
| 270 | + // output file name are not used as part of /ID generation. Instead, a digest of all significant | ||
| 271 | + // parts of the output file's contents is included in the /ID calculation. Use of a | ||
| 272 | + // deterministic /ID can be handy when it is desirable for a repeat of the same qpdf operation | ||
| 273 | + // on the same inputs being written to the same outputs with the same parameters to generate | ||
| 274 | + // exactly the same results. This feature is incompatible with encrypted files because, for | ||
| 275 | + // encrypted files, the /ID is generated before any part of the file is written since it is an | ||
| 276 | + // input to the encryption process. | ||
| 330 | QPDF_DLL | 277 | QPDF_DLL |
| 331 | void setDeterministicID(bool); | 278 | void setDeterministicID(bool); |
| 332 | 279 | ||
| 333 | - // Cause a static /ID value to be generated. Use only in test | ||
| 334 | - // suites. See also setDeterministicID. | 280 | + // Cause a static /ID value to be generated. Use only in test suites. See also |
| 281 | + // setDeterministicID. | ||
| 335 | QPDF_DLL | 282 | QPDF_DLL |
| 336 | void setStaticID(bool); | 283 | void setStaticID(bool); |
| 337 | 284 | ||
| 338 | - // Use a fixed initialization vector for AES-CBC encryption. This | ||
| 339 | - // is not secure. It should be used only in test suites for | ||
| 340 | - // creating predictable encrypted output. | 285 | + // Use a fixed initialization vector for AES-CBC encryption. This is not secure. It should be |
| 286 | + // used only in test suites for creating predictable encrypted output. | ||
| 341 | QPDF_DLL | 287 | QPDF_DLL |
| 342 | void setStaticAesIV(bool); | 288 | void setStaticAesIV(bool); |
| 343 | 289 | ||
| 344 | - // Suppress inclusion of comments indicating original object IDs | ||
| 345 | - // when writing QDF files. This can also be useful for testing, | ||
| 346 | - // particularly when using comparison of two qdf files to | 290 | + // Suppress inclusion of comments indicating original object IDs when writing QDF files. This |
| 291 | + // can also be useful for testing, particularly when using comparison of two qdf files to | ||
| 347 | // determine whether two PDF files have identical content. | 292 | // determine whether two PDF files have identical content. |
| 348 | QPDF_DLL | 293 | QPDF_DLL |
| 349 | void setSuppressOriginalObjectIDs(bool); | 294 | void setSuppressOriginalObjectIDs(bool); |
| 350 | 295 | ||
| 351 | - // Preserve encryption. The default is true unless prefilering, | ||
| 352 | - // content normalization, or qdf mode has been selected in which | ||
| 353 | - // case encryption is never preserved. Encryption is also not | 296 | + // Preserve encryption. The default is true unless prefilering, content normalization, or qdf |
| 297 | + // mode has been selected in which case encryption is never preserved. Encryption is also not | ||
| 354 | // preserved if we explicitly set encryption parameters. | 298 | // preserved if we explicitly set encryption parameters. |
| 355 | QPDF_DLL | 299 | QPDF_DLL |
| 356 | void setPreserveEncryption(bool); | 300 | void setPreserveEncryption(bool); |
| 357 | 301 | ||
| 358 | - // Copy encryption parameters from another QPDF object. If you | ||
| 359 | - // want to copy encryption from the object you are writing, call | ||
| 360 | - // setPreserveEncryption(true) instead. | 302 | + // Copy encryption parameters from another QPDF object. If you want to copy encryption from the |
| 303 | + // object you are writing, call setPreserveEncryption(true) instead. | ||
| 361 | QPDF_DLL | 304 | QPDF_DLL |
| 362 | void copyEncryptionParameters(QPDF&); | 305 | void copyEncryptionParameters(QPDF&); |
| 363 | 306 | ||
| 364 | - // Set up for encrypted output. User and owner password both must | ||
| 365 | - // be specified. Either or both may be the empty string. Note | ||
| 366 | - // that qpdf does not apply any special treatment to the empty | ||
| 367 | - // string, which makes it possible to create encrypted files with | ||
| 368 | - // empty owner passwords and non-empty user passwords or with the | ||
| 369 | - // same password for both user and owner. Some PDF reading | ||
| 370 | - // products don't handle such files very well. Enabling | ||
| 371 | - // encryption disables stream prefiltering and content | ||
| 372 | - // normalization. Note that setting R2 encryption parameters sets | ||
| 373 | - // the PDF version to at least 1.3, setting R3 encryption | ||
| 374 | - // parameters pushes the PDF version number to at least 1.4, | ||
| 375 | - // setting R4 parameters pushes the version to at least 1.5, or if | ||
| 376 | - // AES is used, 1.6, and setting R5 or R6 parameters pushes the | ||
| 377 | - // version to at least 1.7 with extension level 3. | 307 | + // Set up for encrypted output. User and owner password both must be specified. Either or both |
| 308 | + // may be the empty string. Note that qpdf does not apply any special treatment to the empty | ||
| 309 | + // string, which makes it possible to create encrypted files with empty owner passwords and | ||
| 310 | + // non-empty user passwords or with the same password for both user and owner. Some PDF reading | ||
| 311 | + // products don't handle such files very well. Enabling encryption disables stream prefiltering | ||
| 312 | + // and content normalization. Note that setting R2 encryption parameters sets the PDF version | ||
| 313 | + // to at least 1.3, setting R3 encryption parameters pushes the PDF version number to at | ||
| 314 | + // least 1.4, setting R4 parameters pushes the version to at least 1.5, or if AES is used, 1.6, | ||
| 315 | + // and setting R5 or R6 parameters pushes the version to at least 1.7 with extension level 3. | ||
| 378 | // | 316 | // |
| 379 | - // Note about Unicode passwords: the PDF specification requires | ||
| 380 | - // passwords to be encoded with PDF Doc encoding for R <= 4 and | ||
| 381 | - // UTF-8 for R >= 5. In all cases, these methods take strings of | ||
| 382 | - // bytes as passwords. It is up to the caller to ensure that | ||
| 383 | - // passwords are properly encoded. The qpdf command-line tool | ||
| 384 | - // tries to do this, as discussed in the manual. If you are doing | ||
| 385 | - // this from your own application, QUtil contains many transcoding | ||
| 386 | - // functions that could be useful to you, most notably | ||
| 387 | - // utf8_to_pdf_doc. | ||
| 388 | - | ||
| 389 | - // R2 uses RC4, which is a weak cryptographic algorithm. Don't use | ||
| 390 | - // it unless you have to. See "Weak Cryptography" in the manual. | ||
| 391 | - // This encryption format is deprecated in the PDF 2.0 | 317 | + // Note about Unicode passwords: the PDF specification requires passwords to be encoded with PDF |
| 318 | + // Doc encoding for R <= 4 and UTF-8 for R >= 5. In all cases, these methods take strings of | ||
| 319 | + // bytes as passwords. It is up to the caller to ensure that passwords are properly encoded. The | ||
| 320 | + // qpdf command-line tool tries to do this, as discussed in the manual. If you are doing this | ||
| 321 | + // from your own application, QUtil contains many transcoding functions that could be useful to | ||
| 322 | + // you, most notably utf8_to_pdf_doc. | ||
| 323 | + | ||
| 324 | + // R2 uses RC4, which is a weak cryptographic algorithm. Don't use it unless you have to. See | ||
| 325 | + // "Weak Cryptography" in the manual. This encryption format is deprecated in the PDF 2.0 | ||
| 392 | // specification. | 326 | // specification. |
| 393 | QPDF_DLL | 327 | QPDF_DLL |
| 394 | void setR2EncryptionParametersInsecure( | 328 | void setR2EncryptionParametersInsecure( |
| @@ -398,9 +332,8 @@ class QPDFWriter | @@ -398,9 +332,8 @@ class QPDFWriter | ||
| 398 | bool allow_modify, | 332 | bool allow_modify, |
| 399 | bool allow_extract, | 333 | bool allow_extract, |
| 400 | bool allow_annotate); | 334 | bool allow_annotate); |
| 401 | - // R3 uses RC4, which is a weak cryptographic algorithm. Don't use | ||
| 402 | - // it unless you have to. See "Weak Cryptography" in the manual. | ||
| 403 | - // This encryption format is deprecated in the PDF 2.0 | 335 | + // R3 uses RC4, which is a weak cryptographic algorithm. Don't use it unless you have to. See |
| 336 | + // "Weak Cryptography" in the manual. This encryption format is deprecated in the PDF 2.0 | ||
| 404 | // specification. | 337 | // specification. |
| 405 | QPDF_DLL | 338 | QPDF_DLL |
| 406 | void setR3EncryptionParametersInsecure( | 339 | void setR3EncryptionParametersInsecure( |
| @@ -413,11 +346,10 @@ class QPDFWriter | @@ -413,11 +346,10 @@ class QPDFWriter | ||
| 413 | bool allow_form_filling, | 346 | bool allow_form_filling, |
| 414 | bool allow_modify_other, | 347 | bool allow_modify_other, |
| 415 | qpdf_r3_print_e print); | 348 | qpdf_r3_print_e print); |
| 416 | - // When use_aes=false, this call enables R4 with RC4, which is a | ||
| 417 | - // weak cryptographic algorithm. Even with use_aes=true, the | ||
| 418 | - // overall encryption scheme is weak. Don't use it unless you have | ||
| 419 | - // to. See "Weak Cryptography" in the manual. This encryption | ||
| 420 | - // format is deprecated in the PDF 2.0 specification. | 349 | + // When use_aes=false, this call enables R4 with RC4, which is a weak cryptographic algorithm. |
| 350 | + // Even with use_aes=true, the overall encryption scheme is weak. Don't use it unless you have | ||
| 351 | + // to. See "Weak Cryptography" in the manual. This encryption format is deprecated in the | ||
| 352 | + // PDF 2.0 specification. | ||
| 421 | QPDF_DLL | 353 | QPDF_DLL |
| 422 | void setR4EncryptionParametersInsecure( | 354 | void setR4EncryptionParametersInsecure( |
| 423 | char const* user_password, | 355 | char const* user_password, |
| @@ -431,9 +363,8 @@ class QPDFWriter | @@ -431,9 +363,8 @@ class QPDFWriter | ||
| 431 | qpdf_r3_print_e print, | 363 | qpdf_r3_print_e print, |
| 432 | bool encrypt_metadata, | 364 | bool encrypt_metadata, |
| 433 | bool use_aes); | 365 | bool use_aes); |
| 434 | - // R5 is deprecated. Do not use it for production use. Writing | ||
| 435 | - // R5 is supported by qpdf primarily to generate test files for | ||
| 436 | - // applications that may need to test R5 support. | 366 | + // R5 is deprecated. Do not use it for production use. Writing R5 is supported by qpdf |
| 367 | + // primarily to generate test files for applications that may need to test R5 support. | ||
| 437 | QPDF_DLL | 368 | QPDF_DLL |
| 438 | void setR5EncryptionParameters( | 369 | void setR5EncryptionParameters( |
| 439 | char const* user_password, | 370 | char const* user_password, |
| @@ -446,8 +377,7 @@ class QPDFWriter | @@ -446,8 +377,7 @@ class QPDFWriter | ||
| 446 | bool allow_modify_other, | 377 | bool allow_modify_other, |
| 447 | qpdf_r3_print_e print, | 378 | qpdf_r3_print_e print, |
| 448 | bool encrypt_metadata); | 379 | bool encrypt_metadata); |
| 449 | - // This is the only password-based encryption format supported by | ||
| 450 | - // the PDF specification. | 380 | + // This is the only password-based encryption format supported by the PDF specification. |
| 451 | QPDF_DLL | 381 | QPDF_DLL |
| 452 | void setR6EncryptionParameters( | 382 | void setR6EncryptionParameters( |
| 453 | char const* user_password, | 383 | char const* user_password, |
| @@ -461,57 +391,49 @@ class QPDFWriter | @@ -461,57 +391,49 @@ class QPDFWriter | ||
| 461 | qpdf_r3_print_e print, | 391 | qpdf_r3_print_e print, |
| 462 | bool encrypt_metadata_aes); | 392 | bool encrypt_metadata_aes); |
| 463 | 393 | ||
| 464 | - // Create linearized output. Disables qdf mode, content | ||
| 465 | - // normalization, and stream prefiltering. | 394 | + // Create linearized output. Disables qdf mode, content normalization, and stream prefiltering. |
| 466 | QPDF_DLL | 395 | QPDF_DLL |
| 467 | void setLinearization(bool); | 396 | void setLinearization(bool); |
| 468 | 397 | ||
| 469 | - // For debugging QPDF: provide the name of a file to write pass1 | ||
| 470 | - // of linearization to. The only reason to use this is to debug | ||
| 471 | - // QPDF. To linearize, QPDF writes out the file in two passes. | ||
| 472 | - // Usually the first pass is discarded, but lots of computations | ||
| 473 | - // are made in pass 1. If a linearized file comes out wrong, it | ||
| 474 | - // can be helpful to look at the first pass. | 398 | + // For debugging QPDF: provide the name of a file to write pass1 of linearization to. The only |
| 399 | + // reason to use this is to debug QPDF. To linearize, QPDF writes out the file in two passes. | ||
| 400 | + // Usually the first pass is discarded, but lots of computations are made in pass 1. If a | ||
| 401 | + // linearized file comes out wrong, it can be helpful to look at the first pass. | ||
| 475 | QPDF_DLL | 402 | QPDF_DLL |
| 476 | void setLinearizationPass1Filename(std::string const&); | 403 | void setLinearizationPass1Filename(std::string const&); |
| 477 | 404 | ||
| 478 | - // Create PCLm output. This is only useful for clients that know | ||
| 479 | - // how to create PCLm files. If a file is structured exactly as | ||
| 480 | - // PCLm requires, this call will tell QPDFWriter to write the PCLm | ||
| 481 | - // header, create certain unreferenced streams required by the | ||
| 482 | - // standard, and write the objects in the required order. Calling | ||
| 483 | - // this on an ordinary PDF serves no purpose. There is no | 405 | + // Create PCLm output. This is only useful for clients that know how to create PCLm files. If a |
| 406 | + // file is structured exactly as PCLm requires, this call will tell QPDFWriter to write the PCLm | ||
| 407 | + // header, create certain unreferenced streams required by the standard, and write the objects | ||
| 408 | + // in the required order. Calling this on an ordinary PDF serves no purpose. There is no | ||
| 484 | // command-line argument that causes this method to be called. | 409 | // command-line argument that causes this method to be called. |
| 485 | QPDF_DLL | 410 | QPDF_DLL |
| 486 | void setPCLm(bool); | 411 | void setPCLm(bool); |
| 487 | 412 | ||
| 488 | - // If you want to be notified of progress, derive a class from | ||
| 489 | - // ProgressReporter and override the reportProgress method. | 413 | + // If you want to be notified of progress, derive a class from ProgressReporter and override the |
| 414 | + // reportProgress method. | ||
| 490 | QPDF_DLL | 415 | QPDF_DLL |
| 491 | void registerProgressReporter(std::shared_ptr<ProgressReporter>); | 416 | void registerProgressReporter(std::shared_ptr<ProgressReporter>); |
| 492 | 417 | ||
| 493 | - // Return the PDF version that will be written into the header. | ||
| 494 | - // Calling this method does all the preparation for writing, so it | ||
| 495 | - // is an error to call any methods that may cause a change to the | ||
| 496 | - // version. Adding new objects to the original file after calling | ||
| 497 | - // this may also cause problems. It is safe to update existing | ||
| 498 | - // objects or stream contents after calling this method, e.g., to | 418 | + // Return the PDF version that will be written into the header. Calling this method does all the |
| 419 | + // preparation for writing, so it is an error to call any methods that may cause a change to the | ||
| 420 | + // version. Adding new objects to the original file after calling this may also cause problems. | ||
| 421 | + // It is safe to update existing objects or stream contents after calling this method, e.g., to | ||
| 499 | // include the final version number in metadata. | 422 | // include the final version number in metadata. |
| 500 | QPDF_DLL | 423 | QPDF_DLL |
| 501 | std::string getFinalVersion(); | 424 | std::string getFinalVersion(); |
| 502 | 425 | ||
| 503 | - // Write the final file. There is no expectation of being able to | ||
| 504 | - // call write() more than once. | 426 | + // Write the final file. There is no expectation of being able to call write() more than once. |
| 505 | QPDF_DLL | 427 | QPDF_DLL |
| 506 | void write(); | 428 | void write(); |
| 507 | 429 | ||
| 508 | - // Return renumbered ObjGen that was written into the final file. | ||
| 509 | - // This method can be used after calling write(). | 430 | + // Return renumbered ObjGen that was written into the final file. This method can be used after |
| 431 | + // calling write(). | ||
| 510 | QPDF_DLL | 432 | QPDF_DLL |
| 511 | QPDFObjGen getRenumberedObjGen(QPDFObjGen); | 433 | QPDFObjGen getRenumberedObjGen(QPDFObjGen); |
| 512 | 434 | ||
| 513 | - // Return XRef entry that was written into the final file. | ||
| 514 | - // This method can be used after calling write(). | 435 | + // Return XRef entry that was written into the final file. This method can be used after calling |
| 436 | + // write(). | ||
| 515 | QPDF_DLL | 437 | QPDF_DLL |
| 516 | std::map<QPDFObjGen, QPDFXRefEntry> getWrittenXRefTable(); | 438 | std::map<QPDFObjGen, QPDFXRefEntry> getWrittenXRefTable(); |
| 517 | 439 | ||
| @@ -525,15 +447,12 @@ class QPDFWriter | @@ -525,15 +447,12 @@ class QPDFWriter | ||
| 525 | 447 | ||
| 526 | enum trailer_e { t_normal, t_lin_first, t_lin_second }; | 448 | enum trailer_e { t_normal, t_lin_first, t_lin_second }; |
| 527 | 449 | ||
| 528 | - // An reference to a PipelinePopper instance is passed into | ||
| 529 | - // activatePipelineStack. When the PipelinePopper goes out of | ||
| 530 | - // scope, the pipeline stack is popped. PipelinePopper's | ||
| 531 | - // destructor calls finish on the current pipeline and pops the | ||
| 532 | - // pipeline stack until the top of stack is a previous active top | ||
| 533 | - // of stack, and restores the pipeline to that point. It deletes | ||
| 534 | - // any pipelines that it pops. If the bp argument is non-null and | ||
| 535 | - // any of the stack items are of type Pl_Buffer, the buffer is | ||
| 536 | - // retrieved. | 450 | + // An reference to a PipelinePopper instance is passed into activatePipelineStack. When the |
| 451 | + // PipelinePopper goes out of scope, the pipeline stack is popped. PipelinePopper's destructor | ||
| 452 | + // calls finish on the current pipeline and pops the pipeline stack until the top of stack is a | ||
| 453 | + // previous active top of stack, and restores the pipeline to that point. It deletes any | ||
| 454 | + // pipelines that it pops. If the bp argument is non-null and any of the stack items are of type | ||
| 455 | + // Pl_Buffer, the buffer is retrieved. | ||
| 537 | class PipelinePopper | 456 | class PipelinePopper |
| 538 | { | 457 | { |
| 539 | friend class QPDFWriter; | 458 | friend class QPDFWriter; |
| @@ -672,10 +591,9 @@ class QPDFWriter | @@ -672,10 +591,9 @@ class QPDFWriter | ||
| 672 | int linearization_pass); | 591 | int linearization_pass); |
| 673 | size_t calculateXrefStreamPadding(qpdf_offset_t xref_bytes); | 592 | size_t calculateXrefStreamPadding(qpdf_offset_t xref_bytes); |
| 674 | 593 | ||
| 675 | - // When filtering subsections, push additional pipelines to the | ||
| 676 | - // stack. When ready to switch, activate the pipeline stack. When | ||
| 677 | - // the passed in PipelinePopper goes out of scope, the stack is | ||
| 678 | - // popped. | 594 | + // When filtering subsections, push additional pipelines to the stack. When ready to switch, |
| 595 | + // activate the pipeline stack. When the passed in PipelinePopper goes out of scope, the stack | ||
| 596 | + // is popped. | ||
| 679 | Pipeline* pushPipeline(Pipeline*); | 597 | Pipeline* pushPipeline(Pipeline*); |
| 680 | void activatePipelineStack(PipelinePopper&); | 598 | void activatePipelineStack(PipelinePopper&); |
| 681 | void initializePipelineStack(Pipeline*); | 599 | void initializePipelineStack(Pipeline*); |
| @@ -779,9 +697,8 @@ class QPDFWriter | @@ -779,9 +697,8 @@ class QPDFWriter | ||
| 779 | int next_progress_report{0}; | 697 | int next_progress_report{0}; |
| 780 | }; | 698 | }; |
| 781 | 699 | ||
| 782 | - // Keep all member variables inside the Members object, which we | ||
| 783 | - // dynamically allocate. This makes it possible to add new private | ||
| 784 | - // members without breaking binary compatibility. | 700 | + // Keep all member variables inside the Members object, which we dynamically allocate. This |
| 701 | + // makes it possible to add new private members without breaking binary compatibility. | ||
| 785 | std::shared_ptr<Members> m; | 702 | std::shared_ptr<Members> m; |
| 786 | }; | 703 | }; |
| 787 | 704 |
include/qpdf/QPDFXRefEntry.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QPDFXREFENTRY_HH | 19 | #ifndef QPDFXREFENTRY_HH |
| 23 | #define QPDFXREFENTRY_HH | 20 | #define QPDFXREFENTRY_HH |
| @@ -28,8 +25,7 @@ | @@ -28,8 +25,7 @@ | ||
| 28 | class QPDFXRefEntry | 25 | class QPDFXRefEntry |
| 29 | { | 26 | { |
| 30 | public: | 27 | public: |
| 31 | - // Type constants are from the PDF spec section | ||
| 32 | - // "Cross-Reference Streams": | 28 | + // Type constants are from the PDF spec section "Cross-Reference Streams": |
| 33 | // 0 = free entry; not used | 29 | // 0 = free entry; not used |
| 34 | // 1 = "uncompressed"; field 1 = offset | 30 | // 1 = "uncompressed"; field 1 = offset |
| 35 | // 2 = "compressed"; field 1 = object stream number, field 2 = index | 31 | // 2 = "compressed"; field 1 = object stream number, field 2 = index |
| @@ -65,8 +61,8 @@ class QPDFXRefEntry | @@ -65,8 +61,8 @@ class QPDFXRefEntry | ||
| 65 | int getObjStreamIndex() const; // only for type 2 | 61 | int getObjStreamIndex() const; // only for type 2 |
| 66 | 62 | ||
| 67 | private: | 63 | private: |
| 68 | - // This class does not use the Members pattern to avoid a memory | ||
| 69 | - // allocation for every one of these. A lot of these get created. | 64 | + // This class does not use the Members pattern to avoid a memory allocation for every one of |
| 65 | + // these. A lot of these get created. | ||
| 70 | int type{0}; | 66 | int type{0}; |
| 71 | qpdf_offset_t field1{0}; | 67 | qpdf_offset_t field1{0}; |
| 72 | int field2{0}; | 68 | int field2{0}; |
include/qpdf/QTC.hh
| @@ -2,33 +2,28 @@ | @@ -2,33 +2,28 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QTC_HH | 19 | #ifndef QTC_HH |
| 23 | #define QTC_HH | 20 | #define QTC_HH |
| 24 | 21 | ||
| 25 | #include <qpdf/DLL.h> | 22 | #include <qpdf/DLL.h> |
| 26 | 23 | ||
| 27 | -// Defining QPDF_DISABLE_QTC will effectively compile out any QTC::TC | ||
| 28 | -// calls in any code that includes this file, but QTC will still be | ||
| 29 | -// built into the library. That way, it is possible to build and | ||
| 30 | -// package qpdf with QPDF_DISABLE_QTC while still making QTC::TC | ||
| 31 | -// available to end users. | 24 | +// Defining QPDF_DISABLE_QTC will effectively compile out any QTC::TC calls in any code that |
| 25 | +// includes this file, but QTC will still be built into the library. That way, it is possible to | ||
| 26 | +// build and package qpdf with QPDF_DISABLE_QTC while still making QTC::TC available to end users. | ||
| 32 | 27 | ||
| 33 | namespace QTC | 28 | namespace QTC |
| 34 | { | 29 | { |
include/qpdf/QUtil.hh
| @@ -2,22 +2,19 @@ | @@ -2,22 +2,19 @@ | ||
| 2 | // | 2 | // |
| 3 | // This file is part of qpdf. | 3 | // This file is part of qpdf. |
| 4 | // | 4 | // |
| 5 | -// Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | -// you may not use this file except in compliance with the License. | ||
| 7 | -// You may obtain a copy of the License at | 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | +// in compliance with the License. You may obtain a copy of the License at | ||
| 8 | // | 7 | // |
| 9 | // http://www.apache.org/licenses/LICENSE-2.0 | 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | // | 9 | // |
| 11 | -// Unless required by applicable law or agreed to in writing, software | ||
| 12 | -// distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | -// See the License for the specific language governing permissions and | ||
| 15 | -// limitations under the License. | 10 | +// Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | +// or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | +// the License. | ||
| 16 | // | 14 | // |
| 17 | -// Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | -// of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | -// continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | -// see the manual for additional information. | 15 | +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | +// License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | +// Please see the manual for additional information. | ||
| 21 | 18 | ||
| 22 | #ifndef QUTIL_HH | 19 | #ifndef QUTIL_HH |
| 23 | #define QUTIL_HH | 20 | #define QUTIL_HH |
| @@ -40,8 +37,7 @@ class Pipeline; | @@ -40,8 +37,7 @@ class Pipeline; | ||
| 40 | 37 | ||
| 41 | namespace QUtil | 38 | namespace QUtil |
| 42 | { | 39 | { |
| 43 | - // This is a collection of useful utility functions that don't | ||
| 44 | - // really go anywhere else. | 40 | + // This is a collection of useful utility functions that don't really go anywhere else. |
| 45 | QPDF_DLL | 41 | QPDF_DLL |
| 46 | std::string int_to_string(long long, int length = 0); | 42 | std::string int_to_string(long long, int length = 0); |
| 47 | QPDF_DLL | 43 | QPDF_DLL |
| @@ -53,8 +49,7 @@ namespace QUtil | @@ -53,8 +49,7 @@ namespace QUtil | ||
| 53 | QPDF_DLL | 49 | QPDF_DLL |
| 54 | std::string double_to_string(double, int decimal_places = 0, bool trim_trailing_zeroes = true); | 50 | std::string double_to_string(double, int decimal_places = 0, bool trim_trailing_zeroes = true); |
| 55 | 51 | ||
| 56 | - // These string to number methods throw std::runtime_error on | ||
| 57 | - // underflow/overflow. | 52 | + // These string to number methods throw std::runtime_error on underflow/overflow. |
| 58 | QPDF_DLL | 53 | QPDF_DLL |
| 59 | long long string_to_ll(char const* str); | 54 | long long string_to_ll(char const* str); |
| 60 | QPDF_DLL | 55 | QPDF_DLL |
| @@ -64,63 +59,53 @@ namespace QUtil | @@ -64,63 +59,53 @@ namespace QUtil | ||
| 64 | QPDF_DLL | 59 | QPDF_DLL |
| 65 | unsigned int string_to_uint(char const* str); | 60 | unsigned int string_to_uint(char const* str); |
| 66 | 61 | ||
| 67 | - // Returns true if this exactly represents a long long. The | ||
| 68 | - // determination is made by converting the string to a long long, | ||
| 69 | - // then converting the result back to a string, and then comparing | 62 | + // Returns true if this exactly represents a long long. The determination is made by converting |
| 63 | + // the string to a long long, then converting the result back to a string, and then comparing | ||
| 70 | // that result with the original string. | 64 | // that result with the original string. |
| 71 | QPDF_DLL | 65 | QPDF_DLL |
| 72 | bool is_long_long(char const* str); | 66 | bool is_long_long(char const* str); |
| 73 | 67 | ||
| 74 | - // Pipeline's write method wants unsigned char*, but we often have | ||
| 75 | - // some other type of string. These methods do combinations of | ||
| 76 | - // const_cast and reinterpret_cast to give us an unsigned char*. | ||
| 77 | - // They should only be used when it is known that it is safe. | ||
| 78 | - // None of the pipelines in qpdf modify the data passed to them, | ||
| 79 | - // so within qpdf, it should always be safe. | 68 | + // Pipeline's write method wants unsigned char*, but we often have some other type of string. |
| 69 | + // These methods do combinations of const_cast and reinterpret_cast to give us an unsigned | ||
| 70 | + // char*. They should only be used when it is known that it is safe. None of the pipelines in | ||
| 71 | + // qpdf modify the data passed to them, so within qpdf, it should always be safe. | ||
| 80 | QPDF_DLL | 72 | QPDF_DLL |
| 81 | unsigned char* unsigned_char_pointer(std::string const& str); | 73 | unsigned char* unsigned_char_pointer(std::string const& str); |
| 82 | QPDF_DLL | 74 | QPDF_DLL |
| 83 | unsigned char* unsigned_char_pointer(char const* str); | 75 | unsigned char* unsigned_char_pointer(char const* str); |
| 84 | 76 | ||
| 85 | - // Throw QPDFSystemError, which is derived from | ||
| 86 | - // std::runtime_error, with a string formed by appending to | ||
| 87 | - // "description: " the standard string corresponding to the | ||
| 88 | - // current value of errno. You can retrieve the value of errno by | ||
| 89 | - // calling getErrno() on the QPDFSystemError. Prior to qpdf 8.2.0, | ||
| 90 | - // this method threw system::runtime_error directly, but since | ||
| 91 | - // QPDFSystemError is derived from system::runtime_error, old code | ||
| 92 | - // that specifically catches std::runtime_error will still work. | 77 | + // Throw QPDFSystemError, which is derived from std::runtime_error, with a string formed by |
| 78 | + // appending to "description: " the standard string corresponding to the current value of errno. | ||
| 79 | + // You can retrieve the value of errno by calling getErrno() on the QPDFSystemError. Prior to | ||
| 80 | + // qpdf 8.2.0, this method threw system::runtime_error directly, but since QPDFSystemError is | ||
| 81 | + // derived from system::runtime_error, old code that specifically catches std::runtime_error | ||
| 82 | + // will still work. | ||
| 93 | QPDF_DLL | 83 | QPDF_DLL |
| 94 | void throw_system_error(std::string const& description); | 84 | void throw_system_error(std::string const& description); |
| 95 | 85 | ||
| 96 | - // The status argument is assumed to be the return value of a | ||
| 97 | - // standard library call that sets errno when it fails. If status | ||
| 98 | - // is -1, convert the current value of errno to a | ||
| 99 | - // std::runtime_error that includes the standard error string. | ||
| 100 | - // Otherwise, return status. | 86 | + // The status argument is assumed to be the return value of a standard library call that sets |
| 87 | + // errno when it fails. If status is -1, convert the current value of errno to a | ||
| 88 | + // std::runtime_error that includes the standard error string. Otherwise, return status. | ||
| 101 | QPDF_DLL | 89 | QPDF_DLL |
| 102 | int os_wrapper(std::string const& description, int status); | 90 | int os_wrapper(std::string const& description, int status); |
| 103 | 91 | ||
| 104 | - // If the open fails, throws std::runtime_error. Otherwise, the | ||
| 105 | - // FILE* is returned. The filename should be UTF-8 encoded, even | ||
| 106 | - // on Windows. It will be converted as needed on Windows. | 92 | + // If the open fails, throws std::runtime_error. Otherwise, the FILE* is returned. The filename |
| 93 | + // should be UTF-8 encoded, even on Windows. It will be converted as needed on Windows. | ||
| 107 | QPDF_DLL | 94 | QPDF_DLL |
| 108 | FILE* safe_fopen(char const* filename, char const* mode); | 95 | FILE* safe_fopen(char const* filename, char const* mode); |
| 109 | 96 | ||
| 110 | - // The FILE* argument is assumed to be the return of fopen. If | ||
| 111 | - // null, throw std::runtime_error. Otherwise, return the FILE* | ||
| 112 | - // argument. | 97 | + // The FILE* argument is assumed to be the return of fopen. If null, throw std::runtime_error. |
| 98 | + // Otherwise, return the FILE* argument. | ||
| 113 | QPDF_DLL | 99 | QPDF_DLL |
| 114 | FILE* fopen_wrapper(std::string const&, FILE*); | 100 | FILE* fopen_wrapper(std::string const&, FILE*); |
| 115 | 101 | ||
| 116 | - // This is a little class to help with automatic closing files. | ||
| 117 | - // You can do something like | 102 | + // This is a little class to help with automatic closing files. You can do something like |
| 118 | // | 103 | // |
| 119 | // QUtil::FileCloser fc(QUtil::safe_fopen(filename, "rb")); | 104 | // QUtil::FileCloser fc(QUtil::safe_fopen(filename, "rb")); |
| 120 | // | 105 | // |
| 121 | - // and then use fc.f to the file. Be sure to actually declare a | ||
| 122 | - // variable of type FileCloser. Using it as a temporary won't work | ||
| 123 | - // because it will close the file as soon as it goes out of scope. | 106 | + // and then use fc.f to the file. Be sure to actually declare a variable of type FileCloser. |
| 107 | + // Using it as a temporary won't work because it will close the file as soon as it goes out of | ||
| 108 | + // scope. | ||
| 124 | class FileCloser | 109 | class FileCloser |
| 125 | { | 110 | { |
| 126 | public: | 111 | public: |
| @@ -160,28 +145,24 @@ namespace QUtil | @@ -160,28 +145,24 @@ namespace QUtil | ||
| 160 | QPDF_DLL | 145 | QPDF_DLL |
| 161 | void rename_file(char const* oldname, char const* newname); | 146 | void rename_file(char const* oldname, char const* newname); |
| 162 | 147 | ||
| 163 | - // Write the contents of filename as a binary file to the | ||
| 164 | - // pipeline. | 148 | + // Write the contents of filename as a binary file to the pipeline. |
| 165 | QPDF_DLL | 149 | QPDF_DLL |
| 166 | void pipe_file(char const* filename, Pipeline* p); | 150 | void pipe_file(char const* filename, Pipeline* p); |
| 167 | 151 | ||
| 168 | - // Return a function that will send the contents of the given file | ||
| 169 | - // through the given pipeline as binary data. | 152 | + // Return a function that will send the contents of the given file through the given pipeline as |
| 153 | + // binary data. | ||
| 170 | QPDF_DLL | 154 | QPDF_DLL |
| 171 | std::function<void(Pipeline*)> file_provider(std::string const& filename); | 155 | std::function<void(Pipeline*)> file_provider(std::string const& filename); |
| 172 | 156 | ||
| 173 | - // Return the last path element. On Windows, either / or \ are | ||
| 174 | - // path separators. Otherwise, only / is a path separator. Strip | ||
| 175 | - // any trailing path separators. Then, if any path separators | ||
| 176 | - // remain, return everything after the last path separator. | ||
| 177 | - // Otherwise, return the whole string. As a special case, if a | ||
| 178 | - // string consists entirely of path separators, the first | ||
| 179 | - // character is returned. | 157 | + // Return the last path element. On Windows, either / or \ are path separators. Otherwise, only |
| 158 | + // / is a path separator. Strip any trailing path separators. Then, if any path separators | ||
| 159 | + // remain, return everything after the last path separator. Otherwise, return the whole string. | ||
| 160 | + // As a special case, if a string consists entirely of path separators, the first character is | ||
| 161 | + // returned. | ||
| 180 | QPDF_DLL | 162 | QPDF_DLL |
| 181 | std::string path_basename(std::string const& filename); | 163 | std::string path_basename(std::string const& filename); |
| 182 | 164 | ||
| 183 | - // Returns a dynamically allocated copy of a string that the | ||
| 184 | - // caller has to delete with delete[]. | 165 | + // Returns a dynamically allocated copy of a string that the caller has to delete with delete[]. |
| 185 | QPDF_DLL | 166 | QPDF_DLL |
| 186 | char* copy_string(std::string const&); | 167 | char* copy_string(std::string const&); |
| 187 | 168 | ||
| @@ -193,8 +174,7 @@ namespace QUtil | @@ -193,8 +174,7 @@ namespace QUtil | ||
| 193 | QPDF_DLL | 174 | QPDF_DLL |
| 194 | std::unique_ptr<char[]> make_unique_cstr(std::string const&); | 175 | std::unique_ptr<char[]> make_unique_cstr(std::string const&); |
| 195 | 176 | ||
| 196 | - // Create a shared pointer to an array. From c++20, | ||
| 197 | - // std::make_shared<T[]>(n) does this. | 177 | + // Create a shared pointer to an array. From c++20, std::make_shared<T[]>(n) does this. |
| 198 | template <typename T> | 178 | template <typename T> |
| 199 | std::shared_ptr<T> | 179 | std::shared_ptr<T> |
| 200 | make_shared_array(size_t n) | 180 | make_shared_array(size_t n) |
| @@ -202,27 +182,24 @@ namespace QUtil | @@ -202,27 +182,24 @@ namespace QUtil | ||
| 202 | return std::shared_ptr<T>(new T[n], std::default_delete<T[]>()); | 182 | return std::shared_ptr<T>(new T[n], std::default_delete<T[]>()); |
| 203 | } | 183 | } |
| 204 | 184 | ||
| 205 | - // Returns lower-case hex-encoded version of the string, treating | ||
| 206 | - // each character in the input string as unsigned. The output | ||
| 207 | - // string will be twice as long as the input string. | 185 | + // Returns lower-case hex-encoded version of the string, treating each character in the input |
| 186 | + // string as unsigned. The output string will be twice as long as the input string. | ||
| 208 | QPDF_DLL | 187 | QPDF_DLL |
| 209 | std::string hex_encode(std::string const&); | 188 | std::string hex_encode(std::string const&); |
| 210 | 189 | ||
| 211 | - // Returns lower-case hex-encoded version of the char including a leading | ||
| 212 | - // "#". | 190 | + // Returns lower-case hex-encoded version of the char including a leading "#". |
| 213 | QPDF_DLL | 191 | QPDF_DLL |
| 214 | inline std::string hex_encode_char(char); | 192 | inline std::string hex_encode_char(char); |
| 215 | 193 | ||
| 216 | - // Returns a string that is the result of decoding the input | ||
| 217 | - // string. The input string may consist of mixed case hexadecimal | ||
| 218 | - // digits. Any characters that are not hexadecimal digits will be | ||
| 219 | - // silently ignored. If there are an odd number of hexadecimal | ||
| 220 | - // digits, a trailing 0 will be assumed. | 194 | + // Returns a string that is the result of decoding the input string. The input string may |
| 195 | + // consist of mixed case hexadecimal digits. Any characters that are not hexadecimal digits will | ||
| 196 | + // be silently ignored. If there are an odd number of hexadecimal digits, a trailing 0 will be | ||
| 197 | + // assumed. | ||
| 221 | QPDF_DLL | 198 | QPDF_DLL |
| 222 | std::string hex_decode(std::string const&); | 199 | std::string hex_decode(std::string const&); |
| 223 | 200 | ||
| 224 | - // Decode a single hex digit into a char in the range 0 <= char < 16. Return | ||
| 225 | - // a char >= 16 if digit is not a valid hex digit. | 201 | + // Decode a single hex digit into a char in the range 0 <= char < 16. Return a char >= 16 if |
| 202 | + // digit is not a valid hex digit. | ||
| 226 | QPDF_DLL | 203 | QPDF_DLL |
| 227 | inline constexpr char hex_decode_char(char digit) noexcept; | 204 | inline constexpr char hex_decode_char(char digit) noexcept; |
| 228 | 205 | ||
| @@ -239,17 +216,15 @@ namespace QUtil | @@ -239,17 +216,15 @@ namespace QUtil | ||
| 239 | QPDF_DLL | 216 | QPDF_DLL |
| 240 | char* getWhoami(char* argv0); | 217 | char* getWhoami(char* argv0); |
| 241 | 218 | ||
| 242 | - // Get the value of an environment variable in a portable fashion. | ||
| 243 | - // Returns true iff the variable is defined. If `value' is | ||
| 244 | - // non-null, initializes it with the value of the variable. | 219 | + // Get the value of an environment variable in a portable fashion. Returns true iff the variable |
| 220 | + // is defined. If `value' is non-null, initializes it with the value of the variable. | ||
| 245 | QPDF_DLL | 221 | QPDF_DLL |
| 246 | bool get_env(std::string const& var, std::string* value = nullptr); | 222 | bool get_env(std::string const& var, std::string* value = nullptr); |
| 247 | 223 | ||
| 248 | QPDF_DLL | 224 | QPDF_DLL |
| 249 | time_t get_current_time(); | 225 | time_t get_current_time(); |
| 250 | 226 | ||
| 251 | - // Portable structure representing a point in time with second | ||
| 252 | - // granularity and time zone offset | 227 | + // Portable structure representing a point in time with second granularity and time zone offset |
| 253 | struct QPDFTime | 228 | struct QPDFTime |
| 254 | { | 229 | { |
| 255 | QPDFTime() = default; | 230 | QPDFTime() = default; |
| @@ -277,12 +252,11 @@ namespace QUtil | @@ -277,12 +252,11 @@ namespace QUtil | ||
| 277 | QPDF_DLL | 252 | QPDF_DLL |
| 278 | QPDFTime get_current_qpdf_time(); | 253 | QPDFTime get_current_qpdf_time(); |
| 279 | 254 | ||
| 280 | - // Convert a QPDFTime structure to a PDF timestamp string, which | ||
| 281 | - // is "D:yyyymmddhhmmss<z>" where <z> is either "Z" for UTC or | ||
| 282 | - // "-hh'mm'" or "+hh'mm'" for timezone offset. <z> may also be | ||
| 283 | - // omitted. Examples: "D:20210207161528-05'00'", | ||
| 284 | - // "D:20210207211528Z", "D:20210207211528". See | ||
| 285 | - // get_current_qpdf_time and the QPDFTime structure above. | 255 | + // Convert a QPDFTime structure to a PDF timestamp string, which is "D:yyyymmddhhmmss<z>" where |
| 256 | + // <z> is either "Z" for UTC or "-hh'mm'" or "+hh'mm'" for timezone offset. <z> may also be | ||
| 257 | + // omitted. | ||
| 258 | + // Examples: "D:20210207161528-05'00'", "D:20210207211528Z", "D:20210207211528". | ||
| 259 | + // See get_current_qpdf_time and the QPDFTime structure above. | ||
| 286 | QPDF_DLL | 260 | QPDF_DLL |
| 287 | std::string qpdf_time_to_pdf_time(QPDFTime const&); | 261 | std::string qpdf_time_to_pdf_time(QPDFTime const&); |
| 288 | 262 | ||
| @@ -290,63 +264,53 @@ namespace QUtil | @@ -290,63 +264,53 @@ namespace QUtil | ||
| 290 | QPDF_DLL | 264 | QPDF_DLL |
| 291 | std::string qpdf_time_to_iso8601(QPDFTime const&); | 265 | std::string qpdf_time_to_iso8601(QPDFTime const&); |
| 292 | 266 | ||
| 293 | - // Convert a PDF timestamp string to a QPDFTime. If syntactically | ||
| 294 | - // valid, return true and fill in qtm. If not valid, return false, | ||
| 295 | - // and do not modify qtm. If qtm is null, just check the validity | ||
| 296 | - // of the string. | 267 | + // Convert a PDF timestamp string to a QPDFTime. If syntactically valid, return true and fill in |
| 268 | + // qtm. If not valid, return false, and do not modify qtm. If qtm is null, just check the | ||
| 269 | + // validity of the string. | ||
| 297 | QPDF_DLL | 270 | QPDF_DLL |
| 298 | bool pdf_time_to_qpdf_time(std::string const&, QPDFTime* qtm = nullptr); | 271 | bool pdf_time_to_qpdf_time(std::string const&, QPDFTime* qtm = nullptr); |
| 299 | 272 | ||
| 300 | - // Convert PDF timestamp to a second-granularity ISO-8601 | ||
| 301 | - // timestamp. If syntactically valid, return true and initialize | ||
| 302 | - // iso8601. Otherwise, return false. | 273 | + // Convert PDF timestamp to a second-granularity ISO-8601 timestamp. If syntactically valid, |
| 274 | + // return true and initialize iso8601. Otherwise, return false. | ||
| 303 | bool pdf_time_to_iso8601(std::string const& pdf_time, std::string& iso8601); | 275 | bool pdf_time_to_iso8601(std::string const& pdf_time, std::string& iso8601); |
| 304 | 276 | ||
| 305 | - // Return a string containing the byte representation of the UTF-8 | ||
| 306 | - // encoding for the unicode value passed in. | 277 | + // Return a string containing the byte representation of the UTF-8 encoding for the unicode |
| 278 | + // value passed in. | ||
| 307 | QPDF_DLL | 279 | QPDF_DLL |
| 308 | std::string toUTF8(unsigned long uval); | 280 | std::string toUTF8(unsigned long uval); |
| 309 | 281 | ||
| 310 | - // Return a string containing the byte representation of the | ||
| 311 | - // UTF-16 big-endian encoding for the unicode value passed in. | ||
| 312 | - // Unrepresentable code points are converted to U+FFFD. | 282 | + // Return a string containing the byte representation of the UTF-16 big-endian encoding for the |
| 283 | + // unicode value passed in. Unrepresentable code points are converted to U+FFFD. | ||
| 313 | QPDF_DLL | 284 | QPDF_DLL |
| 314 | std::string toUTF16(unsigned long uval); | 285 | std::string toUTF16(unsigned long uval); |
| 315 | 286 | ||
| 316 | - // If utf8_val.at(pos) points to the beginning of a valid | ||
| 317 | - // UTF-8-encoded character, return the codepoint of the character | ||
| 318 | - // and set error to false. Otherwise, return 0xfffd and set error | ||
| 319 | - // to true. In all cases, pos is advanced to the next position | ||
| 320 | - // that may begin a valid character. When the string has been | ||
| 321 | - // consumed, pos will be set to the string length. It is an error | ||
| 322 | - // to pass a value of pos that is greater than or equal to the | ||
| 323 | - // length of the string. | 287 | + // If utf8_val.at(pos) points to the beginning of a valid UTF-8-encoded character, return the |
| 288 | + // codepoint of the character and set error to false. Otherwise, return 0xfffd and set error to | ||
| 289 | + // true. In all cases, pos is advanced to the next position that may begin a valid character. | ||
| 290 | + // When the string has been consumed, pos will be set to the string length. It is an error to | ||
| 291 | + // pass a value of pos that is greater than or equal to the length of the string. | ||
| 324 | QPDF_DLL | 292 | QPDF_DLL |
| 325 | unsigned long get_next_utf8_codepoint(std::string const& utf8_val, size_t& pos, bool& error); | 293 | unsigned long get_next_utf8_codepoint(std::string const& utf8_val, size_t& pos, bool& error); |
| 326 | 294 | ||
| 327 | - // Test whether this is a UTF-16 string. This is indicated by | ||
| 328 | - // first two bytes being 0xFE 0xFF (big-endian) or 0xFF 0xFE | ||
| 329 | - // (little-endian), each of which is the encoding of U+FEFF, the | ||
| 330 | - // Unicode marker. Starting in qpdf 10.6.2, this detects | ||
| 331 | - // little-endian as well as big-endian. Even though the PDF spec | ||
| 332 | - // doesn't allow little-endian, most readers seem to accept it. | 295 | + // Test whether this is a UTF-16 string. This is indicated by first two bytes being 0xFE 0xFF |
| 296 | + // (big-endian) or 0xFF 0xFE (little-endian), each of which is the encoding of U+FEFF, the | ||
| 297 | + // Unicode marker. Starting in qpdf 10.6.2, this detects little-endian as well as big-endian. | ||
| 298 | + // Even though the PDF spec doesn't allow little-endian, most readers seem to accept it. | ||
| 333 | QPDF_DLL | 299 | QPDF_DLL |
| 334 | bool is_utf16(std::string const&); | 300 | bool is_utf16(std::string const&); |
| 335 | 301 | ||
| 336 | - // Test whether this is an explicit UTF-8 string as allowed by the | ||
| 337 | - // PDF 2.0 spec. This is indicated by first three bytes being 0xEF | ||
| 338 | - // 0xBB 0xBF, which is the UTF-8 encoding of U+FEFF. | 302 | + // Test whether this is an explicit UTF-8 string as allowed by the PDF 2.0 spec. This is |
| 303 | + // indicated by first three bytes being 0xEF 0xBB 0xBF, which is the UTF-8 encoding of U+FEFF. | ||
| 339 | QPDF_DLL | 304 | QPDF_DLL |
| 340 | bool is_explicit_utf8(std::string const&); | 305 | bool is_explicit_utf8(std::string const&); |
| 341 | 306 | ||
| 342 | - // Convert a UTF-8 encoded string to UTF-16 big-endian. | ||
| 343 | - // Unrepresentable code points are converted to U+FFFD. | 307 | + // Convert a UTF-8 encoded string to UTF-16 big-endian. Unrepresentable code points are |
| 308 | + // converted to U+FFFD. | ||
| 344 | QPDF_DLL | 309 | QPDF_DLL |
| 345 | std::string utf8_to_utf16(std::string const& utf8); | 310 | std::string utf8_to_utf16(std::string const& utf8); |
| 346 | 311 | ||
| 347 | - // Convert a UTF-8 encoded string to the specified single-byte | ||
| 348 | - // encoding system by replacing all unsupported characters with | ||
| 349 | - // the given unknown_char. | 312 | + // Convert a UTF-8 encoded string to the specified single-byte encoding system by replacing all |
| 313 | + // unsupported characters with the given unknown_char. | ||
| 350 | QPDF_DLL | 314 | QPDF_DLL |
| 351 | std::string utf8_to_ascii(std::string const& utf8, char unknown_char = '?'); | 315 | std::string utf8_to_ascii(std::string const& utf8, char unknown_char = '?'); |
| 352 | QPDF_DLL | 316 | QPDF_DLL |
| @@ -356,9 +320,8 @@ namespace QUtil | @@ -356,9 +320,8 @@ namespace QUtil | ||
| 356 | QPDF_DLL | 320 | QPDF_DLL |
| 357 | std::string utf8_to_pdf_doc(std::string const& utf8, char unknown_char = '?'); | 321 | std::string utf8_to_pdf_doc(std::string const& utf8, char unknown_char = '?'); |
| 358 | 322 | ||
| 359 | - // These versions return true if the conversion was successful and | ||
| 360 | - // false if any unrepresentable characters were found and had to | ||
| 361 | - // be substituted with the unknown character. | 323 | + // These versions return true if the conversion was successful and false if any unrepresentable |
| 324 | + // characters were found and had to be substituted with the unknown character. | ||
| 362 | QPDF_DLL | 325 | QPDF_DLL |
| 363 | bool utf8_to_ascii(std::string const& utf8, std::string& ascii, char unknown_char = '?'); | 326 | bool utf8_to_ascii(std::string const& utf8, std::string& ascii, char unknown_char = '?'); |
| 364 | QPDF_DLL | 327 | QPDF_DLL |
| @@ -373,9 +336,8 @@ namespace QUtil | @@ -373,9 +336,8 @@ namespace QUtil | ||
| 373 | QPDF_DLL | 336 | QPDF_DLL |
| 374 | std::string utf16_to_utf8(std::string const& utf16); | 337 | std::string utf16_to_utf8(std::string const& utf16); |
| 375 | 338 | ||
| 376 | - // Convert from the specified single-byte encoding system to | ||
| 377 | - // UTF-8. There is no ascii_to_utf8 because all ASCII strings are | ||
| 378 | - // already valid UTF-8. | 339 | + // Convert from the specified single-byte encoding system to UTF-8. There is no ascii_to_utf8 |
| 340 | + // because all ASCII strings are already valid UTF-8. | ||
| 379 | QPDF_DLL | 341 | QPDF_DLL |
| 380 | std::string win_ansi_to_utf8(std::string const& win); | 342 | std::string win_ansi_to_utf8(std::string const& win); |
| 381 | QPDF_DLL | 343 | QPDF_DLL |
| @@ -383,39 +345,33 @@ namespace QUtil | @@ -383,39 +345,33 @@ namespace QUtil | ||
| 383 | QPDF_DLL | 345 | QPDF_DLL |
| 384 | std::string pdf_doc_to_utf8(std::string const& pdfdoc); | 346 | std::string pdf_doc_to_utf8(std::string const& pdfdoc); |
| 385 | 347 | ||
| 386 | - // Analyze a string for encoding. We can't tell the difference | ||
| 387 | - // between any single-byte encodings, and we can't tell for sure | ||
| 388 | - // whether a string that happens to be valid UTF-8 isn't a | ||
| 389 | - // different encoding, but we can at least tell a few things to | ||
| 390 | - // help us guess. If there are no characters with the high bit | ||
| 391 | - // set, has_8bit_chars is false, and the other values are also | ||
| 392 | - // false, even though ASCII strings are valid UTF-8. is_valid_utf8 | ||
| 393 | - // means that the string is non-trivially valid UTF-8. Although | ||
| 394 | - // the PDF spec requires UTF-16 to be UTF-16BE, qpdf (and just | ||
| 395 | - // about everything else) accepts UTF-16LE (as of 10.6.2). | 348 | + // Analyze a string for encoding. We can't tell the difference between any single-byte |
| 349 | + // encodings, and we can't tell for sure whether a string that happens to be valid UTF-8 isn't a | ||
| 350 | + // different encoding, but we can at least tell a few things to help us guess. If there are no | ||
| 351 | + // characters with the high bit set, has_8bit_chars is false, and the other values are also | ||
| 352 | + // false, even though ASCII strings are valid UTF-8. is_valid_utf8 means that the string is | ||
| 353 | + // non-trivially valid UTF-8. Although the PDF spec requires UTF-16 to be UTF-16BE, qpdf (and | ||
| 354 | + // just about everything else) accepts UTF-16LE (as of 10.6.2). | ||
| 396 | QPDF_DLL | 355 | QPDF_DLL |
| 397 | void analyze_encoding( | 356 | void analyze_encoding( |
| 398 | std::string const& str, bool& has_8bit_chars, bool& is_valid_utf8, bool& is_utf16); | 357 | std::string const& str, bool& has_8bit_chars, bool& is_valid_utf8, bool& is_utf16); |
| 399 | 358 | ||
| 400 | - // Try to compensate for previously incorrectly encoded strings. | ||
| 401 | - // We want to compensate for the following errors: | 359 | + // Try to compensate for previously incorrectly encoded strings. We want to compensate for the |
| 360 | + // following errors: | ||
| 402 | // | 361 | // |
| 403 | - // * The string was supposed to be UTF-8 but was one of the | ||
| 404 | - // single-byte encodings | ||
| 405 | - // * The string was supposed to be PDF Doc but was either UTF-8 or | ||
| 406 | - // one of the other single-byte encodings | 362 | + // * The string was supposed to be UTF-8 but was one of the single-byte encodings |
| 363 | + // * The string was supposed to be PDF Doc but was either UTF-8 or one of the other single-byte | ||
| 364 | + // encodings | ||
| 407 | // | 365 | // |
| 408 | - // The returned vector always contains the original string first, | ||
| 409 | - // and then it contains what the correct string would be in the | ||
| 410 | - // event that the original string was the result of any of the | 366 | + // The returned vector always contains the original string first, and then it contains what the |
| 367 | + // correct string would be in the event that the original string was the result of any of the | ||
| 411 | // above errors. | 368 | // above errors. |
| 412 | // | 369 | // |
| 413 | - // This method is useful for attempting to recover a password that | ||
| 414 | - // may have been previously incorrectly encoded. For example, the | ||
| 415 | - // password was supposed to be UTF-8 but the previous application | ||
| 416 | - // used a password encoded in WinAnsi, or if the previous password | ||
| 417 | - // was supposed to be PDFDoc but was actually given as UTF-8 or | ||
| 418 | - // WinAnsi, this method would find the correct password. | 370 | + // This method is useful for attempting to recover a password that may have been previously |
| 371 | + // incorrectly encoded. For example, the password was supposed to be UTF-8 but the previous | ||
| 372 | + // application used a password encoded in WinAnsi, or if the previous password was supposed to | ||
| 373 | + // be PDFDoc but was actually given as UTF-8 or WinAnsi, this method would find the correct | ||
| 374 | + // password. | ||
| 419 | QPDF_DLL | 375 | QPDF_DLL |
| 420 | std::vector<std::string> possible_repaired_encodings(std::string); | 376 | std::vector<std::string> possible_repaired_encodings(std::string); |
| 421 | 377 | ||
| @@ -427,30 +383,25 @@ namespace QUtil | @@ -427,30 +383,25 @@ namespace QUtil | ||
| 427 | QPDF_DLL | 383 | QPDF_DLL |
| 428 | void initializeWithRandomBytes(unsigned char* data, size_t len); | 384 | void initializeWithRandomBytes(unsigned char* data, size_t len); |
| 429 | 385 | ||
| 430 | - // Supply a random data provider. Starting in qpdf 10.0.0, qpdf | ||
| 431 | - // uses the crypto provider as its source of random numbers. If | ||
| 432 | - // you are using the native crypto provider, then qpdf will either | ||
| 433 | - // use the operating system's secure random number source or, only | ||
| 434 | - // if enabled at build time, an insecure random source from | ||
| 435 | - // stdlib. The caller is responsible for managing the memory for | ||
| 436 | - // the RandomDataProvider. This method modifies a static variable. | ||
| 437 | - // If you are providing your own random data provider, you should | ||
| 438 | - // call this at the beginning of your program before creating any | ||
| 439 | - // QPDF objects. Passing a null to this method will reset the | ||
| 440 | - // library back to its default random data provider. | 386 | + // Supply a random data provider. Starting in qpdf 10.0.0, qpdf uses the crypto provider as its |
| 387 | + // source of random numbers. If you are using the native crypto provider, then qpdf will either | ||
| 388 | + // use the operating system's secure random number source or, only if enabled at build time, an | ||
| 389 | + // insecure random source from stdlib. The caller is responsible for managing the memory for the | ||
| 390 | + // RandomDataProvider. This method modifies a static variable. If you are providing your own | ||
| 391 | + // random data provider, you should call this at the beginning of your program before creating | ||
| 392 | + // any QPDF objects. Passing a null to this method will reset the library back to its default | ||
| 393 | + // random data provider. | ||
| 441 | QPDF_DLL | 394 | QPDF_DLL |
| 442 | void setRandomDataProvider(RandomDataProvider*); | 395 | void setRandomDataProvider(RandomDataProvider*); |
| 443 | 396 | ||
| 444 | - // This returns the random data provider that would be used the | ||
| 445 | - // next time qpdf needs random data. It will never return null. | ||
| 446 | - // If no random data provider has been provided and the library | ||
| 447 | - // was not compiled with any random data provider available, an | ||
| 448 | - // exception will be thrown. | 397 | + // This returns the random data provider that would be used the next time qpdf needs random |
| 398 | + // data. It will never return null. If no random data provider has been provided and the | ||
| 399 | + // library was not compiled with any random data provider available, an exception will be | ||
| 400 | + // thrown. | ||
| 449 | QPDF_DLL | 401 | QPDF_DLL |
| 450 | RandomDataProvider* getRandomDataProvider(); | 402 | RandomDataProvider* getRandomDataProvider(); |
| 451 | 403 | ||
| 452 | - // Filename is UTF-8 encoded, even on Windows, as described in the | ||
| 453 | - // comments for safe_fopen. | 404 | + // Filename is UTF-8 encoded, even on Windows, as described in the comments for safe_fopen. |
| 454 | QPDF_DLL | 405 | QPDF_DLL |
| 455 | std::list<std::string> read_lines_from_file(char const* filename, bool preserve_eol = false); | 406 | std::list<std::string> read_lines_from_file(char const* filename, bool preserve_eol = false); |
| 456 | QPDF_DLL | 407 | QPDF_DLL |
| @@ -471,15 +422,13 @@ namespace QUtil | @@ -471,15 +422,13 @@ namespace QUtil | ||
| 471 | QPDF_DLL | 422 | QPDF_DLL |
| 472 | std::string read_file_into_string(FILE* f, std::string_view filename = ""); | 423 | std::string read_file_into_string(FILE* f, std::string_view filename = ""); |
| 473 | 424 | ||
| 474 | - // This used to be called strcasecmp, but that is a macro on some | ||
| 475 | - // platforms, so we have to give it a name that is not likely to | ||
| 476 | - // be a macro anywhere. | 425 | + // This used to be called strcasecmp, but that is a macro on some platforms, so we have to give |
| 426 | + // it a name that is not likely to be a macro anywhere. | ||
| 477 | QPDF_DLL | 427 | QPDF_DLL |
| 478 | int str_compare_nocase(char const*, char const*); | 428 | int str_compare_nocase(char const*, char const*); |
| 479 | 429 | ||
| 480 | - // These routines help the tokenizer recognize certain character | ||
| 481 | - // classes without using ctype, which we avoid because of locale | ||
| 482 | - // considerations. | 430 | + // These routines help the tokenizer recognize certain character classes without using ctype, |
| 431 | + // which we avoid because of locale considerations. | ||
| 483 | QPDF_DLL | 432 | QPDF_DLL |
| 484 | inline bool is_hex_digit(char); | 433 | inline bool is_hex_digit(char); |
| 485 | 434 | ||
| @@ -492,21 +441,19 @@ namespace QUtil | @@ -492,21 +441,19 @@ namespace QUtil | ||
| 492 | QPDF_DLL | 441 | QPDF_DLL |
| 493 | inline bool is_number(char const*); | 442 | inline bool is_number(char const*); |
| 494 | 443 | ||
| 495 | - // This method parses the numeric range syntax used by the qpdf | ||
| 496 | - // command-line tool. May throw std::runtime_error. | 444 | + // This method parses the numeric range syntax used by the qpdf command-line tool. May throw |
| 445 | + // std::runtime_error. | ||
| 497 | QPDF_DLL | 446 | QPDF_DLL |
| 498 | std::vector<int> parse_numrange(char const* range, int max); | 447 | std::vector<int> parse_numrange(char const* range, int max); |
| 499 | 448 | ||
| 500 | #ifndef QPDF_NO_WCHAR_T | 449 | #ifndef QPDF_NO_WCHAR_T |
| 501 | - // If you are building qpdf on a stripped down system that doesn't | ||
| 502 | - // have wchar_t, such as may be the case in some embedded | ||
| 503 | - // environments, you may define QPDF_NO_WCHAR_T in your build. | ||
| 504 | - // This symbol is never defined automatically. Search for wchar_t | ||
| 505 | - // in qpdf's top-level README.md file for details. | 450 | + // If you are building qpdf on a stripped down system that doesn't have wchar_t, such as may be |
| 451 | + // the case in some embedded environments, you may define QPDF_NO_WCHAR_T in your build. This | ||
| 452 | + // symbol is never defined automatically. Search for wchar_t in qpdf's top-level README.md file | ||
| 453 | + // for details. | ||
| 506 | 454 | ||
| 507 | - // Take an argv array consisting of wchar_t, as when wmain is | ||
| 508 | - // invoked, convert all UTF-16 encoded strings to UTF-8, and call | ||
| 509 | - // another main. | 455 | + // Take an argv array consisting of wchar_t, as when wmain is invoked, convert all UTF-16 |
| 456 | + // encoded strings to UTF-8, and call another main. | ||
| 510 | QPDF_DLL | 457 | QPDF_DLL |
| 511 | int call_main_from_wmain(int argc, wchar_t* argv[], std::function<int(int, char*[])> realmain); | 458 | int call_main_from_wmain(int argc, wchar_t* argv[], std::function<int(int, char*[])> realmain); |
| 512 | QPDF_DLL | 459 | QPDF_DLL |
| @@ -516,13 +463,10 @@ namespace QUtil | @@ -516,13 +463,10 @@ namespace QUtil | ||
| 516 | std::function<int(int, char const* const[])> realmain); | 463 | std::function<int(int, char const* const[])> realmain); |
| 517 | #endif // QPDF_NO_WCHAR_T | 464 | #endif // QPDF_NO_WCHAR_T |
| 518 | 465 | ||
| 519 | - // Try to return the maximum amount of memory allocated by the | ||
| 520 | - // current process and its threads. Return 0 if unable to | ||
| 521 | - // determine. This is Linux-specific and not implemented to be | ||
| 522 | - // completely reliable. It is used during development for | ||
| 523 | - // performance testing to detect changes that may significantly | ||
| 524 | - // change memory usage. It is not recommended for use for other | ||
| 525 | - // purposes. | 466 | + // Try to return the maximum amount of memory allocated by the current process and its threads. |
| 467 | + // Return 0 if unable to determine. This is Linux-specific and not implemented to be completely | ||
| 468 | + // reliable. It is used during development for performance testing to detect changes that may | ||
| 469 | + // significantly change memory usage. It is not recommended for use for other purposes. | ||
| 526 | QPDF_DLL | 470 | QPDF_DLL |
| 527 | size_t get_max_memory_usage(); | 471 | size_t get_max_memory_usage(); |
| 528 | }; // namespace QUtil | 472 | }; // namespace QUtil |
include/qpdf/qpdf-c.h
| @@ -2,138 +2,113 @@ | @@ -2,138 +2,113 @@ | ||
| 2 | * | 2 | * |
| 3 | * This file is part of qpdf. | 3 | * This file is part of qpdf. |
| 4 | * | 4 | * |
| 5 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | - * you may not use this file except in compliance with the License. | ||
| 7 | - * You may obtain a copy of the License at | 5 | + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | + * in compliance with the License. You may obtain a copy of the License at | ||
| 8 | * | 7 | * |
| 9 | * http://www.apache.org/licenses/LICENSE-2.0 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | * | 9 | * |
| 11 | - * Unless required by applicable law or agreed to in writing, software | ||
| 12 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | - * See the License for the specific language governing permissions and | ||
| 15 | - * limitations under the License. | 10 | + * Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | + * or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | + * the License. | ||
| 16 | * | 14 | * |
| 17 | - * Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | - * of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | - * continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | - * see the manual for additional information. | 15 | + * Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | + * License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | + * Please see the manual for additional information. | ||
| 21 | */ | 18 | */ |
| 22 | 19 | ||
| 23 | #ifndef QPDF_C_H | 20 | #ifndef QPDF_C_H |
| 24 | #define QPDF_C_H | 21 | #define QPDF_C_H |
| 25 | 22 | ||
| 26 | /* | 23 | /* |
| 27 | - * This file defines a basic "C" API for qpdf. It provides access to | ||
| 28 | - * a subset of the QPDF library's capabilities to make them accessible | ||
| 29 | - * to callers who can't handle calling C++ functions or working with | ||
| 30 | - * C++ classes. This may be especially useful to Windows users who | ||
| 31 | - * are accessing the qpdf DLL directly or to other people programming | ||
| 32 | - * in non-C/C++ languages that can call C code but not C++ code. | 24 | + * This file defines a basic "C" API for qpdf. It provides access to a subset of the QPDF library's |
| 25 | + * capabilities to make them accessible to callers who can't handle calling C++ functions or working | ||
| 26 | + * with C++ classes. This may be especially useful to Windows users who are accessing the qpdf DLL | ||
| 27 | + * directly or to other people programming in non-C/C++ languages that can call C code but not C++ | ||
| 28 | + * code. | ||
| 33 | * | 29 | * |
| 34 | * There are several things to keep in mind when using the C API. | 30 | * There are several things to keep in mind when using the C API. |
| 35 | * | 31 | * |
| 36 | - * Error handling is tricky because the underlying C++ API uses | ||
| 37 | - * exception handling. See "ERROR HANDLING" below for a detailed | ||
| 38 | - * explanation. | 32 | + * Error handling is tricky because the underlying C++ API uses exception handling. See "ERROR |
| 33 | + * HANDLING" below for a detailed explanation. | ||
| 39 | * | 34 | * |
| 40 | - * The C API is not as rich as the C++ API. For any operations | ||
| 41 | - * that involve actually manipulating PDF objects, you must use | ||
| 42 | - * the C++ API. The C API is primarily useful for doing basic | ||
| 43 | - * transformations on PDF files similar to what you might do with | ||
| 44 | - * the qpdf command-line tool. | 35 | + * The C API is not as rich as the C++ API. For any operations that involve actually |
| 36 | + * manipulating PDF objects, you must use the C++ API. The C API is primarily useful for doing | ||
| 37 | + * basic transformations on PDF files similar to what you might do with the qpdf command-line | ||
| 38 | + * tool. | ||
| 45 | * | 39 | * |
| 46 | - * These functions store their state in a qpdf_data object. | ||
| 47 | - * Individual instances of qpdf_data are not thread-safe: although | ||
| 48 | - * you may access different qpdf_data objects from different | ||
| 49 | - * threads, you may not access one qpdf_data simultaneously from | ||
| 50 | - * multiple threads. | 40 | + * These functions store their state in a qpdf_data object. Individual instances of qpdf_data |
| 41 | + * are not thread-safe: although you may access different qpdf_data objects from different | ||
| 42 | + * threads, you may not access one qpdf_data simultaneously from multiple threads. | ||
| 51 | * | 43 | * |
| 52 | - * All dynamic memory, except for that of the qpdf_data object | ||
| 53 | - * itself, is managed by the library unless otherwise noted. You | ||
| 54 | - * must create a qpdf_data object using qpdf_init and free it | ||
| 55 | - * using qpdf_cleanup. | 44 | + * All dynamic memory, except for that of the qpdf_data object itself, is managed by the library |
| 45 | + * unless otherwise noted. You must create a qpdf_data object using qpdf_init and free it using | ||
| 46 | + * qpdf_cleanup. | ||
| 56 | * | 47 | * |
| 57 | - * Many functions return char*. In all cases, the char* values | ||
| 58 | - * returned are pointers to data inside the qpdf_data object. As | ||
| 59 | - * such, they are always freed by qpdf_cleanup. In most cases, | ||
| 60 | - * strings returned by functions here may be invalidated by | ||
| 61 | - * subsequent function calls, sometimes even to different | ||
| 62 | - * functions. If you want a string to last past the next qpdf call | ||
| 63 | - * or after a call to qpdf_cleanup, you should make a copy of it. | 48 | + * Many functions return char*. In all cases, the char* values returned are pointers to data |
| 49 | + * inside the qpdf_data object. As such, they are always freed by qpdf_cleanup. In most cases, | ||
| 50 | + * strings returned by functions here may be invalidated by subsequent function calls, sometimes | ||
| 51 | + * even to different functions. If you want a string to last past the next qpdf call or after a | ||
| 52 | + * call to qpdf_cleanup, you should make a copy of it. | ||
| 64 | * | 53 | * |
| 65 | - * Since it is possible for a PDF string to contain null | ||
| 66 | - * characters, a function that returns data originating from a PDF | ||
| 67 | - * string may also contain null characters. To handle that case, | ||
| 68 | - * you call qpdf_get_last_string_length() to get the length of | ||
| 69 | - * whatever string was just returned. See STRING FUNCTIONS below. | 54 | + * Since it is possible for a PDF string to contain null characters, a function that returns |
| 55 | + * data originating from a PDF string may also contain null characters. To handle that case, you | ||
| 56 | + * call qpdf_get_last_string_length() to get the length of whatever string was just returned. | ||
| 57 | + * See STRING FUNCTIONS below. | ||
| 70 | * | 58 | * |
| 71 | - * Most functions defined here have obvious counterparts that are | ||
| 72 | - * methods to either QPDF or QPDFWriter. Please see comments in | ||
| 73 | - * QPDF.hh and QPDFWriter.hh for details on their use. In order | ||
| 74 | - * to avoid duplication of information, comments here focus | ||
| 75 | - * primarily on differences between the C and C++ API. | 59 | + * Most functions defined here have obvious counterparts that are methods to either QPDF or |
| 60 | + * QPDFWriter. Please see comments in QPDF.hh and QPDFWriter.hh for details on their use. In | ||
| 61 | + * order to avoid duplication of information, comments here focus primarily on differences | ||
| 62 | + * between the C and C++ API. | ||
| 76 | */ | 63 | */ |
| 77 | 64 | ||
| 78 | /* ERROR HANDLING -- changed in qpdf 10.5 */ | 65 | /* ERROR HANDLING -- changed in qpdf 10.5 */ |
| 79 | 66 | ||
| 80 | -/* SUMMARY: The only way to know whether a function that does not | ||
| 81 | - * return an error code has encountered an error is to call | ||
| 82 | - * qpdf_has_error after each function. You can do this even for | ||
| 83 | - * functions that do return error codes. You can also call | ||
| 84 | - * qpdf_silence_errors to prevent qpdf from writing these errors to | ||
| 85 | - * stderr. | 67 | +/* SUMMARY: The only way to know whether a function that does not return an error code has |
| 68 | + * encountered an error is to call qpdf_has_error after each function. You can do this even for | ||
| 69 | + * functions that do return error codes. You can also call qpdf_silence_errors to prevent qpdf from | ||
| 70 | + * writing these errors to stderr. | ||
| 86 | * | 71 | * |
| 87 | * DETAILS: | 72 | * DETAILS: |
| 88 | * | 73 | * |
| 89 | - * The data type underlying qpdf_data maintains a list of warnings and | ||
| 90 | - * a single error. To retrieve warnings, call qpdf_next_warning while | ||
| 91 | - * qpdf_more_warnings is true. To retrieve the error, call | 74 | + * The data type underlying qpdf_data maintains a list of warnings and a single error. To retrieve |
| 75 | + * warnings, call qpdf_next_warning while qpdf_more_warnings is true. To retrieve the error, call | ||
| 92 | * qpdf_get_error when qpdf_has_error is true. | 76 | * qpdf_get_error when qpdf_has_error is true. |
| 93 | * | 77 | * |
| 94 | * There are several things that are important to understand. | 78 | * There are several things that are important to understand. |
| 95 | * | 79 | * |
| 96 | - * Some functions return an error code. The value of the error code is | ||
| 97 | - * made up of a bitwise-OR of QPDF_WARNINGS and QPDF_ERRORS. The | ||
| 98 | - * QPDF_ERRORS bit is set if there was an error during the *most | ||
| 99 | - * recent call* to the API. The QPDF_WARNINGS bit is set if there are | ||
| 100 | - * any warnings that have not yet been retrieved by calling | ||
| 101 | - * qpdf_more_warnings. It is possible for both its or neither bit to | ||
| 102 | - * be set. | 80 | + * Some functions return an error code. The value of the error code is made up of a bitwise-OR of |
| 81 | + * QPDF_WARNINGS and QPDF_ERRORS. The QPDF_ERRORS bit is set if there was an error during the *most | ||
| 82 | + * recent call* to the API. The QPDF_WARNINGS bit is set if there are any warnings that have not yet | ||
| 83 | + * been retrieved by calling qpdf_more_warnings. It is possible for both its or neither bit to be | ||
| 84 | + * set. | ||
| 103 | * | 85 | * |
| 104 | - * The expected mode of operation is to go through a series of | ||
| 105 | - * operations, checking for errors after each call, but only checking | ||
| 106 | - * for warnings at the end. This is similar to how it works in the C++ | ||
| 107 | - * API where warnings are handled in exactly this way but errors | ||
| 108 | - * result in exceptions being thrown. However, in both the C and C++ | ||
| 109 | - * API, it is possible to check for and handle warnings as they arise. | 86 | + * The expected mode of operation is to go through a series of operations, checking for errors after |
| 87 | + * each call, but only checking for warnings at the end. This is similar to how it works in the C++ | ||
| 88 | + * API where warnings are handled in exactly this way but errors result in exceptions being thrown. | ||
| 89 | + * However, in both the C and C++ API, it is possible to check for and handle warnings as they | ||
| 90 | + * arise. | ||
| 110 | * | 91 | * |
| 111 | - * Some functions return values (or void) rather than an error code. | ||
| 112 | - * This is especially true with the object handling functions. Those | ||
| 113 | - * functions can still generate errors. To handle errors in those | ||
| 114 | - * cases, you should explicitly call qpdf_has_error(). Note that, if | ||
| 115 | - * you want to avoid the inconsistencies in the interface, you can | ||
| 116 | - * always check for error conditions in this way rather than looking | ||
| 117 | - * at status return codes. | 92 | + * Some functions return values (or void) rather than an error code. This is especially true with |
| 93 | + * the object handling functions. Those functions can still generate errors. To handle errors in | ||
| 94 | + * those cases, you should explicitly call qpdf_has_error(). Note that, if you want to avoid the | ||
| 95 | + * inconsistencies in the interface, you can always check for error conditions in this way rather | ||
| 96 | + * than looking at status return codes. | ||
| 118 | * | 97 | * |
| 119 | - * Prior to qpdf 10.5, if one of the functions that does not return an | ||
| 120 | - * error code encountered an exception, it would cause the entire | ||
| 121 | - * program to crash. Starting in qpdf 10.5, the default response to an | ||
| 122 | - * error condition in these situations is to print the error to | ||
| 123 | - * standard error, issue exactly one warning indicating that such an | ||
| 124 | - * error occurred, and return a sensible fallback value (0 for | ||
| 125 | - * numbers, QPDF_FALSE for booleans, "" for strings, or a null or | ||
| 126 | - * uninitialized object handle). This is better than the old behavior | ||
| 127 | - * but still undesirable as the best option is to explicitly check for | ||
| 128 | - * error conditions. | 98 | + * Prior to qpdf 10.5, if one of the functions that does not return an error code encountered an |
| 99 | + * exception, it would cause the entire program to crash. Starting in qpdf 10.5, the default | ||
| 100 | + * response to an error condition in these situations is to print the error to standard error, issue | ||
| 101 | + * exactly one warning indicating that such an error occurred, and return a sensible fallback value | ||
| 102 | + * (0 for numbers, QPDF_FALSE for booleans, "" for strings, or a null or uninitialized object | ||
| 103 | + * handle). This is better than the old behavior but still undesirable as the best option is to | ||
| 104 | + * explicitly check for error conditions. | ||
| 129 | * | 105 | * |
| 130 | - * To prevent qpdf from writing error messages to stderr in this way, | ||
| 131 | - * you can call qpdf_silence_errors(). This signals to the qpdf | ||
| 132 | - * library that you intend to check the error codes yourself. | 106 | + * To prevent qpdf from writing error messages to stderr in this way, you can call |
| 107 | + * qpdf_silence_errors(). This signals to the qpdf library that you intend to check the error codes | ||
| 108 | + * yourself. | ||
| 133 | * | 109 | * |
| 134 | - * If you encounter a situation where an exception from the C++ code | ||
| 135 | - * is not properly converted to an error as described above, it is a | ||
| 136 | - * bug in qpdf, which should be reported at | 110 | + * If you encounter a situation where an exception from the C++ code is not properly converted to an |
| 111 | + * error as described above, it is a bug in qpdf, which should be reported at | ||
| 137 | * https://github.com/qpdf/qpdf/issues/new. | 112 | * https://github.com/qpdf/qpdf/issues/new. |
| 138 | */ | 113 | */ |
| 139 | 114 | ||
| @@ -150,9 +125,8 @@ extern "C" { | @@ -150,9 +125,8 @@ extern "C" { | ||
| 150 | typedef struct _qpdf_data* qpdf_data; | 125 | typedef struct _qpdf_data* qpdf_data; |
| 151 | typedef struct _qpdf_error* qpdf_error; | 126 | typedef struct _qpdf_error* qpdf_error; |
| 152 | 127 | ||
| 153 | - /* Many functions return an integer error code. Codes are defined | ||
| 154 | - * below. See comments at the top of the file for details. Note | ||
| 155 | - * that the values below can be logically orred together. | 128 | + /* Many functions return an integer error code. Codes are defined below. See comments at the |
| 129 | + * top of the file for details. Note that the values below can be logically orred together. | ||
| 156 | */ | 130 | */ |
| 157 | typedef int QPDF_ERROR_CODE; | 131 | typedef int QPDF_ERROR_CODE; |
| 158 | #define QPDF_SUCCESS 0 | 132 | #define QPDF_SUCCESS 0 |
| @@ -163,76 +137,68 @@ extern "C" { | @@ -163,76 +137,68 @@ extern "C" { | ||
| 163 | #define QPDF_TRUE 1 | 137 | #define QPDF_TRUE 1 |
| 164 | #define QPDF_FALSE 0 | 138 | #define QPDF_FALSE 0 |
| 165 | 139 | ||
| 166 | - /* From qpdf 10.5: call this method to signal to the library that | ||
| 167 | - * you are explicitly handling errors from functions that don't | ||
| 168 | - * return error codes. Otherwise, the library will print these | ||
| 169 | - * error conditions to stderr and issue a warning. Prior to 10.5, | ||
| 170 | - * the program would have crashed from an unhandled exception. | 140 | + /* From qpdf 10.5: call this method to signal to the library that you are explicitly handling |
| 141 | + * errors from functions that don't return error codes. Otherwise, the library will print these | ||
| 142 | + * error conditions to stderr and issue a warning. Prior to 10.5, the program would have | ||
| 143 | + * crashed from an unhandled exception. | ||
| 171 | */ | 144 | */ |
| 172 | QPDF_DLL | 145 | QPDF_DLL |
| 173 | void qpdf_silence_errors(qpdf_data qpdf); | 146 | void qpdf_silence_errors(qpdf_data qpdf); |
| 174 | 147 | ||
| 175 | - /* Returns the version of the qpdf software. This is guaranteed to | ||
| 176 | - * be a static value. | 148 | + /* Returns the version of the qpdf software. This is guaranteed to be a static value. |
| 177 | */ | 149 | */ |
| 178 | QPDF_DLL | 150 | QPDF_DLL |
| 179 | char const* qpdf_get_qpdf_version(); | 151 | char const* qpdf_get_qpdf_version(); |
| 180 | 152 | ||
| 181 | - /* Returns dynamically allocated qpdf_data pointer; must be freed | ||
| 182 | - * by calling qpdf_cleanup. You must call qpdf_read, one of the | ||
| 183 | - * other qpdf_read_* functions, or qpdf_empty_pdf before calling | 153 | + /* Returns dynamically allocated qpdf_data pointer; must be freed by calling qpdf_cleanup. You |
| 154 | + * must call qpdf_read, one of the other qpdf_read_* functions, or qpdf_empty_pdf before calling | ||
| 184 | * any function that would need to operate on the PDF file. | 155 | * any function that would need to operate on the PDF file. |
| 185 | */ | 156 | */ |
| 186 | QPDF_DLL | 157 | QPDF_DLL |
| 187 | qpdf_data qpdf_init(); | 158 | qpdf_data qpdf_init(); |
| 188 | 159 | ||
| 189 | - /* Pass a pointer to the qpdf_data pointer created by qpdf_init to | ||
| 190 | - * clean up resources. This does not include buffers initialized | ||
| 191 | - * by functions that return stream data but it otherwise includes | ||
| 192 | - * all data associated with the QPDF object or any object handles. | 160 | + /* Pass a pointer to the qpdf_data pointer created by qpdf_init to clean up resources. This does |
| 161 | + * not include buffers initialized by functions that return stream data but it otherwise | ||
| 162 | + * includes all data associated with the QPDF object or any object handles. | ||
| 193 | */ | 163 | */ |
| 194 | QPDF_DLL | 164 | QPDF_DLL |
| 195 | void qpdf_cleanup(qpdf_data* qpdf); | 165 | void qpdf_cleanup(qpdf_data* qpdf); |
| 196 | 166 | ||
| 197 | /* ERROR REPORTING */ | 167 | /* ERROR REPORTING */ |
| 198 | 168 | ||
| 199 | - /* Returns 1 if there is an error condition. The error condition | ||
| 200 | - * can be retrieved by a single call to qpdf_get_error. | 169 | + /* Returns 1 if there is an error condition. The error condition can be retrieved by a single |
| 170 | + * call to qpdf_get_error. | ||
| 201 | */ | 171 | */ |
| 202 | QPDF_DLL | 172 | QPDF_DLL |
| 203 | QPDF_BOOL qpdf_has_error(qpdf_data qpdf); | 173 | QPDF_BOOL qpdf_has_error(qpdf_data qpdf); |
| 204 | 174 | ||
| 205 | - /* Returns the error condition, if any. The return value is a | ||
| 206 | - * pointer to data that will become invalid after the next call to | ||
| 207 | - * this function, qpdf_next_warning, or qpdf_cleanup. After this | ||
| 208 | - * function is called, qpdf_has_error will return QPDF_FALSE until | ||
| 209 | - * the next error condition occurs. If there is no error | ||
| 210 | - * condition, this function returns a null pointer. | 175 | + /* Returns the error condition, if any. The return value is a pointer to data that will become |
| 176 | + * invalid after the next call to this function, qpdf_next_warning, or qpdf_cleanup. After this | ||
| 177 | + * function is called, qpdf_has_error will return QPDF_FALSE until the next error condition | ||
| 178 | + * occurs. If there is no error condition, this function returns a null pointer. | ||
| 211 | */ | 179 | */ |
| 212 | QPDF_DLL | 180 | QPDF_DLL |
| 213 | qpdf_error qpdf_get_error(qpdf_data qpdf); | 181 | qpdf_error qpdf_get_error(qpdf_data qpdf); |
| 214 | 182 | ||
| 215 | - /* Returns 1 if there are any unretrieved warnings, and zero | ||
| 216 | - * otherwise. | 183 | + /* Returns 1 if there are any unretrieved warnings, and zero otherwise. |
| 217 | */ | 184 | */ |
| 218 | QPDF_DLL | 185 | QPDF_DLL |
| 219 | QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf); | 186 | QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf); |
| 220 | 187 | ||
| 221 | - /* If there are any warnings, returns a pointer to the next | ||
| 222 | - * warning. Otherwise returns a null pointer. | 188 | + /* If there are any warnings, returns a pointer to the next warning. Otherwise returns a null |
| 189 | + * pointer. | ||
| 223 | */ | 190 | */ |
| 224 | QPDF_DLL | 191 | QPDF_DLL |
| 225 | qpdf_error qpdf_next_warning(qpdf_data qpdf); | 192 | qpdf_error qpdf_next_warning(qpdf_data qpdf); |
| 226 | 193 | ||
| 227 | /* Extract fields of the error. */ | 194 | /* Extract fields of the error. */ |
| 228 | 195 | ||
| 229 | - /* Use this function to get a full error message suitable for | ||
| 230 | - * showing to the user. */ | 196 | + /* Use this function to get a full error message suitable for showing to the user. */ |
| 231 | QPDF_DLL | 197 | QPDF_DLL |
| 232 | char const* qpdf_get_error_full_text(qpdf_data q, qpdf_error e); | 198 | char const* qpdf_get_error_full_text(qpdf_data q, qpdf_error e); |
| 233 | 199 | ||
| 234 | - /* Use these functions to extract individual fields from the | ||
| 235 | - * error; see QPDFExc.hh for details. */ | 200 | + /* Use these functions to extract individual fields from the error; see QPDFExc.hh for details. |
| 201 | + */ | ||
| 236 | QPDF_DLL | 202 | QPDF_DLL |
| 237 | enum qpdf_error_code_e qpdf_get_error_code(qpdf_data q, qpdf_error e); | 203 | enum qpdf_error_code_e qpdf_get_error_code(qpdf_data q, qpdf_error e); |
| 238 | QPDF_DLL | 204 | QPDF_DLL |
| @@ -242,9 +208,8 @@ extern "C" { | @@ -242,9 +208,8 @@ extern "C" { | ||
| 242 | QPDF_DLL | 208 | QPDF_DLL |
| 243 | char const* qpdf_get_error_message_detail(qpdf_data q, qpdf_error e); | 209 | char const* qpdf_get_error_message_detail(qpdf_data q, qpdf_error e); |
| 244 | 210 | ||
| 245 | - /* By default, warnings are written to stderr. Passing true to | ||
| 246 | - * this function will prevent warnings from being written to | ||
| 247 | - * stderr. They will still be available by calls to | 211 | + /* By default, warnings are written to stderr. Passing true to this function will prevent |
| 212 | + * warnings from being written to stderr. They will still be available by calls to | ||
| 248 | * qpdf_next_warning. | 213 | * qpdf_next_warning. |
| 249 | */ | 214 | */ |
| 250 | QPDF_DLL | 215 | QPDF_DLL |
| @@ -252,11 +217,9 @@ extern "C" { | @@ -252,11 +217,9 @@ extern "C" { | ||
| 252 | 217 | ||
| 253 | /* LOG FUNCTIONS */ | 218 | /* LOG FUNCTIONS */ |
| 254 | 219 | ||
| 255 | - /* Set or get the current logger. You need to call | ||
| 256 | - * qpdflogger_cleanup on the logger handles when you are done with | ||
| 257 | - * the handles. The underlying logger is cleaned up automatically | ||
| 258 | - * and persists if needed after the logger handle is destroyed. | ||
| 259 | - * See comments in qpdflogger-c.h for details. | 220 | + /* Set or get the current logger. You need to call qpdflogger_cleanup on the logger handles when |
| 221 | + * you are done with the handles. The underlying logger is cleaned up automatically and persists | ||
| 222 | + * if needed after the logger handle is destroyed. See comments in qpdflogger-c.h for details. | ||
| 260 | */ | 223 | */ |
| 261 | 224 | ||
| 262 | QPDF_DLL | 225 | QPDF_DLL |
| @@ -266,8 +229,7 @@ extern "C" { | @@ -266,8 +229,7 @@ extern "C" { | ||
| 266 | 229 | ||
| 267 | /* CHECK FUNCTIONS */ | 230 | /* CHECK FUNCTIONS */ |
| 268 | 231 | ||
| 269 | - /* Attempt to read the entire PDF file to see if there are any | ||
| 270 | - * errors qpdf can detect. | 232 | + /* Attempt to read the entire PDF file to see if there are any errors qpdf can detect. |
| 271 | */ | 233 | */ |
| 272 | QPDF_DLL | 234 | QPDF_DLL |
| 273 | QPDF_ERROR_CODE qpdf_check_pdf(qpdf_data qpdf); | 235 | QPDF_ERROR_CODE qpdf_check_pdf(qpdf_data qpdf); |
| @@ -284,20 +246,17 @@ extern "C" { | @@ -284,20 +246,17 @@ extern "C" { | ||
| 284 | 246 | ||
| 285 | /* This functions process a PDF or JSON input source. */ | 247 | /* This functions process a PDF or JSON input source. */ |
| 286 | 248 | ||
| 287 | - /* Calling qpdf_read causes processFile to be called in the C++ | ||
| 288 | - * API. Basic parsing is performed, but data from the file is | ||
| 289 | - * only read as needed. For files without passwords, pass a null | ||
| 290 | - * pointer or an empty string as the password. | 249 | + /* Calling qpdf_read causes processFile to be called in the C++ API. Basic parsing is |
| 250 | + * performed, but data from the file is only read as needed. For files without passwords, pass | ||
| 251 | + * a null pointer or an empty string as the password. | ||
| 291 | */ | 252 | */ |
| 292 | QPDF_DLL | 253 | QPDF_DLL |
| 293 | QPDF_ERROR_CODE | 254 | QPDF_ERROR_CODE |
| 294 | qpdf_read(qpdf_data qpdf, char const* filename, char const* password); | 255 | qpdf_read(qpdf_data qpdf, char const* filename, char const* password); |
| 295 | 256 | ||
| 296 | - /* Calling qpdf_read_memory causes processMemoryFile to be called | ||
| 297 | - * in the C++ API. Otherwise, it behaves in the same way as | ||
| 298 | - * qpdf_read. The description argument will be used in place of | ||
| 299 | - * the file name in any error or warning messages generated by the | ||
| 300 | - * library. | 257 | + /* Calling qpdf_read_memory causes processMemoryFile to be called in the C++ API. Otherwise, it |
| 258 | + * behaves in the same way as qpdf_read. The description argument will be used in place of the | ||
| 259 | + * file name in any error or warning messages generated by the library. | ||
| 301 | */ | 260 | */ |
| 302 | QPDF_DLL | 261 | QPDF_DLL |
| 303 | QPDF_ERROR_CODE qpdf_read_memory( | 262 | QPDF_ERROR_CODE qpdf_read_memory( |
| @@ -307,22 +266,20 @@ extern "C" { | @@ -307,22 +266,20 @@ extern "C" { | ||
| 307 | unsigned long long size, | 266 | unsigned long long size, |
| 308 | char const* password); | 267 | char const* password); |
| 309 | 268 | ||
| 310 | - /* Calling qpdf_empty_pdf initializes this qpdf object with an | ||
| 311 | - * empty PDF, making it possible to create a PDF from scratch | ||
| 312 | - * using the C API. Added in 10.6. | 269 | + /* Calling qpdf_empty_pdf initializes this qpdf object with an empty PDF, making it possible to |
| 270 | + * create a PDF from scratch using the C API. Added in 10.6. | ||
| 313 | */ | 271 | */ |
| 314 | QPDF_DLL | 272 | QPDF_DLL |
| 315 | QPDF_ERROR_CODE qpdf_empty_pdf(qpdf_data qpdf); | 273 | QPDF_ERROR_CODE qpdf_empty_pdf(qpdf_data qpdf); |
| 316 | 274 | ||
| 317 | - /* Create a PDF from a JSON file. This calls createFromJSON in the | ||
| 318 | - * C++ API. | 275 | + /* Create a PDF from a JSON file. This calls createFromJSON in the C++ API. |
| 319 | */ | 276 | */ |
| 320 | QPDF_DLL | 277 | QPDF_DLL |
| 321 | QPDF_ERROR_CODE | 278 | QPDF_ERROR_CODE |
| 322 | qpdf_create_from_json_file(qpdf_data qpdf, char const* filename); | 279 | qpdf_create_from_json_file(qpdf_data qpdf, char const* filename); |
| 323 | 280 | ||
| 324 | - /* Create a PDF from JSON data in a null-terminated string. This | ||
| 325 | - * calls createFromJSON in the C++ API. | 281 | + /* Create a PDF from JSON data in a null-terminated string. This calls createFromJSON in the C++ |
| 282 | + * API. | ||
| 326 | */ | 283 | */ |
| 327 | QPDF_DLL | 284 | QPDF_DLL |
| 328 | QPDF_ERROR_CODE | 285 | QPDF_ERROR_CODE |
| @@ -330,10 +287,9 @@ extern "C" { | @@ -330,10 +287,9 @@ extern "C" { | ||
| 330 | 287 | ||
| 331 | /* JSON UPDATE FUNCTIONS */ | 288 | /* JSON UPDATE FUNCTIONS */ |
| 332 | 289 | ||
| 333 | - /* Update a QPDF object from a JSON file or buffer. These | ||
| 334 | - * functions call updateFromJSON. One of the other processing | ||
| 335 | - * functions has to be called first so that the QPDF object is | ||
| 336 | - * initialized with PDF data. | 290 | + /* Update a QPDF object from a JSON file or buffer. These functions call updateFromJSON. One of |
| 291 | + * the other processing functions has to be called first so that the QPDF object is initialized | ||
| 292 | + * with PDF data. | ||
| 337 | */ | 293 | */ |
| 338 | QPDF_DLL | 294 | QPDF_DLL |
| 339 | QPDF_ERROR_CODE | 295 | QPDF_ERROR_CODE |
| @@ -344,18 +300,16 @@ extern "C" { | @@ -344,18 +300,16 @@ extern "C" { | ||
| 344 | 300 | ||
| 345 | /* READ FUNCTIONS */ | 301 | /* READ FUNCTIONS */ |
| 346 | 302 | ||
| 347 | - /* Read functions below must be called after qpdf_read or any of | ||
| 348 | - * the other functions that process a PDF. */ | 303 | + /* Read functions below must be called after qpdf_read or any of the other functions that |
| 304 | + * process a PDF. */ | ||
| 349 | 305 | ||
| 350 | /* | 306 | /* |
| 351 | - * NOTE: Functions that return char* are returning a pointer to an | ||
| 352 | - * internal buffer that will be reused for each call to a function | ||
| 353 | - * that returns a char*. You must use or copy the value before | ||
| 354 | - * calling any other qpdf library functions. | 307 | + * NOTE: Functions that return char* are returning a pointer to an internal buffer that will be |
| 308 | + * reused for each call to a function that returns a char*. You must use or copy the value | ||
| 309 | + * before calling any other qpdf library functions. | ||
| 355 | */ | 310 | */ |
| 356 | 311 | ||
| 357 | - /* Return the version of the PDF file. See warning above about | ||
| 358 | - * functions that return char*. */ | 312 | + /* Return the version of the PDF file. See warning above about functions that return char*. */ |
| 359 | QPDF_DLL | 313 | QPDF_DLL |
| 360 | char const* qpdf_get_pdf_version(qpdf_data qpdf); | 314 | char const* qpdf_get_pdf_version(qpdf_data qpdf); |
| 361 | 315 | ||
| @@ -363,30 +317,26 @@ extern "C" { | @@ -363,30 +317,26 @@ extern "C" { | ||
| 363 | QPDF_DLL | 317 | QPDF_DLL |
| 364 | int qpdf_get_pdf_extension_level(qpdf_data qpdf); | 318 | int qpdf_get_pdf_extension_level(qpdf_data qpdf); |
| 365 | 319 | ||
| 366 | - /* Return the user password. If the file is opened using the | ||
| 367 | - * owner password, the user password may be retrieved using this | ||
| 368 | - * function. If the file is opened using the user password, this | ||
| 369 | - * function will return that user password. See warning above | ||
| 370 | - * about functions that return char*. | 320 | + /* Return the user password. If the file is opened using the owner password, the user password |
| 321 | + * may be retrieved using this function. If the file is opened using the user password, this | ||
| 322 | + * function will return that user password. See warning above about functions that return | ||
| 323 | + * char*. | ||
| 371 | */ | 324 | */ |
| 372 | QPDF_DLL | 325 | QPDF_DLL |
| 373 | char const* qpdf_get_user_password(qpdf_data qpdf); | 326 | char const* qpdf_get_user_password(qpdf_data qpdf); |
| 374 | 327 | ||
| 375 | - /* Return the string value of a key in the document's Info | ||
| 376 | - * dictionary. The key parameter should include the leading | ||
| 377 | - * slash, e.g. "/Author". If the key is not present or has a | ||
| 378 | - * non-string value, a null pointer is returned. Otherwise, a | ||
| 379 | - * pointer to an internal buffer is returned. See warning above | ||
| 380 | - * about functions that return char*. | 328 | + /* Return the string value of a key in the document's Info dictionary. The key parameter should |
| 329 | + * include the leading slash, e.g. "/Author". If the key is not present or has a non-string | ||
| 330 | + * value, a null pointer is returned. Otherwise, a pointer to an internal buffer is returned. | ||
| 331 | + * See warning above about functions that return char*. | ||
| 381 | */ | 332 | */ |
| 382 | QPDF_DLL | 333 | QPDF_DLL |
| 383 | char const* qpdf_get_info_key(qpdf_data qpdf, char const* key); | 334 | char const* qpdf_get_info_key(qpdf_data qpdf, char const* key); |
| 384 | 335 | ||
| 385 | - /* Set a value in the info dictionary, possibly replacing an | ||
| 386 | - * existing value. The key must include the leading slash | ||
| 387 | - * (e.g. "/Author"). Passing a null pointer as a value will | ||
| 388 | - * remove the key from the info dictionary. Otherwise, a copy | ||
| 389 | - * will be made of the string that is passed in. | 336 | + /* Set a value in the info dictionary, possibly replacing an existing value. The key must |
| 337 | + * include the leading slash (e.g. "/Author"). Passing a null pointer as a value will remove | ||
| 338 | + * the key from the info dictionary. Otherwise, a copy will be made of the string that is | ||
| 339 | + * passed in. | ||
| 390 | */ | 340 | */ |
| 391 | QPDF_DLL | 341 | QPDF_DLL |
| 392 | void qpdf_set_info_key(qpdf_data qpdf, char const* key, char const* value); | 342 | void qpdf_set_info_key(qpdf_data qpdf, char const* key, char const* value); |
| @@ -420,21 +370,16 @@ extern "C" { | @@ -420,21 +370,16 @@ extern "C" { | ||
| 420 | 370 | ||
| 421 | /* JSON WRITE FUNCTIONS */ | 371 | /* JSON WRITE FUNCTIONS */ |
| 422 | 372 | ||
| 423 | - /* This function serializes the PDF to JSON. This calls writeJSON | ||
| 424 | - * from the C++ API. | 373 | + /* This function serializes the PDF to JSON. This calls writeJSON from the C++ API. |
| 425 | * | 374 | * |
| 426 | * - version: the JSON version, currently must be 2 | 375 | * - version: the JSON version, currently must be 2 |
| 427 | - * - fn: a function that will be called with blocks of JSON data; | ||
| 428 | - * will be called with data, a length, and the value of the | ||
| 429 | - * udata parameter to this function | ||
| 430 | - * - udata: will be passed as the third argument to fn with each | ||
| 431 | - * call; use this for your own tracking or pass a null pointer | ||
| 432 | - * if you don't need it | ||
| 433 | - * - For decode_level, json_stream_data, file_prefix, and | ||
| 434 | - * wanted_objects, see comments in QPDF.hh. For this API, | ||
| 435 | - * wanted_objects should be a null-terminated array of | ||
| 436 | - * null-terminated strings. Pass a null pointer if you want all | ||
| 437 | - * objects. | 376 | + * - fn: a function that will be called with blocks of JSON data; will be called with data, a |
| 377 | + * length, and the value of the udata parameter to this function | ||
| 378 | + * - udata: will be passed as the third argument to fn with each call; use this for your own | ||
| 379 | + * tracking or pass a null pointer if you don't need it | ||
| 380 | + * - For decode_level, json_stream_data, file_prefix, and wanted_objects, see comments in | ||
| 381 | + * QPDF.hh. For this API, wanted_objects should be a null-terminated array of null-terminated | ||
| 382 | + * strings. Pass a null pointer if you want all objects. | ||
| 438 | */ | 383 | */ |
| 439 | 384 | ||
| 440 | /* Function should return 0 on success. */ | 385 | /* Function should return 0 on success. */ |
| @@ -453,37 +398,29 @@ extern "C" { | @@ -453,37 +398,29 @@ extern "C" { | ||
| 453 | 398 | ||
| 454 | /* WRITE FUNCTIONS */ | 399 | /* WRITE FUNCTIONS */ |
| 455 | 400 | ||
| 456 | - /* Set up for writing. No writing is actually performed until the | ||
| 457 | - * call to qpdf_write(). | 401 | + /* Set up for writing. No writing is actually performed until the call to qpdf_write(). |
| 458 | */ | 402 | */ |
| 459 | 403 | ||
| 460 | - /* Supply the name of the file to be written and initialize the | ||
| 461 | - * qpdf_data object to handle writing operations. This function | ||
| 462 | - * also attempts to create the file. The PDF data is not written | ||
| 463 | - * until the call to qpdf_write. qpdf_init_write may be called | ||
| 464 | - * multiple times for the same qpdf_data object. When | ||
| 465 | - * qpdf_init_write is called, all information from previous calls | ||
| 466 | - * to functions that set write parameters (qpdf_set_linearization, | ||
| 467 | - * etc.) is lost, so any write parameter functions must be called | ||
| 468 | - * again. | 404 | + /* Supply the name of the file to be written and initialize the qpdf_data object to handle |
| 405 | + * writing operations. This function also attempts to create the file. The PDF data is not | ||
| 406 | + * written until the call to qpdf_write. qpdf_init_write may be called multiple times for the | ||
| 407 | + * same qpdf_data object. When qpdf_init_write is called, all information from previous calls | ||
| 408 | + * to functions that set write parameters (qpdf_set_linearization, etc.) is lost, so any write | ||
| 409 | + * parameter functions must be called again. | ||
| 469 | */ | 410 | */ |
| 470 | QPDF_DLL | 411 | QPDF_DLL |
| 471 | QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename); | 412 | QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename); |
| 472 | 413 | ||
| 473 | - /* Initialize for writing but indicate that the PDF file should be | ||
| 474 | - * written to memory. Call qpdf_get_buffer_length and | ||
| 475 | - * qpdf_get_buffer to retrieve the resulting buffer. The memory | ||
| 476 | - * containing the PDF file will be destroyed when qpdf_cleanup is | ||
| 477 | - * called. | 414 | + /* Initialize for writing but indicate that the PDF file should be written to memory. Call |
| 415 | + * qpdf_get_buffer_length and qpdf_get_buffer to retrieve the resulting buffer. The memory | ||
| 416 | + * containing the PDF file will be destroyed when qpdf_cleanup is called. | ||
| 478 | */ | 417 | */ |
| 479 | QPDF_DLL | 418 | QPDF_DLL |
| 480 | QPDF_ERROR_CODE qpdf_init_write_memory(qpdf_data qpdf); | 419 | QPDF_ERROR_CODE qpdf_init_write_memory(qpdf_data qpdf); |
| 481 | 420 | ||
| 482 | - /* Retrieve the buffer used if the file was written to memory. | ||
| 483 | - * qpdf_get_buffer returns a null pointer if data was not written | ||
| 484 | - * to memory. The memory is freed when qpdf_cleanup is called or | ||
| 485 | - * if a subsequent call to qpdf_init_write or | ||
| 486 | - * qpdf_init_write_memory is called. */ | 421 | + /* Retrieve the buffer used if the file was written to memory. qpdf_get_buffer returns a null |
| 422 | + * pointer if data was not written to memory. The memory is freed when qpdf_cleanup is called | ||
| 423 | + * or if a subsequent call to qpdf_init_write or qpdf_init_write_memory is called. */ | ||
| 487 | QPDF_DLL | 424 | QPDF_DLL |
| 488 | size_t qpdf_get_buffer_length(qpdf_data qpdf); | 425 | size_t qpdf_get_buffer_length(qpdf_data qpdf); |
| 489 | QPDF_DLL | 426 | QPDF_DLL |
| @@ -516,14 +453,14 @@ extern "C" { | @@ -516,14 +453,14 @@ extern "C" { | ||
| 516 | QPDF_DLL | 453 | QPDF_DLL |
| 517 | void qpdf_set_deterministic_ID(qpdf_data qpdf, QPDF_BOOL value); | 454 | void qpdf_set_deterministic_ID(qpdf_data qpdf, QPDF_BOOL value); |
| 518 | 455 | ||
| 519 | - /* Never use qpdf_set_static_ID except in test suites to suppress | ||
| 520 | - * generation of a random /ID. See also qpdf_set_deterministic_ID. | 456 | + /* Never use qpdf_set_static_ID except in test suites to suppress generation of a random /ID. |
| 457 | + * See also qpdf_set_deterministic_ID. | ||
| 521 | */ | 458 | */ |
| 522 | QPDF_DLL | 459 | QPDF_DLL |
| 523 | void qpdf_set_static_ID(qpdf_data qpdf, QPDF_BOOL value); | 460 | void qpdf_set_static_ID(qpdf_data qpdf, QPDF_BOOL value); |
| 524 | 461 | ||
| 525 | - /* Never use qpdf_set_static_aes_IV except in test suites to | ||
| 526 | - * create predictable AES encrypted output. | 462 | + /* Never use qpdf_set_static_aes_IV except in test suites to create predictable AES encrypted |
| 463 | + * output. | ||
| 527 | */ | 464 | */ |
| 528 | QPDF_DLL | 465 | QPDF_DLL |
| 529 | void qpdf_set_static_aes_IV(qpdf_data qpdf, QPDF_BOOL value); | 466 | void qpdf_set_static_aes_IV(qpdf_data qpdf, QPDF_BOOL value); |
| @@ -534,9 +471,8 @@ extern "C" { | @@ -534,9 +471,8 @@ extern "C" { | ||
| 534 | QPDF_DLL | 471 | QPDF_DLL |
| 535 | void qpdf_set_preserve_encryption(qpdf_data qpdf, QPDF_BOOL value); | 472 | void qpdf_set_preserve_encryption(qpdf_data qpdf, QPDF_BOOL value); |
| 536 | 473 | ||
| 537 | - /* The *_insecure functions are identical to the old versions but | ||
| 538 | - * have been renamed as a an alert to the caller that they are | ||
| 539 | - * insecure. See "Weak Cryptographic" in the manual for | 474 | + /* The *_insecure functions are identical to the old versions but have been renamed as a an |
| 475 | + * alert to the caller that they are insecure. See "Weak Cryptographic" in the manual for | ||
| 540 | * details. | 476 | * details. |
| 541 | */ | 477 | */ |
| 542 | QPDF_DLL | 478 | QPDF_DLL |
| @@ -622,15 +558,12 @@ extern "C" { | @@ -622,15 +558,12 @@ extern "C" { | ||
| 622 | void | 558 | void |
| 623 | qpdf_force_pdf_version_and_extension(qpdf_data qpdf, char const* version, int extension_level); | 559 | qpdf_force_pdf_version_and_extension(qpdf_data qpdf, char const* version, int extension_level); |
| 624 | 560 | ||
| 625 | - /* During write, your report_progress function will be called with | ||
| 626 | - * a value between 0 and 100 representing the approximate write | ||
| 627 | - * progress. The data object you pass to | ||
| 628 | - * qpdf_register_progress_reporter will be handed back to your | ||
| 629 | - * function. This function must be called after qpdf_init_write | ||
| 630 | - * (or qpdf_init_write_memory) and before qpdf_write. The | ||
| 631 | - * registered progress reporter applies only to a single write, so | ||
| 632 | - * you must call it again if you perform a subsequent write with a | ||
| 633 | - * new writer. | 561 | + /* During write, your report_progress function will be called with a value between 0 and 100 |
| 562 | + * representing the approximate write progress. The data object you pass to | ||
| 563 | + * qpdf_register_progress_reporter will be handed back to your function. This function must be | ||
| 564 | + * called after qpdf_init_write (or qpdf_init_write_memory) and before qpdf_write. The | ||
| 565 | + * registered progress reporter applies only to a single write, so you must call it again if you | ||
| 566 | + * perform a subsequent write with a new writer. | ||
| 634 | */ | 567 | */ |
| 635 | QPDF_DLL | 568 | QPDF_DLL |
| 636 | void qpdf_register_progress_reporter( | 569 | void qpdf_register_progress_reporter( |
| @@ -642,67 +575,51 @@ extern "C" { | @@ -642,67 +575,51 @@ extern "C" { | ||
| 642 | 575 | ||
| 643 | /* Object handling. | 576 | /* Object handling. |
| 644 | * | 577 | * |
| 645 | - * These functions take and return a qpdf_oh object handle, which | ||
| 646 | - * is just an unsigned integer. The value 0 is never returned, which | ||
| 647 | - * makes it usable as an uninitialized value. The handles returned by | ||
| 648 | - * these functions are guaranteed to be unique, i.e. two calls to | ||
| 649 | - * (the same of different) functions will return distinct handles | ||
| 650 | - * even when they refer to the same object. | 578 | + * These functions take and return a qpdf_oh object handle, which is just an unsigned integer. |
| 579 | + * The value 0 is never returned, which makes it usable as an uninitialized value. The handles | ||
| 580 | + * returned by these functions are guaranteed to be unique, i.e. two calls to (the same of | ||
| 581 | + * different) functions will return distinct handles even when they refer to the same object. | ||
| 651 | * | 582 | * |
| 652 | - * Each function below, starting with qpdf_oh, corresponds to a | ||
| 653 | - * specific method of QPDFObjectHandler. For example, | ||
| 654 | - * qpdf_oh_is_bool corresponds to QPDFObjectHandle::isBool. If the | ||
| 655 | - * C++ method is overloaded, the C function's name will be | ||
| 656 | - * disambiguated. If the C++ method takes optional arguments, the C | ||
| 657 | - * function will have required arguments in those positions. For | ||
| 658 | - * details about the method, please see comments in | ||
| 659 | - * QPDFObjectHandle.hh. Comments here only explain things that are | ||
| 660 | - * specific to the "C" API. | 583 | + * Each function below, starting with qpdf_oh, corresponds to a specific method of |
| 584 | + * QPDFObjectHandler. For example, qpdf_oh_is_bool corresponds to QPDFObjectHandle::isBool. If | ||
| 585 | + * the C++ method is overloaded, the C function's name will be disambiguated. If the C++ method | ||
| 586 | + * takes optional arguments, the C function will have required arguments in those positions. For | ||
| 587 | + * details about the method, please see comments in QPDFObjectHandle.hh. Comments here only | ||
| 588 | + * explain things that are specific to the "C" API. | ||
| 661 | * | 589 | * |
| 662 | - * Only a fraction of the methods of QPDFObjectHandle are | ||
| 663 | - * available here. Most of the basic methods for creating, | ||
| 664 | - * accessing, and modifying most types of objects are present. | ||
| 665 | - * Most of the higher-level functions are not implemented. | ||
| 666 | - * Functions for dealing with content streams as well as objects | ||
| 667 | - * that only exist in content streams (operators and inline | ||
| 668 | - * images) are mostly not provided. | 590 | + * Only a fraction of the methods of QPDFObjectHandle are available here. Most of the basic |
| 591 | + * methods for creating, accessing, and modifying most types of objects are present. Most of the | ||
| 592 | + * higher-level functions are not implemented. Functions for dealing with content streams as | ||
| 593 | + * well as objects that only exist in content streams (operators and inline images) are mostly | ||
| 594 | + * not provided. | ||
| 669 | * | 595 | * |
| 670 | - * To refer to a specific QPDFObjectHandle, you need a pair | ||
| 671 | - * consisting of a qpdf_data and a qpdf_oh, which is just an index | ||
| 672 | - * into an internal table of objects. All memory allocated by any | ||
| 673 | - * of these functions is returned when qpdf_cleanup is called. | 596 | + * To refer to a specific QPDFObjectHandle, you need a pair consisting of a qpdf_data and a |
| 597 | + * qpdf_oh, which is just an index into an internal table of objects. All memory allocated by | ||
| 598 | + * any of these functions is returned when qpdf_cleanup is called. | ||
| 674 | * | 599 | * |
| 675 | - * Regarding memory, the same rules apply as the above functions. | ||
| 676 | - * Specifically, if a function returns a char*, the memory is | ||
| 677 | - * managed by the library and, unless otherwise specified, is not | 600 | + * Regarding memory, the same rules apply as the above functions. Specifically, if a function |
| 601 | + * returns a char*, the memory is managed by the library and, unless otherwise specified, is not | ||
| 678 | * expected to be valid after the next qpdf call. | 602 | * expected to be valid after the next qpdf call. |
| 679 | * | 603 | * |
| 680 | - * The qpdf_data object keeps a cache of handles returned by these | ||
| 681 | - * functions. Once you are finished referencing a handle, you can | ||
| 682 | - * optionally release it. Releasing handles is optional since they | ||
| 683 | - * will all get released by qpdf_cleanup, but it can help to | ||
| 684 | - * reduce the memory footprint of the qpdf_data object to release | ||
| 685 | - * them when you're done. Releasing a handle does not destroy the | ||
| 686 | - * object. All QPDFObjectHandle objects are deleted when they are | ||
| 687 | - * no longer referenced. Releasing an object handle simply | ||
| 688 | - * invalidates it. For example, if you create an object, | ||
| 689 | - * add it to an existing dictionary or array, and then release its | ||
| 690 | - * handle, the object is safely part of the dictionary or array. | ||
| 691 | - * Similarly, any other object handle refering to the object remains | ||
| 692 | - * valid. Explicitly releasing an object handle is essentially the | ||
| 693 | - * same as letting a QPDFObjectHandle go out of scope in the C++ | ||
| 694 | - * API. | 604 | + * The qpdf_data object keeps a cache of handles returned by these functions. Once you are |
| 605 | + * finished referencing a handle, you can optionally release it. Releasing handles is optional | ||
| 606 | + * since they will all get released by qpdf_cleanup, but it can help to reduce the memory | ||
| 607 | + * footprint of the qpdf_data object to release them when you're done. Releasing a handle does | ||
| 608 | + * not destroy the object. All QPDFObjectHandle objects are deleted when they are no longer | ||
| 609 | + * referenced. Releasing an object handle simply invalidates it. For example, if you create an | ||
| 610 | + * object, add it to an existing dictionary or array, and then release its handle, the object is | ||
| 611 | + * safely part of the dictionary or array. Similarly, any other object handle refering to the | ||
| 612 | + * object remains valid. Explicitly releasing an object handle is essentially the same as | ||
| 613 | + * letting a QPDFObjectHandle go out of scope in the C++ API. | ||
| 695 | * | 614 | * |
| 696 | - * Please see "ERROR HANDLING" above for details on how error | ||
| 697 | - * conditions are handled. | 615 | + * Please see "ERROR HANDLING" above for details on how error conditions are handled. |
| 698 | */ | 616 | */ |
| 699 | 617 | ||
| 700 | /* For examples of using this API, see examples/pdf-c-objects.c */ | 618 | /* For examples of using this API, see examples/pdf-c-objects.c */ |
| 701 | 619 | ||
| 702 | typedef unsigned int qpdf_oh; | 620 | typedef unsigned int qpdf_oh; |
| 703 | 621 | ||
| 704 | - /* Releasing objects -- see comments above. These functions have no | ||
| 705 | - * equivalent in the C++ API. | 622 | + /* Releasing objects -- see comments above. These functions have no equivalent in the C++ API. |
| 706 | */ | 623 | */ |
| 707 | QPDF_DLL | 624 | QPDF_DLL |
| 708 | void qpdf_oh_release(qpdf_data qpdf, qpdf_oh oh); | 625 | void qpdf_oh_release(qpdf_data qpdf, qpdf_oh oh); |
| @@ -727,13 +644,11 @@ extern "C" { | @@ -727,13 +644,11 @@ extern "C" { | ||
| 727 | QPDF_DLL | 644 | QPDF_DLL |
| 728 | void qpdf_replace_object(qpdf_data qpdf, int objid, int generation, qpdf_oh oh); | 645 | void qpdf_replace_object(qpdf_data qpdf, int objid, int generation, qpdf_oh oh); |
| 729 | 646 | ||
| 730 | - /* Wrappers around QPDFObjectHandle methods. Be sure to read | ||
| 731 | - * corresponding comments in QPDFObjectHandle.hh to understand | ||
| 732 | - * what each function does and what kinds of objects it applies | ||
| 733 | - * to. Note that names are to appear in a canonicalized form | ||
| 734 | - * starting with a leading slash and with all PDF escaping | ||
| 735 | - * resolved. See comments for getName() in QPDFObjectHandle.hh for | ||
| 736 | - * details. | 647 | + /* Wrappers around QPDFObjectHandle methods. Be sure to read corresponding comments in |
| 648 | + * QPDFObjectHandle.hh to understand what each function does and what kinds of objects it | ||
| 649 | + * applies to. Note that names are to appear in a canonicalized form starting with a leading | ||
| 650 | + * slash and with all PDF escaping resolved. See comments for getName() in QPDFObjectHandle.hh | ||
| 651 | + * for details. | ||
| 737 | */ | 652 | */ |
| 738 | 653 | ||
| 739 | QPDF_DLL | 654 | QPDF_DLL |
| @@ -829,18 +744,14 @@ extern "C" { | @@ -829,18 +744,14 @@ extern "C" { | ||
| 829 | QPDF_BOOL | 744 | QPDF_BOOL |
| 830 | qpdf_oh_get_value_as_name(qpdf_data qpdf, qpdf_oh oh, char const** value, size_t* length); | 745 | qpdf_oh_get_value_as_name(qpdf_data qpdf, qpdf_oh oh, char const** value, size_t* length); |
| 831 | 746 | ||
| 832 | - /* Return the length of the last string returned. This enables you | ||
| 833 | - * to retrieve the entire string for cases in which a char* | ||
| 834 | - * returned by one of the functions below points to a string with | ||
| 835 | - * embedded null characters. The function | ||
| 836 | - * qpdf_oh_get_binary_string_value takes a length pointer, which | ||
| 837 | - * can be useful if you are retrieving the value of a string that | ||
| 838 | - * is expected to contain binary data, such as a checksum or | ||
| 839 | - * document ID. It is always valid to call | ||
| 840 | - * qpdf_get_last_string_length, but it is usually not necessary as | ||
| 841 | - * C strings returned by the library are only expected to be able | ||
| 842 | - * to contain null characters if their values originate from PDF | ||
| 843 | - * strings in the input. | 747 | + /* Return the length of the last string returned. This enables you to retrieve the entire string |
| 748 | + * for cases in which a char* returned by one of the functions below points to a string with | ||
| 749 | + * embedded null characters. The function qpdf_oh_get_binary_string_value takes a length | ||
| 750 | + * pointer, which can be useful if you are retrieving the value of a string that is expected to | ||
| 751 | + * contain binary data, such as a checksum or document ID. It is always valid to call | ||
| 752 | + * qpdf_get_last_string_length, but it is usually not necessary as C strings returned by the | ||
| 753 | + * library are only expected to be able to contain null characters if their values originate | ||
| 754 | + * from PDF strings in the input. | ||
| 844 | */ | 755 | */ |
| 845 | QPDF_DLL | 756 | QPDF_DLL |
| 846 | size_t qpdf_get_last_string_length(qpdf_data qpdf); | 757 | size_t qpdf_get_last_string_length(qpdf_data qpdf); |
| @@ -865,10 +776,9 @@ extern "C" { | @@ -865,10 +776,9 @@ extern "C" { | ||
| 865 | QPDF_DLL | 776 | QPDF_DLL |
| 866 | qpdf_oh qpdf_oh_get_array_item(qpdf_data qpdf, qpdf_oh oh, int n); | 777 | qpdf_oh qpdf_oh_get_array_item(qpdf_data qpdf, qpdf_oh oh, int n); |
| 867 | 778 | ||
| 868 | - /* In all dictionary APIs, keys are specified/represented as | ||
| 869 | - * canonicalized name strings starting with / and with all PDF | ||
| 870 | - * escaping resolved. See comments for getName() in | ||
| 871 | - * QPDFObjectHandle for details. | 779 | + /* In all dictionary APIs, keys are specified/represented as canonicalized name strings starting |
| 780 | + * with / and with all PDF escaping resolved. See comments for getName() in QPDFObjectHandle for | ||
| 781 | + * details. | ||
| 872 | */ | 782 | */ |
| 873 | 783 | ||
| 874 | /* "C"-specific dictionary key iteration */ | 784 | /* "C"-specific dictionary key iteration */ |
| @@ -878,11 +788,9 @@ extern "C" { | @@ -878,11 +788,9 @@ extern "C" { | ||
| 878 | void qpdf_oh_begin_dict_key_iter(qpdf_data qpdf, qpdf_oh dict); | 788 | void qpdf_oh_begin_dict_key_iter(qpdf_data qpdf, qpdf_oh dict); |
| 879 | QPDF_DLL | 789 | QPDF_DLL |
| 880 | QPDF_BOOL qpdf_oh_dict_more_keys(qpdf_data qpdf); | 790 | QPDF_BOOL qpdf_oh_dict_more_keys(qpdf_data qpdf); |
| 881 | - /* The memory returned by qpdf_oh_dict_next_key is owned by | ||
| 882 | - * qpdf_data. It is good until the next call to | ||
| 883 | - * qpdf_oh_dict_next_key with the same qpdf_data object. Calling | ||
| 884 | - * the function again, even with a different dict, invalidates | ||
| 885 | - * previous return values. | 791 | + /* The memory returned by qpdf_oh_dict_next_key is owned by qpdf_data. It is good until the next |
| 792 | + * call to qpdf_oh_dict_next_key with the same qpdf_data object. Calling the function again, | ||
| 793 | + * even with a different dict, invalidates previous return values. | ||
| 886 | */ | 794 | */ |
| 887 | QPDF_DLL | 795 | QPDF_DLL |
| 888 | char const* qpdf_oh_dict_next_key(qpdf_data qpdf); | 796 | char const* qpdf_oh_dict_next_key(qpdf_data qpdf); |
| @@ -918,8 +826,8 @@ extern "C" { | @@ -918,8 +826,8 @@ extern "C" { | ||
| 918 | qpdf_oh qpdf_oh_new_string(qpdf_data qpdf, char const* str); | 826 | qpdf_oh qpdf_oh_new_string(qpdf_data qpdf, char const* str); |
| 919 | QPDF_DLL | 827 | QPDF_DLL |
| 920 | qpdf_oh qpdf_oh_new_unicode_string(qpdf_data qpdf, char const* utf8_str); | 828 | qpdf_oh qpdf_oh_new_unicode_string(qpdf_data qpdf, char const* utf8_str); |
| 921 | - /* Use qpdf_oh_new_binary_string for creating a string that may | ||
| 922 | - * contain atrbitary binary data including embedded null characters. | 829 | + /* Use qpdf_oh_new_binary_string for creating a string that may contain atrbitary binary data |
| 830 | + * including embedded null characters. | ||
| 923 | */ | 831 | */ |
| 924 | QPDF_DLL | 832 | QPDF_DLL |
| 925 | qpdf_oh qpdf_oh_new_binary_string(qpdf_data qpdf, char const* str, size_t length); | 833 | qpdf_oh qpdf_oh_new_binary_string(qpdf_data qpdf, char const* str, size_t length); |
| @@ -930,11 +838,10 @@ extern "C" { | @@ -930,11 +838,10 @@ extern "C" { | ||
| 930 | QPDF_DLL | 838 | QPDF_DLL |
| 931 | qpdf_oh qpdf_oh_new_dictionary(qpdf_data qpdf); | 839 | qpdf_oh qpdf_oh_new_dictionary(qpdf_data qpdf); |
| 932 | 840 | ||
| 933 | - /* Create a new stream. Use qpdf_oh_get_dict to get (and | ||
| 934 | - * subsequently modify) the stream dictionary if needed. See | ||
| 935 | - * comments in QPDFObjectHandle.hh for newStream() for additional | ||
| 936 | - * notes. You must call qpdf_oh_replace_stream_data to provide | ||
| 937 | - * data for the stream. See STREAM FUNCTIONS below. | 841 | + /* Create a new stream. Use qpdf_oh_get_dict to get (and subsequently modify) the stream |
| 842 | + * dictionary if needed. See comments in QPDFObjectHandle.hh for newStream() for additional | ||
| 843 | + * notes. You must call qpdf_oh_replace_stream_data to provide data for the stream. See STREAM | ||
| 844 | + * FUNCTIONS below. | ||
| 938 | */ | 845 | */ |
| 939 | QPDF_DLL | 846 | QPDF_DLL |
| 940 | qpdf_oh qpdf_oh_new_stream(qpdf_data qpdf); | 847 | qpdf_oh qpdf_oh_new_stream(qpdf_data qpdf); |
| @@ -973,40 +880,33 @@ extern "C" { | @@ -973,40 +880,33 @@ extern "C" { | ||
| 973 | QPDF_DLL | 880 | QPDF_DLL |
| 974 | char const* qpdf_oh_unparse_binary(qpdf_data qpdf, qpdf_oh oh); | 881 | char const* qpdf_oh_unparse_binary(qpdf_data qpdf, qpdf_oh oh); |
| 975 | 882 | ||
| 976 | - /* Note about foreign objects: the C API does not have enough | ||
| 977 | - * information in the value of a qpdf_oh to know what QPDF object | ||
| 978 | - * it belongs to. To uniquely specify a qpdf object handle from a | ||
| 979 | - * specific qpdf_data instance, you always pair the qpdf_oh with | ||
| 980 | - * the correct qpdf_data. Otherwise, you are likely to get | ||
| 981 | - * completely the wrong object if you are not lucky enough to get | ||
| 982 | - * an error about the object being invalid. | 883 | + /* Note about foreign objects: the C API does not have enough information in the value of a |
| 884 | + * qpdf_oh to know what QPDF object it belongs to. To uniquely specify a qpdf object handle from | ||
| 885 | + * a specific qpdf_data instance, you always pair the qpdf_oh with the correct qpdf_data. | ||
| 886 | + * Otherwise, you are likely to get completely the wrong object if you are not lucky enough to | ||
| 887 | + * get an error about the object being invalid. | ||
| 983 | */ | 888 | */ |
| 984 | 889 | ||
| 985 | - /* Copy foreign object: the qpdf_oh returned belongs to `qpdf`, | ||
| 986 | - * while `foreign_oh` belongs to `other_qpdf`. | 890 | + /* Copy foreign object: the qpdf_oh returned belongs to `qpdf`, while `foreign_oh` belongs to |
| 891 | + * `other_qpdf`. | ||
| 987 | */ | 892 | */ |
| 988 | QPDF_DLL | 893 | QPDF_DLL |
| 989 | qpdf_oh qpdf_oh_copy_foreign_object(qpdf_data qpdf, qpdf_data other_qpdf, qpdf_oh foreign_oh); | 894 | qpdf_oh qpdf_oh_copy_foreign_object(qpdf_data qpdf, qpdf_data other_qpdf, qpdf_oh foreign_oh); |
| 990 | 895 | ||
| 991 | /* STREAM FUNCTIONS */ | 896 | /* STREAM FUNCTIONS */ |
| 992 | 897 | ||
| 993 | - /* These functions provide basic access to streams and stream | ||
| 994 | - * data. They are not as comprehensive as what is in | ||
| 995 | - * QPDFObjectHandle, but they do allow for working with streams | ||
| 996 | - * and stream data as caller-managed memory. | 898 | + /* These functions provide basic access to streams and stream data. They are not as |
| 899 | + * comprehensive as what is in QPDFObjectHandle, but they do allow for working with streams and | ||
| 900 | + * stream data as caller-managed memory. | ||
| 997 | */ | 901 | */ |
| 998 | 902 | ||
| 999 | - /* Get stream data as a buffer. The buffer is allocated with | ||
| 1000 | - * malloc and must be freed by the caller. The size of the buffer | ||
| 1001 | - * is stored in *len. The arguments are similar to those in | ||
| 1002 | - * QPDFObjectHandle::pipeStreamData. To get raw stream data, pass | ||
| 1003 | - * qpdf_dl_none as decode_level. Otherwise, filtering is attempted | ||
| 1004 | - * and *filtered is set to indicate whether it was successful. If | ||
| 1005 | - * *filtered is QPDF_FALSE, then raw, unfiltered stream data was | ||
| 1006 | - * returned. You may pass a null pointer as filtered if you don't | ||
| 1007 | - * care about the result. If you pass a null pointer as bufp (and | ||
| 1008 | - * len), the value of filtered will be set to whether the stream | ||
| 1009 | - * can be filterable. | 903 | + /* Get stream data as a buffer. The buffer is allocated with malloc and must be freed by the |
| 904 | + * caller. The size of the buffer is stored in *len. The arguments are similar to those in | ||
| 905 | + * QPDFObjectHandle::pipeStreamData. To get raw stream data, pass qpdf_dl_none as decode_level. | ||
| 906 | + * Otherwise, filtering is attempted and *filtered is set to indicate whether it was successful. | ||
| 907 | + * If *filtered is QPDF_FALSE, then raw, unfiltered stream data was returned. You may pass a | ||
| 908 | + * null pointer as filtered if you don't care about the result. If you pass a null pointer as | ||
| 909 | + * bufp (and len), the value of filtered will be set to whether the stream can be filterable. | ||
| 1010 | */ | 910 | */ |
| 1011 | QPDF_DLL | 911 | QPDF_DLL |
| 1012 | QPDF_ERROR_CODE qpdf_oh_get_stream_data( | 912 | QPDF_ERROR_CODE qpdf_oh_get_stream_data( |
| @@ -1017,17 +917,16 @@ extern "C" { | @@ -1017,17 +917,16 @@ extern "C" { | ||
| 1017 | unsigned char** bufp, | 917 | unsigned char** bufp, |
| 1018 | size_t* len); | 918 | size_t* len); |
| 1019 | 919 | ||
| 1020 | - /* This function returns the concatenation of all of a page's | ||
| 1021 | - * content streams as a single, dynamically allocated buffer. As | ||
| 1022 | - * with qpdf_oh_get_stream_data, the buffer is allocated with | 920 | + /* This function returns the concatenation of all of a page's content streams as a single, |
| 921 | + * dynamically allocated buffer. As with qpdf_oh_get_stream_data, the buffer is allocated with | ||
| 1023 | * malloc and must be freed by the caller. | 922 | * malloc and must be freed by the caller. |
| 1024 | */ | 923 | */ |
| 1025 | QPDF_DLL | 924 | QPDF_DLL |
| 1026 | QPDF_ERROR_CODE qpdf_oh_get_page_content_data( | 925 | QPDF_ERROR_CODE qpdf_oh_get_page_content_data( |
| 1027 | qpdf_data qpdf, qpdf_oh page_oh, unsigned char** bufp, size_t* len); | 926 | qpdf_data qpdf, qpdf_oh page_oh, unsigned char** bufp, size_t* len); |
| 1028 | 927 | ||
| 1029 | - /* The data pointed to by bufp will be copied by the library. It | ||
| 1030 | - * does not need to remain valid after the call returns. | 928 | + /* The data pointed to by bufp will be copied by the library. It does not need to remain valid |
| 929 | + * after the call returns. | ||
| 1031 | */ | 930 | */ |
| 1032 | QPDF_DLL | 931 | QPDF_DLL |
| 1033 | void qpdf_oh_replace_stream_data( | 932 | void qpdf_oh_replace_stream_data( |
| @@ -1040,21 +939,18 @@ extern "C" { | @@ -1040,21 +939,18 @@ extern "C" { | ||
| 1040 | 939 | ||
| 1041 | /* PAGE FUNCTIONS */ | 940 | /* PAGE FUNCTIONS */ |
| 1042 | 941 | ||
| 1043 | - /* The first time a page function is called, qpdf will traverse | ||
| 1044 | - * the /Pages tree. Subsequent calls to retrieve the number of | ||
| 1045 | - * pages or a specific page run in constant time as they are | ||
| 1046 | - * accessing the pages cache. If you manipulate the page tree | ||
| 1047 | - * outside of these functions, you should call | ||
| 1048 | - * qpdf_update_all_pages_cache. See comments for getAllPages() and | 942 | + /* The first time a page function is called, qpdf will traverse the /Pages tree. Subsequent |
| 943 | + * calls to retrieve the number of pages or a specific page run in constant time as they are | ||
| 944 | + * accessing the pages cache. If you manipulate the page tree outside of these functions, you | ||
| 945 | + * should call qpdf_update_all_pages_cache. See comments for getAllPages() and | ||
| 1049 | * updateAllPagesCache() in QPDF.hh. | 946 | * updateAllPagesCache() in QPDF.hh. |
| 1050 | */ | 947 | */ |
| 1051 | 948 | ||
| 1052 | - /* For each function, the corresponding method in QPDF.hh is | ||
| 1053 | - * referenced. Please see comments in QPDF.hh for details. | 949 | + /* For each function, the corresponding method in QPDF.hh is referenced. Please see comments in |
| 950 | + * QPDF.hh for details. | ||
| 1054 | */ | 951 | */ |
| 1055 | 952 | ||
| 1056 | - /* calls getAllPages(). On error, returns -1 and sets error for | ||
| 1057 | - * qpdf_get_error. */ | 953 | + /* calls getAllPages(). On error, returns -1 and sets error for qpdf_get_error. */ |
| 1058 | QPDF_DLL | 954 | QPDF_DLL |
| 1059 | int qpdf_get_num_pages(qpdf_data qpdf); | 955 | int qpdf_get_num_pages(qpdf_data qpdf); |
| 1060 | /* returns uninitialized object if out of range */ | 956 | /* returns uninitialized object if out of range */ |
| @@ -1065,9 +961,8 @@ extern "C" { | @@ -1065,9 +961,8 @@ extern "C" { | ||
| 1065 | QPDF_DLL | 961 | QPDF_DLL |
| 1066 | QPDF_ERROR_CODE qpdf_update_all_pages_cache(qpdf_data qpdf); | 962 | QPDF_ERROR_CODE qpdf_update_all_pages_cache(qpdf_data qpdf); |
| 1067 | 963 | ||
| 1068 | - /* findPage() -- return zero-based index. If page is not found, | ||
| 1069 | - * return -1 and save the error to be retrieved with | ||
| 1070 | - * qpdf_get_error. | 964 | + /* findPage() -- return zero-based index. If page is not found, return -1 and save the error to |
| 965 | + * be retrieved with qpdf_get_error. | ||
| 1071 | */ | 966 | */ |
| 1072 | QPDF_DLL | 967 | QPDF_DLL |
| 1073 | int qpdf_find_page_by_id(qpdf_data qpdf, int objid, int generation); | 968 | int qpdf_find_page_by_id(qpdf_data qpdf, int objid, int generation); |
| @@ -1078,10 +973,9 @@ extern "C" { | @@ -1078,10 +973,9 @@ extern "C" { | ||
| 1078 | QPDF_DLL | 973 | QPDF_DLL |
| 1079 | QPDF_ERROR_CODE qpdf_push_inherited_attributes_to_page(qpdf_data qpdf); | 974 | QPDF_ERROR_CODE qpdf_push_inherited_attributes_to_page(qpdf_data qpdf); |
| 1080 | 975 | ||
| 1081 | - /* Functions that add pages may add pages from other files. If | ||
| 1082 | - * adding a page from the same file, newpage_qpdf and qpdf are the | ||
| 1083 | - * same. | ||
| 1084 | - /*/ | 976 | + /* Functions that add pages may add pages from other files. If adding a page from the same file, |
| 977 | + newpage_qpdf and qpdf are the same. | ||
| 978 | + */ | ||
| 1085 | 979 | ||
| 1086 | /* addPage() */ | 980 | /* addPage() */ |
| 1087 | QPDF_DLL | 981 | QPDF_DLL |
include/qpdf/qpdfjob-c.h
| @@ -2,33 +2,29 @@ | @@ -2,33 +2,29 @@ | ||
| 2 | * | 2 | * |
| 3 | * This file is part of qpdf. | 3 | * This file is part of qpdf. |
| 4 | * | 4 | * |
| 5 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | - * you may not use this file except in compliance with the License. | ||
| 7 | - * You may obtain a copy of the License at | 5 | + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | + * in compliance with the License. You may obtain a copy of the License at | ||
| 8 | * | 7 | * |
| 9 | * http://www.apache.org/licenses/LICENSE-2.0 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | * | 9 | * |
| 11 | - * Unless required by applicable law or agreed to in writing, software | ||
| 12 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | - * See the License for the specific language governing permissions and | ||
| 15 | - * limitations under the License. | 10 | + * Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | + * or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | + * the License. | ||
| 16 | * | 14 | * |
| 17 | - * Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | - * of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | - * continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | - * see the manual for additional information. | 15 | + * Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | + * License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | + * Please see the manual for additional information. | ||
| 21 | */ | 18 | */ |
| 22 | 19 | ||
| 23 | #ifndef QPDFJOB_C_H | 20 | #ifndef QPDFJOB_C_H |
| 24 | #define QPDFJOB_C_H | 21 | #define QPDFJOB_C_H |
| 25 | 22 | ||
| 26 | /* | 23 | /* |
| 27 | - * This file defines a basic "C" API for QPDFJob. See also qpdf-c.h, | ||
| 28 | - * which defines an API that exposes more of the library's API. This | ||
| 29 | - * API is primarily intended to make it simpler for programs in | ||
| 30 | - * languages other than C++ to incorporate functionality that could be | ||
| 31 | - * run directly from the command-line. | 24 | + * This file defines a basic "C" API for QPDFJob. See also qpdf-c.h, which defines an API that |
| 25 | + * exposes more of the library's API. This API is primarily intended to make it simpler for programs | ||
| 26 | + * in languages other than C++ to incorporate functionality that could be run directly from the | ||
| 27 | + * command-line. | ||
| 32 | */ | 28 | */ |
| 33 | 29 | ||
| 34 | #include <qpdf/DLL.h> | 30 | #include <qpdf/DLL.h> |
| @@ -40,52 +36,46 @@ | @@ -40,52 +36,46 @@ | ||
| 40 | #endif | 36 | #endif |
| 41 | 37 | ||
| 42 | /* | 38 | /* |
| 43 | - * This file provides a minimal wrapper around QPDFJob. See | ||
| 44 | - * examples/qpdfjob-c.c for an example of its use. | 39 | + * This file provides a minimal wrapper around QPDFJob. See examples/qpdfjob-c.c for an example of |
| 40 | + * its use. | ||
| 45 | */ | 41 | */ |
| 46 | 42 | ||
| 47 | #ifdef __cplusplus | 43 | #ifdef __cplusplus |
| 48 | extern "C" { | 44 | extern "C" { |
| 49 | #endif | 45 | #endif |
| 50 | - /* SHORT INTERFACE -- These functions are single calls that take | ||
| 51 | - * care of the whole life cycle of QPDFJob. They can be used for | ||
| 52 | - * one-shot operations where no additional configuration is | 46 | + /* SHORT INTERFACE -- These functions are single calls that take care of the whole life cycle of |
| 47 | + * QPDFJob. They can be used for one-shot operations where no additional configuration is | ||
| 53 | * needed. See FULL INTERFACE below. */ | 48 | * needed. See FULL INTERFACE below. */ |
| 54 | 49 | ||
| 55 | - /* This function does the equivalent of running the qpdf | ||
| 56 | - * command-line with the given arguments and returns the exit code | ||
| 57 | - * that qpdf would use. argv must be a null-terminated array of | ||
| 58 | - * null-terminated UTF8-encoded strings. If calling this from | ||
| 59 | - * wmain on Windows, use qpdfjob_run_from_wide_argv instead. Exit | ||
| 60 | - * code values are defined in Constants.h in the qpdf_exit_code_e | ||
| 61 | - * type. | 50 | + /* This function does the equivalent of running the qpdf command-line with the given arguments |
| 51 | + * and returns the exit code that qpdf would use. argv must be a null-terminated array of | ||
| 52 | + * null-terminated UTF8-encoded strings. If calling this from wmain on Windows, use | ||
| 53 | + * qpdfjob_run_from_wide_argv instead. Exit code values are defined in Constants.h in the | ||
| 54 | + * qpdf_exit_code_e type. | ||
| 62 | */ | 55 | */ |
| 63 | QPDF_DLL | 56 | QPDF_DLL |
| 64 | int qpdfjob_run_from_argv(char const* const argv[]); | 57 | int qpdfjob_run_from_argv(char const* const argv[]); |
| 65 | 58 | ||
| 66 | #ifndef QPDF_NO_WCHAR_T | 59 | #ifndef QPDF_NO_WCHAR_T |
| 67 | - /* This function is the same as qpdfjob_run_from_argv except argv | ||
| 68 | - * is encoded with wide characters. This would be suitable for | ||
| 69 | - * calling from a Windows wmain function. | 60 | + /* This function is the same as qpdfjob_run_from_argv except argv is encoded with wide |
| 61 | + * characters. This would be suitable for calling from a Windows wmain function. | ||
| 70 | */ | 62 | */ |
| 71 | QPDF_DLL | 63 | QPDF_DLL |
| 72 | int qpdfjob_run_from_wide_argv(wchar_t const* const argv[]); | 64 | int qpdfjob_run_from_wide_argv(wchar_t const* const argv[]); |
| 73 | #endif /* QPDF_NO_WCHAR_T */ | 65 | #endif /* QPDF_NO_WCHAR_T */ |
| 74 | 66 | ||
| 75 | - /* This function runs QPDFJob from a job JSON file. See the "QPDF | ||
| 76 | - * Job" section of the manual for details. The JSON string must be | ||
| 77 | - * UTF8-encoded. It returns the error code that qpdf would return | ||
| 78 | - * with the equivalent command-line invocation. Exit code values | ||
| 79 | - * are defined in Constants.h in the qpdf_exit_code_e type. | 67 | + /* This function runs QPDFJob from a job JSON file. See the "QPDF Job" section of the manual for |
| 68 | + * details. The JSON string must be UTF8-encoded. It returns the error code that qpdf would | ||
| 69 | + * return with the equivalent command-line invocation. Exit code values are defined in | ||
| 70 | + * Constants.h in the qpdf_exit_code_e type. | ||
| 80 | */ | 71 | */ |
| 81 | QPDF_DLL | 72 | QPDF_DLL |
| 82 | int qpdfjob_run_from_json(char const* json); | 73 | int qpdfjob_run_from_json(char const* json); |
| 83 | 74 | ||
| 84 | - /* FULL INTERFACE -- new in qpdf11. Similar to the qpdf-c.h API, | ||
| 85 | - * you must call qpdfjob_init to get a qpdfjob_handle and, when | ||
| 86 | - * done, call qpdfjob_cleanup to free resources. Remaining methods | ||
| 87 | - * take qpdfjob_handle as an argument. This interface requires | ||
| 88 | - * more calls but also offers greater flexibility. | 75 | + /* FULL INTERFACE -- new in qpdf11. Similar to the qpdf-c.h API, you must call qpdfjob_init to |
| 76 | + * get a qpdfjob_handle and, when done, call qpdfjob_cleanup to free resources. Remaining | ||
| 77 | + * methods take qpdfjob_handle as an argument. This interface requires more calls but also | ||
| 78 | + * offers greater flexibility. | ||
| 89 | */ | 79 | */ |
| 90 | typedef struct _qpdfjob_handle* qpdfjob_handle; | 80 | typedef struct _qpdfjob_handle* qpdfjob_handle; |
| 91 | QPDF_DLL | 81 | QPDF_DLL |
| @@ -94,11 +84,9 @@ extern "C" { | @@ -94,11 +84,9 @@ extern "C" { | ||
| 94 | QPDF_DLL | 84 | QPDF_DLL |
| 95 | void qpdfjob_cleanup(qpdfjob_handle* j); | 85 | void qpdfjob_cleanup(qpdfjob_handle* j); |
| 96 | 86 | ||
| 97 | - /* Set or get the current logger. You need to call | ||
| 98 | - * qpdflogger_cleanup on the logger handles when you are done with | ||
| 99 | - * the handles. The underlying logger is cleaned up automatically | ||
| 100 | - * and persists if needed after the logger handle is destroyed. | ||
| 101 | - * See comments in qpdflogger-c.h for details. | 87 | + /* Set or get the current logger. You need to call qpdflogger_cleanup on the logger handles when |
| 88 | + * you are done with the handles. The underlying logger is cleaned up automatically and persists | ||
| 89 | + * if needed after the logger handle is destroyed. See comments in qpdflogger-c.h for details. | ||
| 102 | */ | 90 | */ |
| 103 | 91 | ||
| 104 | QPDF_DLL | 92 | QPDF_DLL |
| @@ -106,62 +94,54 @@ extern "C" { | @@ -106,62 +94,54 @@ extern "C" { | ||
| 106 | QPDF_DLL | 94 | QPDF_DLL |
| 107 | qpdflogger_handle qpdfjob_get_logger(qpdfjob_handle j); | 95 | qpdflogger_handle qpdfjob_get_logger(qpdfjob_handle j); |
| 108 | 96 | ||
| 109 | - /* This function wraps QPDFJob::initializeFromArgv. The return | ||
| 110 | - * value is the same as qpdfjob_run. If this returns an error, it | ||
| 111 | - * is invalid to call any other functions this job handle. | 97 | + /* This function wraps QPDFJob::initializeFromArgv. The return value is the same as qpdfjob_run. |
| 98 | + * If this returns an error, it is invalid to call any other functions this job handle. | ||
| 112 | */ | 99 | */ |
| 113 | QPDF_DLL | 100 | QPDF_DLL |
| 114 | int qpdfjob_initialize_from_argv(qpdfjob_handle j, char const* const argv[]); | 101 | int qpdfjob_initialize_from_argv(qpdfjob_handle j, char const* const argv[]); |
| 115 | 102 | ||
| 116 | #ifndef QPDF_NO_WCHAR_T | 103 | #ifndef QPDF_NO_WCHAR_T |
| 117 | - /* This function is the same as qpdfjob_initialize_from_argv | ||
| 118 | - * except argv is encoded with wide characters. This would be | ||
| 119 | - * suitable for calling from a Windows wmain function. | 104 | + /* This function is the same as qpdfjob_initialize_from_argv except argv is encoded with wide |
| 105 | + * characters. This would be suitable for calling from a Windows wmain function. | ||
| 120 | */ | 106 | */ |
| 121 | QPDF_DLL | 107 | QPDF_DLL |
| 122 | int qpdfjob_initialize_from_wide_argv(qpdfjob_handle j, wchar_t const* const argv[]); | 108 | int qpdfjob_initialize_from_wide_argv(qpdfjob_handle j, wchar_t const* const argv[]); |
| 123 | #endif /* QPDF_NO_WCHAR_T */ | 109 | #endif /* QPDF_NO_WCHAR_T */ |
| 124 | 110 | ||
| 125 | - /* This function wraps QPDFJob::initializeFromJson. The return | ||
| 126 | - * value is the same as qpdfjob_run. If this returns an error, it | ||
| 127 | - * is invalid to call any other functions this job handle. | 111 | + /* This function wraps QPDFJob::initializeFromJson. The return value is the same as qpdfjob_run. |
| 112 | + * If this returns an error, it is invalid to call any other functions this job handle. | ||
| 128 | */ | 113 | */ |
| 129 | QPDF_DLL | 114 | QPDF_DLL |
| 130 | int qpdfjob_initialize_from_json(qpdfjob_handle j, char const* json); | 115 | int qpdfjob_initialize_from_json(qpdfjob_handle j, char const* json); |
| 131 | 116 | ||
| 132 | - /* This function wraps QPDFJob::run. It returns the error code | ||
| 133 | - * that qpdf would return with the equivalent command-line | ||
| 134 | - * invocation. Exit code values are defined in Constants.h in the | 117 | + /* This function wraps QPDFJob::run. It returns the error code that qpdf would return with the |
| 118 | + * equivalent command-line invocation. Exit code values are defined in Constants.h in the | ||
| 135 | * qpdf_exit_code_e type. | 119 | * qpdf_exit_code_e type. |
| 136 | */ | 120 | */ |
| 137 | QPDF_DLL | 121 | QPDF_DLL |
| 138 | int qpdfjob_run(qpdfjob_handle j); | 122 | int qpdfjob_run(qpdfjob_handle j); |
| 139 | 123 | ||
| 140 | - /* The following two functions allow a job to be run in two stages - | ||
| 141 | - * creation of a qpdf_data object and writing of the qpdf_data object. This | ||
| 142 | - * allows the qpdf_data object to be modified prior to writing it out. See | ||
| 143 | - * examples/qpdfjob-remove-annotations for a C++ illustration of its use. | 124 | + /* The following two functions allow a job to be run in two stages - creation of a qpdf_data |
| 125 | + * object and writing of the qpdf_data object. This allows the qpdf_data object to be modified | ||
| 126 | + * prior to writing it out. See examples/qpdfjob-remove-annotations for a C++ illustration of | ||
| 127 | + * its use. | ||
| 144 | * | 128 | * |
| 145 | - * This function wraps QPDFJob::createQPDF. It runs the first stage of the | ||
| 146 | - * job. A nullptr is returned if the job did not produce any pdf file to be | ||
| 147 | - * written. | 129 | + * This function wraps QPDFJob::createQPDF. It runs the first stage of the job. A nullptr is |
| 130 | + * returned if the job did not produce any pdf file to be written. | ||
| 148 | */ | 131 | */ |
| 149 | QPDF_DLL | 132 | QPDF_DLL |
| 150 | qpdf_data qpdfjob_create_qpdf(qpdfjob_handle j); | 133 | qpdf_data qpdfjob_create_qpdf(qpdfjob_handle j); |
| 151 | 134 | ||
| 152 | - /* This function wraps QPDFJob::writeQPDF. It returns the error code that | ||
| 153 | - * qpdf would return with the equivalent command-line invocation. Exit code | ||
| 154 | - * values are defined in Constants.h in the qpdf_exit_code_e type. NOTE it | ||
| 155 | - * is the callers responsibility to clean up the resources associated | ||
| 156 | - * qpdf_data object by calling qpdf_cleanup after the call to | ||
| 157 | - * qpdfjob_write_qpdf. | 135 | + /* This function wraps QPDFJob::writeQPDF. It returns the error code that qpdf would return with |
| 136 | + * the equivalent command-line invocation. Exit code values are defined in Constants.h in the | ||
| 137 | + * qpdf_exit_code_e type. NOTE it is the callers responsibility to clean up the resources | ||
| 138 | + * associated qpdf_data object by calling qpdf_cleanup after the call to qpdfjob_write_qpdf. | ||
| 158 | */ | 139 | */ |
| 159 | QPDF_DLL | 140 | QPDF_DLL |
| 160 | int qpdfjob_write_qpdf(qpdfjob_handle j, qpdf_data qpdf); | 141 | int qpdfjob_write_qpdf(qpdfjob_handle j, qpdf_data qpdf); |
| 161 | 142 | ||
| 162 | - /* Allow specification of a custom progress reporter. The progress | ||
| 163 | - * reporter is only used if progress is otherwise requested (with | ||
| 164 | - * the --progress option or "progress": "" in the JSON). | 143 | + /* Allow specification of a custom progress reporter. The progress reporter is only used if |
| 144 | + * progress is otherwise requested (with the --progress option or "progress": "" in the JSON). | ||
| 165 | */ | 145 | */ |
| 166 | QPDF_DLL | 146 | QPDF_DLL |
| 167 | void qpdfjob_register_progress_reporter( | 147 | void qpdfjob_register_progress_reporter( |
include/qpdf/qpdflogger-c.h
| @@ -2,30 +2,26 @@ | @@ -2,30 +2,26 @@ | ||
| 2 | * | 2 | * |
| 3 | * This file is part of qpdf. | 3 | * This file is part of qpdf. |
| 4 | * | 4 | * |
| 5 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | - * you may not use this file except in compliance with the License. | ||
| 7 | - * You may obtain a copy of the License at | 5 | + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| 6 | + * in compliance with the License. You may obtain a copy of the License at | ||
| 8 | * | 7 | * |
| 9 | * http://www.apache.org/licenses/LICENSE-2.0 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | * | 9 | * |
| 11 | - * Unless required by applicable law or agreed to in writing, software | ||
| 12 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | - * See the License for the specific language governing permissions and | ||
| 15 | - * limitations under the License. | 10 | + * Unless required by applicable law or agreed to in writing, software distributed under the License |
| 11 | + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
| 12 | + * or implied. See the License for the specific language governing permissions and limitations under | ||
| 13 | + * the License. | ||
| 16 | * | 14 | * |
| 17 | - * Versions of qpdf prior to version 7 were released under the terms | ||
| 18 | - * of version 2.0 of the Artistic License. At your option, you may | ||
| 19 | - * continue to consider qpdf to be licensed under those terms. Please | ||
| 20 | - * see the manual for additional information. | 15 | + * Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic |
| 16 | + * License. At your option, you may continue to consider qpdf to be licensed under those terms. | ||
| 17 | + * Please see the manual for additional information. | ||
| 21 | */ | 18 | */ |
| 22 | 19 | ||
| 23 | #ifndef QPDFLOGGER_H | 20 | #ifndef QPDFLOGGER_H |
| 24 | #define QPDFLOGGER_H | 21 | #define QPDFLOGGER_H |
| 25 | 22 | ||
| 26 | /* | 23 | /* |
| 27 | - * This file provides a C API for QPDFLogger. See QPDFLogger.hh for | ||
| 28 | - * information about the logger and | 24 | + * This file provides a C API for QPDFLogger. See QPDFLogger.hh for information about the logger and |
| 29 | * examples/qpdfjob-c-save-attachment.c for an example. | 25 | * examples/qpdfjob-c-save-attachment.c for an example. |
| 30 | */ | 26 | */ |
| 31 | 27 | ||
| @@ -36,26 +32,21 @@ | @@ -36,26 +32,21 @@ | ||
| 36 | extern "C" { | 32 | extern "C" { |
| 37 | #endif | 33 | #endif |
| 38 | 34 | ||
| 39 | - /* To operate on a logger, you need a handle to it. call | ||
| 40 | - * qpdflogger_default_logger to get a handle for the default | ||
| 41 | - * logger. There are functions in qpdf-c.h and qpdfjob-c.h that | ||
| 42 | - * also take or return logger handles. When you're done with the | ||
| 43 | - * logger handler, call qpdflogger_cleanup. This cleans up the | ||
| 44 | - * handle but leaves the underlying log object intact. (It uses a | ||
| 45 | - * shared pointer and will be cleaned up automatically when it is | ||
| 46 | - * no longer in use.) That means you can create a logger with | ||
| 47 | - * qpdflogger_create(), pass the logger handle to a function in | ||
| 48 | - * qpdf-c.h or qpdfjob-c.h, and then clean it up, subject to | ||
| 49 | - * constraints imposed by the other function. | 35 | + /* To operate on a logger, you need a handle to it. call qpdflogger_default_logger to get a |
| 36 | + * handle for the default logger. There are functions in qpdf-c.h and qpdfjob-c.h that also take | ||
| 37 | + * or return logger handles. When you're done with the logger handler, call qpdflogger_cleanup. | ||
| 38 | + * This cleans up the handle but leaves the underlying log object intact. (It uses a shared | ||
| 39 | + * pointer and will be cleaned up automatically when it is no longer in use.) That means you can | ||
| 40 | + * create a logger with qpdflogger_create(), pass the logger handle to a function in qpdf-c.h or | ||
| 41 | + * qpdfjob-c.h, and then clean it up, subject to constraints imposed by the other function. | ||
| 50 | */ | 42 | */ |
| 51 | 43 | ||
| 52 | typedef struct _qpdflogger_handle* qpdflogger_handle; | 44 | typedef struct _qpdflogger_handle* qpdflogger_handle; |
| 53 | QPDF_DLL | 45 | QPDF_DLL |
| 54 | qpdflogger_handle qpdflogger_default_logger(); | 46 | qpdflogger_handle qpdflogger_default_logger(); |
| 55 | 47 | ||
| 56 | - /* Calling cleanup on the handle returned by qpdflogger_create | ||
| 57 | - * destroys the handle but not the underlying logger. See comments | ||
| 58 | - * above. | 48 | + /* Calling cleanup on the handle returned by qpdflogger_create destroys the handle but not the |
| 49 | + * underlying logger. See comments above. | ||
| 59 | */ | 50 | */ |
| 60 | QPDF_DLL | 51 | QPDF_DLL |
| 61 | qpdflogger_handle qpdflogger_create(); | 52 | qpdflogger_handle qpdflogger_create(); |
| @@ -84,8 +75,8 @@ extern "C" { | @@ -84,8 +75,8 @@ extern "C" { | ||
| 84 | void qpdflogger_set_error( | 75 | void qpdflogger_set_error( |
| 85 | qpdflogger_handle l, enum qpdf_log_dest_e dest, qpdf_log_fn_t fn, void* udata); | 76 | qpdflogger_handle l, enum qpdf_log_dest_e dest, qpdf_log_fn_t fn, void* udata); |
| 86 | 77 | ||
| 87 | - /* A non-zero value for only_if_not_set means that the save | ||
| 88 | - * pipeline will only be changed if it is not already set. | 78 | + /* A non-zero value for only_if_not_set means that the save pipeline will only be changed if it |
| 79 | + * is not already set. | ||
| 89 | */ | 80 | */ |
| 90 | QPDF_DLL | 81 | QPDF_DLL |
| 91 | void qpdflogger_set_save( | 82 | void qpdflogger_set_save( |
libqpdf/ClosedFileInputSource.cc
| @@ -11,8 +11,7 @@ ClosedFileInputSource::ClosedFileInputSource(char const* filename) : | @@ -11,8 +11,7 @@ ClosedFileInputSource::ClosedFileInputSource(char const* filename) : | ||
| 11 | 11 | ||
| 12 | ClosedFileInputSource::~ClosedFileInputSource() | 12 | ClosedFileInputSource::~ClosedFileInputSource() |
| 13 | { | 13 | { |
| 14 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 15 | - // README-maintainer | 14 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| 16 | } | 15 | } |
| 17 | 16 | ||
| 18 | void | 17 | void |
| @@ -91,8 +90,7 @@ ClosedFileInputSource::unreadCh(char ch) | @@ -91,8 +90,7 @@ ClosedFileInputSource::unreadCh(char ch) | ||
| 91 | { | 90 | { |
| 92 | before(); | 91 | before(); |
| 93 | this->fis->unreadCh(ch); | 92 | this->fis->unreadCh(ch); |
| 94 | - // Don't call after -- the file has to stay open after this | ||
| 95 | - // operation. | 93 | + // Don't call after -- the file has to stay open after this operation. |
| 96 | } | 94 | } |
| 97 | 95 | ||
| 98 | void | 96 | void |
libqpdf/ContentNormalizer.cc
| @@ -41,9 +41,8 @@ ContentNormalizer::handleToken(QPDFTokenizer::Token const& token) | @@ -41,9 +41,8 @@ ContentNormalizer::handleToken(QPDFTokenizer::Token const& token) | ||
| 41 | break; | 41 | break; |
| 42 | 42 | ||
| 43 | case QPDFTokenizer::tt_string: | 43 | case QPDFTokenizer::tt_string: |
| 44 | - // Replacing string and name tokens in this way normalizes | ||
| 45 | - // their representation as this will automatically handle | ||
| 46 | - // quoting of unprintable characters, etc. | 44 | + // Replacing string and name tokens in this way normalizes their representation as this will |
| 45 | + // automatically handle quoting of unprintable characters, etc. | ||
| 47 | writeToken(QPDFTokenizer::Token(QPDFTokenizer::tt_string, token.getValue())); | 46 | writeToken(QPDFTokenizer::Token(QPDFTokenizer::tt_string, token.getValue())); |
| 48 | break; | 47 | break; |
| 49 | 48 |
libqpdf/FileInputSource.cc
| @@ -27,8 +27,7 @@ FileInputSource::FileInputSource(char const* description, FILE* filep, bool clos | @@ -27,8 +27,7 @@ FileInputSource::FileInputSource(char const* description, FILE* filep, bool clos | ||
| 27 | 27 | ||
| 28 | FileInputSource::~FileInputSource() | 28 | FileInputSource::~FileInputSource() |
| 29 | { | 29 | { |
| 30 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 31 | - // README-maintainer | 30 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| 32 | if (this->file && this->close_file) { | 31 | if (this->file && this->close_file) { |
| 33 | fclose(this->file); | 32 | fclose(this->file); |
| 34 | } | 33 | } |
| @@ -68,8 +67,7 @@ FileInputSource::findAndSkipNextEOL() | @@ -68,8 +67,7 @@ FileInputSource::findAndSkipNextEOL() | ||
| 68 | char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2; | 67 | char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2; |
| 69 | if (p) { | 68 | if (p) { |
| 70 | result = cur_offset + (p - buf); | 69 | result = cur_offset + (p - buf); |
| 71 | - // We found \r or \n. Keep reading until we get past | ||
| 72 | - // \r and \n characters. | 70 | + // We found \r or \n. Keep reading until we get past \r and \n characters. |
| 73 | this->seek(result + 1, SEEK_SET); | 71 | this->seek(result + 1, SEEK_SET); |
| 74 | char ch; | 72 | char ch; |
| 75 | while (!done) { | 73 | while (!done) { |
libqpdf/InputSource.cc
| @@ -20,12 +20,10 @@ InputSource::getLastOffset() const | @@ -20,12 +20,10 @@ InputSource::getLastOffset() const | ||
| 20 | std::string | 20 | std::string |
| 21 | InputSource::readLine(size_t max_line_length) | 21 | InputSource::readLine(size_t max_line_length) |
| 22 | { | 22 | { |
| 23 | - // Return at most max_line_length characters from the next line. | ||
| 24 | - // Lines are terminated by one or more \r or \n characters. | ||
| 25 | - // Consume the trailing newline characters but don't return them. | ||
| 26 | - // After this is called, the file will be positioned after a line | ||
| 27 | - // terminator or at the end of the file, and last_offset will | ||
| 28 | - // point to position the file had when this method was called. | 23 | + // Return at most max_line_length characters from the next line. Lines are terminated by one or |
| 24 | + // more \r or \n characters. Consume the trailing newline characters but don't return them. | ||
| 25 | + // After this is called, the file will be positioned after a line terminator or at the end of | ||
| 26 | + // the file, and last_offset will point to position the file had when this method was called. | ||
| 29 | 27 | ||
| 30 | qpdf_offset_t offset = this->tell(); | 28 | qpdf_offset_t offset = this->tell(); |
| 31 | auto bp = std::make_unique<char[]>(max_line_length + 1); | 29 | auto bp = std::make_unique<char[]>(max_line_length + 1); |
| @@ -45,22 +43,18 @@ InputSource::readLine(size_t max_line_length) | @@ -45,22 +43,18 @@ InputSource::readLine(size_t max_line_length) | ||
| 45 | bool | 43 | bool |
| 46 | InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len, Finder& finder) | 44 | InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len, Finder& finder) |
| 47 | { | 45 | { |
| 48 | - // Basic approach: search for the first character of start_chars | ||
| 49 | - // starting from offset but not going past len (if len != 0). Once | ||
| 50 | - // the first character is found, see if it is the beginning of a | ||
| 51 | - // sequence of characters matching start_chars. If so, call | ||
| 52 | - // finder.check() to do caller-specific additional checks. If not, | ||
| 53 | - // keep searching. | 46 | + // Basic approach: search for the first character of start_chars starting from offset but not |
| 47 | + // going past len (if len != 0). Once the first character is found, see if it is the beginning | ||
| 48 | + // of a sequence of characters matching start_chars. If so, call finder.check() to do | ||
| 49 | + // caller-specific additional checks. If not, keep searching. | ||
| 54 | 50 | ||
| 55 | - // This code is tricky and highly subject to off-by-one or other | ||
| 56 | - // edge case logic errors. See comments throughout that explain | ||
| 57 | - // how we're not missing any edge cases. There are also tests | ||
| 58 | - // specifically constructed to make sure we caught the edge cases | ||
| 59 | - // in testing. | 51 | + // This code is tricky and highly subject to off-by-one or other edge case logic errors. See |
| 52 | + // comments throughout that explain how we're not missing any edge cases. There are also tests | ||
| 53 | + // specifically constructed to make sure we caught the edge cases in testing. | ||
| 60 | 54 | ||
| 61 | char buf[1025]; // size known to input_source.cc in libtests | 55 | char buf[1025]; // size known to input_source.cc in libtests |
| 62 | - // To enable us to guarantee null-termination, save an extra byte | ||
| 63 | - // so that buf[size] is valid memory. | 56 | + // To enable us to guarantee null-termination, save an extra byte so that buf[size] is valid |
| 57 | + // memory. | ||
| 64 | size_t size = sizeof(buf) - 1; | 58 | size_t size = sizeof(buf) - 1; |
| 65 | if ((strlen(start_chars) < 1) || (strlen(start_chars) > size)) { | 59 | if ((strlen(start_chars) < 1) || (strlen(start_chars) > size)) { |
| 66 | throw std::logic_error("InputSource::findSource called with" | 60 | 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 | @@ -71,19 +65,15 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len | ||
| 71 | qpdf_offset_t buf_offset = offset; | 65 | qpdf_offset_t buf_offset = offset; |
| 72 | size_t bytes_read = 0; | 66 | size_t bytes_read = 0; |
| 73 | 67 | ||
| 74 | - // Guarantee that we return from this loop. Each time through, we | ||
| 75 | - // either return, advance p, or restart the loop with a condition | ||
| 76 | - // that will cause return on the next pass. Eventually we will | ||
| 77 | - // either be out of range or hit EOF, either of which forces us to | ||
| 78 | - // return. | 68 | + // Guarantee that we return from this loop. Each time through, we either return, advance p, or |
| 69 | + // restart the loop with a condition that will cause return on the next pass. Eventually we will | ||
| 70 | + // either be out of range or hit EOF, either of which forces us to return. | ||
| 79 | while (true) { | 71 | while (true) { |
| 80 | - // Do we need to read more data? Pretend size = 5, buf starts | ||
| 81 | - // at 0, and start_chars has 3 characters. buf[5] is valid and | ||
| 82 | - // null. If p == 2, start_chars could be buf[2] through | ||
| 83 | - // buf[4], so p + strlen(start_chars) == buf + size is okay. | ||
| 84 | - // If p points to buf[size], since strlen(start_chars) is | ||
| 85 | - // always >= 1, this overflow test will be correct for that | ||
| 86 | - // case regardless of start_chars. | 72 | + // Do we need to read more data? Pretend size = 5, buf starts at 0, and start_chars has 3 |
| 73 | + // characters. buf[5] is valid and null. If p == 2, start_chars could be buf[2] through | ||
| 74 | + // buf[4], so p + strlen(start_chars) == buf + size is okay. If p points to buf[size], since | ||
| 75 | + // strlen(start_chars) is always >= 1, this overflow test will be correct for that case | ||
| 76 | + // regardless of start_chars. | ||
| 87 | if ((p == nullptr) || ((p + strlen(start_chars)) > (buf + bytes_read))) { | 77 | if ((p == nullptr) || ((p + strlen(start_chars)) > (buf + bytes_read))) { |
| 88 | if (p) { | 78 | if (p) { |
| 89 | QTC::TC( | 79 | QTC::TC( |
| @@ -91,9 +81,8 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len | @@ -91,9 +81,8 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len | ||
| 91 | buf_offset += (p - buf); | 81 | buf_offset += (p - buf); |
| 92 | } | 82 | } |
| 93 | this->seek(buf_offset, SEEK_SET); | 83 | this->seek(buf_offset, SEEK_SET); |
| 94 | - // Read into buffer and zero out the rest of the buffer | ||
| 95 | - // including buf[size]. We allocated an extra byte so that | ||
| 96 | - // we could guarantee null termination as an extra | 84 | + // Read into buffer and zero out the rest of the buffer including buf[size]. We |
| 85 | + // allocated an extra byte so that we could guarantee null termination as an extra | ||
| 97 | // protection against overrun when using string functions. | 86 | // protection against overrun when using string functions. |
| 98 | bytes_read = this->read(buf, size); | 87 | bytes_read = this->read(buf, size); |
| 99 | if (bytes_read < strlen(start_chars)) { | 88 | if (bytes_read < strlen(start_chars)) { |
| @@ -122,19 +111,16 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len | @@ -122,19 +111,16 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len | ||
| 122 | } | 111 | } |
| 123 | } | 112 | } |
| 124 | if ((p + strlen(start_chars)) > (buf + bytes_read)) { | 113 | if ((p + strlen(start_chars)) > (buf + bytes_read)) { |
| 125 | - // If there are not enough bytes left in the file for | ||
| 126 | - // start_chars, we will detect this on the next pass | ||
| 127 | - // as EOF and return. | 114 | + // If there are not enough bytes left in the file for start_chars, we will detect |
| 115 | + // this on the next pass as EOF and return. | ||
| 128 | QTC::TC("libtests", "InputSource not enough bytes"); | 116 | QTC::TC("libtests", "InputSource not enough bytes"); |
| 129 | continue; | 117 | continue; |
| 130 | } | 118 | } |
| 131 | 119 | ||
| 132 | - // See if p points to a sequence matching start_chars. We | ||
| 133 | - // already checked above to make sure we are not going to | ||
| 134 | - // overrun memory. | 120 | + // See if p points to a sequence matching start_chars. We already checked above to make |
| 121 | + // sure we are not going to overrun memory. | ||
| 135 | if (strncmp(p, start_chars, strlen(start_chars)) == 0) { | 122 | if (strncmp(p, start_chars, strlen(start_chars)) == 0) { |
| 136 | - // Call finder.check() with the input source | ||
| 137 | - // positioned to the point of the match. | 123 | + // Call finder.check() with the input source positioned to the point of the match. |
| 138 | this->seek(buf_offset + (p - buf), SEEK_SET); | 124 | this->seek(buf_offset + (p - buf), SEEK_SET); |
| 139 | if (finder.check()) { | 125 | if (finder.check()) { |
| 140 | return true; | 126 | return true; |
| @@ -144,8 +130,8 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len | @@ -144,8 +130,8 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len | ||
| 144 | } else { | 130 | } else { |
| 145 | QTC::TC("libtests", "InputSource first char matched but not string"); | 131 | QTC::TC("libtests", "InputSource first char matched but not string"); |
| 146 | } | 132 | } |
| 147 | - // This occurrence of the first character wasn't a match. | ||
| 148 | - // Skip over it and keep searching. | 133 | + // This occurrence of the first character wasn't a match. Skip over it and keep |
| 134 | + // searching. | ||
| 149 | ++p; | 135 | ++p; |
| 150 | } else { | 136 | } else { |
| 151 | // Trigger reading the next block | 137 | // Trigger reading the next block |
libqpdf/InsecureRandomDataProvider.cc
| @@ -21,9 +21,8 @@ long | @@ -21,9 +21,8 @@ long | ||
| 21 | InsecureRandomDataProvider::random() | 21 | InsecureRandomDataProvider::random() |
| 22 | { | 22 | { |
| 23 | if (!this->seeded_random) { | 23 | if (!this->seeded_random) { |
| 24 | - // Seed the random number generator with something simple, but | ||
| 25 | - // just to be interesting, don't use the unmodified current | ||
| 26 | - // time. It would be better if this were a more secure seed. | 24 | + // Seed the random number generator with something simple, but just to be interesting, don't |
| 25 | + // use the unmodified current time. It would be better if this were a more secure seed. | ||
| 27 | auto seed = static_cast<unsigned int>(QUtil::get_current_time() ^ 0xcccc); | 26 | auto seed = static_cast<unsigned int>(QUtil::get_current_time() ^ 0xcccc); |
| 28 | #ifdef HAVE_RANDOM | 27 | #ifdef HAVE_RANDOM |
| 29 | ::srandom(seed); | 28 | ::srandom(seed); |
libqpdf/JSONHandler.cc
| @@ -133,12 +133,10 @@ JSONHandler::handle(std::string const& path, JSON j) | @@ -133,12 +133,10 @@ JSONHandler::handle(std::string const& path, JSON j) | ||
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | if (!handled) { | 135 | if (!handled) { |
| 136 | - // It would be nice to include information about what type the | ||
| 137 | - // object was and what types were allowed, but we're relying | ||
| 138 | - // on schema validation to make sure input is properly | ||
| 139 | - // structured before calling the handlers. It would be | ||
| 140 | - // different if this code were trying to be part of a | ||
| 141 | - // general-purpose JSON package. | 136 | + // It would be nice to include information about what type the object was and what types |
| 137 | + // were allowed, but we're relying on schema validation to make sure input is properly | ||
| 138 | + // structured before calling the handlers. It would be different if this code were trying to | ||
| 139 | + // be part of a general-purpose JSON package. | ||
| 142 | QTC::TC("libtests", "JSONHandler unhandled value"); | 140 | QTC::TC("libtests", "JSONHandler unhandled value"); |
| 143 | usage("JSON handler: value at " + path + " is not of expected type"); | 141 | usage("JSON handler: value at " + path + " is not of expected type"); |
| 144 | } | 142 | } |
libqpdf/MD5.cc
| @@ -78,8 +78,7 @@ MD5::encodeFile(char const* filename, qpdf_offset_t up_to_offset) | @@ -78,8 +78,7 @@ MD5::encodeFile(char const* filename, qpdf_offset_t up_to_offset) | ||
| 78 | } | 78 | } |
| 79 | } while (len > 0); | 79 | } while (len > 0); |
| 80 | if (ferror(file)) { | 80 | if (ferror(file)) { |
| 81 | - // Assume, perhaps incorrectly, that errno was set by the | ||
| 82 | - // underlying call to read.... | 81 | + // Assume, perhaps incorrectly, that errno was set by the underlying call to read.... |
| 83 | (void)fclose(file); | 82 | (void)fclose(file); |
| 84 | QUtil::throw_system_error(std::string("MD5: read error on ") + filename); | 83 | QUtil::throw_system_error(std::string("MD5: read error on ") + filename); |
| 85 | } | 84 | } |
libqpdf/NNTree.cc
| @@ -36,23 +36,18 @@ NNTreeIterator::NNTreeIterator(NNTreeImpl& impl) : | @@ -36,23 +36,18 @@ NNTreeIterator::NNTreeIterator(NNTreeImpl& impl) : | ||
| 36 | void | 36 | void |
| 37 | NNTreeIterator::updateIValue(bool allow_invalid) | 37 | NNTreeIterator::updateIValue(bool allow_invalid) |
| 38 | { | 38 | { |
| 39 | - // ivalue should never be used inside the class since we return a | ||
| 40 | - // pointer/reference to it. Every bit of code that ever changes | ||
| 41 | - // what object the iterator points to should take care to call | ||
| 42 | - // updateIValue. Failure to do this means that any old references | ||
| 43 | - // to *iter will point to incorrect objects, though the next | ||
| 44 | - // dereference of the iterator will fix it. This isn't necessarily | ||
| 45 | - // catastrophic, but it would be confusing. The test suite | ||
| 46 | - // attempts to exercise various cases to ensure we don't introduce | ||
| 47 | - // that bug in the future, but sadly it's tricky to verify by | ||
| 48 | - // reasoning about the code that this constraint is always | ||
| 49 | - // satisfied. Whenever we update what the iterator points to, we | ||
| 50 | - // should call setItemNumber, which calls this. If we change what | ||
| 51 | - // the iterator in some other way, such as replacing a value or | ||
| 52 | - // removing an item and making the iterator point at a different | ||
| 53 | - // item in potentially the same position, we must call | ||
| 54 | - // updateIValue as well. These cases are handled, and for good | ||
| 55 | - // measure, we also call updateIValue in operator* and operator->. | 39 | + // ivalue should never be used inside the class since we return a pointer/reference to it. Every |
| 40 | + // bit of code that ever changes what object the iterator points to should take care to call | ||
| 41 | + // updateIValue. Failure to do this means that any old references to *iter will point to | ||
| 42 | + // incorrect objects, though the next dereference of the iterator will fix it. This isn't | ||
| 43 | + // necessarily catastrophic, but it would be confusing. The test suite attempts to exercise | ||
| 44 | + // various cases to ensure we don't introduce that bug in the future, but sadly it's tricky to | ||
| 45 | + // verify by reasoning about the code that this constraint is always satisfied. Whenever we | ||
| 46 | + // update what the iterator points to, we should call setItemNumber, which calls this. If we | ||
| 47 | + // change what the iterator in some other way, such as replacing a value or removing an item and | ||
| 48 | + // making the iterator point at a different item in potentially the same position, we must call | ||
| 49 | + // updateIValue as well. These cases are handled, and for good measure, we also call | ||
| 50 | + // updateIValue in operator* and operator->. | ||
| 56 | 51 | ||
| 57 | bool okay = false; | 52 | bool okay = false; |
| 58 | if ((item_number >= 0) && this->node.isDictionary()) { | 53 | if ((item_number >= 0) && this->node.isDictionary()) { |
| @@ -228,12 +223,11 @@ NNTreeIterator::resetLimits(QPDFObjectHandle node, std::list<PathElement>::itera | @@ -228,12 +223,11 @@ NNTreeIterator::resetLimits(QPDFObjectHandle node, std::list<PathElement>::itera | ||
| 228 | void | 223 | void |
| 229 | NNTreeIterator::split(QPDFObjectHandle to_split, std::list<PathElement>::iterator parent) | 224 | NNTreeIterator::split(QPDFObjectHandle to_split, std::list<PathElement>::iterator parent) |
| 230 | { | 225 | { |
| 231 | - // Split some node along the path to the item pointed to by this | ||
| 232 | - // iterator, and adjust the iterator so it points to the same | ||
| 233 | - // item. | 226 | + // Split some node along the path to the item pointed to by this iterator, and adjust the |
| 227 | + // iterator so it points to the same item. | ||
| 234 | 228 | ||
| 235 | - // In examples, for simplicity, /Nums is show to just contain | ||
| 236 | - // numbers instead of pairs. Imagine this tree: | 229 | + // In examples, for simplicity, /Nums is show to just contain numbers instead of pairs. Imagine |
| 230 | + // this tree: | ||
| 237 | // | 231 | // |
| 238 | // root: << /Kids [ A B C D ] >> | 232 | // root: << /Kids [ A B C D ] >> |
| 239 | // A: << /Nums [ 1 2 3 4 ] >> | 233 | // A: << /Nums [ 1 2 3 4 ] >> |
| @@ -260,8 +254,7 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list<PathElement>::iterato | @@ -260,8 +254,7 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list<PathElement>::iterato | ||
| 260 | throw std::logic_error("NNTreeIterator::split called an invalid iterator"); | 254 | throw std::logic_error("NNTreeIterator::split called an invalid iterator"); |
| 261 | } | 255 | } |
| 262 | 256 | ||
| 263 | - // Find the array we actually need to split, which is either this | ||
| 264 | - // node's kids or items. | 257 | + // Find the array we actually need to split, which is either this node's kids or items. |
| 265 | auto kids = to_split.getKey("/Kids"); | 258 | auto kids = to_split.getKey("/Kids"); |
| 266 | int nkids = kids.isArray() ? kids.getArrayNItems() : 0; | 259 | int nkids = kids.isArray() ? kids.getArrayNItems() : 0; |
| 267 | auto items = to_split.getKey(impl.details.itemsKey()); | 260 | auto items = to_split.getKey(impl.details.itemsKey()); |
| @@ -294,30 +287,22 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list<PathElement>::iterato | @@ -294,30 +287,22 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list<PathElement>::iterato | ||
| 294 | bool is_root = (parent == this->path.end()); | 287 | bool is_root = (parent == this->path.end()); |
| 295 | bool is_leaf = (nitems > 0); | 288 | bool is_leaf = (nitems > 0); |
| 296 | 289 | ||
| 297 | - // CURRENT STATE: tree is in original state; iterator is valid and | ||
| 298 | - // unchanged. | 290 | + // CURRENT STATE: tree is in original state; iterator is valid and unchanged. |
| 299 | 291 | ||
| 300 | if (is_root) { | 292 | if (is_root) { |
| 301 | - // What we want to do is to create a new node for the second | ||
| 302 | - // half of the items and put it in the parent's /Kids array | ||
| 303 | - // right after the element that points to the current to_split | ||
| 304 | - // node, but if we're splitting root, there is no parent, so | ||
| 305 | - // handle that first. | ||
| 306 | - | ||
| 307 | - // In the non-root case, parent points to the path element | ||
| 308 | - // whose /Kids contains the first half node, and the first | ||
| 309 | - // half node is to_split. If we are splitting the root, we | ||
| 310 | - // need to push everything down a level, but we want to keep | ||
| 311 | - // the actual root object the same so that indirect references | ||
| 312 | - // to it remain intact (and also in case it might be a direct | ||
| 313 | - // object, which it shouldn't be but that case probably exists | ||
| 314 | - // in the wild). To achieve this, we create a new node for the | ||
| 315 | - // first half and then replace /Kids in the root to contain | ||
| 316 | - // it. Then we adjust the path so that the first element is | ||
| 317 | - // root and the second element, if any, is the new first half. | ||
| 318 | - // In this way, we make the root case identical to the | ||
| 319 | - // non-root case so remaining logic can handle them in the | ||
| 320 | - // same way. | 293 | + // What we want to do is to create a new node for the second half of the items and put it in |
| 294 | + // the parent's /Kids array right after the element that points to the current to_split | ||
| 295 | + // node, but if we're splitting root, there is no parent, so handle that first. | ||
| 296 | + | ||
| 297 | + // In the non-root case, parent points to the path element whose /Kids contains the first | ||
| 298 | + // half node, and the first half node is to_split. If we are splitting the root, we need to | ||
| 299 | + // push everything down a level, but we want to keep the actual root object the same so that | ||
| 300 | + // indirect references to it remain intact (and also in case it might be a direct object, | ||
| 301 | + // which it shouldn't be but that case probably exists in the wild). To achieve this, we | ||
| 302 | + // create a new node for the first half and then replace /Kids in the root to contain it. | ||
| 303 | + // Then we adjust the path so that the first element is root and the second element, if any, | ||
| 304 | + // is the new first half. In this way, we make the root case identical to the non-root case | ||
| 305 | + // so remaining logic can handle them in the same way. | ||
| 321 | 306 | ||
| 322 | auto first_node = impl.qpdf.makeIndirectObject(QPDFObjectHandle::newDictionary()); | 307 | auto first_node = impl.qpdf.makeIndirectObject(QPDFObjectHandle::newDictionary()); |
| 323 | first_node.replaceKey(key, first_half); | 308 | first_node.replaceKey(key, first_half); |
| @@ -339,12 +324,11 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list<PathElement>::iterato | @@ -339,12 +324,11 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list<PathElement>::iterato | ||
| 339 | to_split = first_node; | 324 | to_split = first_node; |
| 340 | } | 325 | } |
| 341 | 326 | ||
| 342 | - // CURRENT STATE: parent is guaranteed to be defined, and we have | ||
| 343 | - // the invariants that parent[/Kids][kid_number] == to_split and | ||
| 344 | - // (++parent).node == to_split. | 327 | + // CURRENT STATE: parent is guaranteed to be defined, and we have the invariants that |
| 328 | + // parent[/Kids][kid_number] == to_split and (++parent).node == to_split. | ||
| 345 | 329 | ||
| 346 | - // Create a second half array, and transfer the second half of the | ||
| 347 | - // items into the second half array. | 330 | + // Create a second half array, and transfer the second half of the items into the second half |
| 331 | + // array. | ||
| 348 | QPDFObjectHandle second_half = QPDFObjectHandle::newArray(); | 332 | QPDFObjectHandle second_half = QPDFObjectHandle::newArray(); |
| 349 | int start_idx = ((n / 2) & ~1); | 333 | int start_idx = ((n / 2) & ~1); |
| 350 | while (first_half.getArrayNItems() > start_idx) { | 334 | while (first_half.getArrayNItems() > start_idx) { |
| @@ -358,15 +342,13 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list<PathElement>::iterato | @@ -358,15 +342,13 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list<PathElement>::iterato | ||
| 358 | second_node.replaceKey(key, second_half); | 342 | second_node.replaceKey(key, second_half); |
| 359 | resetLimits(second_node, parent); | 343 | resetLimits(second_node, parent); |
| 360 | 344 | ||
| 361 | - // CURRENT STATE: half the items from the kids or items array in | ||
| 362 | - // the node being split have been moved into a new node. The new | ||
| 363 | - // node is not yet attached to the tree. The iterator may have a | 345 | + // CURRENT STATE: half the items from the kids or items array in the node being split have been |
| 346 | + // moved into a new node. The new node is not yet attached to the tree. The iterator may have a | ||
| 364 | // path element or leaf node that is out of bounds. | 347 | // path element or leaf node that is out of bounds. |
| 365 | 348 | ||
| 366 | - // We need to adjust the parent to add the second node to /Kids | ||
| 367 | - // and, if needed, update kid_number to traverse through it. We | ||
| 368 | - // need to update to_split's path element, or the node if this is | ||
| 369 | - // a leaf, so that the kid/item number points to the right place. | 349 | + // We need to adjust the parent to add the second node to /Kids and, if needed, update |
| 350 | + // kid_number to traverse through it. We need to update to_split's path element, or the node if | ||
| 351 | + // this is a leaf, so that the kid/item number points to the right place. | ||
| 370 | 352 | ||
| 371 | auto parent_kids = parent->node.getKey("/Kids"); | 353 | auto parent_kids = parent->node.getKey("/Kids"); |
| 372 | parent_kids.insertItem(parent->kid_number + 1, second_node); | 354 | parent_kids.insertItem(parent->kid_number + 1, second_node); |
| @@ -430,8 +412,7 @@ NNTreeIterator::insertAfter(QPDFObjectHandle key, QPDFObjectHandle value) | @@ -430,8 +412,7 @@ NNTreeIterator::insertAfter(QPDFObjectHandle key, QPDFObjectHandle value) | ||
| 430 | void | 412 | void |
| 431 | NNTreeIterator::remove() | 413 | NNTreeIterator::remove() |
| 432 | { | 414 | { |
| 433 | - // Remove this item, leaving the tree valid and this iterator | ||
| 434 | - // pointing to the next item. | 415 | + // Remove this item, leaving the tree valid and this iterator pointing to the next item. |
| 435 | 416 | ||
| 436 | if (!valid()) { | 417 | if (!valid()) { |
| 437 | throw std::logic_error("attempt made to remove an invalid iterator"); | 418 | throw std::logic_error("attempt made to remove an invalid iterator"); |
| @@ -450,34 +431,32 @@ NNTreeIterator::remove() | @@ -450,34 +431,32 @@ NNTreeIterator::remove() | ||
| 450 | // There are still items left | 431 | // There are still items left |
| 451 | 432 | ||
| 452 | if ((this->item_number == 0) || (this->item_number == nitems)) { | 433 | if ((this->item_number == 0) || (this->item_number == nitems)) { |
| 453 | - // We removed either the first or last item of an items array | ||
| 454 | - // that remains non-empty, so we have to adjust limits. | 434 | + // We removed either the first or last item of an items array that remains non-empty, so |
| 435 | + // we have to adjust limits. | ||
| 455 | QTC::TC("qpdf", "NNTree remove reset limits"); | 436 | QTC::TC("qpdf", "NNTree remove reset limits"); |
| 456 | resetLimits(this->node, lastPathElement()); | 437 | resetLimits(this->node, lastPathElement()); |
| 457 | } | 438 | } |
| 458 | 439 | ||
| 459 | if (this->item_number == nitems) { | 440 | if (this->item_number == nitems) { |
| 460 | - // We removed the last item of a non-empty items array, so | ||
| 461 | - // advance to the successor of the previous item. | 441 | + // We removed the last item of a non-empty items array, so advance to the successor of |
| 442 | + // the previous item. | ||
| 462 | QTC::TC("qpdf", "NNTree erased last item"); | 443 | QTC::TC("qpdf", "NNTree erased last item"); |
| 463 | this->item_number -= 2; | 444 | this->item_number -= 2; |
| 464 | increment(false); | 445 | increment(false); |
| 465 | } else if (this->item_number < nitems) { | 446 | } else if (this->item_number < nitems) { |
| 466 | - // We don't have to do anything since the removed item's | ||
| 467 | - // successor now occupies its former location. | 447 | + // We don't have to do anything since the removed item's successor now occupies its |
| 448 | + // former location. | ||
| 468 | QTC::TC("qpdf", "NNTree erased non-last item"); | 449 | QTC::TC("qpdf", "NNTree erased non-last item"); |
| 469 | updateIValue(); | 450 | updateIValue(); |
| 470 | } else { | 451 | } else { |
| 471 | - // We already checked to ensure this condition would not | ||
| 472 | - // happen. | 452 | + // We already checked to ensure this condition would not happen. |
| 473 | throw std::logic_error("NNTreeIterator::remove: item_number > nitems after erase"); | 453 | throw std::logic_error("NNTreeIterator::remove: item_number > nitems after erase"); |
| 474 | } | 454 | } |
| 475 | return; | 455 | return; |
| 476 | } | 456 | } |
| 477 | 457 | ||
| 478 | if (this->path.empty()) { | 458 | if (this->path.empty()) { |
| 479 | - // Special case: if this is the root node, we can leave it | ||
| 480 | - // empty. | 459 | + // Special case: if this is the root node, we can leave it empty. |
| 481 | QTC::TC("qpdf", "NNTree erased all items on leaf/root"); | 460 | QTC::TC("qpdf", "NNTree erased all items on leaf/root"); |
| 482 | setItemNumber(impl.oh, -1); | 461 | setItemNumber(impl.oh, -1); |
| 483 | return; | 462 | return; |
| @@ -485,9 +464,8 @@ NNTreeIterator::remove() | @@ -485,9 +464,8 @@ NNTreeIterator::remove() | ||
| 485 | 464 | ||
| 486 | QTC::TC("qpdf", "NNTree items is empty after remove"); | 465 | QTC::TC("qpdf", "NNTree items is empty after remove"); |
| 487 | 466 | ||
| 488 | - // We removed the last item from this items array, so we need to | ||
| 489 | - // remove this node from the parent on up the tree. Then we need | ||
| 490 | - // to position ourselves at the removed item's successor. | 467 | + // We removed the last item from this items array, so we need to remove this node from the |
| 468 | + // parent on up the tree. Then we need to position ourselves at the removed item's successor. | ||
| 491 | bool done = false; | 469 | bool done = false; |
| 492 | while (!done) { | 470 | while (!done) { |
| 493 | auto element = lastPathElement(); | 471 | auto element = lastPathElement(); |
| @@ -503,8 +481,7 @@ NNTreeIterator::remove() | @@ -503,8 +481,7 @@ NNTreeIterator::remove() | ||
| 503 | resetLimits(element->node, parent); | 481 | resetLimits(element->node, parent); |
| 504 | } | 482 | } |
| 505 | if (element->kid_number == nkids) { | 483 | if (element->kid_number == nkids) { |
| 506 | - // Move to the successor of the last child of the | ||
| 507 | - // previous kid. | 484 | + // Move to the successor of the last child of the previous kid. |
| 508 | setItemNumber(QPDFObjectHandle(), -1); | 485 | setItemNumber(QPDFObjectHandle(), -1); |
| 509 | --element->kid_number; | 486 | --element->kid_number; |
| 510 | deepen(kids.getArrayItem(element->kid_number), false, true); | 487 | deepen(kids.getArrayItem(element->kid_number), false, true); |
| @@ -523,8 +500,7 @@ NNTreeIterator::remove() | @@ -523,8 +500,7 @@ NNTreeIterator::remove() | ||
| 523 | } | 500 | } |
| 524 | done = true; | 501 | done = true; |
| 525 | } else if (parent == this->path.end()) { | 502 | } else if (parent == this->path.end()) { |
| 526 | - // We erased the very last item. Convert the root to an | ||
| 527 | - // empty items array. | 503 | + // We erased the very last item. Convert the root to an empty items array. |
| 528 | QTC::TC("qpdf", "NNTree non-flat tree is empty after remove"); | 504 | QTC::TC("qpdf", "NNTree non-flat tree is empty after remove"); |
| 529 | element->node.removeKey("/Kids"); | 505 | element->node.removeKey("/Kids"); |
| 530 | element->node.replaceKey(impl.details.itemsKey(), QPDFObjectHandle::newArray()); | 506 | element->node.replaceKey(impl.details.itemsKey(), QPDFObjectHandle::newArray()); |
| @@ -608,9 +584,8 @@ NNTreeIterator::addPathElement(QPDFObjectHandle const& node, int kid_number) | @@ -608,9 +584,8 @@ NNTreeIterator::addPathElement(QPDFObjectHandle const& node, int kid_number) | ||
| 608 | bool | 584 | bool |
| 609 | NNTreeIterator::deepen(QPDFObjectHandle node, bool first, bool allow_empty) | 585 | NNTreeIterator::deepen(QPDFObjectHandle node, bool first, bool allow_empty) |
| 610 | { | 586 | { |
| 611 | - // Starting at this node, descend through the first or last kid | ||
| 612 | - // until we reach a node with items. If we succeed, return true; | ||
| 613 | - // otherwise return false and leave path alone. | 587 | + // Starting at this node, descend through the first or last kid until we reach a node with |
| 588 | + // items. If we succeed, return true; otherwise return false and leave path alone. | ||
| 614 | 589 | ||
| 615 | auto opath = this->path; | 590 | auto opath = this->path; |
| 616 | bool failed = false; | 591 | bool failed = false; |
libqpdf/Pl_AES_PDF.cc
| @@ -98,9 +98,8 @@ Pl_AES_PDF::finish() | @@ -98,9 +98,8 @@ Pl_AES_PDF::finish() | ||
| 98 | flush(false); | 98 | flush(false); |
| 99 | } | 99 | } |
| 100 | if (!this->disable_padding) { | 100 | if (!this->disable_padding) { |
| 101 | - // Pad as described in section 3.5.1 of version 1.7 of the PDF | ||
| 102 | - // specification, including providing an entire block of padding | ||
| 103 | - // if the input was a multiple of 16 bytes. | 101 | + // Pad as described in section 3.5.1 of version 1.7 of the PDF specification, including |
| 102 | + // providing an entire block of padding if the input was a multiple of 16 bytes. | ||
| 104 | unsigned char pad = QIntC::to_uchar(this->buf_size - this->offset); | 103 | unsigned char pad = QIntC::to_uchar(this->buf_size - this->offset); |
| 105 | memset(this->inbuf + this->offset, pad, pad); | 104 | memset(this->inbuf + this->offset, pad, pad); |
| 106 | this->offset = this->buf_size; | 105 | this->offset = this->buf_size; |
| @@ -108,11 +107,9 @@ Pl_AES_PDF::finish() | @@ -108,11 +107,9 @@ Pl_AES_PDF::finish() | ||
| 108 | } | 107 | } |
| 109 | } else { | 108 | } else { |
| 110 | if (this->offset != this->buf_size) { | 109 | if (this->offset != this->buf_size) { |
| 111 | - // This is never supposed to happen as the output is | ||
| 112 | - // always supposed to be padded. However, we have | ||
| 113 | - // encountered files for which the output is not a | ||
| 114 | - // multiple of the block size. In this case, pad with | ||
| 115 | - // zeroes and hope for the best. | 110 | + // This is never supposed to happen as the output is always supposed to be padded. |
| 111 | + // However, we have encountered files for which the output is not a multiple of the | ||
| 112 | + // block size. In this case, pad with zeroes and hope for the best. | ||
| 116 | if (this->offset >= this->buf_size) { | 113 | if (this->offset >= this->buf_size) { |
| 117 | throw std::logic_error("buffer overflow in AES encryption" | 114 | throw std::logic_error("buffer overflow in AES encryption" |
| 118 | " pipeline"); | 115 | " pipeline"); |
| @@ -156,19 +153,19 @@ Pl_AES_PDF::flush(bool strip_padding) | @@ -156,19 +153,19 @@ Pl_AES_PDF::flush(bool strip_padding) | ||
| 156 | bool return_after_init = false; | 153 | bool return_after_init = false; |
| 157 | if (this->cbc_mode) { | 154 | if (this->cbc_mode) { |
| 158 | if (encrypt) { | 155 | if (encrypt) { |
| 159 | - // Set cbc_block to the initialization vector, and if | ||
| 160 | - // not zero, write it to the output stream. | 156 | + // Set cbc_block to the initialization vector, and if not zero, write it to the |
| 157 | + // output stream. | ||
| 161 | initializeVector(); | 158 | initializeVector(); |
| 162 | if (!(this->use_zero_iv || this->use_specified_iv)) { | 159 | if (!(this->use_zero_iv || this->use_specified_iv)) { |
| 163 | getNext()->write(this->cbc_block, this->buf_size); | 160 | getNext()->write(this->cbc_block, this->buf_size); |
| 164 | } | 161 | } |
| 165 | } else if (this->use_zero_iv || this->use_specified_iv) { | 162 | } else if (this->use_zero_iv || this->use_specified_iv) { |
| 166 | - // Initialize vector with zeroes; zero vector was not | ||
| 167 | - // written to the beginning of the input file. | 163 | + // Initialize vector with zeroes; zero vector was not written to the beginning of |
| 164 | + // the input file. | ||
| 168 | initializeVector(); | 165 | initializeVector(); |
| 169 | } else { | 166 | } else { |
| 170 | - // Take the first block of input as the initialization | ||
| 171 | - // vector. There's nothing to write at this time. | 167 | + // Take the first block of input as the initialization vector. There's nothing to |
| 168 | + // write at this time. | ||
| 172 | memcpy(this->cbc_block, this->inbuf, this->buf_size); | 169 | memcpy(this->cbc_block, this->inbuf, this->buf_size); |
| 173 | this->offset = 0; | 170 | this->offset = 0; |
| 174 | return_after_init = true; | 171 | return_after_init = true; |
libqpdf/Pl_ASCII85Decoder.cc
| @@ -91,8 +91,7 @@ Pl_ASCII85Decoder::flush() | @@ -91,8 +91,7 @@ Pl_ASCII85Decoder::flush() | ||
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | QTC::TC("libtests", "Pl_ASCII85Decoder partial flush", (this->pos == 5) ? 0 : 1); | 93 | QTC::TC("libtests", "Pl_ASCII85Decoder partial flush", (this->pos == 5) ? 0 : 1); |
| 94 | - // Reset before calling getNext()->write in case that throws an | ||
| 95 | - // exception. | 94 | + // Reset before calling getNext()->write in case that throws an exception. |
| 96 | auto t = this->pos - 1; | 95 | auto t = this->pos - 1; |
| 97 | this->pos = 0; | 96 | this->pos = 0; |
| 98 | memset(this->inbuf, 117, 5); | 97 | memset(this->inbuf, 117, 5); |
libqpdf/Pl_ASCIIHexDecoder.cc
| @@ -79,8 +79,7 @@ Pl_ASCIIHexDecoder::flush() | @@ -79,8 +79,7 @@ Pl_ASCIIHexDecoder::flush() | ||
| 79 | auto ch = static_cast<unsigned char>((b[0] << 4) + b[1]); | 79 | auto ch = static_cast<unsigned char>((b[0] << 4) + b[1]); |
| 80 | 80 | ||
| 81 | QTC::TC("libtests", "Pl_ASCIIHexDecoder partial flush", (this->pos == 2) ? 0 : 1); | 81 | QTC::TC("libtests", "Pl_ASCIIHexDecoder partial flush", (this->pos == 2) ? 0 : 1); |
| 82 | - // Reset before calling getNext()->write in case that throws an | ||
| 83 | - // exception. | 82 | + // Reset before calling getNext()->write in case that throws an exception. |
| 84 | this->pos = 0; | 83 | this->pos = 0; |
| 85 | this->inbuf[0] = '0'; | 84 | this->inbuf[0] = '0'; |
| 86 | this->inbuf[1] = '0'; | 85 | this->inbuf[1] = '0'; |
libqpdf/Pl_Concatenate.cc
| @@ -7,8 +7,7 @@ Pl_Concatenate::Pl_Concatenate(char const* identifier, Pipeline* next) : | @@ -7,8 +7,7 @@ Pl_Concatenate::Pl_Concatenate(char const* identifier, Pipeline* next) : | ||
| 7 | 7 | ||
| 8 | Pl_Concatenate::~Pl_Concatenate() | 8 | Pl_Concatenate::~Pl_Concatenate() |
| 9 | { | 9 | { |
| 10 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 11 | - // README-maintainer | 10 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| 12 | } | 11 | } |
| 13 | 12 | ||
| 14 | void | 13 | void |
libqpdf/Pl_Count.cc
| @@ -16,8 +16,7 @@ Pl_Count::Pl_Count(char const* identifier, Pipeline* next) : | @@ -16,8 +16,7 @@ Pl_Count::Pl_Count(char const* identifier, Pipeline* next) : | ||
| 16 | 16 | ||
| 17 | Pl_Count::~Pl_Count() | 17 | Pl_Count::~Pl_Count() |
| 18 | { | 18 | { |
| 19 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 20 | - // README-maintainer | 19 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| 21 | } | 20 | } |
| 22 | 21 | ||
| 23 | void | 22 | void |
libqpdf/Pl_DCT.cc
| @@ -77,8 +77,7 @@ Pl_DCT::Pl_DCT( | @@ -77,8 +77,7 @@ Pl_DCT::Pl_DCT( | ||
| 77 | 77 | ||
| 78 | Pl_DCT::~Pl_DCT() | 78 | Pl_DCT::~Pl_DCT() |
| 79 | { | 79 | { |
| 80 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 81 | - // README-maintainer | 80 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| 82 | } | 81 | } |
| 83 | 82 | ||
| 84 | void | 83 | void |
| @@ -92,14 +91,12 @@ Pl_DCT::finish() | @@ -92,14 +91,12 @@ Pl_DCT::finish() | ||
| 92 | { | 91 | { |
| 93 | m->buf.finish(); | 92 | m->buf.finish(); |
| 94 | 93 | ||
| 95 | - // Using a std::shared_ptr<Buffer> here and passing it into compress | ||
| 96 | - // and decompress causes a memory leak with setjmp/longjmp. Just | ||
| 97 | - // use a pointer and delete it. | 94 | + // Using a std::shared_ptr<Buffer> here and passing it into compress and decompress causes a |
| 95 | + // memory leak with setjmp/longjmp. Just use a pointer and delete it. | ||
| 98 | Buffer* b = m->buf.getBuffer(); | 96 | Buffer* b = m->buf.getBuffer(); |
| 99 | if (b->getSize() == 0) { | 97 | if (b->getSize() == 0) { |
| 100 | - // Special case: empty data will never succeed and probably | ||
| 101 | - // means we're calling finish a second time from an exception | ||
| 102 | - // handler. | 98 | + // Special case: empty data will never succeed and probably means we're calling finish a |
| 99 | + // second time from an exception handler. | ||
| 103 | delete b; | 100 | delete b; |
| 104 | this->getNext()->finish(); | 101 | this->getNext()->finish(); |
| 105 | return; | 102 | return; |
| @@ -114,8 +111,7 @@ Pl_DCT::finish() | @@ -114,8 +111,7 @@ Pl_DCT::finish() | ||
| 114 | jerr.pub.error_exit = error_handler; | 111 | jerr.pub.error_exit = error_handler; |
| 115 | 112 | ||
| 116 | bool error = false; | 113 | bool error = false; |
| 117 | - // The jpeg library is a "C" library, so we use setjmp and longjmp | ||
| 118 | - // for exception handling. | 114 | + // The jpeg library is a "C" library, so we use setjmp and longjmp for exception handling. |
| 119 | if (setjmp(jerr.jmpbuf) == 0) { | 115 | if (setjmp(jerr.jmpbuf) == 0) { |
| 120 | try { | 116 | try { |
| 121 | if (m->action == a_compress) { | 117 | if (m->action == a_compress) { |
| @@ -124,9 +120,8 @@ Pl_DCT::finish() | @@ -124,9 +120,8 @@ Pl_DCT::finish() | ||
| 124 | decompress(reinterpret_cast<void*>(&cinfo_decompress), b); | 120 | decompress(reinterpret_cast<void*>(&cinfo_decompress), b); |
| 125 | } | 121 | } |
| 126 | } catch (std::exception& e) { | 122 | } catch (std::exception& e) { |
| 127 | - // Convert an exception back to a longjmp so we can ensure | ||
| 128 | - // that the right cleanup happens. This will get converted | ||
| 129 | - // back to an exception. | 123 | + // Convert an exception back to a longjmp so we can ensure that the right cleanup |
| 124 | + // happens. This will get converted back to an exception. | ||
| 130 | jerr.msg = e.what(); | 125 | jerr.msg = e.what(); |
| 131 | longjmp(jerr.jmpbuf, 1); | 126 | longjmp(jerr.jmpbuf, 1); |
| 132 | } | 127 | } |
| @@ -205,9 +200,8 @@ init_buffer_source(j_decompress_ptr) | @@ -205,9 +200,8 @@ init_buffer_source(j_decompress_ptr) | ||
| 205 | static boolean | 200 | static boolean |
| 206 | fill_buffer_input_buffer(j_decompress_ptr) | 201 | fill_buffer_input_buffer(j_decompress_ptr) |
| 207 | { | 202 | { |
| 208 | - // The whole JPEG data is expected to reside in the supplied memory | ||
| 209 | - // buffer, so any request for more data beyond the given buffer size | ||
| 210 | - // is treated as an error. | 203 | + // The whole JPEG data is expected to reside in the supplied memory buffer, so any request for |
| 204 | + // more data beyond the given buffer size is treated as an error. | ||
| 211 | throw std::runtime_error("invalid jpeg data reading from buffer"); | 205 | throw std::runtime_error("invalid jpeg data reading from buffer"); |
| 212 | return TRUE; | 206 | return TRUE; |
| 213 | } | 207 | } |
| @@ -216,8 +210,8 @@ static void | @@ -216,8 +210,8 @@ static void | ||
| 216 | skip_buffer_input_data(j_decompress_ptr cinfo, long num_bytes) | 210 | skip_buffer_input_data(j_decompress_ptr cinfo, long num_bytes) |
| 217 | { | 211 | { |
| 218 | if (num_bytes < 0) { | 212 | if (num_bytes < 0) { |
| 219 | - throw std::runtime_error("reading jpeg: jpeg library requested" | ||
| 220 | - " skipping a negative number of bytes"); | 213 | + throw std::runtime_error( |
| 214 | + "reading jpeg: jpeg library requested skipping a negative number of bytes"); | ||
| 221 | } | 215 | } |
| 222 | size_t to_skip = QIntC::to_size(num_bytes); | 216 | size_t to_skip = QIntC::to_size(num_bytes); |
| 223 | if ((to_skip > 0) && (to_skip <= cinfo->src->bytes_in_buffer)) { | 217 | if ((to_skip > 0) && (to_skip <= cinfo->src->bytes_in_buffer)) { |
libqpdf/Pl_Discard.cc
| @@ -9,8 +9,7 @@ Pl_Discard::Pl_Discard() : | @@ -9,8 +9,7 @@ Pl_Discard::Pl_Discard() : | ||
| 9 | 9 | ||
| 10 | Pl_Discard::~Pl_Discard() | 10 | Pl_Discard::~Pl_Discard() |
| 11 | { | 11 | { |
| 12 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 13 | - // README-maintainer | 12 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| 14 | } | 13 | } |
| 15 | 14 | ||
| 16 | void | 15 | void |
libqpdf/Pl_Flate.cc
| @@ -16,16 +16,14 @@ Pl_Flate::Members::Members(size_t out_bufsize, action_e action) : | @@ -16,16 +16,14 @@ Pl_Flate::Members::Members(size_t out_bufsize, action_e action) : | ||
| 16 | zdata(nullptr) | 16 | zdata(nullptr) |
| 17 | { | 17 | { |
| 18 | this->outbuf = QUtil::make_shared_array<unsigned char>(out_bufsize); | 18 | this->outbuf = QUtil::make_shared_array<unsigned char>(out_bufsize); |
| 19 | - // Indirect through zdata to reach the z_stream so we don't have | ||
| 20 | - // to include zlib.h in Pl_Flate.hh. This means people using | ||
| 21 | - // shared library versions of qpdf don't have to have zlib | ||
| 22 | - // development files available, which particularly helps in a | ||
| 23 | - // Windows environment. | 19 | + // Indirect through zdata to reach the z_stream so we don't have to include zlib.h in |
| 20 | + // Pl_Flate.hh. This means people using shared library versions of qpdf don't have to have zlib | ||
| 21 | + // development files available, which particularly helps in a Windows environment. | ||
| 24 | this->zdata = new z_stream; | 22 | this->zdata = new z_stream; |
| 25 | 23 | ||
| 26 | if (out_bufsize > UINT_MAX) { | 24 | if (out_bufsize > UINT_MAX) { |
| 27 | - throw std::runtime_error("Pl_Flate: zlib doesn't support buffer" | ||
| 28 | - " sizes larger than unsigned int"); | 25 | + throw std::runtime_error( |
| 26 | + "Pl_Flate: zlib doesn't support buffer sizes larger than unsigned int"); | ||
| 29 | } | 27 | } |
| 30 | 28 | ||
| 31 | z_stream& zstream = *(static_cast<z_stream*>(this->zdata)); | 29 | z_stream& zstream = *(static_cast<z_stream*>(this->zdata)); |
| @@ -62,8 +60,7 @@ Pl_Flate::Pl_Flate( | @@ -62,8 +60,7 @@ Pl_Flate::Pl_Flate( | ||
| 62 | 60 | ||
| 63 | Pl_Flate::~Pl_Flate() | 61 | Pl_Flate::~Pl_Flate() |
| 64 | { | 62 | { |
| 65 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 66 | - // README-maintainer | 63 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| 67 | } | 64 | } |
| 68 | 65 | ||
| 69 | void | 66 | void |
| @@ -88,8 +85,7 @@ Pl_Flate::write(unsigned char const* data, size_t len) | @@ -88,8 +85,7 @@ Pl_Flate::write(unsigned char const* data, size_t len) | ||
| 88 | this->identifier + ": Pl_Flate: write() called after finish() called"); | 85 | this->identifier + ": Pl_Flate: write() called after finish() called"); |
| 89 | } | 86 | } |
| 90 | 87 | ||
| 91 | - // Write in chunks in case len is too big to fit in an int. | ||
| 92 | - // Assume int is at least 32 bits. | 88 | + // Write in chunks in case len is too big to fit in an int. Assume int is at least 32 bits. |
| 93 | static size_t const max_bytes = 1 << 30; | 89 | static size_t const max_bytes = 1 << 30; |
| 94 | size_t bytes_left = len; | 90 | size_t bytes_left = len; |
| 95 | unsigned char const* buf = data; | 91 | unsigned char const* buf = data; |
| @@ -105,20 +101,18 @@ void | @@ -105,20 +101,18 @@ void | ||
| 105 | Pl_Flate::handleData(unsigned char const* data, size_t len, int flush) | 101 | Pl_Flate::handleData(unsigned char const* data, size_t len, int flush) |
| 106 | { | 102 | { |
| 107 | if (len > UINT_MAX) { | 103 | if (len > UINT_MAX) { |
| 108 | - throw std::runtime_error("Pl_Flate: zlib doesn't support data" | ||
| 109 | - " blocks larger than int"); | 104 | + throw std::runtime_error("Pl_Flate: zlib doesn't support data blocks larger than int"); |
| 110 | } | 105 | } |
| 111 | z_stream& zstream = *(static_cast<z_stream*>(m->zdata)); | 106 | z_stream& zstream = *(static_cast<z_stream*>(m->zdata)); |
| 112 | - // zlib is known not to modify the data pointed to by next_in but | ||
| 113 | - // doesn't declare the field value const unless compiled to do so. | 107 | + // zlib is known not to modify the data pointed to by next_in but doesn't declare the field |
| 108 | + // value const unless compiled to do so. | ||
| 114 | zstream.next_in = const_cast<unsigned char*>(data); | 109 | zstream.next_in = const_cast<unsigned char*>(data); |
| 115 | zstream.avail_in = QIntC::to_uint(len); | 110 | zstream.avail_in = QIntC::to_uint(len); |
| 116 | 111 | ||
| 117 | if (!m->initialized) { | 112 | if (!m->initialized) { |
| 118 | int err = Z_OK; | 113 | int err = Z_OK; |
| 119 | 114 | ||
| 120 | - // deflateInit and inflateInit are macros that use old-style | ||
| 121 | - // casts. | 115 | + // deflateInit and inflateInit are macros that use old-style casts. |
| 122 | #if ((defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406) || defined(__clang__)) | 116 | #if ((defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406) || defined(__clang__)) |
| 123 | # pragma GCC diagnostic push | 117 | # pragma GCC diagnostic push |
| 124 | # pragma GCC diagnostic ignored "-Wold-style-cast" | 118 | # pragma GCC diagnostic ignored "-Wold-style-cast" |
| @@ -147,21 +141,18 @@ Pl_Flate::handleData(unsigned char const* data, size_t len, int flush) | @@ -147,21 +141,18 @@ Pl_Flate::handleData(unsigned char const* data, size_t len, int flush) | ||
| 147 | } | 141 | } |
| 148 | if ((m->action == a_inflate) && (err != Z_OK) && zstream.msg && | 142 | if ((m->action == a_inflate) && (err != Z_OK) && zstream.msg && |
| 149 | (strcmp(zstream.msg, "incorrect data check") == 0)) { | 143 | (strcmp(zstream.msg, "incorrect data check") == 0)) { |
| 150 | - // Other PDF readers ignore this specific error. Combining | ||
| 151 | - // this with Z_SYNC_FLUSH enables qpdf to handle some | ||
| 152 | - // broken zlib streams without losing data. | 144 | + // Other PDF readers ignore this specific error. Combining this with Z_SYNC_FLUSH |
| 145 | + // enables qpdf to handle some broken zlib streams without losing data. | ||
| 153 | err = Z_STREAM_END; | 146 | err = Z_STREAM_END; |
| 154 | } | 147 | } |
| 155 | switch (err) { | 148 | switch (err) { |
| 156 | case Z_BUF_ERROR: | 149 | case Z_BUF_ERROR: |
| 157 | - // Probably shouldn't be able to happen, but possible as a | ||
| 158 | - // boundary condition: if the last call to inflate exactly | ||
| 159 | - // filled the output buffer, it's possible that the next | ||
| 160 | - // call to inflate could have nothing to do. There are PDF | ||
| 161 | - // files in the wild that have this error (including at | ||
| 162 | - // least one in qpdf's test suite). In some cases, we want | ||
| 163 | - // to know about this, because it indicates incorrect | ||
| 164 | - // compression, so call a callback if provided. | 150 | + // Probably shouldn't be able to happen, but possible as a boundary condition: if the |
| 151 | + // last call to inflate exactly filled the output buffer, it's possible that the next | ||
| 152 | + // call to inflate could have nothing to do. There are PDF files in the wild that have | ||
| 153 | + // this error (including at least one in qpdf's test suite). In some cases, we want to | ||
| 154 | + // know about this, because it indicates incorrect compression, so call a callback if | ||
| 155 | + // provided. | ||
| 165 | this->warn("input stream is complete but output may still be valid", err); | 156 | this->warn("input stream is complete but output may still be valid", err); |
| 166 | done = true; | 157 | done = true; |
| 167 | break; | 158 | break; |
| @@ -173,9 +164,8 @@ Pl_Flate::handleData(unsigned char const* data, size_t len, int flush) | @@ -173,9 +164,8 @@ Pl_Flate::handleData(unsigned char const* data, size_t len, int flush) | ||
| 173 | case Z_OK: | 164 | case Z_OK: |
| 174 | { | 165 | { |
| 175 | if ((zstream.avail_in == 0) && (zstream.avail_out > 0)) { | 166 | if ((zstream.avail_in == 0) && (zstream.avail_out > 0)) { |
| 176 | - // There is nothing left to read, and there was | ||
| 177 | - // sufficient buffer space to write everything we | ||
| 178 | - // needed, so we're done for now. | 167 | + // There is nothing left to read, and there was sufficient buffer space to write |
| 168 | + // everything we needed, so we're done for now. | ||
| 179 | done = true; | 169 | done = true; |
| 180 | } | 170 | } |
| 181 | uLong ready = QIntC::to_ulong(m->out_bufsize - zstream.avail_out); | 171 | uLong ready = QIntC::to_ulong(m->out_bufsize - zstream.avail_out); |
libqpdf/Pl_Function.cc
| @@ -41,8 +41,7 @@ Pl_Function::Pl_Function(char const* identifier, Pipeline* next, writer_c_char_t | @@ -41,8 +41,7 @@ Pl_Function::Pl_Function(char const* identifier, Pipeline* next, writer_c_char_t | ||
| 41 | 41 | ||
| 42 | Pl_Function::~Pl_Function() | 42 | Pl_Function::~Pl_Function() |
| 43 | { | 43 | { |
| 44 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 45 | - // README-maintainer | 44 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| 46 | } | 45 | } |
| 47 | 46 | ||
| 48 | void | 47 | void |
libqpdf/Pl_LZWDecoder.cc
| @@ -149,9 +149,8 @@ Pl_LZWDecoder::handleCode(unsigned int code) | @@ -149,9 +149,8 @@ Pl_LZWDecoder::handleCode(unsigned int code) | ||
| 149 | this->eod = true; | 149 | this->eod = true; |
| 150 | } else { | 150 | } else { |
| 151 | if (this->last_code != 256) { | 151 | if (this->last_code != 256) { |
| 152 | - // Add to the table from last time. New table entry would | ||
| 153 | - // be what we read last plus the first character of what | ||
| 154 | - // we're reading now. | 152 | + // Add to the table from last time. New table entry would be what we read last plus the |
| 153 | + // first character of what we're reading now. | ||
| 155 | unsigned char next = '\0'; | 154 | unsigned char next = '\0'; |
| 156 | unsigned int table_size = QIntC::to_uint(table.size()); | 155 | unsigned int table_size = QIntC::to_uint(table.size()); |
| 157 | if (code < 256) { | 156 | if (code < 256) { |
| @@ -162,10 +161,8 @@ Pl_LZWDecoder::handleCode(unsigned int code) | @@ -162,10 +161,8 @@ Pl_LZWDecoder::handleCode(unsigned int code) | ||
| 162 | if (idx > table_size) { | 161 | if (idx > table_size) { |
| 163 | throw std::runtime_error("LZWDecoder: bad code received"); | 162 | throw std::runtime_error("LZWDecoder: bad code received"); |
| 164 | } else if (idx == table_size) { | 163 | } else if (idx == table_size) { |
| 165 | - // The encoder would have just created this entry, | ||
| 166 | - // so the first character of this entry would have | ||
| 167 | - // been the same as the first character of the | ||
| 168 | - // last entry. | 164 | + // The encoder would have just created this entry, so the first character of |
| 165 | + // this entry would have been the same as the first character of the last entry. | ||
| 169 | QTC::TC("libtests", "Pl_LZWDecoder last was table size"); | 166 | QTC::TC("libtests", "Pl_LZWDecoder last was table size"); |
| 170 | next = getFirstChar(this->last_code); | 167 | next = getFirstChar(this->last_code); |
| 171 | } else { | 168 | } else { |
libqpdf/Pl_MD5.cc
| @@ -19,8 +19,7 @@ Pl_MD5::write(unsigned char const* buf, size_t len) | @@ -19,8 +19,7 @@ Pl_MD5::write(unsigned char const* buf, size_t len) | ||
| 19 | this->in_progress = true; | 19 | this->in_progress = true; |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | - // Write in chunks in case len is too big to fit in an int. | ||
| 23 | - // Assume int is at least 32 bits. | 22 | + // Write in chunks in case len is too big to fit in an int. Assume int is at least 32 bits. |
| 24 | static size_t const max_bytes = 1 << 30; | 23 | static size_t const max_bytes = 1 << 30; |
| 25 | size_t bytes_left = len; | 24 | size_t bytes_left = len; |
| 26 | unsigned char const* data = buf; | 25 | unsigned char const* data = buf; |
libqpdf/Pl_OStream.cc
| @@ -15,8 +15,7 @@ Pl_OStream::Pl_OStream(char const* identifier, std::ostream& os) : | @@ -15,8 +15,7 @@ Pl_OStream::Pl_OStream(char const* identifier, std::ostream& os) : | ||
| 15 | 15 | ||
| 16 | Pl_OStream::~Pl_OStream() | 16 | Pl_OStream::~Pl_OStream() |
| 17 | { | 17 | { |
| 18 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 19 | - // README-maintainer | 18 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| 20 | } | 19 | } |
| 21 | 20 | ||
| 22 | void | 21 | void |
libqpdf/Pl_PNGFilter.cc
| @@ -33,8 +33,8 @@ Pl_PNGFilter::Pl_PNGFilter( | @@ -33,8 +33,8 @@ Pl_PNGFilter::Pl_PNGFilter( | ||
| 33 | } | 33 | } |
| 34 | if (!((bits_per_sample == 1) || (bits_per_sample == 2) || (bits_per_sample == 4) || | 34 | if (!((bits_per_sample == 1) || (bits_per_sample == 2) || (bits_per_sample == 4) || |
| 35 | (bits_per_sample == 8) || (bits_per_sample == 16))) { | 35 | (bits_per_sample == 8) || (bits_per_sample == 16))) { |
| 36 | - throw std::runtime_error("PNGFilter created with invalid bits_per_sample not" | ||
| 37 | - " 1, 2, 4, 8, or 16"); | 36 | + throw std::runtime_error( |
| 37 | + "PNGFilter created with invalid bits_per_sample not 1, 2, 4, 8, or 16"); | ||
| 38 | } | 38 | } |
| 39 | this->bytes_per_pixel = ((bits_per_sample * samples_per_pixel) + 7) / 8; | 39 | this->bytes_per_pixel = ((bits_per_sample * samples_per_pixel) + 7) / 8; |
| 40 | unsigned long long bpr = ((columns * bits_per_sample * samples_per_pixel) + 7) / 8; | 40 | unsigned long long bpr = ((columns * bits_per_sample * samples_per_pixel) + 7) / 8; |
libqpdf/Pl_QPDFTokenizer.cc
| @@ -23,8 +23,7 @@ Pl_QPDFTokenizer::Pl_QPDFTokenizer( | @@ -23,8 +23,7 @@ Pl_QPDFTokenizer::Pl_QPDFTokenizer( | ||
| 23 | 23 | ||
| 24 | Pl_QPDFTokenizer::~Pl_QPDFTokenizer() | 24 | Pl_QPDFTokenizer::~Pl_QPDFTokenizer() |
| 25 | { | 25 | { |
| 26 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 27 | - // README-maintainer | 26 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| 28 | } | 27 | } |
| 29 | 28 | ||
| 30 | void | 29 | void |
libqpdf/Pl_RunLength.cc
| @@ -18,8 +18,7 @@ Pl_RunLength::Pl_RunLength(char const* identifier, Pipeline* next, action_e acti | @@ -18,8 +18,7 @@ Pl_RunLength::Pl_RunLength(char const* identifier, Pipeline* next, action_e acti | ||
| 18 | 18 | ||
| 19 | Pl_RunLength::~Pl_RunLength() | 19 | Pl_RunLength::~Pl_RunLength() |
| 20 | { | 20 | { |
| 21 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 22 | - // README-maintainer | 21 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| 23 | } | 22 | } |
| 24 | 23 | ||
| 25 | void | 24 | void |
| @@ -135,10 +134,9 @@ Pl_RunLength::flush_encode() | @@ -135,10 +134,9 @@ Pl_RunLength::flush_encode() | ||
| 135 | void | 134 | void |
| 136 | Pl_RunLength::finish() | 135 | Pl_RunLength::finish() |
| 137 | { | 136 | { |
| 138 | - // When decoding, we might have read a length byte not followed by | ||
| 139 | - // data, which means the stream was terminated early, but we will | ||
| 140 | - // just ignore this case since this is the only sensible thing to | ||
| 141 | - // do. | 137 | + // When decoding, we might have read a length byte not followed by data, which means the stream |
| 138 | + // was terminated early, but we will just ignore this case since this is the only sensible thing | ||
| 139 | + // to do. | ||
| 142 | if (m->action == a_encode) { | 140 | if (m->action == a_encode) { |
| 143 | flush_encode(); | 141 | flush_encode(); |
| 144 | unsigned char ch = 128; | 142 | unsigned char ch = 128; |
libqpdf/Pl_SHA2.cc
| @@ -20,8 +20,7 @@ Pl_SHA2::write(unsigned char const* buf, size_t len) | @@ -20,8 +20,7 @@ Pl_SHA2::write(unsigned char const* buf, size_t len) | ||
| 20 | this->in_progress = true; | 20 | this->in_progress = true; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | - // Write in chunks in case len is too big to fit in an int. | ||
| 24 | - // Assume int is at least 32 bits. | 23 | + // Write in chunks in case len is too big to fit in an int. Assume int is at least 32 bits. |
| 25 | static size_t const max_bytes = 1 << 30; | 24 | static size_t const max_bytes = 1 << 30; |
| 26 | size_t bytes_left = len; | 25 | size_t bytes_left = len; |
| 27 | unsigned char const* data = buf; | 26 | unsigned char const* data = buf; |
libqpdf/Pl_StdioFile.cc
| @@ -19,8 +19,7 @@ Pl_StdioFile::Pl_StdioFile(char const* identifier, FILE* f) : | @@ -19,8 +19,7 @@ Pl_StdioFile::Pl_StdioFile(char const* identifier, FILE* f) : | ||
| 19 | 19 | ||
| 20 | Pl_StdioFile::~Pl_StdioFile() | 20 | Pl_StdioFile::~Pl_StdioFile() |
| 21 | { | 21 | { |
| 22 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 23 | - // README-maintainer | 22 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| 24 | } | 23 | } |
| 25 | 24 | ||
| 26 | void | 25 | void |
libqpdf/Pl_String.cc
| @@ -15,8 +15,7 @@ Pl_String::Pl_String(char const* identifier, Pipeline* next, std::string& s) : | @@ -15,8 +15,7 @@ Pl_String::Pl_String(char const* identifier, Pipeline* next, std::string& s) : | ||
| 15 | 15 | ||
| 16 | Pl_String::~Pl_String() | 16 | Pl_String::~Pl_String() |
| 17 | { | 17 | { |
| 18 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 19 | - // README-maintainer | 18 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| 20 | } | 19 | } |
| 21 | 20 | ||
| 22 | void | 21 | void |
libqpdf/QPDF.cc
| @@ -106,9 +106,8 @@ namespace | @@ -106,9 +106,8 @@ namespace | ||
| 106 | throwException() | 106 | throwException() |
| 107 | { | 107 | { |
| 108 | throw std::logic_error("QPDF operation attempted on a QPDF object with no input " | 108 | throw std::logic_error("QPDF operation attempted on a QPDF object with no input " |
| 109 | - "source." | ||
| 110 | - " QPDF operations are invalid before processFile (or another" | ||
| 111 | - " process method) or after closeInputSource"); | 109 | + "source. QPDF operations are invalid before processFile (or " |
| 110 | + "another process method) or after closeInputSource"); | ||
| 112 | } | 111 | } |
| 113 | }; | 112 | }; |
| 114 | } // namespace | 113 | } // namespace |
libqpdf/QPDFAnnotationObjectHelper.cc
| @@ -54,13 +54,10 @@ QPDFAnnotationObjectHelper::getAppearanceStream(std::string const& which, std::s | @@ -54,13 +54,10 @@ QPDFAnnotationObjectHelper::getAppearanceStream(std::string const& which, std::s | ||
| 54 | if (ap.isDictionary()) { | 54 | if (ap.isDictionary()) { |
| 55 | QPDFObjectHandle ap_sub = ap.getKey(which); | 55 | QPDFObjectHandle ap_sub = ap.getKey(which); |
| 56 | if (ap_sub.isStream()) { | 56 | if (ap_sub.isStream()) { |
| 57 | - // According to the spec, Appearance State is supposed to | ||
| 58 | - // refer to a subkey of the appearance stream when /AP is | ||
| 59 | - // a dictionary, but files have been seen in the wild | ||
| 60 | - // where Appearance State is `/N` and `/AP` is a stream. | ||
| 61 | - // Therefore, if `which` points to a stream, disregard | ||
| 62 | - // state and just use the stream. See qpdf issue #949 for | ||
| 63 | - // details. | 57 | + // According to the spec, Appearance State is supposed to refer to a subkey of the |
| 58 | + // appearance stream when /AP is a dictionary, but files have been seen in the wild | ||
| 59 | + // where Appearance State is `/N` and `/AP` is a stream. Therefore, if `which` points to | ||
| 60 | + // a stream, disregard state and just use the stream. See qpdf issue #949 for details. | ||
| 64 | QTC::TC("qpdf", "QPDFAnnotationObjectHelper AP stream"); | 61 | QTC::TC("qpdf", "QPDFAnnotationObjectHelper AP stream"); |
| 65 | return ap_sub; | 62 | return ap_sub; |
| 66 | } | 63 | } |
| @@ -85,84 +82,66 @@ QPDFAnnotationObjectHelper::getPageContentForAppearance( | @@ -85,84 +82,66 @@ QPDFAnnotationObjectHelper::getPageContentForAppearance( | ||
| 85 | return ""; | 82 | return ""; |
| 86 | } | 83 | } |
| 87 | 84 | ||
| 88 | - // The appearance matrix computed by this method is the | ||
| 89 | - // transformation matrix that needs to be in effect when drawing | ||
| 90 | - // this annotation's appearance stream on the page. The algorithm | ||
| 91 | - // for computing the appearance matrix described in section 12.5.5 | ||
| 92 | - // of the ISO-32000 PDF spec is similar but not identical to what | ||
| 93 | - // we are doing here. | 85 | + // The appearance matrix computed by this method is the transformation matrix that needs to be |
| 86 | + // in effect when drawing this annotation's appearance stream on the page. The algorithm for | ||
| 87 | + // computing the appearance matrix described in section 12.5.5 of the ISO-32000 PDF spec is | ||
| 88 | + // similar but not identical to what we are doing here. | ||
| 94 | 89 | ||
| 95 | - // When rendering an appearance stream associated with an | ||
| 96 | - // annotation, there are four relevant components: | 90 | + // When rendering an appearance stream associated with an annotation, there are four relevant |
| 91 | + // components: | ||
| 97 | // | 92 | // |
| 98 | // * The appearance stream's bounding box (/BBox) | 93 | // * The appearance stream's bounding box (/BBox) |
| 99 | // * The appearance stream's matrix (/Matrix) | 94 | // * The appearance stream's matrix (/Matrix) |
| 100 | // * The annotation's rectangle (/Rect) | 95 | // * The annotation's rectangle (/Rect) |
| 101 | - // * In the case of form fields with the NoRotate flag, the | ||
| 102 | - // page's rotation | 96 | + // * In the case of form fields with the NoRotate flag, the page's rotation |
| 103 | 97 | ||
| 104 | - // When rendering a form xobject in isolation, just drawn with a | ||
| 105 | - // /Do operator, there is no form field, so page rotation is not | ||
| 106 | - // relevant, and there is no annotation, so /Rect is not relevant, | ||
| 107 | - // so only /BBox and /Matrix are relevant. The effect of these are | ||
| 108 | - // as follows: | 98 | + // When rendering a form xobject in isolation, just drawn with a /Do operator, there is no form |
| 99 | + // field, so page rotation is not relevant, and there is no annotation, so /Rect is not | ||
| 100 | + // relevant, so only /BBox and /Matrix are relevant. The effect of these are as follows: | ||
| 109 | 101 | ||
| 110 | // * /BBox is treated as a clipping region | 102 | // * /BBox is treated as a clipping region |
| 111 | - // * /Matrix is applied as a transformation prior to rendering the | ||
| 112 | - // appearance stream. | ||
| 113 | - | ||
| 114 | - // There is no relationship between /BBox and /Matrix in this | ||
| 115 | - // case. | ||
| 116 | - | ||
| 117 | - // When rendering a form xobject in the context of an annotation, | ||
| 118 | - // things are a little different. In particular, a matrix is | ||
| 119 | - // established such that /BBox, when transformed by /Matrix, would | ||
| 120 | - // fit completely inside of /Rect. /BBox is no longer a clipping | ||
| 121 | - // region. To illustrate the difference, consider a /Matrix of | ||
| 122 | - // [2 0 0 2 0 0], which is scaling by a factor of two along both | ||
| 123 | - // axes. If the appearance stream drew a rectangle equal to /BBox, | ||
| 124 | - // in the case of the form xobject in isolation, this matrix would | ||
| 125 | - // cause only the lower-left quadrant of the rectangle to be | ||
| 126 | - // visible since the scaling would cause the rest of it to fall | ||
| 127 | - // outside of the clipping region. In the case of the form xobject | ||
| 128 | - // displayed in the context of an annotation, such a matrix would | ||
| 129 | - // have no effect at all because it would be applied to the | ||
| 130 | - // bounding box first, and then when the resulting enclosing | ||
| 131 | - // quadrilateral was transformed to fit into /Rect, the effect of | ||
| 132 | - // the scaling would be undone. | ||
| 133 | - | ||
| 134 | - // Our job is to create a transformation matrix that compensates | ||
| 135 | - // for these differences so that the appearance stream of an | ||
| 136 | - // annotation can be drawn as a regular form xobject. | ||
| 137 | - | ||
| 138 | - // To do this, we perform the following steps, which overlap | ||
| 139 | - // significantly with the algorithm in 12.5.5: | ||
| 140 | - | ||
| 141 | - // 1. Transform the four corners of /BBox by applying /Matrix to | ||
| 142 | - // them, creating an arbitrarily transformed quadrilateral. | ||
| 143 | - | ||
| 144 | - // 2. Find the minimum upright rectangle that encompasses the | ||
| 145 | - // resulting quadrilateral. This is the "transformed appearance | ||
| 146 | - // box", T. | ||
| 147 | - | ||
| 148 | - // 3. Compute matrix A that maps the lower left and upper right | ||
| 149 | - // corners of T to the annotation's /Rect. This can be done by | ||
| 150 | - // scaling so that the sizes match and translating so that the | 103 | + // * /Matrix is applied as a transformation prior to rendering the appearance stream. |
| 104 | + | ||
| 105 | + // There is no relationship between /BBox and /Matrix in this case. | ||
| 106 | + | ||
| 107 | + // When rendering a form xobject in the context of an annotation, things are a little different. | ||
| 108 | + // In particular, a matrix is established such that /BBox, when transformed by /Matrix, would | ||
| 109 | + // fit completely inside of /Rect. /BBox is no longer a clipping region. To illustrate the | ||
| 110 | + // difference, consider a /Matrix of [2 0 0 2 0 0], which is scaling by a factor of two along | ||
| 111 | + // both axes. If the appearance stream drew a rectangle equal to /BBox, in the case of the form | ||
| 112 | + // xobject in isolation, this matrix would cause only the lower-left quadrant of the rectangle | ||
| 113 | + // to be visible since the scaling would cause the rest of it to fall outside of the clipping | ||
| 114 | + // region. In the case of the form xobject displayed in the context of an annotation, such a | ||
| 115 | + // matrix would have no effect at all because it would be applied to the bounding box first, and | ||
| 116 | + // then when the resulting enclosing quadrilateral was transformed to fit into /Rect, the effect | ||
| 117 | + // of the scaling would be undone. | ||
| 118 | + | ||
| 119 | + // Our job is to create a transformation matrix that compensates for these differences so that | ||
| 120 | + // the appearance stream of an annotation can be drawn as a regular form xobject. | ||
| 121 | + | ||
| 122 | + // To do this, we perform the following steps, which overlap significantly with the algorithm | ||
| 123 | + // in 12.5.5: | ||
| 124 | + | ||
| 125 | + // 1. Transform the four corners of /BBox by applying /Matrix to them, creating an arbitrarily | ||
| 126 | + // transformed quadrilateral. | ||
| 127 | + | ||
| 128 | + // 2. Find the minimum upright rectangle that encompasses the resulting quadrilateral. This is | ||
| 129 | + // the "transformed appearance box", T. | ||
| 130 | + | ||
| 131 | + // 3. Compute matrix A that maps the lower left and upper right corners of T to the annotation's | ||
| 132 | + // /Rect. This can be done by scaling so that the sizes match and translating so that the | ||
| 151 | // scaled T exactly overlaps /Rect. | 133 | // scaled T exactly overlaps /Rect. |
| 152 | 134 | ||
| 153 | - // If the annotation's /F flag has bit 4 set, this means that | ||
| 154 | - // annotation is to be rotated about its upper left corner to | ||
| 155 | - // counteract any rotation of the page so it remains upright. To | 135 | + // If the annotation's /F flag has bit 4 set, this means that annotation is to be rotated about |
| 136 | + // its upper left corner to counteract any rotation of the page so it remains upright. To | ||
| 156 | // achieve this effect, we do the following extra steps: | 137 | // achieve this effect, we do the following extra steps: |
| 157 | 138 | ||
| 158 | - // 1. Perform the rotation on /BBox box prior to transforming it | ||
| 159 | - // with /Matrix (by replacing matrix with concatenation of | ||
| 160 | - // matrix onto the rotation) | 139 | + // 1. Perform the rotation on /BBox box prior to transforming it with /Matrix (by replacing |
| 140 | + // matrix with concatenation of matrix onto the rotation) | ||
| 161 | 141 | ||
| 162 | // 2. Rotate the destination rectangle by the specified amount | 142 | // 2. Rotate the destination rectangle by the specified amount |
| 163 | 143 | ||
| 164 | - // 3. Apply the rotation to A as computed above to get the final | ||
| 165 | - // appearance matrix. | 144 | + // 3. Apply the rotation to A as computed above to get the final appearance matrix. |
| 166 | 145 | ||
| 167 | QPDFObjectHandle rect_obj = this->oh.getKey("/Rect"); | 146 | QPDFObjectHandle rect_obj = this->oh.getKey("/Rect"); |
| 168 | QPDFObjectHandle as = getAppearanceStream("/N").getDict(); | 147 | QPDFObjectHandle as = getAppearanceStream("/N").getDict(); |
| @@ -192,14 +171,12 @@ QPDFAnnotationObjectHelper::getPageContentForAppearance( | @@ -192,14 +171,12 @@ QPDFAnnotationObjectHelper::getPageContentForAppearance( | ||
| 192 | QPDFObjectHandle::Rectangle rect = rect_obj.getArrayAsRectangle(); | 171 | QPDFObjectHandle::Rectangle rect = rect_obj.getArrayAsRectangle(); |
| 193 | bool do_rotate = (rotate && (flags & an_no_rotate)); | 172 | bool do_rotate = (rotate && (flags & an_no_rotate)); |
| 194 | if (do_rotate) { | 173 | if (do_rotate) { |
| 195 | - // If the the annotation flags include the NoRotate bit and | ||
| 196 | - // the page is rotated, we have to rotate the annotation about | ||
| 197 | - // its upper left corner by the same amount in the opposite | ||
| 198 | - // direction so that it will remain upright in absolute | ||
| 199 | - // coordinates. Since the semantics of /Rotate for a page are | ||
| 200 | - // to rotate the page, while the effect of rotating using a | ||
| 201 | - // transformation matrix is to rotate the coordinate system, | ||
| 202 | - // the opposite directionality is explicit in the code. | 174 | + // If the the annotation flags include the NoRotate bit and the page is rotated, we have to |
| 175 | + // rotate the annotation about its upper left corner by the same amount in the opposite | ||
| 176 | + // direction so that it will remain upright in absolute coordinates. Since the semantics of | ||
| 177 | + // /Rotate for a page are to rotate the page, while the effect of rotating using a | ||
| 178 | + // transformation matrix is to rotate the coordinate system, the opposite directionality is | ||
| 179 | + // explicit in the code. | ||
| 203 | QPDFMatrix mr; | 180 | QPDFMatrix mr; |
| 204 | mr.rotatex90(rotate); | 181 | mr.rotatex90(rotate); |
| 205 | mr.concat(matrix); | 182 | mr.concat(matrix); |
libqpdf/QPDFArgParser.cc
| @@ -139,8 +139,8 @@ QPDFArgParser::addInvalidChoiceHandler(std::string const& arg, param_arg_handler | @@ -139,8 +139,8 @@ QPDFArgParser::addInvalidChoiceHandler(std::string const& arg, param_arg_handler | ||
| 139 | auto i = m->option_table->find(arg); | 139 | auto i = m->option_table->find(arg); |
| 140 | if (i == m->option_table->end()) { | 140 | if (i == m->option_table->end()) { |
| 141 | QTC::TC("libtests", "QPDFArgParser invalid choice handler to unknown"); | 141 | QTC::TC("libtests", "QPDFArgParser invalid choice handler to unknown"); |
| 142 | - throw std::logic_error("QPDFArgParser: attempt to add invalid choice handler" | ||
| 143 | - " to unknown argument"); | 142 | + throw std::logic_error( |
| 143 | + "QPDFArgParser: attempt to add invalid choice handler to unknown argument"); | ||
| 144 | } | 144 | } |
| 145 | auto& oe = i->second; | 145 | auto& oe = i->second; |
| 146 | oe.invalid_choice_handler = handler; | 146 | oe.invalid_choice_handler = handler; |
| @@ -231,9 +231,9 @@ QPDFArgParser::invalidHelpArg(std::string const& p) | @@ -231,9 +231,9 @@ QPDFArgParser::invalidHelpArg(std::string const& p) | ||
| 231 | void | 231 | void |
| 232 | QPDFArgParser::handleArgFileArguments() | 232 | QPDFArgParser::handleArgFileArguments() |
| 233 | { | 233 | { |
| 234 | - // Support reading arguments from files. Create a new argv. Ensure | ||
| 235 | - // that argv itself as well as all its contents are automatically | ||
| 236 | - // deleted by using shared pointers to back the pointers in argv. | 234 | + // Support reading arguments from files. Create a new argv. Ensure that argv itself as well as |
| 235 | + // all its contents are automatically deleted by using shared pointers to back the pointers in | ||
| 236 | + // argv. | ||
| 237 | m->new_argv.push_back(QUtil::make_shared_cstr(m->argv[0])); | 237 | m->new_argv.push_back(QUtil::make_shared_cstr(m->argv[0])); |
| 238 | for (int i = 1; i < m->argc; ++i) { | 238 | for (int i = 1; i < m->argc; ++i) { |
| 239 | char const* argfile = nullptr; | 239 | char const* argfile = nullptr; |
| @@ -264,12 +264,10 @@ QPDFArgParser::handleArgFileArguments() | @@ -264,12 +264,10 @@ QPDFArgParser::handleArgFileArguments() | ||
| 264 | void | 264 | void |
| 265 | QPDFArgParser::handleBashArguments() | 265 | QPDFArgParser::handleBashArguments() |
| 266 | { | 266 | { |
| 267 | - // Do a minimal job of parsing bash_line into arguments. This | ||
| 268 | - // doesn't do everything the shell does (e.g. $(...), variable | ||
| 269 | - // expansion, arithmetic, globs, etc.), but it should be good | ||
| 270 | - // enough for purposes of handling completion. As we build up the | ||
| 271 | - // new argv, we can't use m->new_argv because this code has to | ||
| 272 | - // interoperate with @file arguments, so memory for both ways of | 267 | + // Do a minimal job of parsing bash_line into arguments. This doesn't do everything the shell |
| 268 | + // does (e.g. $(...), variable expansion, arithmetic, globs, etc.), but it should be good enough | ||
| 269 | + // for purposes of handling completion. As we build up the new argv, we can't use m->new_argv | ||
| 270 | + // because this code has to interoperate with @file arguments, so memory for both ways of | ||
| 273 | // fabricating argv has to be protected. | 271 | // fabricating argv has to be protected. |
| 274 | 272 | ||
| 275 | bool last_was_backslash = false; | 273 | bool last_was_backslash = false; |
| @@ -321,12 +319,11 @@ QPDFArgParser::handleBashArguments() | @@ -321,12 +319,11 @@ QPDFArgParser::handleBashArguments() | ||
| 321 | } | 319 | } |
| 322 | } | 320 | } |
| 323 | if (m->bash_argv.empty()) { | 321 | if (m->bash_argv.empty()) { |
| 324 | - // This can't happen if properly invoked by bash, but ensure | ||
| 325 | - // we have a valid argv[0] regardless. | 322 | + // This can't happen if properly invoked by bash, but ensure we have a valid argv[0] |
| 323 | + // regardless. | ||
| 326 | m->bash_argv.push_back(QUtil::make_shared_cstr(m->argv[0])); | 324 | m->bash_argv.push_back(QUtil::make_shared_cstr(m->argv[0])); |
| 327 | } | 325 | } |
| 328 | - // Explicitly discard any non-space-terminated word. The "current | ||
| 329 | - // word" is handled specially. | 326 | + // Explicitly discard any non-space-terminated word. The "current word" is handled specially. |
| 330 | m->bash_argv_ph = QUtil::make_shared_array<char const*>(1 + m->bash_argv.size()); | 327 | m->bash_argv_ph = QUtil::make_shared_array<char const*>(1 + m->bash_argv.size()); |
| 331 | for (size_t i = 0; i < m->bash_argv.size(); ++i) { | 328 | for (size_t i = 0; i < m->bash_argv.size(); ++i) { |
| 332 | m->bash_argv_ph.get()[i] = m->bash_argv.at(i).get(); | 329 | m->bash_argv_ph.get()[i] = m->bash_argv.at(i).get(); |
| @@ -367,12 +364,10 @@ QPDFArgParser::checkCompletion() | @@ -367,12 +364,10 @@ QPDFArgParser::checkCompletion() | ||
| 367 | { | 364 | { |
| 368 | // See if we're being invoked from bash completion. | 365 | // See if we're being invoked from bash completion. |
| 369 | std::string bash_point_env; | 366 | std::string bash_point_env; |
| 370 | - // On Windows with mingw, there have been times when there appears | ||
| 371 | - // to be no way to distinguish between an empty environment | ||
| 372 | - // variable and an unset variable. There are also conditions under | ||
| 373 | - // which bash doesn't set COMP_LINE. Therefore, enter this logic | ||
| 374 | - // if either COMP_LINE or COMP_POINT are set. They will both be | ||
| 375 | - // set together under ordinary circumstances. | 367 | + // On Windows with mingw, there have been times when there appears to be no way to distinguish |
| 368 | + // between an empty environment variable and an unset variable. There are also conditions under | ||
| 369 | + // which bash doesn't set COMP_LINE. Therefore, enter this logic if either COMP_LINE or | ||
| 370 | + // COMP_POINT are set. They will both be set together under ordinary circumstances. | ||
| 376 | bool got_line = QUtil::get_env("COMP_LINE", &m->bash_line); | 371 | bool got_line = QUtil::get_env("COMP_LINE", &m->bash_line); |
| 377 | bool got_point = QUtil::get_env("COMP_POINT", &bash_point_env); | 372 | bool got_point = QUtil::get_env("COMP_POINT", &bash_point_env); |
| 378 | if (got_line || got_point) { | 373 | if (got_line || got_point) { |
| @@ -385,15 +380,12 @@ QPDFArgParser::checkCompletion() | @@ -385,15 +380,12 @@ QPDFArgParser::checkCompletion() | ||
| 385 | if (p > m->bash_line.length()) { | 380 | if (p > m->bash_line.length()) { |
| 386 | p = m->bash_line.length(); | 381 | p = m->bash_line.length(); |
| 387 | } | 382 | } |
| 388 | - // Set bash_cur and bash_prev based on bash_line rather than | ||
| 389 | - // relying on argv. This enables us to use bashcompinit to get | ||
| 390 | - // completion in zsh too since bashcompinit sets COMP_LINE and | ||
| 391 | - // COMP_POINT but doesn't invoke the command with options like | ||
| 392 | - // bash does. | ||
| 393 | - | ||
| 394 | - // p is equal to length of the string. Walk backwards looking | ||
| 395 | - // for the first separator. bash_cur is everything after the | ||
| 396 | - // last separator, possibly empty. | 383 | + // Set bash_cur and bash_prev based on bash_line rather than relying on argv. This enables |
| 384 | + // us to use bashcompinit to get completion in zsh too since bashcompinit sets COMP_LINE and | ||
| 385 | + // COMP_POINT but doesn't invoke the command with options like bash does. | ||
| 386 | + | ||
| 387 | + // p is equal to length of the string. Walk backwards looking for the first separator. | ||
| 388 | + // bash_cur is everything after the last separator, possibly empty. | ||
| 397 | char sep(0); | 389 | char sep(0); |
| 398 | while (p > 0) { | 390 | while (p > 0) { |
| 399 | --p; | 391 | --p; |
| @@ -407,10 +399,9 @@ QPDFArgParser::checkCompletion() | @@ -407,10 +399,9 @@ QPDFArgParser::checkCompletion() | ||
| 407 | m->bash_cur = m->bash_line.substr(1 + p, std::string::npos); | 399 | m->bash_cur = m->bash_line.substr(1 + p, std::string::npos); |
| 408 | } | 400 | } |
| 409 | if ((sep == ':') || (sep == '=')) { | 401 | if ((sep == ':') || (sep == '=')) { |
| 410 | - // Bash sets prev to the non-space separator if any. | ||
| 411 | - // Actually, if there are multiple separators in a row, | ||
| 412 | - // they are all included in prev, but that detail is not | ||
| 413 | - // important to us and not worth coding. | 402 | + // Bash sets prev to the non-space separator if any. Actually, if there are multiple |
| 403 | + // separators in a row, they are all included in prev, but that detail is not important | ||
| 404 | + // to us and not worth coding. | ||
| 414 | m->bash_prev = m->bash_line.substr(p, 1); | 405 | m->bash_prev = m->bash_line.substr(p, 1); |
| 415 | } else { | 406 | } else { |
| 416 | // Go back to the last separator and set prev based on | 407 | // Go back to the last separator and set prev based on |
| @@ -429,8 +420,8 @@ QPDFArgParser::checkCompletion() | @@ -429,8 +420,8 @@ QPDFArgParser::checkCompletion() | ||
| 429 | m->bash_prev = m->bash_line.substr(0, p); | 420 | m->bash_prev = m->bash_line.substr(0, p); |
| 430 | } | 421 | } |
| 431 | if (m->argc == 1) { | 422 | if (m->argc == 1) { |
| 432 | - // This is probably zsh using bashcompinit. There are a | ||
| 433 | - // few differences in the expected output. | 423 | + // This is probably zsh using bashcompinit. There are a few differences in the expected |
| 424 | + // output. | ||
| 434 | m->zsh_completion = true; | 425 | m->zsh_completion = true; |
| 435 | } | 426 | } |
| 436 | handleBashArguments(); | 427 | handleBashArguments(); |
| @@ -454,8 +445,7 @@ QPDFArgParser::parseArgs() | @@ -454,8 +445,7 @@ QPDFArgParser::parseArgs() | ||
| 454 | std::string o_arg(arg); | 445 | std::string o_arg(arg); |
| 455 | std::string arg_s(arg); | 446 | std::string arg_s(arg); |
| 456 | if (strcmp(arg, "--") == 0) { | 447 | if (strcmp(arg, "--") == 0) { |
| 457 | - // Special case for -- option, which is used to break out | ||
| 458 | - // of subparsers. | 448 | + // Special case for -- option, which is used to break out of subparsers. |
| 459 | oep = m->option_table->find("--"); | 449 | oep = m->option_table->find("--"); |
| 460 | end_option = true; | 450 | end_option = true; |
| 461 | if (oep == m->option_table->end()) { | 451 | if (oep == m->option_table->end()) { |
| @@ -471,11 +461,9 @@ QPDFArgParser::parseArgs() | @@ -471,11 +461,9 @@ QPDFArgParser::parseArgs() | ||
| 471 | QTC::TC("libtests", "QPDFArgParser single dash"); | 461 | QTC::TC("libtests", "QPDFArgParser single dash"); |
| 472 | } | 462 | } |
| 473 | 463 | ||
| 474 | - // Prevent --=something from being treated as an empty arg | ||
| 475 | - // by searching for = from after the first character. We | ||
| 476 | - // do this since the empty string in the option table is | ||
| 477 | - // for positional arguments. Besides, it doesn't make | ||
| 478 | - // sense to have an empty option. | 464 | + // Prevent --=something from being treated as an empty arg by searching for = from after |
| 465 | + // the first character. We do this since the empty string in the option table is for | ||
| 466 | + // positional arguments. Besides, it doesn't make sense to have an empty option. | ||
| 479 | arg_s = arg; | 467 | arg_s = arg; |
| 480 | size_t equal_pos = std::string::npos; | 468 | size_t equal_pos = std::string::npos; |
| 481 | if (arg_s.length() > 0) { | 469 | if (arg_s.length() > 0) { |
| @@ -489,8 +477,7 @@ QPDFArgParser::parseArgs() | @@ -489,8 +477,7 @@ QPDFArgParser::parseArgs() | ||
| 489 | 477 | ||
| 490 | if ((!m->bash_completion) && (m->argc == 2) && (m->cur_arg == 1) && | 478 | if ((!m->bash_completion) && (m->argc == 2) && (m->cur_arg == 1) && |
| 491 | m->help_option_table.count(arg_s)) { | 479 | m->help_option_table.count(arg_s)) { |
| 492 | - // Handle help option, which is only valid as the sole | ||
| 493 | - // option. | 480 | + // Handle help option, which is only valid as the sole option. |
| 494 | QTC::TC("libtests", "QPDFArgParser help option"); | 481 | QTC::TC("libtests", "QPDFArgParser help option"); |
| 495 | oep = m->help_option_table.find(arg_s); | 482 | oep = m->help_option_table.find(arg_s); |
| 496 | help_option = true; | 483 | help_option = true; |
| @@ -500,8 +487,7 @@ QPDFArgParser::parseArgs() | @@ -500,8 +487,7 @@ QPDFArgParser::parseArgs() | ||
| 500 | oep = m->option_table->find(arg_s); | 487 | oep = m->option_table->find(arg_s); |
| 501 | } | 488 | } |
| 502 | } else { | 489 | } else { |
| 503 | - // The empty string maps to the positional argument | ||
| 504 | - // handler. | 490 | + // The empty string maps to the positional argument handler. |
| 505 | QTC::TC("libtests", "QPDFArgParser positional"); | 491 | QTC::TC("libtests", "QPDFArgParser positional"); |
| 506 | oep = m->option_table->find(""); | 492 | oep = m->option_table->find(""); |
| 507 | parameter = arg; | 493 | parameter = arg; |
| @@ -522,8 +508,7 @@ QPDFArgParser::parseArgs() | @@ -522,8 +508,7 @@ QPDFArgParser::parseArgs() | ||
| 522 | std::string message = "--" + arg_s + " must be given as --" + arg_s + "="; | 508 | std::string message = "--" + arg_s + " must be given as --" + arg_s + "="; |
| 523 | if (oe.invalid_choice_handler) { | 509 | if (oe.invalid_choice_handler) { |
| 524 | oe.invalid_choice_handler(parameter); | 510 | oe.invalid_choice_handler(parameter); |
| 525 | - // Method should call usage() or exit. Just in case it | ||
| 526 | - // doesn't... | 511 | + // Method should call usage() or exit. Just in case it doesn't... |
| 527 | message += "option"; | 512 | message += "option"; |
| 528 | } else if (!oe.choices.empty()) { | 513 | } else if (!oe.choices.empty()) { |
| 529 | QTC::TC("libtests", "QPDFArgParser required choices"); | 514 | QTC::TC("libtests", "QPDFArgParser required choices"); |
| @@ -609,8 +594,8 @@ QPDFArgParser::addOptionsToCompletions(option_table_t& option_table) | @@ -609,8 +594,8 @@ QPDFArgParser::addOptionsToCompletions(option_table_t& option_table) | ||
| 609 | std::string base = "--" + arg; | 594 | std::string base = "--" + arg; |
| 610 | if (oe.param_arg_handler) { | 595 | if (oe.param_arg_handler) { |
| 611 | if (m->zsh_completion) { | 596 | if (m->zsh_completion) { |
| 612 | - // zsh doesn't treat = as a word separator, so add all | ||
| 613 | - // the options so we don't get a space after the =. | 597 | + // zsh doesn't treat = as a word separator, so add all the options so we don't get a |
| 598 | + // space after the =. | ||
| 614 | addChoicesToCompletions(option_table, arg, base + "="); | 599 | addChoicesToCompletions(option_table, arg, base + "="); |
| 615 | } | 600 | } |
| 616 | m->completions.insert(base + "="); | 601 | m->completions.insert(base + "="); |
libqpdf/QPDFCryptoProvider.cc
| @@ -92,8 +92,7 @@ QPDFCryptoProvider::setDefaultProvider_internal(std::string const& name) | @@ -92,8 +92,7 @@ QPDFCryptoProvider::setDefaultProvider_internal(std::string const& name) | ||
| 92 | { | 92 | { |
| 93 | if (!m->providers.count(name)) { | 93 | if (!m->providers.count(name)) { |
| 94 | throw std::logic_error( | 94 | throw std::logic_error( |
| 95 | - "QPDFCryptoProvider: request to set default" | ||
| 96 | - " provider to unknown implementation \"" + | 95 | + "QPDFCryptoProvider: request to set default provider to unknown implementation \"" + |
| 97 | name + "\""); | 96 | name + "\""); |
| 98 | } | 97 | } |
| 99 | m->default_provider = name; | 98 | m->default_provider = name; |
libqpdf/QPDFCrypto_gnutls.cc
| @@ -233,9 +233,8 @@ QPDFCrypto_gnutls::rijndael_process(unsigned char* in_data, unsigned char* out_d | @@ -233,9 +233,8 @@ QPDFCrypto_gnutls::rijndael_process(unsigned char* in_data, unsigned char* out_d | ||
| 233 | this->cipher_ctx, in_data, rijndael_buf_size, out_data, rijndael_buf_size); | 233 | this->cipher_ctx, in_data, rijndael_buf_size, out_data, rijndael_buf_size); |
| 234 | } | 234 | } |
| 235 | 235 | ||
| 236 | - // Gnutls doesn't support AES in ECB (non-CBC) mode, but the | ||
| 237 | - // result is the same as if you just reset the cbc block to all | ||
| 238 | - // zeroes each time. We jump through a few hoops here to make this | 236 | + // Gnutls doesn't support AES in ECB (non-CBC) mode, but the result is the same as if you just |
| 237 | + // reset the cbc block to all zeroes each time. We jump through a few hoops here to make this | ||
| 239 | // work. | 238 | // work. |
| 240 | if (!this->cbc_mode) { | 239 | if (!this->cbc_mode) { |
| 241 | static unsigned char zeroes[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | 240 | static unsigned char zeroes[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; |
libqpdf/QPDFCrypto_openssl.cc
| @@ -83,8 +83,8 @@ static void | @@ -83,8 +83,8 @@ static void | ||
| 83 | check_openssl(int status) | 83 | check_openssl(int status) |
| 84 | { | 84 | { |
| 85 | if (status != 1) { | 85 | if (status != 1) { |
| 86 | - // OpenSSL creates a "queue" of errors; copy the first (innermost) | ||
| 87 | - // error to the exception message. | 86 | + // OpenSSL creates a "queue" of errors; copy the first (innermost) error to the exception |
| 87 | + // message. | ||
| 88 | char buf[256] = ""; | 88 | char buf[256] = ""; |
| 89 | ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); | 89 | ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); |
| 90 | std::string what = "OpenSSL error: "; | 90 | std::string what = "OpenSSL error: "; |
libqpdf/QPDFDocumentHelper.cc
| @@ -2,6 +2,5 @@ | @@ -2,6 +2,5 @@ | ||
| 2 | 2 | ||
| 3 | QPDFDocumentHelper::~QPDFDocumentHelper() | 3 | QPDFDocumentHelper::~QPDFDocumentHelper() |
| 4 | { | 4 | { |
| 5 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 6 | - // README-maintainer | 5 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| 7 | } | 6 | } |
libqpdf/QPDFEFStreamObjectHelper.cc
| @@ -134,8 +134,8 @@ QPDFEFStreamObjectHelper::newFromStream(QPDFObjectHandle stream) | @@ -134,8 +134,8 @@ QPDFEFStreamObjectHelper::newFromStream(QPDFObjectHandle stream) | ||
| 134 | QPDFEFStreamObjectHelper result(stream); | 134 | QPDFEFStreamObjectHelper result(stream); |
| 135 | stream.getDict().replaceKey("/Type", QPDFObjectHandle::newName("/EmbeddedFile")); | 135 | stream.getDict().replaceKey("/Type", QPDFObjectHandle::newName("/EmbeddedFile")); |
| 136 | Pl_Discard discard; | 136 | Pl_Discard discard; |
| 137 | - // The PDF spec specifies use of MD5 here and notes that it is not | ||
| 138 | - // to be used for security. MD5 is known to be insecure. | 137 | + // The PDF spec specifies use of MD5 here and notes that it is not to be used for security. MD5 |
| 138 | + // is known to be insecure. | ||
| 139 | Pl_MD5 md5("EF md5", &discard); | 139 | Pl_MD5 md5("EF md5", &discard); |
| 140 | Pl_Count count("EF size", &md5); | 140 | Pl_Count count("EF size", &md5); |
| 141 | if (!stream.pipeStreamData(&count, nullptr, 0, qpdf_dl_all)) { | 141 | if (!stream.pipeStreamData(&count, nullptr, 0, qpdf_dl_all)) { |
libqpdf/QPDFEmbeddedFileDocumentHelper.cc
| 1 | #include <qpdf/QPDFEmbeddedFileDocumentHelper.hh> | 1 | #include <qpdf/QPDFEmbeddedFileDocumentHelper.hh> |
| 2 | 2 | ||
| 3 | -// File attachments are stored in the /EmbeddedFiles (name tree) key | ||
| 4 | -// of the /Names dictionary from the document catalog. Each entry | ||
| 5 | -// points to a /FileSpec, which in turn points to one more Embedded | ||
| 6 | -// File Streams. Note that file specs can appear in other places as | ||
| 7 | -// well, such as file attachment annotations, among others. | 3 | +// File attachments are stored in the /EmbeddedFiles (name tree) key of the /Names dictionary from |
| 4 | +// the document catalog. Each entry points to a /FileSpec, which in turn points to one more Embedded | ||
| 5 | +// File Streams. Note that file specs can appear in other places as well, such as file attachment | ||
| 6 | +// annotations, among others. | ||
| 8 | // | 7 | // |
| 9 | // root -> /Names -> /EmbeddedFiles = name tree | 8 | // root -> /Names -> /EmbeddedFiles = name tree |
| 10 | // filename -> filespec | 9 | // filename -> filespec |
libqpdf/QPDFJob_argv.cc
| @@ -65,9 +65,9 @@ ArgParser::initOptionTables() | @@ -65,9 +65,9 @@ ArgParser::initOptionTables() | ||
| 65 | this->ap.addFinalCheck([this]() { c_main->checkConfiguration(); }); | 65 | this->ap.addFinalCheck([this]() { c_main->checkConfiguration(); }); |
| 66 | // add_help is defined in auto_job_help.hh | 66 | // add_help is defined in auto_job_help.hh |
| 67 | add_help(this->ap); | 67 | add_help(this->ap); |
| 68 | - // Special case: ignore -- at the top level. This undocumented | ||
| 69 | - // behavior is for backward compatibility; it was unintentionally | ||
| 70 | - // the case prior to 10.6, and some users were relying on it. | 68 | + // Special case: ignore -- at the top level. This undocumented behavior is for backward |
| 69 | + // compatibility; it was unintentionally the case prior to 10.6, and some users were relying on | ||
| 70 | + // it. | ||
| 71 | this->ap.selectMainOptionTable(); | 71 | this->ap.selectMainOptionTable(); |
| 72 | this->ap.addBare("--", []() {}); | 72 | this->ap.addBare("--", []() {}); |
| 73 | } | 73 | } |
| @@ -254,8 +254,7 @@ ArgParser::argPagesPositional(std::string const& arg) | @@ -254,8 +254,7 @@ ArgParser::argPagesPositional(std::string const& arg) | ||
| 254 | range_p = this->accumulated_args.at(1).c_str(); | 254 | range_p = this->accumulated_args.at(1).c_str(); |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | - // See if the user omitted the range entirely, in which case we | ||
| 258 | - // assume "1-z". | 257 | + // See if the user omitted the range entirely, in which case we assume "1-z". |
| 259 | std::string next_file; | 258 | std::string next_file; |
| 260 | if (range_p == nullptr) { | 259 | if (range_p == nullptr) { |
| 261 | if (arg.empty()) { | 260 | if (arg.empty()) { |
libqpdf/QPDFJob_config.cc
| @@ -25,18 +25,14 @@ QPDFJob::Config* | @@ -25,18 +25,14 @@ QPDFJob::Config* | ||
| 25 | QPDFJob::Config::emptyInput() | 25 | QPDFJob::Config::emptyInput() |
| 26 | { | 26 | { |
| 27 | if (o.m->infilename == nullptr) { | 27 | if (o.m->infilename == nullptr) { |
| 28 | - // Various places in QPDFJob.cc know that the empty string for | ||
| 29 | - // infile means empty. We set it to something other than a | ||
| 30 | - // null pointer as an indication that some input source has | ||
| 31 | - // been specified. This approach means that passing "" as | ||
| 32 | - // the argument to inputFile in job JSON, or equivalently | ||
| 33 | - // using "" as a positional command-line argument would be the | ||
| 34 | - // same as --empty. This probably isn't worth blocking or | ||
| 35 | - // coding around. | 28 | + // Various places in QPDFJob.cc know that the empty string for infile means empty. We set it |
| 29 | + // to something other than a null pointer as an indication that some input source has been | ||
| 30 | + // specified. This approach means that passing "" as the argument to inputFile in job JSON, | ||
| 31 | + // or equivalently using "" as a positional command-line argument would be the same as | ||
| 32 | + // --empty. This probably isn't worth blocking or coding around. | ||
| 36 | o.m->infilename = QUtil::make_shared_cstr(""); | 33 | o.m->infilename = QUtil::make_shared_cstr(""); |
| 37 | } else { | 34 | } else { |
| 38 | - usage("empty input can't be used" | ||
| 39 | - " since input file has already been given"); | 35 | + usage("empty input can't be used since input file has already been given"); |
| 40 | } | 36 | } |
| 41 | return this; | 37 | return this; |
| 42 | } | 38 | } |
| @@ -58,8 +54,7 @@ QPDFJob::Config::replaceInput() | @@ -58,8 +54,7 @@ QPDFJob::Config::replaceInput() | ||
| 58 | if ((o.m->outfilename == nullptr) && (!o.m->replace_input)) { | 54 | if ((o.m->outfilename == nullptr) && (!o.m->replace_input)) { |
| 59 | o.m->replace_input = true; | 55 | o.m->replace_input = true; |
| 60 | } else { | 56 | } else { |
| 61 | - usage("replace-input can't be used" | ||
| 62 | - " since output file has already been given"); | 57 | + usage("replace-input can't be used since output file has already been given"); |
| 63 | } | 58 | } |
| 64 | return this; | 59 | return this; |
| 65 | } | 60 | } |
| @@ -298,8 +293,7 @@ QPDFJob::Config::jsonOutput(std::string const& parameter) | @@ -298,8 +293,7 @@ QPDFJob::Config::jsonOutput(std::string const& parameter) | ||
| 298 | o.m->json_output = true; | 293 | o.m->json_output = true; |
| 299 | json(parameter); | 294 | json(parameter); |
| 300 | if (!o.m->json_stream_data_set) { | 295 | if (!o.m->json_stream_data_set) { |
| 301 | - // No need to set json_stream_data_set -- that indicates | ||
| 302 | - // explicit use of --json-stream-data. | 296 | + // No need to set json_stream_data_set -- that indicates explicit use of --json-stream-data. |
| 303 | o.m->json_stream_data = qpdf_sj_inline; | 297 | o.m->json_stream_data = qpdf_sj_inline; |
| 304 | } | 298 | } |
| 305 | if (!o.m->decode_level_set) { | 299 | if (!o.m->decode_level_set) { |
libqpdf/QPDFJob_json.cc
| @@ -30,27 +30,20 @@ namespace | @@ -30,27 +30,20 @@ namespace | ||
| 30 | typedef std::function<void(char const*)> param_handler_t; | 30 | typedef std::function<void(char const*)> param_handler_t; |
| 31 | typedef std::function<void(JSON)> json_handler_t; | 31 | typedef std::function<void(JSON)> json_handler_t; |
| 32 | 32 | ||
| 33 | - // The code that calls these methods is automatically | ||
| 34 | - // generated by generate_auto_job. This describes how we | ||
| 35 | - // implement what it does. We keep a stack of handlers in | ||
| 36 | - // json_handlers. The top of the stack is the "current" json | ||
| 37 | - // handler, intially for the top-level object. Whenever we | ||
| 38 | - // encounter a scalar, we add a handler using addBare, | ||
| 39 | - // addParameter, or addChoices. Whenever we encounter a | ||
| 40 | - // dictionary, we first add the dictionary handlers. Then we | ||
| 41 | - // walk into the dictionary and, for each key, we register a | ||
| 42 | - // dict key handler and push it to the stack, then do the same | ||
| 43 | - // process for the key's value. Then we pop the key handler | ||
| 44 | - // off the stack. When we encounter an array, we add the array | ||
| 45 | - // handlers, push an item handler to the stack, call | ||
| 46 | - // recursively for the array's single item (as this is what is | ||
| 47 | - // expected in a schema), and pop the item handler. Note that | ||
| 48 | - // we don't pop dictionary start/end handlers. The dictionary | ||
| 49 | - // handlers and the key handlers are at the same level in | ||
| 50 | - // JSONHandler. This logic is subtle and took several tries to | ||
| 51 | - // get right. It's best understood by carefully understanding | ||
| 52 | - // the behavior of JSONHandler, the JSON schema, and the code | ||
| 53 | - // in generate_auto_job. | 33 | + // The code that calls these methods is automatically generated by generate_auto_job. This |
| 34 | + // describes how we implement what it does. We keep a stack of handlers in json_handlers. | ||
| 35 | + // The top of the stack is the "current" json handler, intially for the top-level object. | ||
| 36 | + // Whenever we encounter a scalar, we add a handler using addBare, addParameter, or | ||
| 37 | + // addChoices. Whenever we encounter a dictionary, we first add the dictionary handlers. | ||
| 38 | + // Then we walk into the dictionary and, for each key, we register a dict key handler and | ||
| 39 | + // push it to the stack, then do the same process for the key's value. Then we pop the key | ||
| 40 | + // handler off the stack. When we encounter an array, we add the array handlers, push an | ||
| 41 | + // item handler to the stack, call recursively for the array's single item (as this is what | ||
| 42 | + // is expected in a schema), and pop the item handler. Note that we don't pop dictionary | ||
| 43 | + // start/end handlers. The dictionary handlers and the key handlers are at the same level in | ||
| 44 | + // JSONHandler. This logic is subtle and took several tries to get right. It's best | ||
| 45 | + // understood by carefully understanding the behavior of JSONHandler, the JSON schema, and | ||
| 46 | + // the code in generate_auto_job. | ||
| 54 | 47 | ||
| 55 | void addBare(bare_handler_t); | 48 | void addBare(bare_handler_t); |
| 56 | void addParameter(param_handler_t); | 49 | void addParameter(param_handler_t); |
| @@ -261,9 +254,8 @@ Handlers::setupReplaceInput() | @@ -261,9 +254,8 @@ Handlers::setupReplaceInput() | ||
| 261 | void | 254 | void |
| 262 | Handlers::beginEncrypt(JSON j) | 255 | Handlers::beginEncrypt(JSON j) |
| 263 | { | 256 | { |
| 264 | - // This method is only called if the overall JSON structure | ||
| 265 | - // matches the schema, so we already know that keys that are | ||
| 266 | - // present have the right types. | 257 | + // This method is only called if the overall JSON structure matches the schema, so we already |
| 258 | + // know that keys that are present have the right types. | ||
| 267 | int key_len = 0; | 259 | int key_len = 0; |
| 268 | std::string user_password; | 260 | std::string user_password; |
| 269 | std::string owner_password; | 261 | std::string owner_password; |
| @@ -284,14 +276,13 @@ Handlers::beginEncrypt(JSON j) | @@ -284,14 +276,13 @@ Handlers::beginEncrypt(JSON j) | ||
| 284 | }); | 276 | }); |
| 285 | if (key_len == 0) { | 277 | if (key_len == 0) { |
| 286 | QTC::TC("qpdf", "QPDFJob json encrypt no key length"); | 278 | QTC::TC("qpdf", "QPDFJob json encrypt no key length"); |
| 287 | - usage("exactly one of 40bit, 128bit, or 256bit must be given;" | ||
| 288 | - " an empty dictionary may be supplied for one of them" | ||
| 289 | - " to set the key length without imposing any restrictions"); | 279 | + usage("exactly one of 40bit, 128bit, or 256bit must be given; an empty dictionary may be " |
| 280 | + "supplied for one of them to set the key length without imposing any restrictions"); | ||
| 290 | } | 281 | } |
| 291 | if (!(user_password_seen && owner_password_seen)) { | 282 | if (!(user_password_seen && owner_password_seen)) { |
| 292 | QTC::TC("qpdf", "QPDFJob json encrypt missing password"); | 283 | QTC::TC("qpdf", "QPDFJob json encrypt missing password"); |
| 293 | - usage("the user and owner password are both required; use the empty" | ||
| 294 | - " string for the user password if you don't want a password"); | 284 | + usage("the user and owner password are both required; use the empty string for the user " |
| 285 | + "password if you don't want a password"); | ||
| 295 | } | 286 | } |
| 296 | this->c_enc = c_main->encrypt(key_len, user_password, owner_password); | 287 | this->c_enc = c_main->encrypt(key_len, user_password, owner_password); |
| 297 | } | 288 | } |
libqpdf/QPDFNameTreeObjectHelper.cc
| @@ -36,9 +36,8 @@ static NameTreeDetails name_tree_details; | @@ -36,9 +36,8 @@ static NameTreeDetails name_tree_details; | ||
| 36 | 36 | ||
| 37 | QPDFNameTreeObjectHelper::~QPDFNameTreeObjectHelper() | 37 | QPDFNameTreeObjectHelper::~QPDFNameTreeObjectHelper() |
| 38 | { | 38 | { |
| 39 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 40 | - // README-maintainer. For this specific class, see github issue | ||
| 41 | - // #745. | 39 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer. For this specific |
| 40 | + // class, see github issue #745. | ||
| 42 | } | 41 | } |
| 43 | 42 | ||
| 44 | QPDFNameTreeObjectHelper::Members::Members(QPDFObjectHandle& oh, QPDF& q, bool auto_repair) : | 43 | QPDFNameTreeObjectHelper::Members::Members(QPDFObjectHandle& oh, QPDF& q, bool auto_repair) : |
libqpdf/QPDFNumberTreeObjectHelper.cc
| @@ -37,9 +37,8 @@ static NumberTreeDetails number_tree_details; | @@ -37,9 +37,8 @@ static NumberTreeDetails number_tree_details; | ||
| 37 | 37 | ||
| 38 | QPDFNumberTreeObjectHelper::~QPDFNumberTreeObjectHelper() | 38 | QPDFNumberTreeObjectHelper::~QPDFNumberTreeObjectHelper() |
| 39 | { | 39 | { |
| 40 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 41 | - // README-maintainer. For this specific class, see github issue | ||
| 42 | - // #745. | 40 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer. For this specific |
| 41 | + // class, see github issue #745. | ||
| 43 | } | 42 | } |
| 44 | 43 | ||
| 45 | QPDFNumberTreeObjectHelper::Members::Members(QPDFObjectHandle& oh, QPDF& q, bool auto_repair) : | 44 | QPDFNumberTreeObjectHelper::Members::Members(QPDFObjectHandle& oh, QPDF& q, bool auto_repair) : |
libqpdf/QPDFObjGen.cc
| @@ -27,8 +27,8 @@ QPDFObjGen::set::add(QPDFObjectHandle const& oh) | @@ -27,8 +27,8 @@ QPDFObjGen::set::add(QPDFObjectHandle const& oh) | ||
| 27 | if (auto* ptr = oh.getObjectPtr()) { | 27 | if (auto* ptr = oh.getObjectPtr()) { |
| 28 | return add(ptr->getObjGen()); | 28 | return add(ptr->getObjGen()); |
| 29 | } else { | 29 | } else { |
| 30 | - throw std::logic_error("attempt to retrieve QPDFObjGen from " | ||
| 31 | - "uninitialized QPDFObjectHandle"); | 30 | + throw std::logic_error( |
| 31 | + "attempt to retrieve QPDFObjGen from uninitialized QPDFObjectHandle"); | ||
| 32 | return false; | 32 | return false; |
| 33 | } | 33 | } |
| 34 | } | 34 | } |
| @@ -39,8 +39,8 @@ QPDFObjGen::set::add(QPDFObjectHelper const& helper) | @@ -39,8 +39,8 @@ QPDFObjGen::set::add(QPDFObjectHelper const& helper) | ||
| 39 | if (auto* ptr = helper.getObjectHandle().getObjectPtr()) { | 39 | if (auto* ptr = helper.getObjectHandle().getObjectPtr()) { |
| 40 | return add(ptr->getObjGen()); | 40 | return add(ptr->getObjGen()); |
| 41 | } else { | 41 | } else { |
| 42 | - throw std::logic_error("attempt to retrieve QPDFObjGen from " | ||
| 43 | - "uninitialized QPDFObjectHandle"); | 42 | + throw std::logic_error( |
| 43 | + "attempt to retrieve QPDFObjGen from uninitialized QPDFObjectHandle"); | ||
| 44 | return false; | 44 | return false; |
| 45 | } | 45 | } |
| 46 | } | 46 | } |
| @@ -51,8 +51,8 @@ QPDFObjGen::set::erase(QPDFObjectHandle const& oh) | @@ -51,8 +51,8 @@ QPDFObjGen::set::erase(QPDFObjectHandle const& oh) | ||
| 51 | if (auto* ptr = oh.getObjectPtr()) { | 51 | if (auto* ptr = oh.getObjectPtr()) { |
| 52 | erase(ptr->getObjGen()); | 52 | erase(ptr->getObjGen()); |
| 53 | } else { | 53 | } else { |
| 54 | - throw std::logic_error("attempt to retrieve QPDFObjGen from " | ||
| 55 | - "uninitialized QPDFObjectHandle"); | 54 | + throw std::logic_error( |
| 55 | + "attempt to retrieve QPDFObjGen from uninitialized QPDFObjectHandle"); | ||
| 56 | } | 56 | } |
| 57 | } | 57 | } |
| 58 | 58 | ||
| @@ -62,7 +62,7 @@ QPDFObjGen::set::erase(QPDFObjectHelper const& helper) | @@ -62,7 +62,7 @@ QPDFObjGen::set::erase(QPDFObjectHelper const& helper) | ||
| 62 | if (auto* ptr = helper.getObjectHandle().getObjectPtr()) { | 62 | if (auto* ptr = helper.getObjectHandle().getObjectPtr()) { |
| 63 | erase(ptr->getObjGen()); | 63 | erase(ptr->getObjGen()); |
| 64 | } else { | 64 | } else { |
| 65 | - throw std::logic_error("attempt to retrieve QPDFObjGen from " | ||
| 66 | - "uninitialized QPDFObjectHandle"); | 65 | + throw std::logic_error( |
| 66 | + "attempt to retrieve QPDFObjGen from uninitialized QPDFObjectHandle"); | ||
| 67 | } | 67 | } |
| 68 | } | 68 | } |
libqpdf/QPDFObjectHandle.cc
| @@ -229,11 +229,9 @@ QPDFObjectHandle::isSameObjectAs(QPDFObjectHandle const& rhs) const | @@ -229,11 +229,9 @@ QPDFObjectHandle::isSameObjectAs(QPDFObjectHandle const& rhs) const | ||
| 229 | void | 229 | void |
| 230 | QPDFObjectHandle::disconnect() | 230 | QPDFObjectHandle::disconnect() |
| 231 | { | 231 | { |
| 232 | - // Recursively remove association with any QPDF object. This | ||
| 233 | - // method may only be called during final destruction. | ||
| 234 | - // QPDF::~QPDF() calls it for indirect objects using the object | ||
| 235 | - // pointer itself, so we don't do that here. Other objects call it | ||
| 236 | - // through this method. | 232 | + // Recursively remove association with any QPDF object. This method may only be called during |
| 233 | + // final destruction. QPDF::~QPDF() calls it for indirect objects using the object pointer | ||
| 234 | + // itself, so we don't do that here. Other objects call it through this method. | ||
| 237 | if (!isIndirect()) { | 235 | if (!isIndirect()) { |
| 238 | this->obj->disconnect(); | 236 | this->obj->disconnect(); |
| 239 | } | 237 | } |
| @@ -1783,10 +1781,9 @@ QPDFObjectHandle::parseContentStream_data( | @@ -1783,10 +1781,9 @@ QPDFObjectHandle::parseContentStream_data( | ||
| 1783 | tokenizer.allowEOF(); | 1781 | tokenizer.allowEOF(); |
| 1784 | bool empty = false; | 1782 | bool empty = false; |
| 1785 | while (QIntC::to_size(input->tell()) < stream_length) { | 1783 | while (QIntC::to_size(input->tell()) < stream_length) { |
| 1786 | - // Read a token and seek to the beginning. The offset we get | ||
| 1787 | - // from this process is the beginning of the next | ||
| 1788 | - // non-ignorable (space, comment) token. This way, the offset | ||
| 1789 | - // and don't including ignorable content. | 1784 | + // Read a token and seek to the beginning. The offset we get from this process is the |
| 1785 | + // beginning of the next non-ignorable (space, comment) token. This way, the offset and | ||
| 1786 | + // don't including ignorable content. | ||
| 1790 | tokenizer.readToken(input, "content", true); | 1787 | tokenizer.readToken(input, "content", true); |
| 1791 | qpdf_offset_t offset = input->getLastOffset(); | 1788 | qpdf_offset_t offset = input->getLastOffset(); |
| 1792 | input->seek(offset, SEEK_SET); | 1789 | input->seek(offset, SEEK_SET); |
libqpdf/QPDFObjectHelper.cc
| @@ -2,6 +2,5 @@ | @@ -2,6 +2,5 @@ | ||
| 2 | 2 | ||
| 3 | QPDFObjectHelper::~QPDFObjectHelper() | 3 | QPDFObjectHelper::~QPDFObjectHelper() |
| 4 | { | 4 | { |
| 5 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 6 | - // README-maintainer | 5 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| 7 | } | 6 | } |
libqpdf/QPDFOutlineObjectHelper.cc
| @@ -14,8 +14,8 @@ QPDFOutlineObjectHelper::QPDFOutlineObjectHelper( | @@ -14,8 +14,8 @@ QPDFOutlineObjectHelper::QPDFOutlineObjectHelper( | ||
| 14 | m(new Members(dh)) | 14 | m(new Members(dh)) |
| 15 | { | 15 | { |
| 16 | if (depth > 50) { | 16 | if (depth > 50) { |
| 17 | - // Not exercised in test suite, but was tested manually by | ||
| 18 | - // temporarily changing max depth to 1. | 17 | + // Not exercised in test suite, but was tested manually by temporarily changing max depth |
| 18 | + // to 1. | ||
| 19 | return; | 19 | return; |
| 20 | } | 20 | } |
| 21 | if (QPDFOutlineDocumentHelper::Accessor::checkSeen(m->dh, this->oh.getObjGen())) { | 21 | if (QPDFOutlineDocumentHelper::Accessor::checkSeen(m->dh, this->oh.getObjGen())) { |
libqpdf/QPDFPageDocumentHelper.cc
| @@ -59,8 +59,8 @@ QPDFPageDocumentHelper::flattenAnnotations(int required_flags, int forbidden_fla | @@ -59,8 +59,8 @@ QPDFPageDocumentHelper::flattenAnnotations(int required_flags, int forbidden_fla | ||
| 59 | if (afdh.getNeedAppearances()) { | 59 | if (afdh.getNeedAppearances()) { |
| 60 | this->qpdf.getRoot() | 60 | this->qpdf.getRoot() |
| 61 | .getKey("/AcroForm") | 61 | .getKey("/AcroForm") |
| 62 | - .warnIfPossible("document does not have updated appearance streams," | ||
| 63 | - " so form fields will not be flattened"); | 62 | + .warnIfPossible("document does not have updated appearance streams, so form fields " |
| 63 | + "will not be flattened"); | ||
| 64 | } | 64 | } |
| 65 | for (auto& ph: getAllPages()) { | 65 | for (auto& ph: getAllPages()) { |
| 66 | QPDFObjectHandle resources = ph.getAttribute("/Resources", true); | 66 | QPDFObjectHandle resources = ph.getAttribute("/Resources", true); |
| @@ -126,11 +126,10 @@ QPDFPageDocumentHelper::flattenAnnotationsForPage( | @@ -126,11 +126,10 @@ QPDFPageDocumentHelper::flattenAnnotationsForPage( | ||
| 126 | } | 126 | } |
| 127 | new_content += content; | 127 | new_content += content; |
| 128 | } else if (process) { | 128 | } else if (process) { |
| 129 | - // If an annotation has no appearance stream, just drop | ||
| 130 | - // the annotation when flattening. This can happen for | ||
| 131 | - // unchecked checkboxes and radio buttons, popup windows | ||
| 132 | - // associated with comments that aren't visible, and other | ||
| 133 | - // types of annotations that aren't visible. | 129 | + // If an annotation has no appearance stream, just drop the annotation when flattening. |
| 130 | + // This can happen for unchecked checkboxes and radio buttons, popup windows associated | ||
| 131 | + // with comments that aren't visible, and other types of annotations that aren't | ||
| 132 | + // visible. | ||
| 134 | QTC::TC("qpdf", "QPDFPageDocumentHelper ignore annotation with no appearance"); | 133 | QTC::TC("qpdf", "QPDFPageDocumentHelper ignore annotation with no appearance"); |
| 135 | } else { | 134 | } else { |
| 136 | new_annots.push_back(aoh.getObjectHandle()); | 135 | new_annots.push_back(aoh.getObjectHandle()); |
libqpdf/QPDFPageLabelDocumentHelper.cc
| @@ -57,19 +57,17 @@ QPDFPageLabelDocumentHelper::getLabelsForPageRange( | @@ -57,19 +57,17 @@ QPDFPageLabelDocumentHelper::getLabelsForPageRange( | ||
| 57 | long long new_start_idx, | 57 | long long new_start_idx, |
| 58 | std::vector<QPDFObjectHandle>& new_labels) | 58 | std::vector<QPDFObjectHandle>& new_labels) |
| 59 | { | 59 | { |
| 60 | - // Start off with a suitable label for the first page. For every | ||
| 61 | - // remaining page, if that page has an explicit entry, copy it. | ||
| 62 | - // Otherwise, let the subsequent page just sequence from the prior | ||
| 63 | - // entry. If there is no entry for the first page, fabricate one | ||
| 64 | - // that would match how the page would look in a new file in which | ||
| 65 | - // it also didn't have an explicit label. | 60 | + // Start off with a suitable label for the first page. For every remaining page, if that page |
| 61 | + // has an explicit entry, copy it. Otherwise, let the subsequent page just sequence from the | ||
| 62 | + // prior entry. If there is no entry for the first page, fabricate one that would match how the | ||
| 63 | + // page would look in a new file in which it also didn't have an explicit label. | ||
| 66 | QPDFObjectHandle label = getLabelForPage(start_idx); | 64 | QPDFObjectHandle label = getLabelForPage(start_idx); |
| 67 | if (label.isNull()) { | 65 | if (label.isNull()) { |
| 68 | label = QPDFObjectHandle::newDictionary(); | 66 | label = QPDFObjectHandle::newDictionary(); |
| 69 | label.replaceKey("/St", QPDFObjectHandle::newInteger(1 + new_start_idx)); | 67 | label.replaceKey("/St", QPDFObjectHandle::newInteger(1 + new_start_idx)); |
| 70 | } | 68 | } |
| 71 | - // See if the new label is redundant based on the previous entry | ||
| 72 | - // in the vector. If so, don't add it. | 69 | + // See if the new label is redundant based on the previous entry in the vector. If so, don't add |
| 70 | + // it. | ||
| 73 | size_t size = new_labels.size(); | 71 | size_t size = new_labels.size(); |
| 74 | bool skip_first = false; | 72 | bool skip_first = false; |
| 75 | if (size >= 2) { | 73 | if (size >= 2) { |
libqpdf/QPDFWriter.cc
| @@ -28,8 +28,7 @@ | @@ -28,8 +28,7 @@ | ||
| 28 | 28 | ||
| 29 | QPDFWriter::ProgressReporter::~ProgressReporter() | 29 | QPDFWriter::ProgressReporter::~ProgressReporter() |
| 30 | { | 30 | { |
| 31 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 32 | - // README-maintainer | 31 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| 33 | } | 32 | } |
| 34 | 33 | ||
| 35 | QPDFWriter::FunctionProgressReporter::FunctionProgressReporter(std::function<void(int)> handler) : | 34 | QPDFWriter::FunctionProgressReporter::FunctionProgressReporter(std::function<void(int)> handler) : |
| @@ -39,8 +38,7 @@ QPDFWriter::FunctionProgressReporter::FunctionProgressReporter(std::function<voi | @@ -39,8 +38,7 @@ QPDFWriter::FunctionProgressReporter::FunctionProgressReporter(std::function<voi | ||
| 39 | 38 | ||
| 40 | QPDFWriter::FunctionProgressReporter::~FunctionProgressReporter() | 39 | QPDFWriter::FunctionProgressReporter::~FunctionProgressReporter() |
| 41 | { | 40 | { |
| 42 | - // Must be explicit and not inline -- see QPDF_DLL_CLASS in | ||
| 43 | - // README-maintainer | 41 | + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| 44 | } | 42 | } |
| 45 | 43 | ||
| 46 | void | 44 | void |
| @@ -534,8 +532,8 @@ QPDFWriter::interpretR3EncryptionParameters( | @@ -534,8 +532,8 @@ QPDFWriter::interpretR3EncryptionParameters( | ||
| 534 | clear.insert(5); | 532 | clear.insert(5); |
| 535 | } | 533 | } |
| 536 | 534 | ||
| 537 | - // Note: these switch statements all "fall through" (no break | ||
| 538 | - // statements). Each option clears successively more access bits. | 535 | + // Note: these switch statements all "fall through" (no break statements). Each option clears |
| 536 | + // successively more access bits. | ||
| 539 | switch (print) { | 537 | switch (print) { |
| 540 | case qpdf_r3p_none: | 538 | case qpdf_r3p_none: |
| 541 | clear.insert(3); // any printing | 539 | clear.insert(3); // any printing |
| @@ -549,11 +547,9 @@ QPDFWriter::interpretR3EncryptionParameters( | @@ -549,11 +547,9 @@ QPDFWriter::interpretR3EncryptionParameters( | ||
| 549 | // no default so gcc warns for missing cases | 547 | // no default so gcc warns for missing cases |
| 550 | } | 548 | } |
| 551 | 549 | ||
| 552 | - // Modify options. The qpdf_r3_modify_e options control groups of | ||
| 553 | - // bits and lack the full flexibility of the spec. This is | ||
| 554 | - // unfortunate, but it's been in the API for ages, and we're stuck | ||
| 555 | - // with it. See also allow checks below to control the bits | ||
| 556 | - // individually. | 550 | + // Modify options. The qpdf_r3_modify_e options control groups of bits and lack the full |
| 551 | + // flexibility of the spec. This is unfortunate, but it's been in the API for ages, and we're | ||
| 552 | + // stuck with it. See also allow checks below to control the bits individually. | ||
| 557 | 553 | ||
| 558 | // NOT EXERCISED IN TEST SUITE | 554 | // NOT EXERCISED IN TEST SUITE |
| 559 | switch (modify) { | 555 | switch (modify) { |
| @@ -607,9 +603,8 @@ QPDFWriter::setEncryptionParameters( | @@ -607,9 +603,8 @@ QPDFWriter::setEncryptionParameters( | ||
| 607 | bits_to_clear.insert(2); | 603 | bits_to_clear.insert(2); |
| 608 | 604 | ||
| 609 | if (R > 3) { | 605 | if (R > 3) { |
| 610 | - // Bit 10 is deprecated and should always be set. This used | ||
| 611 | - // to mean accessibility. There is no way to disable | ||
| 612 | - // accessibility with R > 3. | 606 | + // Bit 10 is deprecated and should always be set. This used to mean accessibility. There |
| 607 | + // is no way to disable accessibility with R > 3. | ||
| 613 | bits_to_clear.erase(10); | 608 | bits_to_clear.erase(10); |
| 614 | } | 609 | } |
| 615 | 610 | ||
| @@ -669,12 +664,10 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf) | @@ -669,12 +664,10 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf) | ||
| 669 | m->encrypt_metadata = encrypt.getKey("/EncryptMetadata").getBoolValue(); | 664 | m->encrypt_metadata = encrypt.getKey("/EncryptMetadata").getBoolValue(); |
| 670 | } | 665 | } |
| 671 | if (V >= 4) { | 666 | if (V >= 4) { |
| 672 | - // When copying encryption parameters, use AES even if the | ||
| 673 | - // original file did not. Acrobat doesn't create files | ||
| 674 | - // with V >= 4 that don't use AES, and the logic of | ||
| 675 | - // figuring out whether AES is used or not is complicated | ||
| 676 | - // with /StmF, /StrF, and /EFF all potentially having | ||
| 677 | - // different values. | 667 | + // When copying encryption parameters, use AES even if the original file did not. |
| 668 | + // Acrobat doesn't create files with V >= 4 that don't use AES, and the logic of | ||
| 669 | + // figuring out whether AES is used or not is complicated with /StmF, /StrF, and /EFF | ||
| 670 | + // all potentially having different values. | ||
| 678 | m->encrypt_use_aes = true; | 671 | m->encrypt_use_aes = true; |
| 679 | } | 672 | } |
| 680 | QTC::TC("qpdf", "QPDFWriter copy encrypt metadata", m->encrypt_metadata ? 0 : 1); | 673 | QTC::TC("qpdf", "QPDFWriter copy encrypt metadata", m->encrypt_metadata ? 0 : 1); |
| @@ -757,11 +750,9 @@ QPDFWriter::parseVersion(std::string const& version, int& major, int& minor) con | @@ -757,11 +750,9 @@ QPDFWriter::parseVersion(std::string const& version, int& major, int& minor) con | ||
| 757 | } | 750 | } |
| 758 | std::string tmp = std::to_string(major) + "." + std::to_string(minor); | 751 | std::string tmp = std::to_string(major) + "." + std::to_string(minor); |
| 759 | if (tmp != version) { | 752 | if (tmp != version) { |
| 760 | - // The version number in the input is probably invalid. This | ||
| 761 | - // happens with some files that are designed to exercise bugs, | ||
| 762 | - // such as files in the fuzzer corpus. Unfortunately | ||
| 763 | - // QPDFWriter doesn't have a way to give a warning, so we just | ||
| 764 | - // ignore this case. | 753 | + // The version number in the input is probably invalid. This happens with some files that |
| 754 | + // are designed to exercise bugs, such as files in the fuzzer corpus. Unfortunately | ||
| 755 | + // QPDFWriter doesn't have a way to give a warning, so we just ignore this case. | ||
| 765 | } | 756 | } |
| 766 | } | 757 | } |
| 767 | 758 | ||
| @@ -826,15 +817,13 @@ QPDFWriter::setEncryptionParametersInternal( | @@ -826,15 +817,13 @@ QPDFWriter::setEncryptionParametersInternal( | ||
| 826 | m->encryption_dictionary["/EncryptMetadata"] = "false"; | 817 | m->encryption_dictionary["/EncryptMetadata"] = "false"; |
| 827 | } | 818 | } |
| 828 | if ((V == 4) || (V == 5)) { | 819 | if ((V == 4) || (V == 5)) { |
| 829 | - // The spec says the value for the crypt filter key can be | ||
| 830 | - // anything, and xpdf seems to agree. However, Adobe Reader | ||
| 831 | - // won't open our files unless we use /StdCF. | 820 | + // The spec says the value for the crypt filter key can be anything, and xpdf seems to |
| 821 | + // agree. However, Adobe Reader won't open our files unless we use /StdCF. | ||
| 832 | m->encryption_dictionary["/StmF"] = "/StdCF"; | 822 | m->encryption_dictionary["/StmF"] = "/StdCF"; |
| 833 | m->encryption_dictionary["/StrF"] = "/StdCF"; | 823 | m->encryption_dictionary["/StrF"] = "/StdCF"; |
| 834 | std::string method = (m->encrypt_use_aes ? ((V < 5) ? "/AESV2" : "/AESV3") : "/V2"); | 824 | std::string method = (m->encrypt_use_aes ? ((V < 5) ? "/AESV2" : "/AESV3") : "/V2"); |
| 835 | - // The PDF spec says the /Length key is optional, but the PDF | ||
| 836 | - // previewer on some versions of MacOS won't open encrypted | ||
| 837 | - // files without it. | 825 | + // The PDF spec says the /Length key is optional, but the PDF previewer on some versions of |
| 826 | + // MacOS won't open encrypted files without it. | ||
| 838 | m->encryption_dictionary["/CF"] = "<< /StdCF << /AuthEvent /DocOpen /CFM " + method + | 827 | m->encryption_dictionary["/CF"] = "<< /StdCF << /AuthEvent /DocOpen /CFM " + method + |
| 839 | " /Length " + std::string((V < 5) ? "16" : "32") + " >> >>"; | 828 | " /Length " + std::string((V < 5) ? "16" : "32") + " >> >>"; |
| 840 | } | 829 | } |
| @@ -950,12 +939,10 @@ QPDFWriter::PipelinePopper::~PipelinePopper() | @@ -950,12 +939,10 @@ QPDFWriter::PipelinePopper::~PipelinePopper() | ||
| 950 | qpdf_assert_debug(qw->m->pipeline_stack.size() >= 2); | 939 | qpdf_assert_debug(qw->m->pipeline_stack.size() >= 2); |
| 951 | qw->m->pipeline->finish(); | 940 | qw->m->pipeline->finish(); |
| 952 | qpdf_assert_debug(dynamic_cast<Pl_Count*>(qw->m->pipeline_stack.back()) == qw->m->pipeline); | 941 | qpdf_assert_debug(dynamic_cast<Pl_Count*>(qw->m->pipeline_stack.back()) == qw->m->pipeline); |
| 953 | - // It might be possible for this assertion to fail if | ||
| 954 | - // writeLinearized exits by exception when deterministic ID, but I | ||
| 955 | - // don't think so. As of this writing, this is the only case in | ||
| 956 | - // which two dynamically allocated PipelinePopper objects ever | ||
| 957 | - // exist at the same time, so the assertion will fail if they get | ||
| 958 | - // popped out of order from automatic destruction. | 942 | + // It might be possible for this assertion to fail if writeLinearized exits by exception when |
| 943 | + // deterministic ID, but I don't think so. As of this writing, this is the only case in which | ||
| 944 | + // two dynamically allocated PipelinePopper objects ever exist at the same time, so the | ||
| 945 | + // assertion will fail if they get popped out of order from automatic destruction. | ||
| 959 | qpdf_assert_debug(qw->m->pipeline->getIdentifier() == stack_id); | 946 | qpdf_assert_debug(qw->m->pipeline->getIdentifier() == stack_id); |
| 960 | delete qw->m->pipeline_stack.back(); | 947 | delete qw->m->pipeline_stack.back(); |
| 961 | qw->m->pipeline_stack.pop_back(); | 948 | qw->m->pipeline_stack.pop_back(); |
| @@ -978,9 +965,8 @@ void | @@ -978,9 +965,8 @@ void | ||
| 978 | QPDFWriter::adjustAESStreamLength(size_t& length) | 965 | QPDFWriter::adjustAESStreamLength(size_t& length) |
| 979 | { | 966 | { |
| 980 | if (m->encrypted && (!m->cur_data_key.empty()) && m->encrypt_use_aes) { | 967 | if (m->encrypted && (!m->cur_data_key.empty()) && m->encrypt_use_aes) { |
| 981 | - // Stream length will be padded with 1 to 16 bytes to end up | ||
| 982 | - // as a multiple of 16. It will also be prepended by 16 bits | ||
| 983 | - // of random data. | 968 | + // Stream length will be padded with 1 to 16 bytes to end up as a multiple of 16. It will |
| 969 | + // also be prepended by 16 bits of random data. | ||
| 984 | length += 32 - (length & 0xf); | 970 | length += 32 - (length & 0xf); |
| 985 | } | 971 | } |
| 986 | } | 972 | } |
| @@ -1006,8 +992,8 @@ QPDFWriter::pushEncryptionFilter(PipelinePopper& pp) | @@ -1006,8 +992,8 @@ QPDFWriter::pushEncryptionFilter(PipelinePopper& pp) | ||
| 1006 | } | 992 | } |
| 1007 | pushPipeline(p); | 993 | pushPipeline(p); |
| 1008 | } | 994 | } |
| 1009 | - // Must call this unconditionally so we can call popPipelineStack | ||
| 1010 | - // to balance pushEncryptionFilter(). | 995 | + // Must call this unconditionally so we can call popPipelineStack to balance |
| 996 | + // pushEncryptionFilter(). | ||
| 1011 | activatePipelineStack(pp); | 997 | activatePipelineStack(pp); |
| 1012 | } | 998 | } |
| 1013 | 999 | ||
| @@ -1031,8 +1017,7 @@ QPDFWriter::pushMD5Pipeline(PipelinePopper& pp) | @@ -1031,8 +1017,7 @@ QPDFWriter::pushMD5Pipeline(PipelinePopper& pp) | ||
| 1031 | qpdf_assert_debug(m->pipeline->getCount() == 0); | 1017 | qpdf_assert_debug(m->pipeline->getCount() == 0); |
| 1032 | m->md5_pipeline = new Pl_MD5("qpdf md5", m->pipeline); | 1018 | m->md5_pipeline = new Pl_MD5("qpdf md5", m->pipeline); |
| 1033 | m->md5_pipeline->persistAcrossFinish(true); | 1019 | m->md5_pipeline->persistAcrossFinish(true); |
| 1034 | - // Special case code in popPipelineStack clears m->md5_pipeline | ||
| 1035 | - // upon deletion. | 1020 | + // Special case code in popPipelineStack clears m->md5_pipeline upon deletion. |
| 1036 | pushPipeline(m->md5_pipeline); | 1021 | pushPipeline(m->md5_pipeline); |
| 1037 | activatePipelineStack(pp); | 1022 | activatePipelineStack(pp); |
| 1038 | } | 1023 | } |
| @@ -1061,8 +1046,7 @@ QPDFWriter::openObject(int objid) | @@ -1061,8 +1046,7 @@ QPDFWriter::openObject(int objid) | ||
| 1061 | void | 1046 | void |
| 1062 | QPDFWriter::closeObject(int objid) | 1047 | QPDFWriter::closeObject(int objid) |
| 1063 | { | 1048 | { |
| 1064 | - // Write a newline before endobj as it makes the file easier to | ||
| 1065 | - // repair. | 1049 | + // Write a newline before endobj as it makes the file easier to repair. |
| 1066 | writeString("\nendobj\n"); | 1050 | writeString("\nendobj\n"); |
| 1067 | writeStringQDF("\n"); | 1051 | writeStringQDF("\n"); |
| 1068 | m->lengths[objid] = m->pipeline->getCount() - m->xref[objid].getOffset(); | 1052 | m->lengths[objid] = m->pipeline->getCount() - m->xref[objid].getOffset(); |
| @@ -1077,8 +1061,7 @@ QPDFWriter::assignCompressedObjectNumbers(QPDFObjGen const& og) | @@ -1077,8 +1061,7 @@ QPDFWriter::assignCompressedObjectNumbers(QPDFObjGen const& og) | ||
| 1077 | return; | 1061 | return; |
| 1078 | } | 1062 | } |
| 1079 | 1063 | ||
| 1080 | - // Reserve numbers for the objects that belong to this object | ||
| 1081 | - // stream. | 1064 | + // Reserve numbers for the objects that belong to this object stream. |
| 1082 | for (auto const& iter: m->object_stream_to_objects[objid]) { | 1065 | for (auto const& iter: m->object_stream_to_objects[objid]) { |
| 1083 | m->obj_renumber[iter] = m->next_objid++; | 1066 | m->obj_renumber[iter] = m->next_objid++; |
| 1084 | } | 1067 | } |
| @@ -1088,26 +1071,21 @@ void | @@ -1088,26 +1071,21 @@ void | ||
| 1088 | QPDFWriter::enqueueObject(QPDFObjectHandle object) | 1071 | QPDFWriter::enqueueObject(QPDFObjectHandle object) |
| 1089 | { | 1072 | { |
| 1090 | if (object.isIndirect()) { | 1073 | if (object.isIndirect()) { |
| 1091 | - // This owner check can only be done for indirect objects. It | ||
| 1092 | - // is possible for a direct object to have an owning QPDF that | ||
| 1093 | - // is from another file if a direct QPDFObjectHandle from one | ||
| 1094 | - // file was insert into another file without copying. Doing | ||
| 1095 | - // that is safe even if the original QPDF gets destroyed, | ||
| 1096 | - // which just disconnects the QPDFObjectHandle from its owner. | 1074 | + // This owner check can only be done for indirect objects. It is possible for a direct |
| 1075 | + // object to have an owning QPDF that is from another file if a direct QPDFObjectHandle from | ||
| 1076 | + // one file was insert into another file without copying. Doing that is safe even if the | ||
| 1077 | + // original QPDF gets destroyed, which just disconnects the QPDFObjectHandle from its owner. | ||
| 1097 | if (object.getOwningQPDF() != &(m->pdf)) { | 1078 | if (object.getOwningQPDF() != &(m->pdf)) { |
| 1098 | QTC::TC("qpdf", "QPDFWriter foreign object"); | 1079 | QTC::TC("qpdf", "QPDFWriter foreign object"); |
| 1099 | - throw std::logic_error("QPDFObjectHandle from different QPDF found while writing." | ||
| 1100 | - " Use QPDF::copyForeignObject to add objects from" | ||
| 1101 | - " another file."); | 1080 | + throw std::logic_error("QPDFObjectHandle from different QPDF found while writing. Use " |
| 1081 | + "QPDF::copyForeignObject to add objects from another file."); | ||
| 1102 | } | 1082 | } |
| 1103 | 1083 | ||
| 1104 | if (m->qdf_mode && object.isStreamOfType("/XRef")) { | 1084 | if (m->qdf_mode && object.isStreamOfType("/XRef")) { |
| 1105 | - // As a special case, do not output any extraneous XRef | ||
| 1106 | - // streams in QDF mode. Doing so will confuse fix-qdf, | ||
| 1107 | - // which expects to see only one XRef stream at the end of | ||
| 1108 | - // the file. This case can occur when creating a QDF from | ||
| 1109 | - // a file with object streams when preserving unreferenced | ||
| 1110 | - // objects since the old cross reference streams are not | 1085 | + // As a special case, do not output any extraneous XRef streams in QDF mode. Doing so |
| 1086 | + // will confuse fix-qdf, which expects to see only one XRef stream at the end of the | ||
| 1087 | + // file. This case can occur when creating a QDF from a file with object streams when | ||
| 1088 | + // preserving unreferenced objects since the old cross reference streams are not | ||
| 1111 | // actually referenced by object number. | 1089 | // actually referenced by object number. |
| 1112 | QTC::TC("qpdf", "QPDFWriter ignore XRef in qdf mode"); | 1090 | QTC::TC("qpdf", "QPDFWriter ignore XRef in qdf mode"); |
| 1113 | return; | 1091 | return; |
| @@ -1117,12 +1095,10 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object) | @@ -1117,12 +1095,10 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object) | ||
| 1117 | 1095 | ||
| 1118 | if (m->obj_renumber.count(og) == 0) { | 1096 | if (m->obj_renumber.count(og) == 0) { |
| 1119 | if (m->object_to_object_stream.count(og)) { | 1097 | if (m->object_to_object_stream.count(og)) { |
| 1120 | - // This is in an object stream. Don't process it | ||
| 1121 | - // here. Instead, enqueue the object stream. Object | ||
| 1122 | - // streams always have generation 0. | 1098 | + // This is in an object stream. Don't process it here. Instead, enqueue the object |
| 1099 | + // stream. Object streams always have generation 0. | ||
| 1123 | int stream_id = m->object_to_object_stream[og]; | 1100 | int stream_id = m->object_to_object_stream[og]; |
| 1124 | - // Detect loops by storing invalid object ID 0, which | ||
| 1125 | - // will get overwritten later. | 1101 | + // Detect loops by storing invalid object ID 0, which will get overwritten later. |
| 1126 | m->obj_renumber[og] = 0; | 1102 | m->obj_renumber[og] = 0; |
| 1127 | enqueueObject(m->pdf.getObjectByID(stream_id, 0)); | 1103 | enqueueObject(m->pdf.getObjectByID(stream_id, 0)); |
| 1128 | } else { | 1104 | } else { |
| @@ -1130,9 +1106,8 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object) | @@ -1130,9 +1106,8 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object) | ||
| 1130 | m->obj_renumber[og] = m->next_objid++; | 1106 | m->obj_renumber[og] = m->next_objid++; |
| 1131 | 1107 | ||
| 1132 | if ((og.getGen() == 0) && m->object_stream_to_objects.count(og.getObj())) { | 1108 | if ((og.getGen() == 0) && m->object_stream_to_objects.count(og.getObj())) { |
| 1133 | - // For linearized files, uncompressed objects go | ||
| 1134 | - // at end, and we take care of assigning numbers | ||
| 1135 | - // to them elsewhere. | 1109 | + // For linearized files, uncompressed objects go at end, and we take care of |
| 1110 | + // assigning numbers to them elsewhere. | ||
| 1136 | if (!m->linearized) { | 1111 | if (!m->linearized) { |
| 1137 | assignCompressedObjectNumbers(og); | 1112 | assignCompressedObjectNumbers(og); |
| 1138 | } | 1113 | } |
| @@ -1142,8 +1117,8 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object) | @@ -1142,8 +1117,8 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object) | ||
| 1142 | } | 1117 | } |
| 1143 | } | 1118 | } |
| 1144 | } else if (m->obj_renumber[og] == 0) { | 1119 | } else if (m->obj_renumber[og] == 0) { |
| 1145 | - // This can happen if a specially constructed file | ||
| 1146 | - // indicates that an object stream is inside itself. | 1120 | + // This can happen if a specially constructed file indicates that an object stream is |
| 1121 | + // inside itself. | ||
| 1147 | QTC::TC("qpdf", "QPDFWriter ignore self-referential object stream"); | 1122 | QTC::TC("qpdf", "QPDFWriter ignore self-referential object stream"); |
| 1148 | } | 1123 | } |
| 1149 | return; | 1124 | return; |
| @@ -1223,12 +1198,10 @@ QPDFWriter::writeTrailer( | @@ -1223,12 +1198,10 @@ QPDFWriter::writeTrailer( | ||
| 1223 | if (original_id1.empty()) { | 1198 | if (original_id1.empty()) { |
| 1224 | writeString("<00000000000000000000000000000000>"); | 1199 | writeString("<00000000000000000000000000000000>"); |
| 1225 | } else { | 1200 | } else { |
| 1226 | - // Write a string of zeroes equal in length to the | ||
| 1227 | - // representation of the original ID. While writing the | ||
| 1228 | - // original ID would have the same number of bytes, it | ||
| 1229 | - // would cause a change to the deterministic ID generated | ||
| 1230 | - // by older versions of the software that hard-coded the | ||
| 1231 | - // length of the ID to 16 bytes. | 1201 | + // Write a string of zeroes equal in length to the representation of the original ID. |
| 1202 | + // While writing the original ID would have the same number of bytes, it would cause a | ||
| 1203 | + // change to the deterministic ID generated by older versions of the software that | ||
| 1204 | + // hard-coded the length of the ID to 16 bytes. | ||
| 1232 | writeString("<"); | 1205 | writeString("<"); |
| 1233 | size_t len = QPDF_String(original_id1).unparse(true).length() - 2; | 1206 | size_t len = QPDF_String(original_id1).unparse(true).length() - 2; |
| 1234 | for (size_t i = 0; i < len; ++i) { | 1207 | for (size_t i = 0; i < len; ++i) { |
| @@ -1284,11 +1257,9 @@ QPDFWriter::willFilterStream( | @@ -1284,11 +1257,9 @@ QPDFWriter::willFilterStream( | ||
| 1284 | filter = false; | 1257 | filter = false; |
| 1285 | } | 1258 | } |
| 1286 | if (filter_on_write && m->compress_streams) { | 1259 | if (filter_on_write && m->compress_streams) { |
| 1287 | - // Don't filter if the stream is already compressed with | ||
| 1288 | - // FlateDecode. This way we don't make it worse if the | ||
| 1289 | - // original file used a better Flate algorithm, and we | ||
| 1290 | - // don't spend time and CPU cycles uncompressing and | ||
| 1291 | - // recompressing stuff. This can be overridden with | 1260 | + // Don't filter if the stream is already compressed with FlateDecode. This way we don't make |
| 1261 | + // it worse if the original file used a better Flate algorithm, and we don't spend time and | ||
| 1262 | + // CPU cycles uncompressing and recompressing stuff. This can be overridden with | ||
| 1292 | // setRecompressFlate(true). | 1263 | // setRecompressFlate(true). |
| 1293 | QPDFObjectHandle filter_obj = stream_dict.getKey("/Filter"); | 1264 | QPDFObjectHandle filter_obj = stream_dict.getKey("/Filter"); |
| 1294 | if ((!m->recompress_flate) && (!stream.isDataModified()) && filter_obj.isName() && | 1265 | if ((!m->recompress_flate) && (!stream.isDataModified()) && filter_obj.isName() && |
| @@ -1351,8 +1322,8 @@ QPDFWriter::unparseObject( | @@ -1351,8 +1322,8 @@ QPDFWriter::unparseObject( | ||
| 1351 | if (level < 0) { | 1322 | if (level < 0) { |
| 1352 | throw std::logic_error("invalid level in QPDFWriter::unparseObject"); | 1323 | throw std::logic_error("invalid level in QPDFWriter::unparseObject"); |
| 1353 | } | 1324 | } |
| 1354 | - // For non-qdf, "indent" is a single space between tokens. | ||
| 1355 | - // For qdf, indent includes the preceding newline. | 1325 | + // For non-qdf, "indent" is a single space between tokens. For qdf, indent includes the |
| 1326 | + // preceding newline. | ||
| 1356 | std::string indent = " "; | 1327 | std::string indent = " "; |
| 1357 | if (m->qdf_mode) { | 1328 | if (m->qdf_mode) { |
| 1358 | indent.append(static_cast<size_t>(2 * level), ' '); | 1329 | indent.append(static_cast<size_t>(2 * level), ' '); |
| @@ -1360,11 +1331,9 @@ QPDFWriter::unparseObject( | @@ -1360,11 +1331,9 @@ QPDFWriter::unparseObject( | ||
| 1360 | } | 1331 | } |
| 1361 | 1332 | ||
| 1362 | if (auto const tc = object.getTypeCode(); tc == ::ot_array) { | 1333 | if (auto const tc = object.getTypeCode(); tc == ::ot_array) { |
| 1363 | - // Note: PDF spec 1.4 implementation note 121 states that | ||
| 1364 | - // Acrobat requires a space after the [ in the /H key of the | ||
| 1365 | - // linearization parameter dictionary. We'll do this | ||
| 1366 | - // unconditionally for all arrays because it looks nicer and | ||
| 1367 | - // doesn't make the files that much bigger. | 1334 | + // Note: PDF spec 1.4 implementation note 121 states that Acrobat requires a space after the |
| 1335 | + // [ in the /H key of the linearization parameter dictionary. We'll do this unconditionally | ||
| 1336 | + // for all arrays because it looks nicer and doesn't make the files that much bigger. | ||
| 1368 | writeString("["); | 1337 | writeString("["); |
| 1369 | for (auto const& item: object.getArrayAsVector()) { | 1338 | for (auto const& item: object.getArrayAsVector()) { |
| 1370 | writeString(indent); | 1339 | writeString(indent); |
| @@ -1374,13 +1343,11 @@ QPDFWriter::unparseObject( | @@ -1374,13 +1343,11 @@ QPDFWriter::unparseObject( | ||
| 1374 | writeString(indent); | 1343 | writeString(indent); |
| 1375 | writeString("]"); | 1344 | writeString("]"); |
| 1376 | } else if (tc == ::ot_dictionary) { | 1345 | } else if (tc == ::ot_dictionary) { |
| 1377 | - // Make a shallow copy of this object so we can modify it | ||
| 1378 | - // safely without affecting the original. This code has logic | ||
| 1379 | - // to skip certain keys in agreement with prepareFileForWrite | ||
| 1380 | - // and with skip_stream_parameters so that replacing them | ||
| 1381 | - // doesn't leave unreferenced objects in the output. We can | ||
| 1382 | - // use unsafeShallowCopy here because we are all we are doing | ||
| 1383 | - // is removing or replacing top-level keys. | 1346 | + // Make a shallow copy of this object so we can modify it safely without affecting the |
| 1347 | + // original. This code has logic to skip certain keys in agreement with prepareFileForWrite | ||
| 1348 | + // and with skip_stream_parameters so that replacing them doesn't leave unreferenced objects | ||
| 1349 | + // in the output. We can use unsafeShallowCopy here because we are all we are doing is | ||
| 1350 | + // removing or replacing top-level keys. | ||
| 1384 | object = object.unsafeShallowCopy(); | 1351 | object = object.unsafeShallowCopy(); |
| 1385 | 1352 | ||
| 1386 | // Handle special cases for specific dictionaries. | 1353 | // Handle special cases for specific dictionaries. |
| @@ -1400,9 +1367,8 @@ QPDFWriter::unparseObject( | @@ -1400,9 +1367,8 @@ QPDFWriter::unparseObject( | ||
| 1400 | // - If it has other things, keep those and remove ADBE | 1367 | // - If it has other things, keep those and remove ADBE |
| 1401 | // - We have no extensions: no action required | 1368 | // - We have no extensions: no action required |
| 1402 | // | 1369 | // |
| 1403 | - // Before writing, we guarantee that /Extensions, if present, | ||
| 1404 | - // is direct through the ADBE dictionary, so we can modify in | ||
| 1405 | - // place. | 1370 | + // Before writing, we guarantee that /Extensions, if present, is direct through the ADBE |
| 1371 | + // dictionary, so we can modify in place. | ||
| 1406 | 1372 | ||
| 1407 | const bool is_root = (old_og == m->root_og); | 1373 | const bool is_root = (old_og == m->root_og); |
| 1408 | bool have_extensions_other = false; | 1374 | bool have_extensions_other = false; |
| @@ -1431,8 +1397,7 @@ QPDFWriter::unparseObject( | @@ -1431,8 +1397,7 @@ QPDFWriter::unparseObject( | ||
| 1431 | if (is_root) { | 1397 | if (is_root) { |
| 1432 | if (need_extensions_adbe) { | 1398 | if (need_extensions_adbe) { |
| 1433 | if (!(have_extensions_other || have_extensions_adbe)) { | 1399 | if (!(have_extensions_other || have_extensions_adbe)) { |
| 1434 | - // We need Extensions and don't have it. Create | ||
| 1435 | - // it here. | 1400 | + // We need Extensions and don't have it. Create it here. |
| 1436 | QTC::TC("qpdf", "QPDFWriter create Extensions", m->qdf_mode ? 0 : 1); | 1401 | QTC::TC("qpdf", "QPDFWriter create Extensions", m->qdf_mode ? 0 : 1); |
| 1437 | extensions = object.replaceKeyAndGetNew( | 1402 | extensions = object.replaceKeyAndGetNew( |
| 1438 | "/Extensions", QPDFObjectHandle::newDictionary()); | 1403 | "/Extensions", QPDFObjectHandle::newDictionary()); |
| @@ -1488,8 +1453,8 @@ QPDFWriter::unparseObject( | @@ -1488,8 +1453,8 @@ QPDFWriter::unparseObject( | ||
| 1488 | object.removeKey("/Filter"); | 1453 | object.removeKey("/Filter"); |
| 1489 | object.removeKey("/DecodeParms"); | 1454 | object.removeKey("/DecodeParms"); |
| 1490 | } else { | 1455 | } else { |
| 1491 | - // Make sure, no matter what else we have, that we | ||
| 1492 | - // don't have /Crypt in the output filters. | 1456 | + // Make sure, no matter what else we have, that we don't have /Crypt in the output |
| 1457 | + // filters. | ||
| 1493 | QPDFObjectHandle filter = object.getKey("/Filter"); | 1458 | QPDFObjectHandle filter = object.getKey("/Filter"); |
| 1494 | QPDFObjectHandle decode_parms = object.getKey("/DecodeParms"); | 1459 | QPDFObjectHandle decode_parms = object.getKey("/DecodeParms"); |
| 1495 | if (filter.isOrHasName("/Crypt")) { | 1460 | if (filter.isOrHasName("/Crypt")) { |
| @@ -1506,12 +1471,10 @@ QPDFWriter::unparseObject( | @@ -1506,12 +1471,10 @@ QPDFWriter::unparseObject( | ||
| 1506 | } | 1471 | } |
| 1507 | } | 1472 | } |
| 1508 | if (idx >= 0) { | 1473 | if (idx >= 0) { |
| 1509 | - // If filter is an array, then the code in | ||
| 1510 | - // QPDF_Stream has already verified that | ||
| 1511 | - // DecodeParms and Filters are arrays of | ||
| 1512 | - // the same length, but if they weren't | ||
| 1513 | - // for some reason, eraseItem does type | ||
| 1514 | - // and bounds checking. | 1474 | + // If filter is an array, then the code in QPDF_Stream has already |
| 1475 | + // verified that DecodeParms and Filters are arrays of the same length, | ||
| 1476 | + // but if they weren't for some reason, eraseItem does type and bounds | ||
| 1477 | + // checking. | ||
| 1515 | QTC::TC("qpdf", "QPDFWriter remove Crypt"); | 1478 | QTC::TC("qpdf", "QPDFWriter remove Crypt"); |
| 1516 | filter.eraseItem(idx); | 1479 | filter.eraseItem(idx); |
| 1517 | decode_parms.eraseItem(idx); | 1480 | decode_parms.eraseItem(idx); |
| @@ -1659,8 +1622,8 @@ QPDFWriter::writeObjectStreamOffsets(std::vector<qpdf_offset_t>& offsets, int fi | @@ -1659,8 +1622,8 @@ QPDFWriter::writeObjectStreamOffsets(std::vector<qpdf_offset_t>& offsets, int fi | ||
| 1659 | void | 1622 | void |
| 1660 | QPDFWriter::writeObjectStream(QPDFObjectHandle object) | 1623 | QPDFWriter::writeObjectStream(QPDFObjectHandle object) |
| 1661 | { | 1624 | { |
| 1662 | - // Note: object might be null if this is a place-holder for an | ||
| 1663 | - // object stream that we are generating from scratch. | 1625 | + // Note: object might be null if this is a place-holder for an object stream that we are |
| 1626 | + // generating from scratch. | ||
| 1664 | 1627 | ||
| 1665 | QPDFObjGen old_og = object.getObjGen(); | 1628 | QPDFObjGen old_og = object.getObjGen(); |
| 1666 | qpdf_assert_debug(old_og.getGen() == 0); | 1629 | qpdf_assert_debug(old_og.getGen() == 0); |
| @@ -1670,8 +1633,8 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) | @@ -1670,8 +1633,8 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) | ||
| 1670 | std::vector<qpdf_offset_t> offsets; | 1633 | std::vector<qpdf_offset_t> offsets; |
| 1671 | qpdf_offset_t first = 0; | 1634 | qpdf_offset_t first = 0; |
| 1672 | 1635 | ||
| 1673 | - // Generate stream itself. We have to do this in two passes so we | ||
| 1674 | - // can calculate offsets in the first pass. | 1636 | + // Generate stream itself. We have to do this in two passes so we can calculate offsets in the |
| 1637 | + // first pass. | ||
| 1675 | std::shared_ptr<Buffer> stream_buffer; | 1638 | std::shared_ptr<Buffer> stream_buffer; |
| 1676 | int first_obj = -1; | 1639 | int first_obj = -1; |
| 1677 | bool compressed = false; | 1640 | bool compressed = false; |
| @@ -1687,8 +1650,7 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) | @@ -1687,8 +1650,7 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) | ||
| 1687 | iter -= first; | 1650 | iter -= first; |
| 1688 | } | 1651 | } |
| 1689 | 1652 | ||
| 1690 | - // Take one pass at writing pairs of numbers so we can get | ||
| 1691 | - // their size information | 1653 | + // Take one pass at writing pairs of numbers so we can get their size information |
| 1692 | { | 1654 | { |
| 1693 | PipelinePopper pp_discard(this); | 1655 | PipelinePopper pp_discard(this); |
| 1694 | pushDiscardFilter(pp_discard); | 1656 | pushDiscardFilter(pp_discard); |
| @@ -1721,11 +1683,9 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) | @@ -1721,11 +1683,9 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) | ||
| 1721 | std::to_string(count)); | 1683 | std::to_string(count)); |
| 1722 | if (!m->suppress_original_object_ids) { | 1684 | if (!m->suppress_original_object_ids) { |
| 1723 | writeString("; original object ID: " + std::to_string(obj.getObj())); | 1685 | writeString("; original object ID: " + std::to_string(obj.getObj())); |
| 1724 | - // For compatibility, only write the generation if | ||
| 1725 | - // non-zero. While object streams only allow | ||
| 1726 | - // objects with generation 0, if we are generating | ||
| 1727 | - // object streams, the old object could have a | ||
| 1728 | - // non-zero generation. | 1686 | + // For compatibility, only write the generation if non-zero. While object |
| 1687 | + // streams only allow objects with generation 0, if we are generating object | ||
| 1688 | + // streams, the old object could have a non-zero generation. | ||
| 1729 | if (obj.getGen() != 0) { | 1689 | if (obj.getGen() != 0) { |
| 1730 | QTC::TC("qpdf", "QPDFWriter original obj non-zero gen"); | 1690 | QTC::TC("qpdf", "QPDFWriter original obj non-zero gen"); |
| 1731 | writeString(" " + std::to_string(obj.getGen())); | 1691 | writeString(" " + std::to_string(obj.getGen())); |
| @@ -1735,16 +1695,14 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) | @@ -1735,16 +1695,14 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) | ||
| 1735 | } | 1695 | } |
| 1736 | if (pass == 1) { | 1696 | if (pass == 1) { |
| 1737 | offsets.push_back(m->pipeline->getCount()); | 1697 | offsets.push_back(m->pipeline->getCount()); |
| 1738 | - // To avoid double-counting objects being written in | ||
| 1739 | - // object streams for progress reporting, decrement in | ||
| 1740 | - // pass 1. | 1698 | + // To avoid double-counting objects being written in object streams for progress |
| 1699 | + // reporting, decrement in pass 1. | ||
| 1741 | indicateProgress(true, false); | 1700 | indicateProgress(true, false); |
| 1742 | } | 1701 | } |
| 1743 | QPDFObjectHandle obj_to_write = m->pdf.getObject(obj); | 1702 | QPDFObjectHandle obj_to_write = m->pdf.getObject(obj); |
| 1744 | if (obj_to_write.isStream()) { | 1703 | if (obj_to_write.isStream()) { |
| 1745 | - // This condition occurred in a fuzz input. Ideally we | ||
| 1746 | - // should block it at at parse time, but it's not | ||
| 1747 | - // clear to me how to construct a case for this. | 1704 | + // This condition occurred in a fuzz input. Ideally we should block it at at parse |
| 1705 | + // time, but it's not clear to me how to construct a case for this. | ||
| 1748 | QTC::TC("qpdf", "QPDFWriter stream in ostream"); | 1706 | QTC::TC("qpdf", "QPDFWriter stream in ostream"); |
| 1749 | obj_to_write.warnIfPossible("stream found inside object stream; treating as null"); | 1707 | obj_to_write.warnIfPossible("stream found inside object stream; treating as null"); |
| 1750 | obj_to_write = QPDFObjectHandle::newNull(); | 1708 | obj_to_write = QPDFObjectHandle::newNull(); |
| @@ -1867,8 +1825,8 @@ QPDFWriter::getOriginalID1() | @@ -1867,8 +1825,8 @@ QPDFWriter::getOriginalID1() | ||
| 1867 | void | 1825 | void |
| 1868 | QPDFWriter::generateID() | 1826 | QPDFWriter::generateID() |
| 1869 | { | 1827 | { |
| 1870 | - // Generate the ID lazily so that we can handle the user's | ||
| 1871 | - // preference to use static or deterministic ID generation. | 1828 | + // Generate the ID lazily so that we can handle the user's preference to use static or |
| 1829 | + // deterministic ID generation. | ||
| 1872 | 1830 | ||
| 1873 | if (!m->id2.empty()) { | 1831 | if (!m->id2.empty()) { |
| 1874 | return; | 1832 | return; |
| @@ -1900,27 +1858,22 @@ QPDFWriter::generateID() | @@ -1900,27 +1858,22 @@ QPDFWriter::generateID() | ||
| 1900 | 0x00}; | 1858 | 0x00}; |
| 1901 | result = reinterpret_cast<char*>(tmp); | 1859 | result = reinterpret_cast<char*>(tmp); |
| 1902 | } else { | 1860 | } else { |
| 1903 | - // The PDF specification has guidelines for creating IDs, but | ||
| 1904 | - // it states clearly that the only thing that's really | ||
| 1905 | - // important is that it is very likely to be unique. We can't | ||
| 1906 | - // really follow the guidelines in the spec exactly because we | ||
| 1907 | - // haven't written the file yet. This scheme should be fine | ||
| 1908 | - // though. The deterministic ID case uses a digest of a | ||
| 1909 | - // sufficient portion of the file's contents such no two | ||
| 1910 | - // non-matching files would match in the subsets used for this | ||
| 1911 | - // computation. Note that we explicitly omit the filename from | ||
| 1912 | - // the digest calculation for deterministic ID so that the same | ||
| 1913 | - // file converted with qpdf, in that case, would have the same | ||
| 1914 | - // ID regardless of the output file's name. | 1861 | + // The PDF specification has guidelines for creating IDs, but it states clearly that the |
| 1862 | + // only thing that's really important is that it is very likely to be unique. We can't | ||
| 1863 | + // really follow the guidelines in the spec exactly because we haven't written the file yet. | ||
| 1864 | + // This scheme should be fine though. The deterministic ID case uses a digest of a | ||
| 1865 | + // sufficient portion of the file's contents such no two non-matching files would match in | ||
| 1866 | + // the subsets used for this computation. Note that we explicitly omit the filename from | ||
| 1867 | + // the digest calculation for deterministic ID so that the same file converted with qpdf, in | ||
| 1868 | + // that case, would have the same ID regardless of the output file's name. | ||
| 1915 | 1869 | ||
| 1916 | std::string seed; | 1870 | std::string seed; |
| 1917 | if (m->deterministic_id) { | 1871 | if (m->deterministic_id) { |
| 1918 | if (m->deterministic_id_data.empty()) { | 1872 | if (m->deterministic_id_data.empty()) { |
| 1919 | QTC::TC("qpdf", "QPDFWriter deterministic with no data"); | 1873 | QTC::TC("qpdf", "QPDFWriter deterministic with no data"); |
| 1920 | - throw std::logic_error("INTERNAL ERROR: QPDFWriter::generateID has no" | ||
| 1921 | - " data for deterministic ID. This may happen if" | ||
| 1922 | - " deterministic ID and file encryption are requested" | ||
| 1923 | - " together."); | 1874 | + throw std::logic_error("INTERNAL ERROR: QPDFWriter::generateID has no data for " |
| 1875 | + "deterministic ID. This may happen if deterministic ID and " | ||
| 1876 | + "file encryption are requested together."); | ||
| 1924 | } | 1877 | } |
| 1925 | seed += m->deterministic_id_data; | 1878 | seed += m->deterministic_id_data; |
| 1926 | } else { | 1879 | } else { |
| @@ -1947,9 +1900,8 @@ QPDFWriter::generateID() | @@ -1947,9 +1900,8 @@ QPDFWriter::generateID() | ||
| 1947 | result = std::string(reinterpret_cast<char*>(digest), sizeof(MD5::Digest)); | 1900 | result = std::string(reinterpret_cast<char*>(digest), sizeof(MD5::Digest)); |
| 1948 | } | 1901 | } |
| 1949 | 1902 | ||
| 1950 | - // If /ID already exists, follow the spec: use the original first | ||
| 1951 | - // word and generate a new second word. Otherwise, we'll use the | ||
| 1952 | - // generated ID for both. | 1903 | + // If /ID already exists, follow the spec: use the original first word and generate a new second |
| 1904 | + // word. Otherwise, we'll use the generated ID for both. | ||
| 1953 | 1905 | ||
| 1954 | m->id2 = result; | 1906 | m->id2 = result; |
| 1955 | // Note: keep /ID from old file even if --static-id was given. | 1907 | // Note: keep /ID from old file even if --static-id was given. |
| @@ -1994,16 +1946,13 @@ QPDFWriter::preserveObjectStreams() | @@ -1994,16 +1946,13 @@ QPDFWriter::preserveObjectStreams() | ||
| 1994 | if (omap.empty()) { | 1946 | if (omap.empty()) { |
| 1995 | return; | 1947 | return; |
| 1996 | } | 1948 | } |
| 1997 | - // Our object_to_object_stream map has to map ObjGen -> ObjGen | ||
| 1998 | - // since we may be generating object streams out of old objects | ||
| 1999 | - // that have generation numbers greater than zero. However in an | ||
| 2000 | - // existing PDF, all object stream objects and all objects in them | ||
| 2001 | - // must have generation 0 because the PDF spec does not provide | ||
| 2002 | - // any way to do otherwise. This code filters out objects that are | ||
| 2003 | - // not allowed to be in object streams. In addition to removing | ||
| 2004 | - // objects that were erroneously included in object streams in the | ||
| 2005 | - // source PDF, it also prevents unreferenced objects from being | ||
| 2006 | - // included. | 1949 | + // Our object_to_object_stream map has to map ObjGen -> ObjGen since we may be generating object |
| 1950 | + // streams out of old objects that have generation numbers greater than zero. However in an | ||
| 1951 | + // existing PDF, all object stream objects and all objects in them must have generation 0 | ||
| 1952 | + // because the PDF spec does not provide any way to do otherwise. This code filters out objects | ||
| 1953 | + // that are not allowed to be in object streams. In addition to removing objects that were | ||
| 1954 | + // erroneously included in object streams in the source PDF, it also prevents unreferenced | ||
| 1955 | + // objects from being included. | ||
| 2007 | std::set<QPDFObjGen> eligible; | 1956 | std::set<QPDFObjGen> eligible; |
| 2008 | if (!m->preserve_unreferenced_objects) { | 1957 | if (!m->preserve_unreferenced_objects) { |
| 2009 | std::vector<QPDFObjGen> eligible_v = QPDF::Writer::getCompressibleObjGens(m->pdf); | 1958 | std::vector<QPDFObjGen> eligible_v = QPDF::Writer::getCompressibleObjGens(m->pdf); |
| @@ -2023,13 +1972,11 @@ QPDFWriter::preserveObjectStreams() | @@ -2023,13 +1972,11 @@ QPDFWriter::preserveObjectStreams() | ||
| 2023 | void | 1972 | void |
| 2024 | QPDFWriter::generateObjectStreams() | 1973 | QPDFWriter::generateObjectStreams() |
| 2025 | { | 1974 | { |
| 2026 | - // Basic strategy: make a list of objects that can go into an | ||
| 2027 | - // object stream. Then figure out how many object streams are | ||
| 2028 | - // needed so that we can distribute objects approximately evenly | ||
| 2029 | - // without having any object stream exceed 100 members. We don't | ||
| 2030 | - // have to worry about linearized files here -- if the file is | ||
| 2031 | - // linearized, we take care of excluding things that aren't | ||
| 2032 | - // allowed here later. | 1975 | + // Basic strategy: make a list of objects that can go into an object stream. Then figure out |
| 1976 | + // how many object streams are needed so that we can distribute objects approximately evenly | ||
| 1977 | + // without having any object stream exceed 100 members. We don't have to worry about linearized | ||
| 1978 | + // files here -- if the file is linearized, we take care of excluding things that aren't allowed | ||
| 1979 | + // here later. | ||
| 2033 | 1980 | ||
| 2034 | // This code doesn't do anything with /Extends. | 1981 | // This code doesn't do anything with /Extends. |
| 2035 | 1982 | ||
| @@ -2052,9 +1999,8 @@ QPDFWriter::generateObjectStreams() | @@ -2052,9 +1999,8 @@ QPDFWriter::generateObjectStreams() | ||
| 2052 | n = 0; | 1999 | n = 0; |
| 2053 | } | 2000 | } |
| 2054 | if (n == 0) { | 2001 | if (n == 0) { |
| 2055 | - // Construct a new null object as the "original" object | ||
| 2056 | - // stream. The rest of the code knows that this means | ||
| 2057 | - // we're creating the object stream from scratch. | 2002 | + // Construct a new null object as the "original" object stream. The rest of the code |
| 2003 | + // knows that this means we're creating the object stream from scratch. | ||
| 2058 | cur_ostream = m->pdf.makeIndirectObject(QPDFObjectHandle::newNull()).getObjectID(); | 2004 | cur_ostream = m->pdf.makeIndirectObject(QPDFObjectHandle::newNull()).getObjectID(); |
| 2059 | } | 2005 | } |
| 2060 | m->object_to_object_stream[iter] = cur_ostream; | 2006 | m->object_to_object_stream[iter] = cur_ostream; |
| @@ -2065,8 +2011,7 @@ QPDFWriter::generateObjectStreams() | @@ -2065,8 +2011,7 @@ QPDFWriter::generateObjectStreams() | ||
| 2065 | QPDFObjectHandle | 2011 | QPDFObjectHandle |
| 2066 | QPDFWriter::getTrimmedTrailer() | 2012 | QPDFWriter::getTrimmedTrailer() |
| 2067 | { | 2013 | { |
| 2068 | - // Remove keys from the trailer that necessarily have to be | ||
| 2069 | - // replaced when writing the file. | 2014 | + // Remove keys from the trailer that necessarily have to be replaced when writing the file. |
| 2070 | 2015 | ||
| 2071 | QPDFObjectHandle trailer = m->pdf.getTrailer().unsafeShallowCopy(); | 2016 | QPDFObjectHandle trailer = m->pdf.getTrailer().unsafeShallowCopy(); |
| 2072 | 2017 | ||
| @@ -2077,8 +2022,7 @@ QPDFWriter::getTrimmedTrailer() | @@ -2077,8 +2022,7 @@ QPDFWriter::getTrimmedTrailer() | ||
| 2077 | // Remove modification information | 2022 | // Remove modification information |
| 2078 | trailer.removeKey("/Prev"); | 2023 | trailer.removeKey("/Prev"); |
| 2079 | 2024 | ||
| 2080 | - // Remove all trailer keys that potentially come from a | ||
| 2081 | - // cross-reference stream | 2025 | + // Remove all trailer keys that potentially come from a cross-reference stream |
| 2082 | trailer.removeKey("/Index"); | 2026 | trailer.removeKey("/Index"); |
| 2083 | trailer.removeKey("/W"); | 2027 | trailer.removeKey("/W"); |
| 2084 | trailer.removeKey("/Length"); | 2028 | trailer.removeKey("/Length"); |
| @@ -2093,8 +2037,7 @@ QPDFWriter::getTrimmedTrailer() | @@ -2093,8 +2037,7 @@ QPDFWriter::getTrimmedTrailer() | ||
| 2093 | void | 2037 | void |
| 2094 | QPDFWriter::prepareFileForWrite() | 2038 | QPDFWriter::prepareFileForWrite() |
| 2095 | { | 2039 | { |
| 2096 | - // Make document extension level information direct as required by | ||
| 2097 | - // the spec. | 2040 | + // Make document extension level information direct as required by the spec. |
| 2098 | 2041 | ||
| 2099 | m->pdf.fixDanglingReferences(); | 2042 | m->pdf.fixDanglingReferences(); |
| 2100 | QPDFObjectHandle root = m->pdf.getRoot(); | 2043 | QPDFObjectHandle root = m->pdf.getRoot(); |
| @@ -2155,8 +2098,8 @@ QPDFWriter::doWriteSetup() | @@ -2155,8 +2098,8 @@ QPDFWriter::doWriteSetup() | ||
| 2155 | // Encryption has been explicitly set | 2098 | // Encryption has been explicitly set |
| 2156 | m->preserve_encryption = false; | 2099 | m->preserve_encryption = false; |
| 2157 | } else if (m->normalize_content || m->stream_decode_level || m->pclm || m->qdf_mode) { | 2100 | } else if (m->normalize_content || m->stream_decode_level || m->pclm || m->qdf_mode) { |
| 2158 | - // Encryption makes looking at contents pretty useless. If | ||
| 2159 | - // the user explicitly encrypted though, we still obey that. | 2101 | + // Encryption makes looking at contents pretty useless. If the user explicitly encrypted |
| 2102 | + // though, we still obey that. | ||
| 2160 | m->preserve_encryption = false; | 2103 | m->preserve_encryption = false; |
| 2161 | } | 2104 | } |
| 2162 | 2105 | ||
| @@ -2180,9 +2123,8 @@ QPDFWriter::doWriteSetup() | @@ -2180,9 +2123,8 @@ QPDFWriter::doWriteSetup() | ||
| 2180 | } | 2123 | } |
| 2181 | 2124 | ||
| 2182 | if (m->qdf_mode) { | 2125 | if (m->qdf_mode) { |
| 2183 | - // Generate indirect stream lengths for qdf mode since fix-qdf | ||
| 2184 | - // uses them for storing recomputed stream length data. | ||
| 2185 | - // Certain streams such as object streams, xref streams, and | 2126 | + // Generate indirect stream lengths for qdf mode since fix-qdf uses them for storing |
| 2127 | + // recomputed stream length data. Certain streams such as object streams, xref streams, and | ||
| 2186 | // hint streams always get direct stream lengths. | 2128 | // hint streams always get direct stream lengths. |
| 2187 | m->direct_stream_lengths = false; | 2129 | m->direct_stream_lengths = false; |
| 2188 | } | 2130 | } |
| @@ -2215,11 +2157,10 @@ QPDFWriter::doWriteSetup() | @@ -2215,11 +2157,10 @@ QPDFWriter::doWriteSetup() | ||
| 2215 | } | 2157 | } |
| 2216 | 2158 | ||
| 2217 | if (m->linearized || m->encrypted) { | 2159 | if (m->linearized || m->encrypted) { |
| 2218 | - // The document catalog is not allowed to be compressed in | ||
| 2219 | - // linearized files either. It also appears that Adobe Reader | ||
| 2220 | - // 8.0.0 has a bug that prevents it from being able to handle | ||
| 2221 | - // encrypted files with compressed document catalogs, so we | ||
| 2222 | - // disable them in that case as well. | 2160 | + // The document catalog is not allowed to be compressed in linearized files either. It also |
| 2161 | + // appears that Adobe Reader 8.0.0 has a bug that prevents it from being able to handle | ||
| 2162 | + // encrypted files with compressed document catalogs, so we disable them in that case as | ||
| 2163 | + // well. | ||
| 2223 | if (m->object_to_object_stream.count(m->root_og)) { | 2164 | if (m->object_to_object_stream.count(m->root_og)) { |
| 2224 | QTC::TC("qpdf", "QPDFWriter uncompressing root"); | 2165 | QTC::TC("qpdf", "QPDFWriter uncompressing root"); |
| 2225 | m->object_to_object_stream.erase(m->root_og); | 2166 | m->object_to_object_stream.erase(m->root_og); |
| @@ -2254,9 +2195,8 @@ QPDFWriter::write() | @@ -2254,9 +2195,8 @@ QPDFWriter::write() | ||
| 2254 | { | 2195 | { |
| 2255 | doWriteSetup(); | 2196 | doWriteSetup(); |
| 2256 | 2197 | ||
| 2257 | - // Set up progress reporting. For linearized files, we write two | ||
| 2258 | - // passes. events_expected is an approximation, but it's good | ||
| 2259 | - // enough for progress reporting, which is mostly a guess anyway. | 2198 | + // Set up progress reporting. For linearized files, we write two passes. events_expected is an |
| 2199 | + // approximation, but it's good enough for progress reporting, which is mostly a guess anyway. | ||
| 2260 | m->events_expected = QIntC::to_int(m->pdf.getObjectCount() * (m->linearized ? 2 : 1)); | 2200 | m->events_expected = QIntC::to_int(m->pdf.getObjectCount() * (m->linearized ? 2 : 1)); |
| 2261 | 2201 | ||
| 2262 | prepareFileForWrite(); | 2202 | prepareFileForWrite(); |
| @@ -2338,17 +2278,16 @@ QPDFWriter::writeHeader() | @@ -2338,17 +2278,16 @@ QPDFWriter::writeHeader() | ||
| 2338 | // PCLm version | 2278 | // PCLm version |
| 2339 | writeString("\n%PCLm 1.0\n"); | 2279 | writeString("\n%PCLm 1.0\n"); |
| 2340 | } else { | 2280 | } else { |
| 2341 | - // This string of binary characters would not be valid UTF-8, so | ||
| 2342 | - // it really should be treated as binary. | 2281 | + // This string of binary characters would not be valid UTF-8, so it really should be treated |
| 2282 | + // as binary. | ||
| 2343 | writeString("\n%\xbf\xf7\xa2\xfe\n"); | 2283 | writeString("\n%\xbf\xf7\xa2\xfe\n"); |
| 2344 | } | 2284 | } |
| 2345 | writeStringQDF("%QDF-1.0\n\n"); | 2285 | writeStringQDF("%QDF-1.0\n\n"); |
| 2346 | 2286 | ||
| 2347 | - // Note: do not write extra header text here. Linearized PDFs | ||
| 2348 | - // must include the entire linearization parameter dictionary | ||
| 2349 | - // within the first 1024 characters of the PDF file, so for | ||
| 2350 | - // linearized files, we have to write extra header text after the | ||
| 2351 | - // linearization parameter dictionary. | 2287 | + // Note: do not write extra header text here. Linearized PDFs must include the entire |
| 2288 | + // linearization parameter dictionary within the first 1024 characters of the PDF file, so for | ||
| 2289 | + // linearized files, we have to write extra header text after the linearization parameter | ||
| 2290 | + // dictionary. | ||
| 2352 | } | 2291 | } |
| 2353 | 2292 | ||
| 2354 | void | 2293 | void |
| @@ -2397,9 +2336,8 @@ QPDFWriter::writeHintStream(int hint_id) | @@ -2397,9 +2336,8 @@ QPDFWriter::writeHintStream(int hint_id) | ||
| 2397 | qpdf_offset_t | 2336 | qpdf_offset_t |
| 2398 | QPDFWriter::writeXRefTable(trailer_e which, int first, int last, int size) | 2337 | QPDFWriter::writeXRefTable(trailer_e which, int first, int last, int size) |
| 2399 | { | 2338 | { |
| 2400 | - // There are too many extra arguments to replace overloaded | ||
| 2401 | - // function with defaults in the header file...too much risk of | ||
| 2402 | - // leaving something off. | 2339 | + // There are too many extra arguments to replace overloaded function with defaults in the header |
| 2340 | + // file...too much risk of leaving something off. | ||
| 2403 | return writeXRefTable(which, first, last, size, 0, false, 0, 0, 0, 0); | 2341 | return writeXRefTable(which, first, last, size, 0, false, 0, 0, 0, 0); |
| 2404 | } | 2342 | } |
| 2405 | 2343 | ||
| @@ -2446,9 +2384,8 @@ qpdf_offset_t | @@ -2446,9 +2384,8 @@ qpdf_offset_t | ||
| 2446 | QPDFWriter::writeXRefStream( | 2384 | QPDFWriter::writeXRefStream( |
| 2447 | int objid, int max_id, qpdf_offset_t max_offset, trailer_e which, int first, int last, int size) | 2385 | int objid, int max_id, qpdf_offset_t max_offset, trailer_e which, int first, int last, int size) |
| 2448 | { | 2386 | { |
| 2449 | - // There are too many extra arguments to replace overloaded | ||
| 2450 | - // function with defaults in the header file...too much risk of | ||
| 2451 | - // leaving something off. | 2387 | + // There are too many extra arguments to replace overloaded function with defaults in the header |
| 2388 | + // file...too much risk of leaving something off. | ||
| 2452 | return writeXRefStream( | 2389 | return writeXRefStream( |
| 2453 | objid, max_id, max_offset, which, first, last, size, 0, 0, 0, 0, false, 0); | 2390 | objid, max_id, max_offset, which, first, last, size, 0, 0, 0, 0, false, 0); |
| 2454 | } | 2391 | } |
| @@ -2480,8 +2417,8 @@ QPDFWriter::writeXRefStream( | @@ -2480,8 +2417,8 @@ QPDFWriter::writeXRefStream( | ||
| 2480 | 2417 | ||
| 2481 | unsigned int esize = 1 + f1_size + f2_size; | 2418 | unsigned int esize = 1 + f1_size + f2_size; |
| 2482 | 2419 | ||
| 2483 | - // Must store in xref table in advance of writing the actual data | ||
| 2484 | - // rather than waiting for openObject to do it. | 2420 | + // Must store in xref table in advance of writing the actual data rather than waiting for |
| 2421 | + // openObject to do it. | ||
| 2485 | m->xref[xref_id] = QPDFXRefEntry(m->pipeline->getCount()); | 2422 | m->xref[xref_id] = QPDFXRefEntry(m->pipeline->getCount()); |
| 2486 | 2423 | ||
| 2487 | Pipeline* p = pushPipeline(new Pl_Buffer("xref stream")); | 2424 | Pipeline* p = pushPipeline(new Pl_Buffer("xref stream")); |
| @@ -2489,9 +2426,8 @@ QPDFWriter::writeXRefStream( | @@ -2489,9 +2426,8 @@ QPDFWriter::writeXRefStream( | ||
| 2489 | if ((m->compress_streams || (m->stream_decode_level == qpdf_dl_none)) && (!m->qdf_mode)) { | 2426 | if ((m->compress_streams || (m->stream_decode_level == qpdf_dl_none)) && (!m->qdf_mode)) { |
| 2490 | compressed = true; | 2427 | compressed = true; |
| 2491 | if (!skip_compression) { | 2428 | if (!skip_compression) { |
| 2492 | - // Write the stream dictionary for compression but don't | ||
| 2493 | - // actually compress. This helps us with computation of | ||
| 2494 | - // padding for pass 1 of linearization. | 2429 | + // Write the stream dictionary for compression but don't actually compress. This helps |
| 2430 | + // us with computation of padding for pass 1 of linearization. | ||
| 2495 | p = pushPipeline(new Pl_Flate("compress xref", p, Pl_Flate::a_deflate)); | 2431 | p = pushPipeline(new Pl_Flate("compress xref", p, Pl_Flate::a_deflate)); |
| 2496 | } | 2432 | } |
| 2497 | p = pushPipeline(new Pl_PNGFilter("pngify xref", p, Pl_PNGFilter::a_encode, esize)); | 2433 | p = pushPipeline(new Pl_PNGFilter("pngify xref", p, Pl_PNGFilter::a_encode, esize)); |
| @@ -2563,13 +2499,11 @@ QPDFWriter::writeXRefStream( | @@ -2563,13 +2499,11 @@ QPDFWriter::writeXRefStream( | ||
| 2563 | size_t | 2499 | size_t |
| 2564 | QPDFWriter::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) | 2500 | QPDFWriter::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) |
| 2565 | { | 2501 | { |
| 2566 | - // This routine is called right after a linearization first pass | ||
| 2567 | - // xref stream has been written without compression. Calculate | ||
| 2568 | - // the amount of padding that would be required in the worst case, | ||
| 2569 | - // assuming the number of uncompressed bytes remains the same. | ||
| 2570 | - // The worst case for zlib is that the output is larger than the | ||
| 2571 | - // input by 6 bytes plus 5 bytes per 16K, and then we'll add 10 | ||
| 2572 | - // extra bytes for number length increases. | 2502 | + // This routine is called right after a linearization first pass xref stream has been written |
| 2503 | + // without compression. Calculate the amount of padding that would be required in the worst | ||
| 2504 | + // case, assuming the number of uncompressed bytes remains the same. The worst case for zlib is | ||
| 2505 | + // that the output is larger than the input by 6 bytes plus 5 bytes per 16K, and then we'll add | ||
| 2506 | + // 10 extra bytes for number length increases. | ||
| 2573 | 2507 | ||
| 2574 | return QIntC::to_size(16 + (5 * ((xref_bytes + 16383) / 16384))); | 2508 | return QIntC::to_size(16 + (5 * ((xref_bytes + 16383) / 16384))); |
| 2575 | } | 2509 | } |
| @@ -2577,17 +2511,14 @@ QPDFWriter::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) | @@ -2577,17 +2511,14 @@ QPDFWriter::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) | ||
| 2577 | void | 2511 | void |
| 2578 | QPDFWriter::discardGeneration(std::map<QPDFObjGen, int> const& in, std::map<int, int>& out) | 2512 | QPDFWriter::discardGeneration(std::map<QPDFObjGen, int> const& in, std::map<int, int>& out) |
| 2579 | { | 2513 | { |
| 2580 | - // There are deep assumptions in the linearization code in QPDF | ||
| 2581 | - // that there is only one object with each object number; i.e., | ||
| 2582 | - // you can't have two objects with the same object number and | ||
| 2583 | - // different generations. This is a pretty safe assumption | ||
| 2584 | - // because Adobe Reader and Acrobat can't actually handle this | ||
| 2585 | - // case. There is not much if any code in QPDF outside | ||
| 2586 | - // linearization that assumes this, but the linearization code as | ||
| 2587 | - // currently implemented would do weird things if we found such a | ||
| 2588 | - // case. In order to avoid breaking ABI changes in QPDF, we will | ||
| 2589 | - // first assert that this condition holds. Then we can create new | ||
| 2590 | - // maps for QPDF that throw away generation numbers. | 2514 | + // There are deep assumptions in the linearization code in QPDF that there is only one object |
| 2515 | + // with each object number; i.e., you can't have two objects with the same object number and | ||
| 2516 | + // different generations. This is a pretty safe assumption because Adobe Reader and Acrobat | ||
| 2517 | + // can't actually handle this case. There is not much if any code in QPDF outside linearization | ||
| 2518 | + // that assumes this, but the linearization code as currently implemented would do weird things | ||
| 2519 | + // if we found such a case. In order to avoid breaking ABI changes in QPDF, we will first | ||
| 2520 | + // assert that this condition holds. Then we can create new maps for QPDF that throw away | ||
| 2521 | + // generation numbers. | ||
| 2591 | 2522 | ||
| 2592 | out.clear(); | 2523 | out.clear(); |
| 2593 | for (auto const& iter: in) { | 2524 | for (auto const& iter: in) { |
| @@ -2707,25 +2638,21 @@ QPDFWriter::writeLinearized() | @@ -2707,25 +2638,21 @@ QPDFWriter::writeLinearized() | ||
| 2707 | m->next_objid = part4_first_obj; | 2638 | m->next_objid = part4_first_obj; |
| 2708 | enqueuePart(part4); | 2639 | enqueuePart(part4); |
| 2709 | if (m->next_objid != after_part4) { | 2640 | if (m->next_objid != after_part4) { |
| 2710 | - // This can happen with very botched files as in the fuzzer | ||
| 2711 | - // test. There are likely some faulty assumptions in | ||
| 2712 | - // calculateLinearizationData | ||
| 2713 | - throw std::runtime_error("error encountered after" | ||
| 2714 | - " writing part 4 of linearized data"); | 2641 | + // This can happen with very botched files as in the fuzzer test. There are likely some |
| 2642 | + // faulty assumptions in calculateLinearizationData | ||
| 2643 | + throw std::runtime_error("error encountered after writing part 4 of linearized data"); | ||
| 2715 | } | 2644 | } |
| 2716 | m->next_objid = part6_first_obj; | 2645 | m->next_objid = part6_first_obj; |
| 2717 | enqueuePart(part6); | 2646 | enqueuePart(part6); |
| 2718 | if (m->next_objid != after_part6) { | 2647 | if (m->next_objid != after_part6) { |
| 2719 | - throw std::runtime_error("error encountered after" | ||
| 2720 | - " writing part 6 of linearized data"); | 2648 | + throw std::runtime_error("error encountered after writing part 6 of linearized data"); |
| 2721 | } | 2649 | } |
| 2722 | m->next_objid = second_half_first_obj; | 2650 | m->next_objid = second_half_first_obj; |
| 2723 | enqueuePart(part7); | 2651 | enqueuePart(part7); |
| 2724 | enqueuePart(part8); | 2652 | enqueuePart(part8); |
| 2725 | enqueuePart(part9); | 2653 | enqueuePart(part9); |
| 2726 | if (m->next_objid != after_second_half) { | 2654 | if (m->next_objid != after_second_half) { |
| 2727 | - throw std::runtime_error("error encountered after" | ||
| 2728 | - " writing part 9 of linearized data"); | 2655 | + throw std::runtime_error("error encountered after writing part 9 of linearized data"); |
| 2729 | } | 2656 | } |
| 2730 | 2657 | ||
| 2731 | qpdf_offset_t hint_length = 0; | 2658 | qpdf_offset_t hint_length = 0; |
| @@ -2754,13 +2681,11 @@ QPDFWriter::writeLinearized() | @@ -2754,13 +2681,11 @@ QPDFWriter::writeLinearized() | ||
| 2754 | 2681 | ||
| 2755 | writeHeader(); | 2682 | writeHeader(); |
| 2756 | 2683 | ||
| 2757 | - // Part 2: linearization parameter dictionary. Save enough | ||
| 2758 | - // space to write real dictionary. 200 characters is enough | ||
| 2759 | - // space if all numerical values in the parameter dictionary | ||
| 2760 | - // that contain offsets are 20 digits long plus a few extra | ||
| 2761 | - // characters for safety. The entire linearization parameter | ||
| 2762 | - // dictionary must appear within the first 1024 characters of | ||
| 2763 | - // the file. | 2684 | + // Part 2: linearization parameter dictionary. Save enough space to write real dictionary. |
| 2685 | + // 200 characters is enough space if all numerical values in the parameter dictionary that | ||
| 2686 | + // contain offsets are 20 digits long plus a few extra characters for safety. The entire | ||
| 2687 | + // linearization parameter dictionary must appear within the first 1024 characters of the | ||
| 2688 | + // file. | ||
| 2764 | 2689 | ||
| 2765 | qpdf_offset_t pos = m->pipeline->getCount(); | 2690 | qpdf_offset_t pos = m->pipeline->getCount(); |
| 2766 | openObject(lindict_id); | 2691 | openObject(lindict_id); |
| @@ -2772,8 +2697,7 @@ QPDFWriter::writeLinearized() | @@ -2772,8 +2697,7 @@ QPDFWriter::writeLinearized() | ||
| 2772 | 2697 | ||
| 2773 | writeString(" /Linearized 1 /L "); | 2698 | writeString(" /Linearized 1 /L "); |
| 2774 | writeString(std::to_string(file_size + hint_length)); | 2699 | writeString(std::to_string(file_size + hint_length)); |
| 2775 | - // Implementation note 121 states that a space is | ||
| 2776 | - // mandatory after this open bracket. | 2700 | + // Implementation note 121 states that a space is mandatory after this open bracket. |
| 2777 | writeString(" /H [ "); | 2701 | writeString(" /H [ "); |
| 2778 | writeString(std::to_string(m->xref[hint_id].getOffset())); | 2702 | writeString(std::to_string(m->xref[hint_id].getOffset())); |
| 2779 | writeString(" "); | 2703 | writeString(" "); |
| @@ -2793,8 +2717,8 @@ QPDFWriter::writeLinearized() | @@ -2793,8 +2717,8 @@ QPDFWriter::writeLinearized() | ||
| 2793 | writePad(QIntC::to_size(pos - m->pipeline->getCount() + pad)); | 2717 | writePad(QIntC::to_size(pos - m->pipeline->getCount() + pad)); |
| 2794 | writeString("\n"); | 2718 | writeString("\n"); |
| 2795 | 2719 | ||
| 2796 | - // If the user supplied any additional header text, write it | ||
| 2797 | - // here after the linearization parameter dictionary. | 2720 | + // If the user supplied any additional header text, write it here after the linearization |
| 2721 | + // parameter dictionary. | ||
| 2798 | writeString(m->extra_header_text); | 2722 | writeString(m->extra_header_text); |
| 2799 | 2723 | ||
| 2800 | // Part 3: first page cross reference table and trailer. | 2724 | // Part 3: first page cross reference table and trailer. |
| @@ -2807,14 +2731,11 @@ QPDFWriter::writeLinearized() | @@ -2807,14 +2731,11 @@ QPDFWriter::writeLinearized() | ||
| 2807 | if (need_xref_stream) { | 2731 | if (need_xref_stream) { |
| 2808 | // Must pad here too. | 2732 | // Must pad here too. |
| 2809 | if (pass == 1) { | 2733 | if (pass == 1) { |
| 2810 | - // Set first_half_max_obj_offset to a value large | ||
| 2811 | - // enough to force four bytes to be reserved for each | ||
| 2812 | - // file offset. This would provide adequate space for | ||
| 2813 | - // the xref stream as long as the last object in page | ||
| 2814 | - // 1 starts with in the first 4 GB of the file, which | ||
| 2815 | - // is extremely likely. In the second pass, we will | ||
| 2816 | - // know the actual value for this, but it's okay if | ||
| 2817 | - // it's smaller. | 2734 | + // Set first_half_max_obj_offset to a value large enough to force four bytes to be |
| 2735 | + // reserved for each file offset. This would provide adequate space for the xref | ||
| 2736 | + // stream as long as the last object in page 1 starts with in the first 4 GB of the | ||
| 2737 | + // file, which is extremely likely. In the second pass, we will know the actual | ||
| 2738 | + // value for this, but it's okay if it's smaller. | ||
| 2818 | first_half_max_obj_offset = 1 << 25; | 2739 | first_half_max_obj_offset = 1 << 25; |
| 2819 | } | 2740 | } |
| 2820 | pos = m->pipeline->getCount(); | 2741 | pos = m->pipeline->getCount(); |
| @@ -2834,13 +2755,11 @@ QPDFWriter::writeLinearized() | @@ -2834,13 +2755,11 @@ QPDFWriter::writeLinearized() | ||
| 2834 | pass); | 2755 | pass); |
| 2835 | qpdf_offset_t endpos = m->pipeline->getCount(); | 2756 | qpdf_offset_t endpos = m->pipeline->getCount(); |
| 2836 | if (pass == 1) { | 2757 | if (pass == 1) { |
| 2837 | - // Pad so we have enough room for the real xref | ||
| 2838 | - // stream. | 2758 | + // Pad so we have enough room for the real xref stream. |
| 2839 | writePad(calculateXrefStreamPadding(endpos - pos)); | 2759 | writePad(calculateXrefStreamPadding(endpos - pos)); |
| 2840 | first_xref_end = m->pipeline->getCount(); | 2760 | first_xref_end = m->pipeline->getCount(); |
| 2841 | } else { | 2761 | } else { |
| 2842 | - // Pad so that the next object starts at the same | ||
| 2843 | - // place as in pass 1. | 2762 | + // Pad so that the next object starts at the same place as in pass 1. |
| 2844 | writePad(QIntC::to_size(first_xref_end - endpos)); | 2763 | writePad(QIntC::to_size(first_xref_end - endpos)); |
| 2845 | 2764 | ||
| 2846 | if (m->pipeline->getCount() != first_xref_end) { | 2765 | if (m->pipeline->getCount() != first_xref_end) { |
| @@ -2913,9 +2832,8 @@ QPDFWriter::writeLinearized() | @@ -2913,9 +2832,8 @@ QPDFWriter::writeLinearized() | ||
| 2913 | qpdf_offset_t endpos = m->pipeline->getCount(); | 2832 | qpdf_offset_t endpos = m->pipeline->getCount(); |
| 2914 | 2833 | ||
| 2915 | if (pass == 1) { | 2834 | if (pass == 1) { |
| 2916 | - // Pad so we have enough room for the real xref | ||
| 2917 | - // stream. See comments for previous xref stream on | ||
| 2918 | - // how we calculate the padding. | 2835 | + // Pad so we have enough room for the real xref stream. See comments for previous |
| 2836 | + // xref stream on how we calculate the padding. | ||
| 2919 | writePad(calculateXrefStreamPadding(endpos - pos)); | 2837 | writePad(calculateXrefStreamPadding(endpos - pos)); |
| 2920 | writeString("\n"); | 2838 | writeString("\n"); |
| 2921 | second_xref_end = m->pipeline->getCount(); | 2839 | second_xref_end = m->pipeline->getCount(); |
| @@ -2925,11 +2843,10 @@ QPDFWriter::writeLinearized() | @@ -2925,11 +2843,10 @@ QPDFWriter::writeLinearized() | ||
| 2925 | QIntC::to_size(second_xref_end + hint_length - 1 - m->pipeline->getCount())); | 2843 | QIntC::to_size(second_xref_end + hint_length - 1 - m->pipeline->getCount())); |
| 2926 | writeString("\n"); | 2844 | writeString("\n"); |
| 2927 | 2845 | ||
| 2928 | - // If this assertion fails, maybe we didn't have | ||
| 2929 | - // enough padding above. | 2846 | + // If this assertion fails, maybe we didn't have enough padding above. |
| 2930 | if (m->pipeline->getCount() != second_xref_end + hint_length) { | 2847 | if (m->pipeline->getCount() != second_xref_end + hint_length) { |
| 2931 | - throw std::logic_error("count mismatch after xref stream;" | ||
| 2932 | - " possible insufficient padding?"); | 2848 | + throw std::logic_error( |
| 2849 | + "count mismatch after xref stream; possible insufficient padding?"); | ||
| 2933 | } | 2850 | } |
| 2934 | } | 2851 | } |
| 2935 | } else { | 2852 | } else { |
| @@ -2954,8 +2871,7 @@ QPDFWriter::writeLinearized() | @@ -2954,8 +2871,7 @@ QPDFWriter::writeLinearized() | ||
| 2954 | file_size = m->pipeline->getCount(); | 2871 | file_size = m->pipeline->getCount(); |
| 2955 | pp_pass1 = nullptr; | 2872 | pp_pass1 = nullptr; |
| 2956 | 2873 | ||
| 2957 | - // Save hint offset since it will be set to zero by | ||
| 2958 | - // calling openObject. | 2874 | + // Save hint offset since it will be set to zero by calling openObject. |
| 2959 | qpdf_offset_t hint_offset1 = m->xref[hint_id].getOffset(); | 2875 | qpdf_offset_t hint_offset1 = m->xref[hint_id].getOffset(); |
| 2960 | 2876 | ||
| 2961 | // Write hint stream to a buffer | 2877 | // Write hint stream to a buffer |
| @@ -3003,10 +2919,8 @@ QPDFWriter::enqueueObjectsStandard() | @@ -3003,10 +2919,8 @@ QPDFWriter::enqueueObjectsStandard() | ||
| 3003 | QPDFObjectHandle trailer = getTrimmedTrailer(); | 2919 | QPDFObjectHandle trailer = getTrimmedTrailer(); |
| 3004 | enqueueObject(trailer.getKey("/Root")); | 2920 | enqueueObject(trailer.getKey("/Root")); |
| 3005 | 2921 | ||
| 3006 | - // Next place any other objects referenced from the trailer | ||
| 3007 | - // dictionary into the queue, handling direct objects recursively. | ||
| 3008 | - // Root is already there, so enqueuing it a second time is a | ||
| 3009 | - // no-op. | 2922 | + // Next place any other objects referenced from the trailer dictionary into the queue, handling |
| 2923 | + // direct objects recursively. Root is already there, so enqueuing it a second time is a no-op. | ||
| 3010 | for (auto const& key: trailer.getKeys()) { | 2924 | for (auto const& key: trailer.getKeys()) { |
| 3011 | enqueueObject(trailer.getKey(key)); | 2925 | enqueueObject(trailer.getKey(key)); |
| 3012 | } | 2926 | } |
| @@ -3015,9 +2929,8 @@ QPDFWriter::enqueueObjectsStandard() | @@ -3015,9 +2929,8 @@ QPDFWriter::enqueueObjectsStandard() | ||
| 3015 | void | 2929 | void |
| 3016 | QPDFWriter::enqueueObjectsPCLm() | 2930 | QPDFWriter::enqueueObjectsPCLm() |
| 3017 | { | 2931 | { |
| 3018 | - // Image transform stream content for page strip images. | ||
| 3019 | - // Each of this new stream has to come after every page image | ||
| 3020 | - // strip written in the pclm file. | 2932 | + // Image transform stream content for page strip images. Each of this new stream has to come |
| 2933 | + // after every page image strip written in the pclm file. | ||
| 3021 | std::string image_transform_content = "q /image Do Q\n"; | 2934 | std::string image_transform_content = "q /image Do Q\n"; |
| 3022 | 2935 | ||
| 3023 | // enqueue all pages first | 2936 | // enqueue all pages first |
libqpdf/QPDF_Array.cc
| @@ -12,9 +12,9 @@ QPDF_Array::checkOwnership(QPDFObjectHandle const& item) const | @@ -12,9 +12,9 @@ QPDF_Array::checkOwnership(QPDFObjectHandle const& item) const | ||
| 12 | if (qpdf) { | 12 | if (qpdf) { |
| 13 | if (auto item_qpdf = obj->getQPDF()) { | 13 | if (auto item_qpdf = obj->getQPDF()) { |
| 14 | if (qpdf != item_qpdf) { | 14 | if (qpdf != item_qpdf) { |
| 15 | - throw std::logic_error("Attempting to add an object from a different QPDF. " | ||
| 16 | - "Use QPDF::copyForeignObject to add objects from " | ||
| 17 | - "another file."); | 15 | + throw std::logic_error( |
| 16 | + "Attempting to add an object from a different QPDF. Use " | ||
| 17 | + "QPDF::copyForeignObject to add objects from another file."); | ||
| 18 | } | 18 | } |
| 19 | } | 19 | } |
| 20 | } | 20 | } |
libqpdf/QPDF_Dictionary.cc
| @@ -89,8 +89,7 @@ QPDF_Dictionary::hasKey(std::string const& key) | @@ -89,8 +89,7 @@ QPDF_Dictionary::hasKey(std::string const& key) | ||
| 89 | QPDFObjectHandle | 89 | QPDFObjectHandle |
| 90 | QPDF_Dictionary::getKey(std::string const& key) | 90 | QPDF_Dictionary::getKey(std::string const& key) |
| 91 | { | 91 | { |
| 92 | - // PDF spec says fetching a non-existent key from a dictionary | ||
| 93 | - // returns the null object. | 92 | + // PDF spec says fetching a non-existent key from a dictionary returns the null object. |
| 94 | auto item = this->items.find(key); | 93 | auto item = this->items.find(key); |
| 95 | if (item != this->items.end()) { | 94 | if (item != this->items.end()) { |
| 96 | // May be a null object | 95 | // May be a null object |
| @@ -123,8 +122,7 @@ void | @@ -123,8 +122,7 @@ void | ||
| 123 | QPDF_Dictionary::replaceKey(std::string const& key, QPDFObjectHandle value) | 122 | QPDF_Dictionary::replaceKey(std::string const& key, QPDFObjectHandle value) |
| 124 | { | 123 | { |
| 125 | if (value.isNull()) { | 124 | if (value.isNull()) { |
| 126 | - // The PDF spec doesn't distinguish between keys with null | ||
| 127 | - // values and missing keys. | 125 | + // The PDF spec doesn't distinguish between keys with null values and missing keys. |
| 128 | removeKey(key); | 126 | removeKey(key); |
| 129 | } else { | 127 | } else { |
| 130 | // add or replace value | 128 | // add or replace value |
libqpdf/QPDF_Name.cc
| @@ -32,8 +32,7 @@ QPDF_Name::normalizeName(std::string const& name) | @@ -32,8 +32,7 @@ QPDF_Name::normalizeName(std::string const& name) | ||
| 32 | char ch = name.at(i); | 32 | char ch = name.at(i); |
| 33 | // Don't use locale/ctype here; follow PDF spec guidelines. | 33 | // Don't use locale/ctype here; follow PDF spec guidelines. |
| 34 | if (ch == '\0') { | 34 | if (ch == '\0') { |
| 35 | - // QPDFTokenizer embeds a null character to encode an | ||
| 36 | - // invalid #. | 35 | + // QPDFTokenizer embeds a null character to encode an invalid #. |
| 37 | result += "#"; | 36 | result += "#"; |
| 38 | } else if ( | 37 | } else if ( |
| 39 | ch < 33 || ch == '#' || ch == '/' || ch == '(' || ch == ')' || ch == '{' || ch == '}' || | 38 | ch < 33 || ch == '#' || ch == '/' || ch == '(' || ch == ')' || ch == '{' || ch == '}' || |
libqpdf/QPDF_Real.cc
| @@ -41,9 +41,8 @@ QPDF_Real::unparse() | @@ -41,9 +41,8 @@ QPDF_Real::unparse() | ||
| 41 | JSON | 41 | JSON |
| 42 | QPDF_Real::getJSON(int json_version) | 42 | QPDF_Real::getJSON(int json_version) |
| 43 | { | 43 | { |
| 44 | - // While PDF allows .x or -.x, JSON does not. Rather than | ||
| 45 | - // converting from string to double and back, just handle this as a | ||
| 46 | - // special case for JSON. | 44 | + // While PDF allows .x or -.x, JSON does not. Rather than converting from string to double and |
| 45 | + // back, just handle this as a special case for JSON. | ||
| 47 | std::string result; | 46 | std::string result; |
| 48 | if (this->val.length() == 0) { | 47 | if (this->val.length() == 0) { |
| 49 | // Can't really happen... | 48 | // Can't really happen... |
libqpdf/QPDF_String.cc
| @@ -2,9 +2,8 @@ | @@ -2,9 +2,8 @@ | ||
| 2 | 2 | ||
| 3 | #include <qpdf/QUtil.hh> | 3 | #include <qpdf/QUtil.hh> |
| 4 | 4 | ||
| 5 | -// DO NOT USE ctype -- it is locale dependent for some things, and | ||
| 6 | -// it's not worth the risk of including it in case it may accidentally | ||
| 7 | -// be used. | 5 | +// DO NOT USE ctype -- it is locale dependent for some things, and it's not worth the risk of |
| 6 | +// including it in case it may accidentally be used. | ||
| 8 | 7 | ||
| 9 | static bool | 8 | static bool |
| 10 | is_iso_latin1_printable(char ch) | 9 | is_iso_latin1_printable(char ch) |
| @@ -62,8 +61,7 @@ QPDF_String::getJSON(int json_version) | @@ -62,8 +61,7 @@ QPDF_String::getJSON(int json_version) | ||
| 62 | } else if (!useHexString()) { | 61 | } else if (!useHexString()) { |
| 63 | std::string test; | 62 | std::string test; |
| 64 | if (QUtil::utf8_to_pdf_doc(candidate, test, '?') && (test == this->val)) { | 63 | if (QUtil::utf8_to_pdf_doc(candidate, test, '?') && (test == this->val)) { |
| 65 | - // This is a PDF-doc string that can be losslessly encoded | ||
| 66 | - // as Unicode. | 64 | + // This is a PDF-doc string that can be losslessly encoded as Unicode. |
| 67 | is_unicode = true; | 65 | is_unicode = true; |
| 68 | result = candidate; | 66 | result = candidate; |
| 69 | } | 67 | } |
| @@ -79,9 +77,8 @@ QPDF_String::getJSON(int json_version) | @@ -79,9 +77,8 @@ QPDF_String::getJSON(int json_version) | ||
| 79 | bool | 77 | bool |
| 80 | QPDF_String::useHexString() const | 78 | QPDF_String::useHexString() const |
| 81 | { | 79 | { |
| 82 | - // Heuristic: use the hexadecimal representation of a string if | ||
| 83 | - // there are any non-printable (in PDF Doc encoding) characters or | ||
| 84 | - // if too large of a proportion of the string consists of | 80 | + // Heuristic: use the hexadecimal representation of a string if there are any non-printable (in |
| 81 | + // PDF Doc encoding) characters or if too large of a proportion of the string consists of | ||
| 85 | // non-ASCII characters. | 82 | // non-ASCII characters. |
| 86 | unsigned int non_ascii = 0; | 83 | unsigned int non_ascii = 0; |
| 87 | for (auto const ch: this->val) { | 84 | for (auto const ch: this->val) { |
| @@ -172,8 +169,8 @@ QPDF_String::getUTF8Val() const | @@ -172,8 +169,8 @@ QPDF_String::getUTF8Val() const | ||
| 172 | if (QUtil::is_utf16(this->val)) { | 169 | if (QUtil::is_utf16(this->val)) { |
| 173 | return QUtil::utf16_to_utf8(this->val); | 170 | return QUtil::utf16_to_utf8(this->val); |
| 174 | } else if (QUtil::is_explicit_utf8(this->val)) { | 171 | } else if (QUtil::is_explicit_utf8(this->val)) { |
| 175 | - // PDF 2.0 allows UTF-8 strings when explicitly prefixed with | ||
| 176 | - // the three-byte representation of U+FEFF. | 172 | + // PDF 2.0 allows UTF-8 strings when explicitly prefixed with the three-byte representation |
| 173 | + // of U+FEFF. | ||
| 177 | return this->val.substr(3); | 174 | return this->val.substr(3); |
| 178 | } else { | 175 | } else { |
| 179 | return QUtil::pdf_doc_to_utf8(this->val); | 176 | return QUtil::pdf_doc_to_utf8(this->val); |
libqpdf/QUtil.cc
| @@ -296,9 +296,8 @@ template <typename T> | @@ -296,9 +296,8 @@ template <typename T> | ||
| 296 | static std::string | 296 | static std::string |
| 297 | int_to_string_base_internal(T num, int base, int length) | 297 | int_to_string_base_internal(T num, int base, int length) |
| 298 | { | 298 | { |
| 299 | - // Backward compatibility -- int_to_string, which calls this | ||
| 300 | - // function, used to use sprintf with %0*d, so we interpret length | ||
| 301 | - // such that a negative value appends spaces and a positive value | 299 | + // Backward compatibility -- int_to_string, which calls this function, used to use sprintf with |
| 300 | + // %0*d, so we interpret length such that a negative value appends spaces and a positive value | ||
| 302 | // prepends zeroes. | 301 | // prepends zeroes. |
| 303 | if (!((base == 8) || (base == 10) || (base == 16))) { | 302 | if (!((base == 8) || (base == 10) || (base == 16))) { |
| 304 | throw std::logic_error("int_to_string_base called with unsupported base"); | 303 | throw std::logic_error("int_to_string_base called with unsupported base"); |
| @@ -352,9 +351,8 @@ QUtil::uint_to_string_base(unsigned long long num, int base, int length) | @@ -352,9 +351,8 @@ QUtil::uint_to_string_base(unsigned long long num, int base, int length) | ||
| 352 | std::string | 351 | std::string |
| 353 | QUtil::double_to_string(double num, int decimal_places, bool trim_trailing_zeroes) | 352 | QUtil::double_to_string(double num, int decimal_places, bool trim_trailing_zeroes) |
| 354 | { | 353 | { |
| 355 | - // Backward compatibility -- this code used to use sprintf and | ||
| 356 | - // treated decimal_places <= 0 to mean to use the default, which | ||
| 357 | - // was six decimal places. Starting in 10.2, we trim trailing | 354 | + // Backward compatibility -- this code used to use sprintf and treated decimal_places <= 0 to |
| 355 | + // mean to use the default, which was six decimal places. Starting in 10.2, we trim trailing | ||
| 358 | // zeroes by default. | 356 | // zeroes by default. |
| 359 | if (decimal_places <= 0) { | 357 | if (decimal_places <= 0) { |
| 360 | decimal_places = 6; | 358 | decimal_places = 6; |
| @@ -739,8 +737,8 @@ std::string | @@ -739,8 +737,8 @@ std::string | ||
| 739 | QUtil::hex_decode(std::string const& input) | 737 | QUtil::hex_decode(std::string const& input) |
| 740 | { | 738 | { |
| 741 | std::string result; | 739 | std::string result; |
| 742 | - // We know result.size() <= 0.5 * input.size() + 1. However, reserving | ||
| 743 | - // string space for this upper bound has a negative impact. | 740 | + // We know result.size() <= 0.5 * input.size() + 1. However, reserving string space for this |
| 741 | + // upper bound has a negative impact. | ||
| 744 | bool first = true; | 742 | bool first = true; |
| 745 | char decoded; | 743 | char decoded; |
| 746 | for (auto ch: input) { | 744 | for (auto ch: input) { |
| @@ -1003,15 +1001,12 @@ QUtil::toUTF8(unsigned long uval) | @@ -1003,15 +1001,12 @@ QUtil::toUTF8(unsigned long uval) | ||
| 1003 | { | 1001 | { |
| 1004 | std::string result; | 1002 | std::string result; |
| 1005 | 1003 | ||
| 1006 | - // A UTF-8 encoding of a Unicode value is a single byte for | ||
| 1007 | - // Unicode values <= 127. For larger values, the first byte of | ||
| 1008 | - // the UTF-8 encoding has '1' as each of its n highest bits and | ||
| 1009 | - // '0' for its (n+1)th highest bit where n is the total number of | ||
| 1010 | - // bytes required. Subsequent bytes start with '10' and have the | ||
| 1011 | - // remaining 6 bits free for encoding. For example, an 11-bit | ||
| 1012 | - // Unicode value can be stored in two bytes where the first is | ||
| 1013 | - // 110zzzzz, the second is 10zzzzzz, and the z's represent the | ||
| 1014 | - // remaining bits. | 1004 | + // A UTF-8 encoding of a Unicode value is a single byte for Unicode values <= 127. For larger |
| 1005 | + // values, the first byte of the UTF-8 encoding has '1' as each of its n highest bits and '0' | ||
| 1006 | + // for its (n+1)th highest bit where n is the total number of bytes required. Subsequent bytes | ||
| 1007 | + // start with '10' and have the remaining 6 bits free for encoding. For example, an 11-bit | ||
| 1008 | + // Unicode value can be stored in two bytes where the first is 110zzzzz, the second is 10zzzzzz, | ||
| 1009 | + // and the z's represent the remaining bits. | ||
| 1015 | 1010 | ||
| 1016 | if (uval > 0x7fffffff) { | 1011 | if (uval > 0x7fffffff) { |
| 1017 | throw std::runtime_error("bounds error in QUtil::toUTF8"); | 1012 | throw std::runtime_error("bounds error in QUtil::toUTF8"); |
| @@ -1026,8 +1021,7 @@ QUtil::toUTF8(unsigned long uval) | @@ -1026,8 +1021,7 @@ QUtil::toUTF8(unsigned long uval) | ||
| 1026 | unsigned char maxval = 0x3f; // six bits | 1021 | unsigned char maxval = 0x3f; // six bits |
| 1027 | 1022 | ||
| 1028 | while (uval > QIntC::to_ulong(maxval)) { | 1023 | while (uval > QIntC::to_ulong(maxval)) { |
| 1029 | - // Assign low six bits plus 10000000 to lowest unused | ||
| 1030 | - // byte position, then shift | 1024 | + // Assign low six bits plus 10000000 to lowest unused byte position, then shift |
| 1031 | *cur_byte = static_cast<unsigned char>(0x80 + (uval & 0x3f)); | 1025 | *cur_byte = static_cast<unsigned char>(0x80 + (uval & 0x3f)); |
| 1032 | uval >>= 6; | 1026 | uval >>= 6; |
| 1033 | // Maximum that will fit in high byte now shrinks by one bit | 1027 | // Maximum that will fit in high byte now shrinks by one bit |
| @@ -1038,8 +1032,7 @@ QUtil::toUTF8(unsigned long uval) | @@ -1038,8 +1032,7 @@ QUtil::toUTF8(unsigned long uval) | ||
| 1038 | } | 1032 | } |
| 1039 | --cur_byte; | 1033 | --cur_byte; |
| 1040 | } | 1034 | } |
| 1041 | - // If maxval is k bits long, the high (7 - k) bits of the | ||
| 1042 | - // resulting byte must be high. | 1035 | + // If maxval is k bits long, the high (7 - k) bits of the resulting byte must be high. |
| 1043 | *cur_byte = static_cast<unsigned char>(QIntC::to_ulong(0xff - (1 + (maxval << 1))) + uval); | 1036 | *cur_byte = static_cast<unsigned char>(QIntC::to_ulong(0xff - (1 + (maxval << 1))) + uval); |
| 1044 | 1037 | ||
| 1045 | result += reinterpret_cast<char*>(cur_byte); | 1038 | result += reinterpret_cast<char*>(cur_byte); |
| @@ -1265,8 +1258,7 @@ QUtil::read_lines_from_file( | @@ -1265,8 +1258,7 @@ QUtil::read_lines_from_file( | ||
| 1265 | if (preserve_eol) { | 1258 | if (preserve_eol) { |
| 1266 | buf->append(1, c); | 1259 | buf->append(1, c); |
| 1267 | } else { | 1260 | } else { |
| 1268 | - // Remove any carriage return that preceded the | ||
| 1269 | - // newline and discard the newline | 1261 | + // Remove any carriage return that preceded the newline and discard the newline |
| 1270 | if ((!buf->empty()) && ((*(buf->rbegin())) == '\r')) { | 1262 | if ((!buf->empty()) && ((*(buf->rbegin())) == '\r')) { |
| 1271 | buf->erase(buf->length() - 1); | 1263 | buf->erase(buf->length() - 1); |
| 1272 | } | 1264 | } |
| @@ -1391,8 +1383,7 @@ QUtil::parse_numrange(char const* range, int max) | @@ -1391,8 +1383,7 @@ QUtil::parse_numrange(char const* range, int max) | ||
| 1391 | p = nullptr; | 1383 | p = nullptr; |
| 1392 | for (size_t i = 0; i < work.size(); i += 2) { | 1384 | for (size_t i = 0; i < work.size(); i += 2) { |
| 1393 | int num = work.at(i); | 1385 | int num = work.at(i); |
| 1394 | - // max == 0 means we don't know the max and are just | ||
| 1395 | - // testing for valid syntax. | 1386 | + // max == 0 means we don't know the max and are just testing for valid syntax. |
| 1396 | if ((max > 0) && ((num < 1) || (num > max))) { | 1387 | if ((max > 0) && ((num < 1) || (num > max))) { |
| 1397 | throw std::runtime_error("number " + QUtil::int_to_string(num) + " out of range"); | 1388 | throw std::runtime_error("number " + QUtil::int_to_string(num) + " out of range"); |
| 1398 | } | 1389 | } |
| @@ -1519,21 +1510,18 @@ transcode_utf8(std::string const& utf8_val, std::string& result, encoding_e enco | @@ -1519,21 +1510,18 @@ transcode_utf8(std::string const& utf8_val, std::string& result, encoding_e enco | ||
| 1519 | result += "\xfe\xff"; | 1510 | result += "\xfe\xff"; |
| 1520 | break; | 1511 | break; |
| 1521 | case e_pdfdoc: | 1512 | case e_pdfdoc: |
| 1522 | - // We need to avoid having the result start with something | ||
| 1523 | - // that will be interpreted as UTF-16 or UTF-8, meaning we | ||
| 1524 | - // can't end up with a string that starts with "fe ff", | ||
| 1525 | - // (UTF-16-BE) "ff fe" (UTF-16-LE, not officially part of the | ||
| 1526 | - // PDF spec, but recognized by most readers including qpdf), | ||
| 1527 | - // or "ef bb bf" (UTF-8). It's more efficient to check the | ||
| 1528 | - // input string to see if it will map to one of those | ||
| 1529 | - // sequences than to check the output string since all cases | ||
| 1530 | - // start with the same starting character. | 1513 | + // We need to avoid having the result start with something that will be interpreted as |
| 1514 | + // UTF-16 or UTF-8, meaning we can't end up with a string that starts with "fe ff", | ||
| 1515 | + // (UTF-16-BE) "ff fe" (UTF-16-LE, not officially part of the PDF spec, but recognized by | ||
| 1516 | + // most readers including qpdf), or "ef bb bf" (UTF-8). It's more efficient to check the | ||
| 1517 | + // input string to see if it will map to one of those sequences than to check the output | ||
| 1518 | + // string since all cases start with the same starting character. | ||
| 1531 | if ((len >= 4) && (utf8_val[0] == '\xc3')) { | 1519 | if ((len >= 4) && (utf8_val[0] == '\xc3')) { |
| 1532 | static std::string fe_ff("\xbe\xc3\xbf"); | 1520 | static std::string fe_ff("\xbe\xc3\xbf"); |
| 1533 | static std::string ff_fe("\xbf\xc3\xbe"); | 1521 | static std::string ff_fe("\xbf\xc3\xbe"); |
| 1534 | static std::string ef_bb_bf("\xaf\xc2\xbb\xc2\xbf"); | 1522 | static std::string ef_bb_bf("\xaf\xc2\xbb\xc2\xbf"); |
| 1535 | - // C++-20 has starts_with, but when this was written, qpdf | ||
| 1536 | - // had a minimum supported version of C++-17. | 1523 | + // C++-20 has starts_with, but when this was written, qpdf had a minimum supported |
| 1524 | + // version of C++-17. | ||
| 1537 | if ((utf8_val.compare(1, 3, fe_ff) == 0) || (utf8_val.compare(1, 3, ff_fe) == 0) || | 1525 | if ((utf8_val.compare(1, 3, fe_ff) == 0) || (utf8_val.compare(1, 3, ff_fe) == 0) || |
| 1538 | (utf8_val.compare(1, 5, ef_bb_bf) == 0)) { | 1526 | (utf8_val.compare(1, 5, ef_bb_bf) == 0)) { |
| 1539 | result += unknown; | 1527 | result += unknown; |
| @@ -1560,10 +1548,9 @@ transcode_utf8(std::string const& utf8_val, std::string& result, encoding_e enco | @@ -1560,10 +1548,9 @@ transcode_utf8(std::string const& utf8_val, std::string& result, encoding_e enco | ||
| 1560 | if (encoding == e_utf16) { | 1548 | if (encoding == e_utf16) { |
| 1561 | result += QUtil::toUTF16(QIntC::to_ulong(ch)); | 1549 | result += QUtil::toUTF16(QIntC::to_ulong(ch)); |
| 1562 | } else if ((encoding == e_pdfdoc) && (((ch >= 0x18) && (ch <= 0x1f)) || (ch == 127))) { | 1550 | } else if ((encoding == e_pdfdoc) && (((ch >= 0x18) && (ch <= 0x1f)) || (ch == 127))) { |
| 1563 | - // PDFDocEncoding maps some low characters to Unicode, | ||
| 1564 | - // so if we encounter those invalid UTF-8 code points, | ||
| 1565 | - // map them to unknown so reversing the mapping | ||
| 1566 | - // doesn't change them into other characters. | 1551 | + // PDFDocEncoding maps some low characters to Unicode, so if we encounter those |
| 1552 | + // invalid UTF-8 code points, map them to unknown so reversing the mapping doesn't | ||
| 1553 | + // change them into other characters. | ||
| 1567 | okay = false; | 1554 | okay = false; |
| 1568 | result.append(1, unknown); | 1555 | result.append(1, unknown); |
| 1569 | } else { | 1556 | } else { |
| @@ -1682,10 +1669,9 @@ std::string | @@ -1682,10 +1669,9 @@ std::string | ||
| 1682 | QUtil::utf16_to_utf8(std::string const& val) | 1669 | QUtil::utf16_to_utf8(std::string const& val) |
| 1683 | { | 1670 | { |
| 1684 | std::string result; | 1671 | std::string result; |
| 1685 | - // This code uses unsigned long and unsigned short to hold | ||
| 1686 | - // codepoint values. It requires unsigned long to be at least | ||
| 1687 | - // 32 bits and unsigned short to be at least 16 bits, but it | ||
| 1688 | - // will work fine if they are larger. | 1672 | + // This code uses unsigned long and unsigned short to hold codepoint values. It requires |
| 1673 | + // unsigned long to be at least 32 bits and unsigned short to be at least 16 bits, but it will | ||
| 1674 | + // work fine if they are larger. | ||
| 1689 | unsigned long codepoint = 0L; | 1675 | unsigned long codepoint = 0L; |
| 1690 | size_t len = val.length(); | 1676 | size_t len = val.length(); |
| 1691 | size_t start = 0; | 1677 | size_t start = 0; |
| @@ -1696,14 +1682,11 @@ QUtil::utf16_to_utf8(std::string const& val) | @@ -1696,14 +1682,11 @@ QUtil::utf16_to_utf8(std::string const& val) | ||
| 1696 | } | 1682 | } |
| 1697 | start += 2; | 1683 | start += 2; |
| 1698 | } | 1684 | } |
| 1699 | - // If the string has an odd number of bytes, the last byte is | ||
| 1700 | - // ignored. | 1685 | + // If the string has an odd number of bytes, the last byte is ignored. |
| 1701 | for (size_t i = start; i + 1 < len; i += 2) { | 1686 | for (size_t i = start; i + 1 < len; i += 2) { |
| 1702 | - // Convert from UTF16-BE. If we get a malformed | ||
| 1703 | - // codepoint, this code will generate incorrect output | ||
| 1704 | - // without giving a warning. Specifically, a high | ||
| 1705 | - // codepoint not followed by a low codepoint will be | ||
| 1706 | - // discarded, and a low codepoint not preceded by a high | 1687 | + // Convert from UTF16-BE. If we get a malformed codepoint, this code will generate |
| 1688 | + // incorrect output without giving a warning. Specifically, a high codepoint not followed | ||
| 1689 | + // by a low codepoint will be discarded, and a low codepoint not preceded by a high | ||
| 1707 | // codepoint will just get its low 10 bits output. | 1690 | // codepoint will just get its low 10 bits output. |
| 1708 | auto msb = is_le ? i + 1 : i; | 1691 | auto msb = is_le ? i + 1 : i; |
| 1709 | auto lsb = is_le ? i : i + 1; | 1692 | auto lsb = is_le ? i : i + 1; |
| @@ -1829,8 +1812,7 @@ QUtil::possible_repaired_encodings(std::string supplied) | @@ -1829,8 +1812,7 @@ QUtil::possible_repaired_encodings(std::string supplied) | ||
| 1829 | } | 1812 | } |
| 1830 | std::string output; | 1813 | std::string output; |
| 1831 | if (is_valid_utf8) { | 1814 | if (is_valid_utf8) { |
| 1832 | - // Maybe we were given UTF-8 but wanted one of the single-byte | ||
| 1833 | - // encodings. | 1815 | + // Maybe we were given UTF-8 but wanted one of the single-byte encodings. |
| 1834 | if (utf8_to_pdf_doc(supplied, output)) { | 1816 | if (utf8_to_pdf_doc(supplied, output)) { |
| 1835 | result.push_back(output); | 1817 | result.push_back(output); |
| 1836 | } | 1818 | } |
| @@ -1841,8 +1823,7 @@ QUtil::possible_repaired_encodings(std::string supplied) | @@ -1841,8 +1823,7 @@ QUtil::possible_repaired_encodings(std::string supplied) | ||
| 1841 | result.push_back(output); | 1823 | result.push_back(output); |
| 1842 | } | 1824 | } |
| 1843 | } else { | 1825 | } else { |
| 1844 | - // Maybe we were given one of the single-byte encodings but | ||
| 1845 | - // wanted UTF-8. | 1826 | + // Maybe we were given one of the single-byte encodings but wanted UTF-8. |
| 1846 | std::string from_pdf_doc(pdf_doc_to_utf8(supplied)); | 1827 | std::string from_pdf_doc(pdf_doc_to_utf8(supplied)); |
| 1847 | result.push_back(from_pdf_doc); | 1828 | result.push_back(from_pdf_doc); |
| 1848 | std::string from_win_ansi(win_ansi_to_utf8(supplied)); | 1829 | std::string from_win_ansi(win_ansi_to_utf8(supplied)); |
| @@ -1850,8 +1831,8 @@ QUtil::possible_repaired_encodings(std::string supplied) | @@ -1850,8 +1831,8 @@ QUtil::possible_repaired_encodings(std::string supplied) | ||
| 1850 | std::string from_mac_roman(mac_roman_to_utf8(supplied)); | 1831 | std::string from_mac_roman(mac_roman_to_utf8(supplied)); |
| 1851 | result.push_back(from_mac_roman); | 1832 | result.push_back(from_mac_roman); |
| 1852 | 1833 | ||
| 1853 | - // Maybe we were given one of the other single-byte encodings | ||
| 1854 | - // but wanted one of the other ones. | 1834 | + // Maybe we were given one of the other single-byte encodings but wanted one of the other |
| 1835 | + // ones. | ||
| 1855 | if (utf8_to_win_ansi(from_pdf_doc, output)) { | 1836 | if (utf8_to_win_ansi(from_pdf_doc, output)) { |
| 1856 | result.push_back(output); | 1837 | result.push_back(output); |
| 1857 | } | 1838 | } |
| @@ -1888,9 +1869,8 @@ static int | @@ -1888,9 +1869,8 @@ static int | ||
| 1888 | call_main_from_wmain( | 1869 | call_main_from_wmain( |
| 1889 | bool, int argc, wchar_t const* const argv[], std::function<int(int, char*[])> realmain) | 1870 | bool, int argc, wchar_t const* const argv[], std::function<int(int, char*[])> realmain) |
| 1890 | { | 1871 | { |
| 1891 | - // argv contains UTF-16-encoded strings with a 16-bit wchar_t. | ||
| 1892 | - // Convert this to UTF-8-encoded strings for compatibility with | ||
| 1893 | - // other systems. That way the rest of qpdf.cc can just act like | 1872 | + // argv contains UTF-16-encoded strings with a 16-bit wchar_t. Convert this to UTF-8-encoded |
| 1873 | + // strings for compatibility with other systems. That way the rest of qpdf.cc can just act like | ||
| 1894 | // arguments are UTF-8. | 1874 | // arguments are UTF-8. |
| 1895 | 1875 | ||
| 1896 | std::vector<std::unique_ptr<char[]>> utf8_argv; | 1876 | std::vector<std::unique_ptr<char[]>> utf8_argv; |
| @@ -1950,16 +1930,13 @@ QUtil::get_max_memory_usage() | @@ -1950,16 +1930,13 @@ QUtil::get_max_memory_usage() | ||
| 1950 | fprintf(stderr, "%s", buf); | 1930 | fprintf(stderr, "%s", buf); |
| 1951 | } | 1931 | } |
| 1952 | 1932 | ||
| 1953 | - // Warning: this code uses regular expression to extract data from | ||
| 1954 | - // an XML string. This is generally a bad idea, but we're going to | ||
| 1955 | - // do it anyway because QUtil.hh warns against using this function | ||
| 1956 | - // for other than development/testing, and if this function fails | ||
| 1957 | - // to generate reasonable output during performance testing, it | ||
| 1958 | - // will be noticed. | 1933 | + // Warning: this code uses regular expression to extract data from an XML string. This is |
| 1934 | + // generally a bad idea, but we're going to do it anyway because QUtil.hh warns against using | ||
| 1935 | + // this function for other than development/testing, and if this function fails to generate | ||
| 1936 | + // reasonable output during performance testing, it will be noticed. | ||
| 1959 | 1937 | ||
| 1960 | - // This is my best guess at how to interpret malloc_info. Anyway | ||
| 1961 | - // it seems to provide useful information for detecting code | ||
| 1962 | - // changes that drastically change memory usage. | 1938 | + // This is my best guess at how to interpret malloc_info. Anyway it seems to provide useful |
| 1939 | + // information for detecting code changes that drastically change memory usage. | ||
| 1963 | size_t result = 0; | 1940 | size_t result = 0; |
| 1964 | try { | 1941 | try { |
| 1965 | std::cregex_iterator m_begin(buf, buf + size, tag_re); | 1942 | std::cregex_iterator m_begin(buf, buf + size, tag_re); |
libqpdf/SecureRandomDataProvider.cc
| @@ -89,10 +89,9 @@ SecureRandomDataProvider::provideRandomData(unsigned char* data, size_t len) | @@ -89,10 +89,9 @@ SecureRandomDataProvider::provideRandomData(unsigned char* data, size_t len) | ||
| 89 | 89 | ||
| 90 | # elif defined(RANDOM_DEVICE) | 90 | # elif defined(RANDOM_DEVICE) |
| 91 | 91 | ||
| 92 | - // Optimization: wrap the file open and close in a class so that | ||
| 93 | - // the file is closed in a destructor, then make this static to | ||
| 94 | - // keep the file handle open. Only do this if it can be done in a | ||
| 95 | - // thread-safe fashion. | 92 | + // Optimization: wrap the file open and close in a class so that the file is closed in a |
| 93 | + // destructor, then make this static to keep the file handle open. Only do this if it can be | ||
| 94 | + // done in a thread-safe fashion. | ||
| 96 | FILE* f = QUtil::safe_fopen(RANDOM_DEVICE, "rb"); | 95 | FILE* f = QUtil::safe_fopen(RANDOM_DEVICE, "rb"); |
| 97 | size_t fr = fread(data, 1, len, f); | 96 | size_t fr = fread(data, 1, len, f); |
| 98 | fclose(f); | 97 | fclose(f); |
libqpdf/qpdf-c.cc
| @@ -269,9 +269,8 @@ qpdf_read(qpdf_data qpdf, char const* filename, char const* password) | @@ -269,9 +269,8 @@ qpdf_read(qpdf_data qpdf, char const* filename, char const* password) | ||
| 269 | qpdf->filename = filename; | 269 | qpdf->filename = filename; |
| 270 | qpdf->password = password; | 270 | qpdf->password = password; |
| 271 | status = trap_errors(qpdf, &call_read); | 271 | status = trap_errors(qpdf, &call_read); |
| 272 | - // We no longer have a good way to exercise a file with both | ||
| 273 | - // warnings and errors because qpdf is getting much better at | ||
| 274 | - // recovering. | 272 | + // We no longer have a good way to exercise a file with both warnings and errors because qpdf is |
| 273 | + // getting much better at recovering. | ||
| 275 | QTC::TC( | 274 | QTC::TC( |
| 276 | "qpdf", | 275 | "qpdf", |
| 277 | "qpdf-c called qpdf_read", | 276 | "qpdf-c called qpdf_read", |
| @@ -806,9 +805,8 @@ template <class RET> | @@ -806,9 +805,8 @@ template <class RET> | ||
| 806 | static RET | 805 | static RET |
| 807 | trap_oh_errors(qpdf_data qpdf, std::function<RET()> fallback, std::function<RET(qpdf_data)> fn) | 806 | trap_oh_errors(qpdf_data qpdf, std::function<RET()> fallback, std::function<RET(qpdf_data)> fn) |
| 808 | { | 807 | { |
| 809 | - // Note: fallback is a function so we don't have to evaluate it | ||
| 810 | - // unless needed. This is important because sometimes the fallback | ||
| 811 | - // creates an object. | 808 | + // Note: fallback is a function so we don't have to evaluate it unless needed. This is important |
| 809 | + // because sometimes the fallback creates an object. | ||
| 812 | RET ret; | 810 | RET ret; |
| 813 | QPDF_ERROR_CODE status = trap_errors(qpdf, [&ret, fn](qpdf_data q) { ret = fn(q); }); | 811 | QPDF_ERROR_CODE status = trap_errors(qpdf, [&ret, fn](qpdf_data q) { ret = fn(q); }); |
| 814 | if (status & QPDF_ERRORS) { | 812 | if (status & QPDF_ERRORS) { |
| @@ -820,9 +818,8 @@ trap_oh_errors(qpdf_data qpdf, std::function<RET()> fallback, std::function<RET( | @@ -820,9 +818,8 @@ trap_oh_errors(qpdf_data qpdf, std::function<RET()> fallback, std::function<RET( | ||
| 820 | qpdf->qpdf->getFilename(), | 818 | qpdf->qpdf->getFilename(), |
| 821 | "", | 819 | "", |
| 822 | 0, | 820 | 0, |
| 823 | - "C API function caught an exception that it isn't" | ||
| 824 | - " returning; please point the application developer" | ||
| 825 | - " to ERROR HANDLING in qpdf-c.h")); | 821 | + "C API function caught an exception that it isn't returning; please point the " |
| 822 | + "application developer to ERROR HANDLING in qpdf-c.h")); | ||
| 826 | qpdf->oh_error_occurred = true; | 823 | qpdf->oh_error_occurred = true; |
| 827 | } | 824 | } |
| 828 | *QPDFLogger::defaultLogger()->getError() << qpdf->error->what() << "\n"; | 825 | *QPDFLogger::defaultLogger()->getError() << qpdf->error->what() << "\n"; |
libqpdf/qpdf/BitStream.hh
| @@ -12,8 +12,7 @@ class BitStream | @@ -12,8 +12,7 @@ class BitStream | ||
| 12 | void reset(); | 12 | void reset(); |
| 13 | unsigned long long getBits(size_t nbits); | 13 | unsigned long long getBits(size_t nbits); |
| 14 | long long getBitsSigned(size_t nbits); | 14 | long long getBitsSigned(size_t nbits); |
| 15 | - // Only call getBitsInt when requesting a number of bits that will | ||
| 16 | - // definitely fit in an int. | 15 | + // Only call getBitsInt when requesting a number of bits that definitely fit in an int. |
| 17 | int getBitsInt(size_t nbits); | 16 | int getBitsInt(size_t nbits); |
| 18 | void skipToNextByte(); | 17 | void skipToNextByte(); |
| 19 | 18 |
libqpdf/qpdf/BitWriter.hh
| @@ -10,8 +10,8 @@ class Pipeline; | @@ -10,8 +10,8 @@ class Pipeline; | ||
| 10 | class BitWriter | 10 | class BitWriter |
| 11 | { | 11 | { |
| 12 | public: | 12 | public: |
| 13 | - // Write bits to the pipeline. It is the caller's responsibility | ||
| 14 | - // to eventually call finish on the pipeline. | 13 | + // Write bits to the pipeline. It is the caller's responsibility to eventually call finish on |
| 14 | + // the pipeline. | ||
| 15 | BitWriter(Pipeline* pl); | 15 | BitWriter(Pipeline* pl); |
| 16 | void writeBits(unsigned long long val, size_t bits); | 16 | void writeBits(unsigned long long val, size_t bits); |
| 17 | void writeBitsSigned(long long val, size_t bits); | 17 | void writeBitsSigned(long long val, size_t bits); |
libqpdf/qpdf/JSONHandler.hh
| @@ -7,37 +7,32 @@ | @@ -7,37 +7,32 @@ | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <string> | 8 | #include <string> |
| 9 | 9 | ||
| 10 | -// This class allows a sax-like walk through a JSON object with | ||
| 11 | -// functionality that mostly mirrors QPDFArgParser. It is primarily | ||
| 12 | -// here to facilitate automatic generation of some of the code to help | ||
| 13 | -// keep QPDFJob json consistent with command-line arguments. | 10 | +// This class allows a sax-like walk through a JSON object with functionality that mostly mirrors |
| 11 | +// QPDFArgParser. It is primarily here to facilitate automatic generation of some of the code to | ||
| 12 | +// help keep QPDFJob json consistent with command-line arguments. | ||
| 14 | 13 | ||
| 15 | class JSONHandler | 14 | class JSONHandler |
| 16 | { | 15 | { |
| 17 | public: | 16 | public: |
| 18 | - // A QPDFUsage exception is thrown if there are any errors | ||
| 19 | - // validating the JSON object. | 17 | + // A QPDFUsage exception is thrown if there are any errors validating the JSON object. |
| 20 | JSONHandler(); | 18 | JSONHandler(); |
| 21 | ~JSONHandler() = default; | 19 | ~JSONHandler() = default; |
| 22 | 20 | ||
| 23 | - // Based on the type of handler, expect the object to be of a | ||
| 24 | - // certain type. QPDFUsage is thrown otherwise. Multiple handlers | ||
| 25 | - // may be registered, which allows the object to be of various | ||
| 26 | - // types. If an anyHandler is added, no other handler will be | ||
| 27 | - // called. There is no "final" handler -- if the top-level is a | ||
| 28 | - // dictionary or array, just use its end handler. | 21 | + // Based on the type of handler, expect the object to be of a certain type. QPDFUsage is thrown |
| 22 | + // otherwise. Multiple handlers may be registered, which allows the object to be of various | ||
| 23 | + // types. If an anyHandler is added, no other handler will be called. There is no "final" | ||
| 24 | + // handler -- if the top-level is a dictionary or array, just use its end handler. | ||
| 29 | 25 | ||
| 30 | typedef std::function<void(std::string const& path, JSON value)> json_handler_t; | 26 | typedef std::function<void(std::string const& path, JSON value)> json_handler_t; |
| 31 | typedef std::function<void(std::string const& path)> void_handler_t; | 27 | typedef std::function<void(std::string const& path)> void_handler_t; |
| 32 | typedef std::function<void(std::string const& path, std::string const& value)> string_handler_t; | 28 | typedef std::function<void(std::string const& path, std::string const& value)> string_handler_t; |
| 33 | typedef std::function<void(std::string const& path, bool value)> bool_handler_t; | 29 | typedef std::function<void(std::string const& path, bool value)> bool_handler_t; |
| 34 | 30 | ||
| 35 | - // If an any handler is added, it will be called for any value | ||
| 36 | - // including null, and no other handler will be called. | 31 | + // If an any handler is added, it will be called for any value including null, and no other |
| 32 | + // handler will be called. | ||
| 37 | void addAnyHandler(json_handler_t fn); | 33 | void addAnyHandler(json_handler_t fn); |
| 38 | 34 | ||
| 39 | - // If any of the remaining handlers are registered, each | ||
| 40 | - // registered handle will be called. | 35 | + // If any of the remaining handlers are registered, each registered handle will be called. |
| 41 | void addNullHandler(void_handler_t fn); | 36 | void addNullHandler(void_handler_t fn); |
| 42 | void addStringHandler(string_handler_t fn); | 37 | void addStringHandler(string_handler_t fn); |
| 43 | void addNumberHandler(string_handler_t fn); | 38 | void addNumberHandler(string_handler_t fn); |
libqpdf/qpdf/MD5.hh
| @@ -29,8 +29,7 @@ class MD5 | @@ -29,8 +29,7 @@ class MD5 | ||
| 29 | // computes a raw digest | 29 | // computes a raw digest |
| 30 | void digest(Digest); | 30 | void digest(Digest); |
| 31 | 31 | ||
| 32 | - // prints the digest to stdout terminated with \r\n (primarily for | ||
| 33 | - // testing) | 32 | + // prints the digest to stdout terminated with \r\n (primarily for testing) |
| 34 | void print(); | 33 | void print(); |
| 35 | 34 | ||
| 36 | // returns the digest as a hexadecimal string | 35 | // returns the digest as a hexadecimal string |
libqpdf/qpdf/NNTree.hh
| @@ -104,9 +104,8 @@ class NNTreeImpl | @@ -104,9 +104,8 @@ class NNTreeImpl | ||
| 104 | iterator insert(QPDFObjectHandle key, QPDFObjectHandle value); | 104 | iterator insert(QPDFObjectHandle key, QPDFObjectHandle value); |
| 105 | bool remove(QPDFObjectHandle key, QPDFObjectHandle* value = nullptr); | 105 | bool remove(QPDFObjectHandle key, QPDFObjectHandle* value = nullptr); |
| 106 | 106 | ||
| 107 | - // Change the split threshold for easier testing. There's no real | ||
| 108 | - // reason to expose this to downstream tree helpers, but it has to | ||
| 109 | - // be public so we can call it from the test suite. | 107 | + // Change the split threshold for easier testing. There's no real reason to expose this to |
| 108 | + // downstream tree helpers, but it has to be public so we can call it from the test suite. | ||
| 110 | void setSplitThreshold(int split_threshold); | 109 | void setSplitThreshold(int split_threshold); |
| 111 | 110 | ||
| 112 | private: | 111 | private: |
libqpdf/qpdf/OffsetInputSource.hh
| 1 | #ifndef QPDF_OFFSETINPUTSOURCE_HH | 1 | #ifndef QPDF_OFFSETINPUTSOURCE_HH |
| 2 | #define QPDF_OFFSETINPUTSOURCE_HH | 2 | #define QPDF_OFFSETINPUTSOURCE_HH |
| 3 | 3 | ||
| 4 | -// This class implements an InputSource that proxies for an underlying | ||
| 5 | -// input source but offset a specific number of bytes. | 4 | +// This class implements an InputSource that proxies for an underlying input source but offset a |
| 5 | +// specific number of bytes. | ||
| 6 | 6 | ||
| 7 | #include <qpdf/InputSource.hh> | 7 | #include <qpdf/InputSource.hh> |
| 8 | 8 |
libqpdf/qpdf/Pl_AES_PDF.hh
| @@ -5,8 +5,8 @@ | @@ -5,8 +5,8 @@ | ||
| 5 | #include <qpdf/QPDFCryptoImpl.hh> | 5 | #include <qpdf/QPDFCryptoImpl.hh> |
| 6 | #include <memory> | 6 | #include <memory> |
| 7 | 7 | ||
| 8 | -// This pipeline implements AES-128 and AES-256 with CBC and block | ||
| 9 | -// padding as specified in the PDF specification. | 8 | +// This pipeline implements AES-128 and AES-256 with CBC and block padding as specified in the PDF |
| 9 | +// specification. | ||
| 10 | 10 | ||
| 11 | class Pl_AES_PDF: public Pipeline | 11 | class Pl_AES_PDF: public Pipeline |
| 12 | { | 12 | { |
libqpdf/qpdf/Pl_MD5.hh
| 1 | #ifndef PL_MD5_HH | 1 | #ifndef PL_MD5_HH |
| 2 | #define PL_MD5_HH | 2 | #define PL_MD5_HH |
| 3 | 3 | ||
| 4 | -// This pipeline sends its output to its successor unmodified. After | ||
| 5 | -// calling finish, the MD5 checksum of the data that passed through | ||
| 6 | -// the pipeline is available. | 4 | +// This pipeline sends its output to its successor unmodified. After calling finish, the MD5 |
| 5 | +// checksum of the data that passed through the pipeline is available. | ||
| 7 | 6 | ||
| 8 | -// This pipeline is reusable; i.e., it is safe to call write() after | ||
| 9 | -// calling finish(). The first call to write() after a call to | ||
| 10 | -// finish() initializes a new MD5 object. | 7 | +// This pipeline is reusable; i.e., it is safe to call write() after calling finish(). The first |
| 8 | +// call to write() after a call to finish() initializes a new MD5 object. | ||
| 11 | 9 | ||
| 12 | #include <qpdf/MD5.hh> | 10 | #include <qpdf/MD5.hh> |
| 13 | #include <qpdf/Pipeline.hh> | 11 | #include <qpdf/Pipeline.hh> |
| @@ -20,15 +18,12 @@ class Pl_MD5: public Pipeline | @@ -20,15 +18,12 @@ class Pl_MD5: public Pipeline | ||
| 20 | virtual void write(unsigned char const*, size_t); | 18 | virtual void write(unsigned char const*, size_t); |
| 21 | virtual void finish(); | 19 | virtual void finish(); |
| 22 | std::string getHexDigest(); | 20 | std::string getHexDigest(); |
| 23 | - // Enable/disable. Disabling the pipeline causes it to become a | ||
| 24 | - // pass-through. This makes it possible to stick an MD5 pipeline | ||
| 25 | - // in a pipeline when it may or may not be required. Disabling it | ||
| 26 | - // avoids incurring the runtime overhead of doing needless | ||
| 27 | - // digest computation. | 21 | + // Enable/disable. Disabling the pipeline causes it to become a pass-through. This makes it |
| 22 | + // possible to stick an MD5 pipeline in a pipeline when it may or may not be required. Disabling | ||
| 23 | + // it avoids incurring the runtime overhead of doing needless digest computation. | ||
| 28 | void enable(bool enabled); | 24 | void enable(bool enabled); |
| 29 | - // If persistAcrossFinish is called, calls to finish do not | ||
| 30 | - // finalize the underlying md5 object. In this case, the object is | ||
| 31 | - // not finalized until getHexDigest() is called. | 25 | + // If persistAcrossFinish is called, calls to finish do not finalize the underlying md5 object. |
| 26 | + // In this case, the object is not finalized until getHexDigest() is called. | ||
| 32 | void persistAcrossFinish(bool); | 27 | void persistAcrossFinish(bool); |
| 33 | 28 | ||
| 34 | private: | 29 | private: |
libqpdf/qpdf/Pl_PNGFilter.hh
| 1 | #ifndef PL_PNGFILTER_HH | 1 | #ifndef PL_PNGFILTER_HH |
| 2 | #define PL_PNGFILTER_HH | 2 | #define PL_PNGFILTER_HH |
| 3 | 3 | ||
| 4 | -// This pipeline applies or reverses the application of a PNG filter | ||
| 5 | -// as described in the PNG specification. | 4 | +// This pipeline applies or reverses the application of a PNG filter as described in the PNG |
| 5 | +// specification. | ||
| 6 | 6 | ||
| 7 | -// NOTE: In its current implementation, this filter always encodes | ||
| 8 | -// using the "up" filter, but it decodes all the filters. | 7 | +// NOTE: In its current implementation, this filter always encodes using the "up" filter, but it |
| 8 | +// decodes all the filters. | ||
| 9 | 9 | ||
| 10 | #include <qpdf/Pipeline.hh> | 10 | #include <qpdf/Pipeline.hh> |
| 11 | 11 |
libqpdf/qpdf/Pl_SHA2.hh
| 1 | #ifndef PL_SHA2_HH | 1 | #ifndef PL_SHA2_HH |
| 2 | #define PL_SHA2_HH | 2 | #define PL_SHA2_HH |
| 3 | 3 | ||
| 4 | -// Bits must be a supported number of bits, currently only 256, 384, | ||
| 5 | -// or 512. Passing 0 as bits leaves the pipeline uncommitted, in | ||
| 6 | -// which case resetBits must be called before the pipeline is used. | ||
| 7 | -// If a next is provided, this pipeline sends its output to its | ||
| 8 | -// successor unmodified. After calling finish, the SHA2 checksum of | ||
| 9 | -// the data that passed through the pipeline is available. | 4 | +// Bits must be a supported number of bits, currently only 256, 384, or 512. Passing 0 as bits |
| 5 | +// leaves the pipeline uncommitted, in which case resetBits must be called before the pipeline is | ||
| 6 | +// used. If a next is provided, this pipeline sends its output to its successor unmodified. After | ||
| 7 | +// calling finish, the SHA2 checksum of the data that passed through the pipeline is available. | ||
| 10 | 8 | ||
| 11 | -// This pipeline is reusable; i.e., it is safe to call write() after | ||
| 12 | -// calling finish(). The first call to write() after a call to | ||
| 13 | -// finish() initializes a new SHA2 object. resetBits may also be | 9 | +// This pipeline is reusable; i.e., it is safe to call write() after calling finish(). The first |
| 10 | +// call to write() after a call to finish() initializes a new SHA2 object. resetBits may also be | ||
| 14 | // called between finish and the next call to write. | 11 | // called between finish and the next call to write. |
| 15 | 12 | ||
| 16 | #include <qpdf/Pipeline.hh> | 13 | #include <qpdf/Pipeline.hh> |
libqpdf/qpdf/Pl_TIFFPredictor.hh
| 1 | #ifndef PL_TIFFPREDICTOR_HH | 1 | #ifndef PL_TIFFPREDICTOR_HH |
| 2 | #define PL_TIFFPREDICTOR_HH | 2 | #define PL_TIFFPREDICTOR_HH |
| 3 | 3 | ||
| 4 | -// This pipeline reverses the application of a TIFF predictor as | ||
| 5 | -// described in the TIFF specification. | 4 | +// This pipeline reverses the application of a TIFF predictor as described in the TIFF |
| 5 | +// specification. | ||
| 6 | 6 | ||
| 7 | #include <qpdf/Pipeline.hh> | 7 | #include <qpdf/Pipeline.hh> |
| 8 | 8 |
libqpdf/qpdf/QPDFArgParser.hh
| @@ -9,41 +9,33 @@ | @@ -9,41 +9,33 @@ | ||
| 9 | #include <string> | 9 | #include <string> |
| 10 | #include <vector> | 10 | #include <vector> |
| 11 | 11 | ||
| 12 | -// This is not a general-purpose argument parser. It is tightly | ||
| 13 | -// crafted to work with qpdf. qpdf's command-line syntax is very | ||
| 14 | -// complex because of its long history, and it doesn't really follow | ||
| 15 | -// any kind of normal standard for arguments, but it's important for | ||
| 16 | -// backward compatibility to ensure we don't break what constitutes a | ||
| 17 | -// valid command. This class handles the quirks of qpdf's argument | ||
| 18 | -// parsing, bash/zsh completion, and support for @argfile to read | ||
| 19 | -// arguments from a file. For the qpdf CLI, setup of QPDFArgParser is | ||
| 20 | -// done mostly by automatically-generated code (one-off code for | ||
| 21 | -// qpdf), though the handlers themselves are hand-coded. See | ||
| 22 | -// generate_auto_job at the top of the source tree for details. | 12 | +// This is not a general-purpose argument parser. It is tightly crafted to work with qpdf. qpdf's |
| 13 | +// command-line syntax is very complex because of its long history, and it doesn't really follow any | ||
| 14 | +// kind of normal standard for arguments, but it's important for backward compatibility to ensure we | ||
| 15 | +// don't break what constitutes a valid command. This class handles the quirks of qpdf's argument | ||
| 16 | +// parsing, bash/zsh completion, and support for @argfile to read arguments from a file. For the | ||
| 17 | +// qpdf CLI, setup of QPDFArgParser is done mostly by automatically-generated code (one-off code for | ||
| 18 | +// qpdf), though the handlers themselves are hand-coded. See generate_auto_job at the top of the | ||
| 19 | +// source tree for details. | ||
| 23 | class QPDFArgParser | 20 | class QPDFArgParser |
| 24 | { | 21 | { |
| 25 | public: | 22 | public: |
| 26 | - // progname_env is used to override argv[0] when figuring out the | ||
| 27 | - // name of the executable for setting up completion. This may be | ||
| 28 | - // needed if the program is invoked by a wrapper. | 23 | + // progname_env is used to override argv[0] when figuring out the name of the executable for |
| 24 | + // setting up completion. This may be needed if the program is invoked by a wrapper. | ||
| 29 | QPDFArgParser(int argc, char const* const argv[], char const* progname_env); | 25 | QPDFArgParser(int argc, char const* const argv[], char const* progname_env); |
| 30 | 26 | ||
| 31 | - // Calls exit(0) if a help option is given or if in completion | ||
| 32 | - // mode. If there are argument parsing errors, QPDFUsage is | ||
| 33 | - // thrown. | 27 | + // Calls exit(0) if a help option is given or if in completion mode. If there are argument |
| 28 | + // parsing errors, QPDFUsage is thrown. | ||
| 34 | void parseArgs(); | 29 | void parseArgs(); |
| 35 | 30 | ||
| 36 | - // Return the program name as the last path element of the program | ||
| 37 | - // executable. | 31 | + // Return the program name as the last path element of the program executable. |
| 38 | std::string getProgname(); | 32 | std::string getProgname(); |
| 39 | 33 | ||
| 40 | - // Methods for registering arguments. QPDFArgParser starts off | ||
| 41 | - // with the main option table selected. You can add handlers for | ||
| 42 | - // arguments in the current option table, and you can select which | ||
| 43 | - // option table is current. The help option table is special and | ||
| 44 | - // contains arguments that are only valid as the first and only | ||
| 45 | - // option. Named option tables are for subparsers and always start | ||
| 46 | - // a series of options that end with `--`. | 34 | + // Methods for registering arguments. QPDFArgParser starts off with the main option table |
| 35 | + // selected. You can add handlers for arguments in the current option table, and you can select | ||
| 36 | + // which option table is current. The help option table is special and contains arguments that | ||
| 37 | + // are only valid as the first and only option. Named option tables are for subparsers and | ||
| 38 | + // always start a series of options that end with `--`. | ||
| 47 | 39 | ||
| 48 | typedef std::function<void()> bare_arg_handler_t; | 40 | typedef std::function<void()> bare_arg_handler_t; |
| 49 | typedef std::function<void(std::string const&)> param_arg_handler_t; | 41 | typedef std::function<void(std::string const&)> param_arg_handler_t; |
| @@ -65,9 +57,8 @@ class QPDFArgParser | @@ -65,9 +57,8 @@ class QPDFArgParser | ||
| 65 | void | 57 | void |
| 66 | addChoices(std::string const& arg, param_arg_handler_t, bool required, char const** choices); | 58 | addChoices(std::string const& arg, param_arg_handler_t, bool required, char const** choices); |
| 67 | 59 | ||
| 68 | - // The default behavior when an invalid choice is specified with | ||
| 69 | - // an option that takes choices is to list all the choices. This | ||
| 70 | - // may not be good if there are too many choices, so you can | 60 | + // The default behavior when an invalid choice is specified with an option that takes choices is |
| 61 | + // to list all the choices. This may not be good if there are too many choices, so you can | ||
| 71 | // provide your own handler in this case. | 62 | // provide your own handler in this case. |
| 72 | void addInvalidChoiceHandler(std::string const& arg, param_arg_handler_t); | 63 | void addInvalidChoiceHandler(std::string const& arg, param_arg_handler_t); |
| 73 | 64 | ||
| @@ -77,42 +68,33 @@ class QPDFArgParser | @@ -77,42 +68,33 @@ class QPDFArgParser | ||
| 77 | 68 | ||
| 78 | // Help generation methods | 69 | // Help generation methods |
| 79 | 70 | ||
| 80 | - // Help is available on topics and options. Options may be | ||
| 81 | - // associated with topics. Users can run --help, --help=topic, or | ||
| 82 | - // --help=--arg to get help. The top-level help tells the user how | ||
| 83 | - // to run help and lists available topics. Help for a topic prints | ||
| 84 | - // a short synopsis about the topic and lists any options that may | ||
| 85 | - // be associated with the topic. Help for an option provides a | ||
| 86 | - // short synopsis for that option. All help output is appended | ||
| 87 | - // with a blurb (if supplied) directing the user to the full | ||
| 88 | - // documentation. Help is not shown for options for which help has | ||
| 89 | - // not been added. This makes it possible to have undocumented | ||
| 90 | - // options for testing, backward-compatibility, etc. Also, it | ||
| 91 | - // could be quite confusing to handle appropriate help for some | ||
| 92 | - // inner options that may be repeated with different semantics | ||
| 93 | - // inside different option tables. There is also no checking for | ||
| 94 | - // whether an option that has help actually exists. In other | ||
| 95 | - // words, it's up to the caller to ensure that help actually | ||
| 96 | - // corresponds to the program's actual options. Rather than this | ||
| 97 | - // being an intentional design decision, it is because this class | ||
| 98 | - // is specifically for qpdf, qpdf generates its help and has other | ||
| 99 | - // means to ensure consistency. | 71 | + // Help is available on topics and options. Options may be associated with topics. Users can run |
| 72 | + // --help, --help=topic, or --help=--arg to get help. The top-level help tells the user how | ||
| 73 | + // to run help and lists available topics. Help for a topic prints a short synopsis about the | ||
| 74 | + // topic and lists any options that may be associated with the topic. Help for an option | ||
| 75 | + // provides a short synopsis for that option. All help output is appended with a blurb (if | ||
| 76 | + // supplied) directing the user to the full documentation. Help is not shown for options for | ||
| 77 | + // which help has not been added. This makes it possible to have undocumented options for | ||
| 78 | + // testing, backward-compatibility, etc. Also, it could be quite confusing to handle appropriate | ||
| 79 | + // help for some inner options that may be repeated with different semantics inside different | ||
| 80 | + // option tables. There is also no checking for whether an option that has help actually exists. | ||
| 81 | + // In other words, it's up to the caller to ensure that help actually corresponds to the | ||
| 82 | + // program's actual options. Rather than this being an intentional design decision, it is | ||
| 83 | + // because this class is specifically for qpdf, qpdf generates its help and has other means to | ||
| 84 | + // ensure consistency. | ||
| 100 | 85 | ||
| 101 | // Note about newlines: | 86 | // Note about newlines: |
| 102 | // | 87 | // |
| 103 | - // short_text should fit easily after the topic/option on the same | ||
| 104 | - // line and should not end with a newline. Keep it to around 40 to | ||
| 105 | - // 60 characters. | 88 | + // short_text should fit easily after the topic/option on the same line and should not end with |
| 89 | + // a newline. Keep it to around 40 to 60 characters. | ||
| 106 | // | 90 | // |
| 107 | - // long_text and footer should end with a single newline. They can | ||
| 108 | - // have embedded newlines. Keep lines to under 80 columns. | 91 | + // long_text and footer should end with a single newline. They can have embedded newlines. Keep |
| 92 | + // lines to under 80 columns. | ||
| 109 | // | 93 | // |
| 110 | - // QPDFArgParser does reformat the text, but it may add blank | ||
| 111 | - // lines in some situations. Following the above conventions will | ||
| 112 | - // keep the help looking uniform. | 94 | + // QPDFArgParser does reformat the text, but it may add blank lines in some situations. |
| 95 | + // Following the above conventions will keep the help looking uniform. | ||
| 113 | 96 | ||
| 114 | - // If provided, this footer is appended to all help, separated by | ||
| 115 | - // a blank line. | 97 | + // If provided, this footer is appended to all help, separated by a blank line. |
| 116 | void addHelpFooter(std::string const&); | 98 | void addHelpFooter(std::string const&); |
| 117 | 99 | ||
| 118 | // Add a help topic along with the text for that topic | 100 | // Add a help topic along with the text for that topic |
| @@ -126,14 +108,12 @@ class QPDFArgParser | @@ -126,14 +108,12 @@ class QPDFArgParser | ||
| 126 | std::string const& short_text, | 108 | std::string const& short_text, |
| 127 | std::string const& long_text); | 109 | std::string const& long_text); |
| 128 | 110 | ||
| 129 | - // Return the help text for a topic or option. Passing a null | ||
| 130 | - // pointer returns the top-level help information. Passing an | ||
| 131 | - // unknown value returns a string directing the user to run the | 111 | + // Return the help text for a topic or option. Passing a null pointer returns the top-level help |
| 112 | + // information. Passing an unknown value returns a string directing the user to run the | ||
| 132 | // top-level --help option. | 113 | // top-level --help option. |
| 133 | std::string getHelp(std::string const& topic_or_option); | 114 | std::string getHelp(std::string const& topic_or_option); |
| 134 | 115 | ||
| 135 | - // Convenience methods for adding member functions of a class as | ||
| 136 | - // handlers. | 116 | + // Convenience methods for adding member functions of a class as handlers. |
| 137 | template <class T> | 117 | template <class T> |
| 138 | static bare_arg_handler_t | 118 | static bare_arg_handler_t |
| 139 | bindBare(void (T::*f)(), T* o) | 119 | bindBare(void (T::*f)(), T* o) |
| @@ -147,21 +127,19 @@ class QPDFArgParser | @@ -147,21 +127,19 @@ class QPDFArgParser | ||
| 147 | return std::bind(std::mem_fn(f), o, std::placeholders::_1); | 127 | return std::bind(std::mem_fn(f), o, std::placeholders::_1); |
| 148 | } | 128 | } |
| 149 | 129 | ||
| 150 | - // When processing arguments, indicate how many arguments remain | ||
| 151 | - // after the one whose handler is being called. | 130 | + // When processing arguments, indicate how many arguments remain after the one whose handler is |
| 131 | + // being called. | ||
| 152 | int argsLeft() const; | 132 | int argsLeft() const; |
| 153 | 133 | ||
| 154 | // Indicate whether we are in completion mode. | 134 | // Indicate whether we are in completion mode. |
| 155 | bool isCompleting() const; | 135 | bool isCompleting() const; |
| 156 | 136 | ||
| 157 | - // Insert a completion during argument parsing; useful for | ||
| 158 | - // customizing completion in the position argument handler. Should | ||
| 159 | - // only be used in completion mode. | 137 | + // Insert a completion during argument parsing; useful for customizing completion in the |
| 138 | + // position argument handler. Should only be used in completion mode. | ||
| 160 | void insertCompletion(std::string const&); | 139 | void insertCompletion(std::string const&); |
| 161 | 140 | ||
| 162 | - // Throw a Usage exception with the given message. In completion | ||
| 163 | - // mode, this just exits to prevent errors from partial commands | ||
| 164 | - // or other error messages from messing up completion. | 141 | + // Throw a Usage exception with the given message. In completion mode, this just exits to |
| 142 | + // prevent errors from partial commands or other error messages from messing up completion. | ||
| 165 | void usage(std::string const& message); | 143 | void usage(std::string const& message); |
| 166 | 144 | ||
| 167 | private: | 145 | private: |
libqpdf/qpdf/QPDFCrypto_gnutls.hh
| @@ -4,8 +4,8 @@ | @@ -4,8 +4,8 @@ | ||
| 4 | #include <qpdf/QPDFCryptoImpl.hh> | 4 | #include <qpdf/QPDFCryptoImpl.hh> |
| 5 | #include <memory> | 5 | #include <memory> |
| 6 | 6 | ||
| 7 | -// gnutls headers must be last to prevent them from interfering with | ||
| 8 | -// other headers. gnutls.h has to be included first. | 7 | +// gnutls headers must be last to prevent them from interfering with other headers. gnutls.h has to |
| 8 | +// be included first. | ||
| 9 | #include <gnutls/gnutls.h> | 9 | #include <gnutls/gnutls.h> |
| 10 | // This comment prevents clang-format from putting crypto.h before gnutls.h | 10 | // This comment prevents clang-format from putting crypto.h before gnutls.h |
| 11 | #include <gnutls/crypto.h> | 11 | #include <gnutls/crypto.h> |
libqpdf/qpdf/QPDFObject_private.hh
| 1 | #ifndef QPDFOBJECT_HH | 1 | #ifndef QPDFOBJECT_HH |
| 2 | #define QPDFOBJECT_HH | 2 | #define QPDFOBJECT_HH |
| 3 | 3 | ||
| 4 | -// NOTE: This file is called QPDFObject_private.hh instead of | ||
| 5 | -// QPDFObject.hh because of include/qpdf/QPDFObject.hh. See comments | ||
| 6 | -// there for an explanation. | 4 | +// NOTE: This file is called QPDFObject_private.hh instead of QPDFObject.hh because of |
| 5 | +// include/qpdf/QPDFObject.hh. See comments there for an explanation. | ||
| 7 | 6 | ||
| 8 | #include <qpdf/Constants.h> | 7 | #include <qpdf/Constants.h> |
| 9 | #include <qpdf/DLL.h> | 8 | #include <qpdf/DLL.h> |
| @@ -51,8 +50,7 @@ class QPDFObject | @@ -51,8 +50,7 @@ class QPDFObject | ||
| 51 | return value->type_code; | 50 | return value->type_code; |
| 52 | } | 51 | } |
| 53 | 52 | ||
| 54 | - // Return a string literal that describes the type, useful for | ||
| 55 | - // debugging and testing | 53 | + // Return a string literal that describes the type, useful for debugging and testing |
| 56 | char const* | 54 | char const* |
| 57 | getTypeName() const | 55 | getTypeName() const |
| 58 | { | 56 | { |
| @@ -146,14 +144,12 @@ class QPDFObject | @@ -146,14 +144,12 @@ class QPDFObject | ||
| 146 | void | 144 | void |
| 147 | disconnect() | 145 | disconnect() |
| 148 | { | 146 | { |
| 149 | - // Disconnect an object from its owning QPDF. This is called | ||
| 150 | - // by QPDF's destructor. | 147 | + // Disconnect an object from its owning QPDF. This is called by QPDF's destructor. |
| 151 | value->disconnect(); | 148 | value->disconnect(); |
| 152 | value->qpdf = nullptr; | 149 | value->qpdf = nullptr; |
| 153 | value->og = QPDFObjGen(); | 150 | value->og = QPDFObjGen(); |
| 154 | } | 151 | } |
| 155 | - // Mark an object as destroyed. Used by QPDF's destructor for its | ||
| 156 | - // indirect objects. | 152 | + // Mark an object as destroyed. Used by QPDF's destructor for its indirect objects. |
| 157 | void destroy(); | 153 | void destroy(); |
| 158 | 154 | ||
| 159 | bool | 155 | bool |
libqpdf/qpdf/QPDF_Dictionary.hh
| @@ -19,16 +19,15 @@ class QPDF_Dictionary: public QPDFValue | @@ -19,16 +19,15 @@ class QPDF_Dictionary: public QPDFValue | ||
| 19 | virtual JSON getJSON(int json_version); | 19 | virtual JSON getJSON(int json_version); |
| 20 | virtual void disconnect(); | 20 | virtual void disconnect(); |
| 21 | 21 | ||
| 22 | - // hasKey() and getKeys() treat keys with null values as if they | ||
| 23 | - // aren't there. getKey() returns null for the value of a | ||
| 24 | - // non-existent key. This is as per the PDF spec. | 22 | + // hasKey() and getKeys() treat keys with null values as if they aren't there. getKey() returns |
| 23 | + // null for the value of a non-existent key. This is as per the PDF spec. | ||
| 25 | bool hasKey(std::string const&); | 24 | bool hasKey(std::string const&); |
| 26 | QPDFObjectHandle getKey(std::string const&); | 25 | QPDFObjectHandle getKey(std::string const&); |
| 27 | std::set<std::string> getKeys(); | 26 | std::set<std::string> getKeys(); |
| 28 | std::map<std::string, QPDFObjectHandle> const& getAsMap() const; | 27 | std::map<std::string, QPDFObjectHandle> const& getAsMap() const; |
| 29 | 28 | ||
| 30 | - // If value is null, remove key; otherwise, replace the value of | ||
| 31 | - // key, adding it if it does not exist. | 29 | + // If value is null, remove key; otherwise, replace the value of key, adding it if it does not |
| 30 | + // exist. | ||
| 32 | void replaceKey(std::string const& key, QPDFObjectHandle value); | 31 | void replaceKey(std::string const& key, QPDFObjectHandle value); |
| 33 | // Remove key, doing nothing if key does not exist | 32 | // Remove key, doing nothing if key does not exist |
| 34 | void removeKey(std::string const& key); | 33 | void removeKey(std::string const& key); |
libqpdf/qpdf/RC4.hh
| @@ -11,8 +11,7 @@ class RC4 | @@ -11,8 +11,7 @@ class RC4 | ||
| 11 | // key_len of -1 means treat key_data as a null-terminated string | 11 | // key_len of -1 means treat key_data as a null-terminated string |
| 12 | RC4(unsigned char const* key_data, int key_len = -1); | 12 | RC4(unsigned char const* key_data, int key_len = -1); |
| 13 | 13 | ||
| 14 | - // It is safe to pass the same pointer to in_data and out_data to | ||
| 15 | - // encrypt/decrypt in place | 14 | + // It is safe to pass the same pointer to in_data and out_data to encrypt/decrypt in place |
| 16 | void process(unsigned char const* in_data, size_t len, unsigned char* out_data); | 15 | void process(unsigned char const* in_data, size_t len, unsigned char* out_data); |
| 17 | 16 | ||
| 18 | private: | 17 | private: |