Commit 16f46703dc405368390023da6968356644a0b3b6

Authored by Jay Berkenbilt
Committed by GitHub
2 parents b27be3ed 99231c43

Merge pull request #916 from m-holger/job

Split QPDFJob::run into createQPDF and writeQPDF
CMakeLists.txt
... ... @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.16)
5 5 # the project line. When updating the version, check make_dist for all
6 6 # the places it has to be updated.
7 7 project(qpdf
8   - VERSION 11.3.1
  8 + VERSION 11.4.0
9 9 LANGUAGES C CXX)
10 10  
11 11 # Enable correct rpath handling for MacOSX
... ...
examples/CMakeLists.txt
... ... @@ -15,6 +15,7 @@ set(EXAMPLE_CXX_PROGRAMS
15 15 pdf-set-form-values
16 16 pdf-split-pages
17 17 qpdf-job
  18 + qpdfjob-remove-annotations
18 19 qpdfjob-save-attachment)
19 20 set(EXAMPLE_C_PROGRAMS
20 21 pdf-c-objects
... ...
examples/qpdfjob-remove-annotations.cc 0 → 100644
  1 +#include <qpdf/QPDFJob.hh>
  2 +#include <qpdf/QPDFUsage.hh>
  3 +#include <qpdf/QUtil.hh>
  4 +
  5 +#include <cstdio>
  6 +#include <cstdlib>
  7 +#include <cstring>
  8 +#include <iostream>
  9 +
  10 +// This example demonstrates how we can use the QPDFJob createQPDF and writeQPDF
  11 +// methods to add custom transformations to the output produced by QPDFJob runs.
  12 +// The example is a full copy of the qpdf program modified to allways remove all
  13 +// annotations from the final output.
  14 +
  15 +static char const* whoami = 0;
  16 +
  17 +static void
  18 +usageExit(std::string const& msg)
  19 +{
  20 + std::cerr << std::endl
  21 + << whoami << ": " << msg << std::endl
  22 + << std::endl
  23 + << "For help:" << std::endl
  24 + << " " << whoami << " --help=usage usage information"
  25 + << std::endl
  26 + << " " << whoami << " --help=topic help on a topic"
  27 + << std::endl
  28 + << " " << whoami << " --help=--option help on an option"
  29 + << std::endl
  30 + << " " << whoami
  31 + << " --help general help and a topic list"
  32 + << std::endl
  33 + << std::endl;
  34 + exit(QPDFJob::EXIT_ERROR);
  35 +}
  36 +
  37 +int
  38 +realmain(int argc, char* argv[])
  39 +{
  40 + whoami = QUtil::getWhoami(argv[0]);
  41 + QUtil::setLineBuf(stdout);
  42 +
  43 + QPDFJob j;
  44 + try {
  45 + // See "HOW TO ADD A COMMAND-LINE ARGUMENT" in README-maintainer.
  46 + j.initializeFromArgv(argv);
  47 + auto qpdf_sp = j.createQPDF();
  48 + auto& pdf = *qpdf_sp;
  49 + for (auto page: pdf.getAllPages()) {
  50 + page.replaceKey("/Annots", "null"_qpdf);
  51 + }
  52 + j.writeQPDF(pdf);
  53 + } catch (QPDFUsage& e) {
  54 + usageExit(e.what());
  55 + } catch (std::exception& e) {
  56 + std::cerr << whoami << ": " << e.what() << std::endl;
  57 + return QPDFJob::EXIT_ERROR;
  58 + }
  59 + return j.getExitCode();
  60 +}
  61 +
  62 +#ifdef WINDOWS_WMAIN
  63 +
  64 +extern "C" int
  65 +wmain(int argc, wchar_t* argv[])
  66 +{
  67 + return QUtil::call_main_from_wmain(argc, argv, realmain);
  68 +}
  69 +
  70 +#else
  71 +
  72 +int
  73 +main(int argc, char* argv[])
  74 +{
  75 + return realmain(argc, argv);
  76 +}
  77 +
  78 +#endif
... ...
examples/qtest/qpdfjob-remove-annotations.test 0 → 100644
  1 +#!/usr/bin/env perl
  2 +require 5.008;
  3 +use warnings;
  4 +use strict;
  5 +
  6 +chdir("qpdfjob-remove-annotations");
  7 +
  8 +require TestDriver;
  9 +
  10 +my $td = new TestDriver('qpdfjob-remove-annotations');
  11 +
  12 +cleanup();
  13 +
  14 +$td->runtest("remove-annotations",
  15 + {$td->COMMAND => "qpdfjob-remove-annotations --static-id annotations.pdf out.pdf"},
  16 + {$td->STRING => "", $td->EXIT_STATUS => 0});
  17 +$td->runtest("compare files",
  18 + {$td->FILE => "out.pdf"},
  19 + {$td->FILE => "annotations-out.pdf"});
  20 +
  21 +cleanup();
  22 +
  23 +$td->report(2);
  24 +
  25 +sub cleanup
  26 +{
  27 + unlink("out.pdf");
  28 +}
... ...
examples/qtest/qpdfjob-remove-annotations/annotations-out.pdf 0 → 100644
No preview for this file type
examples/qtest/qpdfjob-remove-annotations/annotations.pdf 0 → 100644
  1 +%PDF-1.6
  2 +%¿÷¢þ
  3 +%QDF-1.0
  4 +
  5 +1 0 obj
  6 +<<
  7 + /AcroForm <<
  8 + /DR 2 0 R
  9 + /Fields [
  10 + 3 0 R
  11 + 4 0 R
  12 + 5 0 R
  13 + ]
  14 + >>
  15 + /Names <<
  16 + /EmbeddedFiles 6 0 R
  17 + >>
  18 + /Pages 7 0 R
  19 + /Type /Catalog
  20 +>>
  21 +endobj
  22 +
  23 +2 0 obj
  24 +<<
  25 + /Font <<
  26 + /F1 8 0 R
  27 + >>
  28 +>>
  29 +endobj
  30 +
  31 +3 0 obj
  32 +<<
  33 + /AP <<
  34 + /N 9 0 R
  35 + >>
  36 + /DA (0 0.4 0 rg /F1 18 Tf)
  37 + /DR 2 0 R
  38 + /DV ()
  39 + /FT /Tx
  40 + /Ff 0
  41 + /Rect [
  42 + 72
  43 + 470.774
  44 + 190.8
  45 + 484.922
  46 + ]
  47 + /Subtype /Widget
  48 + /T (Text Box 1)
  49 + /Type /Annot
  50 + /V (Formy field)
  51 +>>
  52 +endobj
  53 +
  54 +4 0 obj
  55 +<<
  56 + /AP <<
  57 + /N 11 0 R
  58 + >>
  59 + /DA (0 0.4 0 rg /F1 18 Tf)
  60 + /DR 2 0 R
  61 + /DV ()
  62 + /FT /Tx
  63 + /Ff 0
  64 + /Rect [
  65 + 372
  66 + 330.774
  67 + 386.148
  68 + 470.374
  69 + ]
  70 + /Subtype /Widget
  71 + /T (Text Box 1)
  72 + /Type /Annot
  73 + /V (Rot-ccw field)
  74 +>>
  75 +endobj
  76 +
  77 +5 0 obj
  78 +<<
  79 + /DV /1
  80 + /FT /Btn
  81 + /Ff 49152
  82 + /Kids [
  83 + 13 0 R
  84 + 14 0 R
  85 + 15 0 R
  86 + ]
  87 + /T (r1)
  88 + /V /2
  89 +>>
  90 +endobj
  91 +
  92 +6 0 obj
  93 +<<
  94 + /Names [
  95 + (attachment1.txt)
  96 + 16 0 R
  97 + ]
  98 +>>
  99 +endobj
  100 +
  101 +7 0 obj
  102 +<<
  103 + /Count 1
  104 + /Kids [
  105 + 17 0 R
  106 + ]
  107 + /Type /Pages
  108 +>>
  109 +endobj
  110 +
  111 +8 0 obj
  112 +<<
  113 + /BaseFont /Courier
  114 + /Encoding /WinAnsiEncoding
  115 + /Subtype /Type1
  116 + /Type /Font
  117 +>>
  118 +endobj
  119 +
  120 +9 0 obj
  121 +<<
  122 + /BBox [
  123 + 0
  124 + -2.826
  125 + 118.8
  126 + 11.322
  127 + ]
  128 + /Resources 2 0 R
  129 + /Subtype /Form
  130 + /Type /XObject
  131 + /Length 10 0 R
  132 +>>
  133 +stream
  134 +/Tx BMC
  135 +q
  136 +BT
  137 + /F1 18 Tf
  138 + (Formy field) Tj
  139 +ET
  140 +Q
  141 +EMC
  142 +endstream
  143 +endobj
  144 +
  145 +10 0 obj
  146 +53
  147 +endobj
  148 +
  149 +11 0 obj
  150 +<<
  151 + /BBox [
  152 + 0
  153 + -2.826
  154 + 140.4
  155 + 11.322
  156 + ]
  157 + /Matrix [
  158 + 0
  159 + 1
  160 + -1
  161 + 0
  162 + 0
  163 + 0
  164 + ]
  165 + /Resources 2 0 R
  166 + /Subtype /Form
  167 + /Type /XObject
  168 + /Length 12 0 R
  169 +>>
  170 +stream
  171 +/Tx BMC
  172 +q
  173 +BT
  174 + /F1 18 Tf
  175 + (Rot-ccw field) Tj
  176 +ET
  177 +Q
  178 +EMC
  179 +endstream
  180 +endobj
  181 +
  182 +12 0 obj
  183 +55
  184 +endobj
  185 +
  186 +13 0 obj
  187 +<<
  188 + /AP <<
  189 + /N <<
  190 + /1 18 0 R
  191 + /Off 20 0 R
  192 + >>
  193 + >>
  194 + /AS /1
  195 + /DA (0.18039 0.20392 0.21176 rg /ZaDi 0 Tf)
  196 + /DR <<
  197 + /Font <<
  198 + /ZaDi 22 0 R
  199 + >>
  200 + >>
  201 + /F 4
  202 + /FT /Btn
  203 + /MK <<
  204 + /CA (l)
  205 + >>
  206 + /Parent 5 0 R
  207 + /Rect [
  208 + 152.749
  209 + 648.501
  210 + 164.801
  211 + 660.549
  212 + ]
  213 + /Subtype /Widget
  214 + /Type /Annot
  215 +>>
  216 +endobj
  217 +
  218 +14 0 obj
  219 +<<
  220 + /AP <<
  221 + /N <<
  222 + /2 23 0 R
  223 + /Off 25 0 R
  224 + >>
  225 + >>
  226 + /AS /2
  227 + /DA (0.18039 0.20392 0.21176 rg /ZaDi 0 Tf)
  228 + /DR <<
  229 + /Font <<
  230 + /ZaDi 22 0 R
  231 + >>
  232 + >>
  233 + /F 4
  234 + /FT /Btn
  235 + /MK <<
  236 + /CA (l)
  237 + >>
  238 + /Parent 5 0 R
  239 + /Rect [
  240 + 152.749
  241 + 627.301
  242 + 164.801
  243 + 639.349
  244 + ]
  245 + /Subtype /Widget
  246 + /Type /Annot
  247 +>>
  248 +endobj
  249 +
  250 +15 0 obj
  251 +<<
  252 + /AP <<
  253 + /N <<
  254 + /3 27 0 R
  255 + /Off 29 0 R
  256 + >>
  257 + >>
  258 + /AS /3
  259 + /DA (0.18039 0.20392 0.21176 rg /ZaDi 0 Tf)
  260 + /DR <<
  261 + /Font <<
  262 + /ZaDi 22 0 R
  263 + >>
  264 + >>
  265 + /F 4
  266 + /FT /Btn
  267 + /MK <<
  268 + /CA (l)
  269 + >>
  270 + /Parent 5 0 R
  271 + /Rect [
  272 + 151.399
  273 + 606.501
  274 + 163.451
  275 + 618.549
  276 + ]
  277 + /Subtype /Widget
  278 + /Type /Annot
  279 +>>
  280 +endobj
  281 +
  282 +16 0 obj
  283 +<<
  284 + /EF <<
  285 + /F 31 0 R
  286 + /UF 31 0 R
  287 + >>
  288 + /F (attachment1.txt)
  289 + /Type /Filespec
  290 + /UF (attachment1.txt)
  291 +>>
  292 +endobj
  293 +
  294 +%% Page 1
  295 +17 0 obj
  296 +<<
  297 + /Annots [
  298 + 33 0 R
  299 + 3 0 R
  300 + 34 0 R
  301 + 4 0 R
  302 + 35 0 R
  303 + 36 0 R
  304 + 37 0 R
  305 + 38 0 R
  306 + 13 0 R
  307 + 14 0 R
  308 + 15 0 R
  309 + ]
  310 + /Contents 39 0 R
  311 + /MediaBox [
  312 + 0
  313 + 0
  314 + 612
  315 + 792
  316 + ]
  317 + /Parent 7 0 R
  318 + /Resources 2 0 R
  319 + /Type /Page
  320 +>>
  321 +endobj
  322 +
  323 +18 0 obj
  324 +<<
  325 + /BBox [
  326 + 0
  327 + 0
  328 + 12.05
  329 + 12.05
  330 + ]
  331 + /Resources 41 0 R
  332 + /Subtype /Form
  333 + /Type /XObject
  334 + /Length 19 0 R
  335 +>>
  336 +stream
  337 +/Tx BMC
  338 +q BT
  339 +0.18039 0.20392 0.21176 rg /ZaDi 12.05 Tf
  340 +0 0 Td
  341 +ET
  342 +Q
  343 +1 0 0 rg
  344 +6 8.4 m 7.35 8.4 8.45 7.35 8.45 6 c
  345 +8.45 4.65 7.35 3.55 6 3.55 c
  346 +4.65 3.55 3.6 4.65 3.6 6 c
  347 +3.6 7.35 4.65 8.4 6 8.4 c f*
  348 +
  349 +EMC
  350 +endstream
  351 +endobj
  352 +
  353 +19 0 obj
  354 +202
  355 +endobj
  356 +
  357 +20 0 obj
  358 +<<
  359 + /BBox [
  360 + 0
  361 + 0
  362 + 12.05
  363 + 12.05
  364 + ]
  365 + /Resources 41 0 R
  366 + /Subtype /Form
  367 + /Type /XObject
  368 + /Length 21 0 R
  369 +>>
  370 +stream
  371 +/Tx BMC
  372 +EMC
  373 +endstream
  374 +endobj
  375 +
  376 +21 0 obj
  377 +12
  378 +endobj
  379 +
  380 +22 0 obj
  381 +<<
  382 + /BaseFont /ZapfDingbats
  383 + /Subtype /Type1
  384 + /Type /Font
  385 +>>
  386 +endobj
  387 +
  388 +23 0 obj
  389 +<<
  390 + /BBox [
  391 + 0
  392 + 0
  393 + 12.05
  394 + 12.05
  395 + ]
  396 + /Resources 41 0 R
  397 + /Subtype /Form
  398 + /Type /XObject
  399 + /Length 24 0 R
  400 +>>
  401 +stream
  402 +/Tx BMC
  403 +q BT
  404 +0.18039 0.20392 0.21176 rg /ZaDi 12.05 Tf
  405 +0 0 Td
  406 +ET
  407 +Q
  408 +0 1 0 rg
  409 +6 8.4 m 7.35 8.4 8.45 7.35 8.45 6 c
  410 +8.45 4.65 7.35 3.55 6 3.55 c
  411 +4.65 3.55 3.6 4.65 3.6 6 c
  412 +3.6 7.35 4.65 8.4 6 8.4 c f*
  413 +
  414 +EMC
  415 +endstream
  416 +endobj
  417 +
  418 +24 0 obj
  419 +202
  420 +endobj
  421 +
  422 +25 0 obj
  423 +<<
  424 + /BBox [
  425 + 0
  426 + 0
  427 + 12.05
  428 + 12.05
  429 + ]
  430 + /Resources 41 0 R
  431 + /Subtype /Form
  432 + /Type /XObject
  433 + /Length 26 0 R
  434 +>>
  435 +stream
  436 +/Tx BMC
  437 +EMC
  438 +endstream
  439 +endobj
  440 +
  441 +26 0 obj
  442 +12
  443 +endobj
  444 +
  445 +27 0 obj
  446 +<<
  447 + /BBox [
  448 + 0
  449 + 0
  450 + 12.05
  451 + 12.05
  452 + ]
  453 + /Resources 41 0 R
  454 + /Subtype /Form
  455 + /Type /XObject
  456 + /Length 28 0 R
  457 +>>
  458 +stream
  459 +/Tx BMC
  460 +q BT
  461 +0.18039 0.20392 0.21176 rg /ZaDi 12.05 Tf
  462 +0 0 Td
  463 +ET
  464 +Q
  465 +0 0 1 rg
  466 +6 8.4 m 7.35 8.4 8.45 7.35 8.45 6 c
  467 +8.45 4.65 7.35 3.55 6 3.55 c
  468 +4.65 3.55 3.6 4.65 3.6 6 c
  469 +3.6 7.35 4.65 8.4 6 8.4 c f*
  470 +
  471 +EMC
  472 +endstream
  473 +endobj
  474 +
  475 +28 0 obj
  476 +202
  477 +endobj
  478 +
  479 +29 0 obj
  480 +<<
  481 + /BBox [
  482 + 0
  483 + 0
  484 + 12.05
  485 + 12.05
  486 + ]
  487 + /Resources 41 0 R
  488 + /Subtype /Form
  489 + /Type /XObject
  490 + /Length 30 0 R
  491 +>>
  492 +stream
  493 +/Tx BMC
  494 +EMC
  495 +endstream
  496 +endobj
  497 +
  498 +30 0 obj
  499 +12
  500 +endobj
  501 +
  502 +31 0 obj
  503 +<<
  504 + /Params <<
  505 + /CheckSum <80a33fc110b5a7b8b4d58b8d57e814bc>
  506 + /Size 22
  507 + /Subtype /text#2fplain
  508 + >>
  509 + /Type /EmbeddedFile
  510 + /Length 32 0 R
  511 +>>
  512 +stream
  513 +content of attachment
  514 +endstream
  515 +endobj
  516 +
  517 +32 0 obj
  518 +22
  519 +endobj
  520 +
  521 +33 0 obj
  522 +<<
  523 + /A <<
  524 + /S /URI
  525 + /URI (https://www.qbilt.org/)
  526 + >>
  527 + /Border [
  528 + 0
  529 + 0
  530 + .4
  531 + ]
  532 + /C [
  533 + .8
  534 + .6
  535 + .6
  536 + ]
  537 + /H /I
  538 + /Rect [
  539 + 72
  540 + 501.832
  541 + 374.4
  542 + 520.696
  543 + ]
  544 + /Subtype /Link
  545 + /Type /Annot
  546 +>>
  547 +endobj
  548 +
  549 +34 0 obj
  550 +<<
  551 + /AP <<
  552 + /N 42 0 R
  553 + >>
  554 + /Contents (attachment1.txt)
  555 + /FS 16 0 R
  556 + /NM (attachment1.txt)
  557 + /Rect [
  558 + 72
  559 + 400
  560 + 92
  561 + 420
  562 + ]
  563 + /Subtype /FileAttachment
  564 + /Type /Annot
  565 +>>
  566 +endobj
  567 +
  568 +35 0 obj
  569 +<<
  570 + /AP <<
  571 + /N 44 0 R
  572 + >>
  573 + /DA ()
  574 + /Rect [
  575 + 72
  576 + 350
  577 + 92
  578 + 360
  579 + ]
  580 + /Subtype /FreeText
  581 + /Type /Annot
  582 +>>
  583 +endobj
  584 +
  585 +36 0 obj
  586 +<<
  587 + /AP <<
  588 + /N 46 0 R
  589 + >>
  590 + /DA ()
  591 + /Rect [
  592 + 102
  593 + 350
  594 + 112
  595 + 370
  596 + ]
  597 + /Subtype /FreeText
  598 + /Type /Annot
  599 +>>
  600 +endobj
  601 +
  602 +37 0 obj
  603 +<<
  604 + /AP <<
  605 + /N 48 0 R
  606 + >>
  607 + /DA ()
  608 + /Rect [
  609 + 122
  610 + 350
  611 + 142
  612 + 360
  613 + ]
  614 + /Subtype /FreeText
  615 + /Type /Annot
  616 +>>
  617 +endobj
  618 +
  619 +38 0 obj
  620 +<<
  621 + /AP <<
  622 + /N 50 0 R
  623 + >>
  624 + /DA ()
  625 + /Rect [
  626 + 152
  627 + 350
  628 + 162
  629 + 370
  630 + ]
  631 + /Subtype /FreeText
  632 + /Type /Annot
  633 +>>
  634 +endobj
  635 +
  636 +%% Contents for page 1
  637 +39 0 obj
  638 +<<
  639 + /Length 40 0 R
  640 +>>
  641 +stream
  642 +q
  643 +1 1 .7 rg
  644 +.5 .5 0 RG
  645 +72 470.77 118.8 14.15 re
  646 +B
  647 +Q
  648 +q
  649 +0 .5 .5 RG
  650 +0 1 1 rg
  651 +372 330.77 14.15 139.4 re
  652 +B
  653 +Q
  654 +q
  655 +1 0 0 RG
  656 +72 310 20 10 re
  657 +72 310 5 10 re
  658 +S
  659 +0 1 0 RG
  660 +102 310 10 20 re
  661 +102 310 10 5 re
  662 +S
  663 +0 0 1 RG
  664 +122 310 20 10 re
  665 +137 310 5 10 re
  666 +S
  667 +0.5 0 1 RG
  668 +152 310 10 20 re
  669 +152 325 10 5 re
  670 +S
  671 +10 w
  672 +0.14 .33 .18 RG
  673 +5 5 602 782 re
  674 +S
  675 +Q
  676 +BT
  677 + /F1 16 Tf
  678 + 20.6 TL
  679 + 170 650 Td
  680 + (radio button 1) Tj
  681 + (radio button 2) '
  682 + (radio button 3) '
  683 + 1 0 0 1 72 546 Tm
  684 + /F1 20 Tf
  685 + (Thick green border surrounds page.) Tj
  686 + 0 -40 Td
  687 + /F1 24 Tf
  688 + 0 0 1 rg
  689 + (https://www.qbilt.org) Tj
  690 + /F1 12 Tf
  691 + 1 0 0 1 202 474 Tm
  692 + (<- Formy field in yellow) Tj
  693 + 1 0 0 1 392 410 Tm
  694 + 14.4 TL
  695 + (<- Rot-ccw field) Tj
  696 + (with "Rot" at bottom) '
  697 + (and text going up) '
  698 + 0 g
  699 + 1 0 0 1 102 405 Tm
  700 + (Arrow to the left points down.) Tj
  701 + 1 0 0 1 182 310 Tm
  702 + (<- Drawn rectangles appear below annotations.) Tj
  703 +ET
  704 +endstream
  705 +endobj
  706 +
  707 +40 0 obj
  708 +874
  709 +endobj
  710 +
  711 +41 0 obj
  712 +<<
  713 + /Font 52 0 R
  714 + /ProcSet [
  715 + /PDF
  716 + /Text
  717 + ]
  718 +>>
  719 +endobj
  720 +
  721 +42 0 obj
  722 +<<
  723 + /BBox [
  724 + 0
  725 + 0
  726 + 20
  727 + 20
  728 + ]
  729 + /Resources <<
  730 + >>
  731 + /Subtype /Form
  732 + /Type /XObject
  733 + /Length 43 0 R
  734 +>>
  735 +stream
  736 +0 10 m
  737 +10 0 l
  738 +20 10 l
  739 +10 0 m
  740 +10 20 l
  741 +0 0 20 20 re
  742 +S
  743 +endstream
  744 +endobj
  745 +
  746 +43 0 obj
  747 +52
  748 +endobj
  749 +
  750 +44 0 obj
  751 +<<
  752 + /BBox [
  753 + 0
  754 + 0
  755 + 20
  756 + 10
  757 + ]
  758 + /Resources 2 0 R
  759 + /Subtype /Form
  760 + /Type /XObject
  761 + /Length 45 0 R
  762 +>>
  763 +stream
  764 +1 0 0 RG
  765 +0 0 20 10 re
  766 +0 0 5 10 re
  767 +S
  768 +endstream
  769 +endobj
  770 +
  771 +45 0 obj
  772 +36
  773 +endobj
  774 +
  775 +46 0 obj
  776 +<<
  777 + /BBox [
  778 + 0
  779 + 0
  780 + 20
  781 + 10
  782 + ]
  783 + /Matrix [
  784 + 0
  785 + 1
  786 + -1
  787 + 0
  788 + 0
  789 + 0
  790 + ]
  791 + /Resources 2 0 R
  792 + /Subtype /Form
  793 + /Type /XObject
  794 + /Length 47 0 R
  795 +>>
  796 +stream
  797 +0 1 0 RG
  798 +0 0 20 10 re
  799 +0 0 5 10 re
  800 +S
  801 +endstream
  802 +endobj
  803 +
  804 +47 0 obj
  805 +36
  806 +endobj
  807 +
  808 +48 0 obj
  809 +<<
  810 + /BBox [
  811 + 0
  812 + 0
  813 + 20
  814 + 10
  815 + ]
  816 + /Matrix [
  817 + -1
  818 + 0
  819 + 0
  820 + -1
  821 + 0
  822 + 0
  823 + ]
  824 + /Resources 2 0 R
  825 + /Subtype /Form
  826 + /Type /XObject
  827 + /Length 49 0 R
  828 +>>
  829 +stream
  830 +0 0 1 RG
  831 +0 0 20 10 re
  832 +0 0 5 10 re
  833 +S
  834 +endstream
  835 +endobj
  836 +
  837 +49 0 obj
  838 +36
  839 +endobj
  840 +
  841 +50 0 obj
  842 +<<
  843 + /BBox [
  844 + 0
  845 + 0
  846 + 20
  847 + 10
  848 + ]
  849 + /Matrix [
  850 + 0
  851 + -1
  852 + 1
  853 + 0
  854 + 0
  855 + 0
  856 + ]
  857 + /Resources 2 0 R
  858 + /Subtype /Form
  859 + /Type /XObject
  860 + /Length 51 0 R
  861 +>>
  862 +stream
  863 +0.5 0 1 RG
  864 +0 0 20 10 re
  865 +0 0 5 10 re
  866 +S
  867 +endstream
  868 +endobj
  869 +
  870 +51 0 obj
  871 +38
  872 +endobj
  873 +
  874 +52 0 obj
  875 +<<
  876 + /ZaDi 22 0 R
  877 +>>
  878 +endobj
  879 +
  880 +xref
  881 +0 53
  882 +0000000000 65535 f
  883 +0000000025 00000 n
  884 +0000000211 00000 n
  885 +0000000263 00000 n
  886 +0000000506 00000 n
  887 +0000000755 00000 n
  888 +0000000874 00000 n
  889 +0000000944 00000 n
  890 +0000001017 00000 n
  891 +0000001121 00000 n
  892 +0000001335 00000 n
  893 +0000001355 00000 n
  894 +0000001625 00000 n
  895 +0000001645 00000 n
  896 +0000001997 00000 n
  897 +0000002349 00000 n
  898 +0000002701 00000 n
  899 +0000002842 00000 n
  900 +0000003114 00000 n
  901 +0000003473 00000 n
  902 +0000003494 00000 n
  903 +0000003663 00000 n
  904 +0000003683 00000 n
  905 +0000003764 00000 n
  906 +0000004123 00000 n
  907 +0000004144 00000 n
  908 +0000004313 00000 n
  909 +0000004333 00000 n
  910 +0000004692 00000 n
  911 +0000004713 00000 n
  912 +0000004882 00000 n
  913 +0000004902 00000 n
  914 +0000005110 00000 n
  915 +0000005130 00000 n
  916 +0000005374 00000 n
  917 +0000005578 00000 n
  918 +0000005718 00000 n
  919 +0000005860 00000 n
  920 +0000006002 00000 n
  921 +0000006167 00000 n
  922 +0000007098 00000 n
  923 +0000007119 00000 n
  924 +0000007193 00000 n
  925 +0000007397 00000 n
  926 +0000007417 00000 n
  927 +0000007603 00000 n
  928 +0000007623 00000 n
  929 +0000007862 00000 n
  930 +0000007882 00000 n
  931 +0000008122 00000 n
  932 +0000008142 00000 n
  933 +0000008383 00000 n
  934 +0000008403 00000 n
  935 +trailer <<
  936 + /Root 1 0 R
  937 + /Size 53
  938 + /ID [<a2f146daeb6d814a742556489dab9882><7b639c67bfc16b5e891fa5468aac3a14>]
  939 +>>
  940 +startxref
  941 +8441
  942 +%%EOF
... ...
include/qpdf/DLL.h
... ... @@ -25,9 +25,9 @@
25 25  
26 26 /* The first version of qpdf to include the version constants is 10.6.0. */
27 27 #define QPDF_MAJOR_VERSION 11
28   -#define QPDF_MINOR_VERSION 3
29   -#define QPDF_PATCH_VERSION 1
30   -#define QPDF_VERSION "11.3.1"
  28 +#define QPDF_MINOR_VERSION 4
  29 +#define QPDF_PATCH_VERSION 0
  30 +#define QPDF_VERSION "11.4.0"
31 31  
32 32 /*
33 33 * This file defines symbols that control the which functions,
... ...
include/qpdf/QPDFJob.hh
... ... @@ -397,6 +397,21 @@ class QPDFJob
397 397 QPDF_DLL
398 398 void run();
399 399  
  400 + // The following two methods allow a job to be run in two stages - creation
  401 + // of a QPDF object and writing of the QPDF object. This allows the QPDF
  402 + // object to be modified prior to writing it out. See
  403 + // examples/qpdfjob-remove-annotations for an illustration of its use.
  404 +
  405 + // Run the first stage of the job. Return a nullptr if the configuration is
  406 + // not valid.
  407 + QPDF_DLL
  408 + std::unique_ptr<QPDF> createQPDF();
  409 +
  410 + // Run the second stage of the job. Do nothing if a nullptr is passed as
  411 + // parameter.
  412 + QPDF_DLL
  413 + void writeQPDF(QPDF& qpdf);
  414 +
400 415 // CHECK STATUS -- these methods provide information known after
401 416 // run() is called.
402 417  
... ... @@ -474,7 +489,7 @@ class QPDFJob
474 489 std::string to_nr;
475 490 std::string from_nr;
476 491 std::string repeat_nr;
477   - std::shared_ptr<QPDF> pdf;
  492 + std::unique_ptr<QPDF> pdf;
478 493 std::vector<int> to_pagenos;
479 494 std::vector<int> from_pagenos;
480 495 std::vector<int> repeat_pagenos;
... ... @@ -490,25 +505,25 @@ class QPDFJob
490 505  
491 506 // Basic file processing
492 507 void processFile(
493   - std::shared_ptr<QPDF>&,
  508 + std::unique_ptr<QPDF>&,
494 509 char const* filename,
495 510 char const* password,
496 511 bool used_for_input,
497 512 bool main_input);
498 513 void processInputSource(
499   - std::shared_ptr<QPDF>&,
  514 + std::unique_ptr<QPDF>&,
500 515 std::shared_ptr<InputSource> is,
501 516 char const* password,
502 517 bool used_for_input);
503 518 void doProcess(
504   - std::shared_ptr<QPDF>&,
  519 + std::unique_ptr<QPDF>&,
505 520 std::function<void(QPDF*, char const*)> fn,
506 521 char const* password,
507 522 bool empty,
508 523 bool used_for_input,
509 524 bool main_input);
510 525 void doProcessOnce(
511   - std::shared_ptr<QPDF>&,
  526 + std::unique_ptr<QPDF>&,
512 527 std::function<void(QPDF*, char const*)> fn,
513 528 char const* password,
514 529 bool empty,
... ... @@ -518,7 +533,7 @@ class QPDFJob
518 533 // Transformations
519 534 void setQPDFOptions(QPDF& pdf);
520 535 void
521   - handlePageSpecs(QPDF& pdf, std::vector<std::shared_ptr<QPDF>>& page_heap);
  536 + handlePageSpecs(QPDF& pdf, std::vector<std::unique_ptr<QPDF>>& page_heap);
522 537 bool shouldRemoveUnreferencedResources(QPDF& pdf);
523 538 void handleRotations(QPDF& pdf);
524 539 void
... ...
libqpdf/QPDFJob.cc
... ... @@ -447,11 +447,11 @@ QPDFJob::parseNumrange(char const* range, int max)
447 447 return std::vector<int>();
448 448 }
449 449  
450   -void
451   -QPDFJob::run()
  450 +std::unique_ptr<QPDF>
  451 +QPDFJob::createQPDF()
452 452 {
453 453 checkConfiguration();
454   - std::shared_ptr<QPDF> pdf_sp;
  454 + std::unique_ptr<QPDF> pdf_sp;
455 455 try {
456 456 processFile(pdf_sp, m->infilename.get(), m->password.get(), true, true);
457 457 } catch (QPDFExc& e) {
... ... @@ -461,12 +461,12 @@ QPDFJob::run()
461 461 if (m->check_is_encrypted || m->check_requires_password) {
462 462 this->m->encryption_status =
463 463 qpdf_es_encrypted | qpdf_es_password_incorrect;
464   - return;
  464 + return nullptr;
465 465 }
466 466 if (m->show_encryption && pdf_sp) {
467 467 this->m->log->info("Incorrect password supplied\n");
468 468 showEncryption(*pdf_sp);
469   - return;
  469 + return nullptr;
470 470 }
471 471 }
472 472 throw e;
... ... @@ -477,7 +477,7 @@ QPDFJob::run()
477 477 }
478 478  
479 479 if (m->check_is_encrypted || m->check_requires_password) {
480   - return;
  480 + return nullptr;
481 481 }
482 482  
483 483 // If we are updating from JSON, this has to be done first before
... ... @@ -486,7 +486,7 @@ QPDFJob::run()
486 486 pdf.updateFromJSON(this->m->update_from_json);
487 487 }
488 488  
489   - std::vector<std::shared_ptr<QPDF>> page_heap;
  489 + std::vector<std::unique_ptr<QPDF>> page_heap;
490 490 if (!m->page_specs.empty()) {
491 491 handlePageSpecs(pdf, page_heap);
492 492 }
... ... @@ -495,7 +495,12 @@ QPDFJob::run()
495 495 }
496 496 handleUnderOverlay(pdf);
497 497 handleTransformations(pdf);
  498 + return pdf_sp;
  499 +}
498 500  
  501 +void
  502 +QPDFJob::writeQPDF(QPDF& pdf)
  503 +{
499 504 if (!createsOutput()) {
500 505 doInspection(pdf);
501 506 } else if (m->split_pages) {
... ... @@ -527,6 +532,15 @@ QPDFJob::run()
527 532 }
528 533 }
529 534  
  535 +void
  536 +QPDFJob::run()
  537 +{
  538 + auto pdf = createQPDF();
  539 + if (pdf) {
  540 + writeQPDF(*pdf);
  541 + }
  542 +}
  543 +
530 544 bool
531 545 QPDFJob::hasWarnings() const
532 546 {
... ... @@ -1868,14 +1882,14 @@ QPDFJob::doInspection(QPDF&amp; pdf)
1868 1882  
1869 1883 void
1870 1884 QPDFJob::doProcessOnce(
1871   - std::shared_ptr<QPDF>& pdf,
  1885 + std::unique_ptr<QPDF>& pdf,
1872 1886 std::function<void(QPDF*, char const*)> fn,
1873 1887 char const* password,
1874 1888 bool empty,
1875 1889 bool used_for_input,
1876 1890 bool main_input)
1877 1891 {
1878   - pdf = QPDF::create();
  1892 + pdf = std::make_unique<QPDF>();
1879 1893 setQPDFOptions(*pdf);
1880 1894 if (empty) {
1881 1895 pdf->emptyPDF();
... ... @@ -1892,7 +1906,7 @@ QPDFJob::doProcessOnce(
1892 1906  
1893 1907 void
1894 1908 QPDFJob::doProcess(
1895   - std::shared_ptr<QPDF>& pdf,
  1909 + std::unique_ptr<QPDF>& pdf,
1896 1910 std::function<void(QPDF*, char const*)> fn,
1897 1911 char const* password,
1898 1912 bool empty,
... ... @@ -1976,7 +1990,7 @@ QPDFJob::doProcess(
1976 1990  
1977 1991 void
1978 1992 QPDFJob::processFile(
1979   - std::shared_ptr<QPDF>& pdf,
  1993 + std::unique_ptr<QPDF>& pdf,
1980 1994 char const* filename,
1981 1995 char const* password,
1982 1996 bool used_for_input,
... ... @@ -1996,7 +2010,7 @@ QPDFJob::processFile(
1996 2010  
1997 2011 void
1998 2012 QPDFJob::processInputSource(
1999   - std::shared_ptr<QPDF>& pdf,
  2013 + std::unique_ptr<QPDF>& pdf,
2000 2014 std::shared_ptr<InputSource> is,
2001 2015 char const* password,
2002 2016 bool used_for_input)
... ... @@ -2278,7 +2292,7 @@ QPDFJob::copyAttachments(QPDF&amp; pdf)
2278 2292 v << prefix << ": copying attachments from " << to_copy.path
2279 2293 << "\n";
2280 2294 });
2281   - std::shared_ptr<QPDF> other;
  2295 + std::unique_ptr<QPDF> other;
2282 2296 processFile(
2283 2297 other,
2284 2298 to_copy.path.c_str(),
... ... @@ -2540,7 +2554,7 @@ added_page(QPDF&amp; pdf, QPDFPageObjectHelper page)
2540 2554  
2541 2555 void
2542 2556 QPDFJob::handlePageSpecs(
2543   - QPDF& pdf, std::vector<std::shared_ptr<QPDF>>& page_heap)
  2557 + QPDF& pdf, std::vector<std::unique_ptr<QPDF>>& page_heap)
2544 2558 {
2545 2559 // Parse all page specifications and translate them into lists of
2546 2560 // actual pages.
... ... @@ -2612,10 +2626,10 @@ QPDFJob::handlePageSpecs(
2612 2626 new FileInputSource(page_spec.filename.c_str());
2613 2627 is = std::shared_ptr<InputSource>(fis);
2614 2628 }
2615   - std::shared_ptr<QPDF> qpdf_sp;
  2629 + std::unique_ptr<QPDF> qpdf_sp;
2616 2630 processInputSource(qpdf_sp, is, password, true);
2617   - page_heap.push_back(qpdf_sp);
2618 2631 page_spec_qpdfs[page_spec.filename] = qpdf_sp.get();
  2632 + page_heap.push_back(std::move(qpdf_sp));
2619 2633 if (cis) {
2620 2634 cis->stayOpen(false);
2621 2635 page_spec_cfis[page_spec.filename] = cis;
... ... @@ -3116,7 +3130,7 @@ QPDFJob::setWriterOptions(QPDF&amp; pdf, QPDFWriter&amp; w)
3116 3130 w.setSuppressOriginalObjectIDs(true);
3117 3131 }
3118 3132 if (m->copy_encryption) {
3119   - std::shared_ptr<QPDF> encryption_pdf;
  3133 + std::unique_ptr<QPDF> encryption_pdf;
3120 3134 processFile(
3121 3135 encryption_pdf,
3122 3136 m->encryption_file.c_str(),
... ...
manual/conf.py
... ... @@ -16,7 +16,7 @@ project = &#39;QPDF&#39;
16 16 copyright = '2005-2023, Jay Berkenbilt'
17 17 author = 'Jay Berkenbilt'
18 18 # make_dist and the CI build lexically find the release version from this file.
19   -release = '11.3.1'
  19 +release = '11.4.0'
20 20 version = release
21 21 extensions = [
22 22 'sphinx_rtd_theme',
... ...