diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/CMakeLists.txt | 8 | ||||
-rw-r--r-- | examples/extend-c-api-impl.cc | 29 | ||||
-rw-r--r-- | examples/extend-c-api.c | 67 | ||||
-rw-r--r-- | examples/extend-c-api.h | 25 | ||||
-rw-r--r-- | examples/qpdf-job.cc | 3 | ||||
-rw-r--r-- | examples/qpdfjob-c.c | 5 | ||||
-rw-r--r-- | examples/qtest/c-objects.test | 4 | ||||
-rw-r--r-- | examples/qtest/custom-filter.test | 8 | ||||
-rw-r--r-- | examples/qtest/extend-c-api.test | 30 | ||||
-rw-r--r-- | examples/qtest/extend-c-api/bad.out | 5 | ||||
-rw-r--r-- | examples/qtest/extend-c-api/bad.pdf | 1 | ||||
-rw-r--r-- | examples/qtest/extend-c-api/good.out | 1 | ||||
-rw-r--r-- | examples/qtest/extend-c-api/good.pdf | 64 | ||||
-rw-r--r-- | examples/qtest/invert-images.test | 4 | ||||
-rw-r--r-- | examples/qtest/overlay-page.test | 8 | ||||
-rw-r--r-- | examples/qtest/qpdf-job/out.pdf | bin | 1300 -> 1278 bytes | |||
-rw-r--r-- | examples/qtest/qpdfjob-remove-annotations.test | 4 | ||||
-rw-r--r-- | examples/qtest/set-form-values.test | 4 |
18 files changed, 251 insertions, 19 deletions
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 9af85fe2..6c1ca0f3 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -34,12 +34,18 @@ foreach(PROG ${EXAMPLE_C_PROGRAMS}) endforeach() target_include_directories(pdf-create PRIVATE ${JPEG_INCLUDE}) +# extend-c-api contains a mixture of C and C++ files. +add_executable(extend-c-api extend-c-api-impl.cc extend-c-api.c) +set_property(TARGET extend-c-api PROPERTY LINKER_LANGUAGE CXX) +target_link_libraries(extend-c-api libqpdf) + add_test( NAME examples COMMAND ${RUN_QTEST} --top ${qpdf_SOURCE_DIR} --bin $<TARGET_FILE_DIR:pdf-create> --bin $<TARGET_FILE_DIR:qpdf> + --bin $<TARGET_FILE_DIR:qpdf-test-compare> --bin $<TARGET_FILE_DIR:libqpdf> # for Windows to find DLL --code ${qpdf_SOURCE_DIR}/examples --color ${QTEST_COLOR} @@ -47,7 +53,7 @@ add_test( --tc "${qpdf_SOURCE_DIR}/examples/*.cc" --tc "${qpdf_SOURCE_DIR}/examples/*.c") -file(GLOB EXAMPLES_SRC "*.c" "*.cc") +file(GLOB EXAMPLES_SRC "*.c" "*.cc" "*.h") if(INSTALL_EXAMPLES) install(FILES ${EXAMPLES_SRC} DESTINATION ${CMAKE_INSTALL_DOCDIR}/examples diff --git a/examples/extend-c-api-impl.cc b/examples/extend-c-api-impl.cc new file mode 100644 index 00000000..680d957b --- /dev/null +++ b/examples/extend-c-api-impl.cc @@ -0,0 +1,29 @@ +// This is an example of how to write C++ functions and make them usable with the qpdf C API. It +// consists of three files: +// - extend-c-api.h -- a plain C header file +// - extend-c-api.c -- a C program that calls the function +// - extend-c-api.cc -- a C++ file that implements the function + +#include "extend-c-api.h" + +// Here, we add a function to get the number of pages in a PDF file and make it callable through the +// C API. + +// This is a normal C++ function that works with QPDF in a normal way. It doesn't do anything +// special to be callable from C. +int +numPages(std::shared_ptr<QPDF> qpdf) +{ + return qpdf->getRoot().getKey("/Pages").getKey("/Count").getIntValueAsInt(); +} + +// Now we define the glue that makes our function callable using the C API. + +// This is the C++ implementation of the C function. +QPDF_ERROR_CODE +num_pages(qpdf_data qc, int* npages) +{ + // Call qpdf_c_wrap to convert any exception our function might through to a QPDF_ERROR_CODE + // and attach it to the qpdf_data object in the same way as other functions in the C API. + return qpdf_c_wrap(qc, [&qc, &npages]() { *npages = numPages(qpdf_c_get_qpdf(qc)); }); +} diff --git a/examples/extend-c-api.c b/examples/extend-c-api.c new file mode 100644 index 00000000..aa603845 --- /dev/null +++ b/examples/extend-c-api.c @@ -0,0 +1,67 @@ +/* + * This is an example of how to write C++ functions and make them usable with the qpdf C API. It + * consists of three files: + * - extend-c-api.h -- a plain C header file + * - extend-c-api.c -- a C program that calls the function + * - extend-c-api.cc -- a C++ file that implements the function + */ + +#include "extend-c-api.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +static char const* whoami = 0; + +static void +usage() +{ + fprintf(stderr, "Usage: %s infile\n", whoami); + exit(2); +} + +int +main(int argc, char* argv[]) +{ + char* infile = NULL; + qpdf_data qpdf = qpdf_init(); + int warnings = 0; + int errors = 0; + char* p = NULL; + + if ((p = strrchr(argv[0], '/')) != NULL) { + whoami = p + 1; + } else if ((p = strrchr(argv[0], '\\')) != NULL) { + whoami = p + 1; + } else { + whoami = argv[0]; + } + + if (argc != 2) { + usage(); + } + + infile = argv[1]; + + if ((qpdf_read(qpdf, infile, NULL) & QPDF_ERRORS) == 0) { + int npages; + if ((num_pages(qpdf, &npages) & QPDF_ERRORS) == 0) { + printf("num pages = %d\n", npages); + } + } + if (qpdf_more_warnings(qpdf)) { + warnings = 1; + } + if (qpdf_has_error(qpdf)) { + errors = 1; + printf("error: %s\n", qpdf_get_error_full_text(qpdf, qpdf_get_error(qpdf))); + } + qpdf_cleanup(&qpdf); + if (errors) { + return 2; + } else if (warnings) { + return 3; + } + + return 0; +} diff --git a/examples/extend-c-api.h b/examples/extend-c-api.h new file mode 100644 index 00000000..3b2d12d4 --- /dev/null +++ b/examples/extend-c-api.h @@ -0,0 +1,25 @@ +#ifndef EXAMPLE_C_EXTEND_H +#define EXAMPLE_C_EXTEND_H + +/* + * This is an example of how to write C++ functions and make them usable with the qpdf C API. It + * consists of three files: + * - extend-c-api.h -- a plain C header file + * - extend-c-api.c -- a C program that calls the function + * - extend-c-api.cc -- a C++ file that implements the function + */ +#include <qpdf/qpdf-c.h> + +/* Declare your custom function to return QPDF_ERROR_CODE and take qpdf_data and anything else you + * need. Any errors are retrievable through the qpdf C APIs normal error-handling mechanism. + */ + +#ifdef __cplusplus +extern "C" { +#endif + QPDF_ERROR_CODE num_pages(qpdf_data qc, int* npages); +#ifdef __cplusplus +} +#endif + +#endif /* EXAMPLE_C_EXTEND_H */ diff --git a/examples/qpdf-job.cc b/examples/qpdf-job.cc index be868a17..99b853ea 100644 --- a/examples/qpdf-job.cc +++ b/examples/qpdf-job.cc @@ -44,6 +44,7 @@ main(int argc, char* argv[]) ->endPages() ->linearize() ->staticId() // for testing only + ->compressStreams("n") // avoid dependency on zlib output ->checkConfiguration(); j.run(); std::cout << "out1 status: " << j.getExitCode() << std::endl; @@ -63,6 +64,7 @@ main(int argc, char* argv[]) "1", "--", "--static-id", + "--compress-streams=n", // avoid dependency on zlib output nullptr}; QPDFJob j; j.initializeFromArgv(new_argv); @@ -81,6 +83,7 @@ main(int argc, char* argv[]) "outputFile": "out3.pdf", "staticId": "", "linearize": "", + "compressStreams": "n", "pages": [ { "file": ".", diff --git a/examples/qpdfjob-c.c b/examples/qpdfjob-c.c index 62528392..6dd68283 100644 --- a/examples/qpdfjob-c.c +++ b/examples/qpdfjob-c.c @@ -19,7 +19,7 @@ main(int argc, char* argv[]) { char* infile = NULL; char* outfile = NULL; - char const* new_argv[6]; + char const* new_argv[7]; int r = 0; char* p = 0; @@ -43,7 +43,8 @@ main(int argc, char* argv[]) new_argv[2] = outfile; new_argv[3] = "--linearize"; new_argv[4] = "--static-id"; /* for testing only */ - new_argv[5] = NULL; + new_argv[5] = "--compress-streams=n"; /* avoid dependency on zlib output */ + new_argv[6] = NULL; /* See qpdf-job.cc for a C++ example of using the json interface. To use that from C just like * the argv one, call qpdfjob_run_from_json instead and pass the json string as a single char diff --git a/examples/qtest/c-objects.test b/examples/qtest/c-objects.test index 9cd496f6..f10f60c7 100644 --- a/examples/qtest/c-objects.test +++ b/examples/qtest/c-objects.test @@ -17,8 +17,8 @@ foreach my $i (qw(1 2)) {$td->COMMAND => "pdf-c-objects $i.pdf '' a.pdf"}, {$td->STRING => "", $td->EXIT_STATUS => 0}); $td->runtest("check output", - {$td->FILE => "a.pdf"}, - {$td->FILE => "$i-out.pdf"}); + {$td->COMMAND => "qpdf-test-compare a.pdf $i-out.pdf"}, + {$td->FILE => "$i-out.pdf", $td->EXIT_STATUS => 0}); } cleanup(); diff --git a/examples/qtest/custom-filter.test b/examples/qtest/custom-filter.test index e674ea66..2d8acec6 100644 --- a/examples/qtest/custom-filter.test +++ b/examples/qtest/custom-filter.test @@ -24,8 +24,8 @@ $td->runtest("custom filter, decode generalized", $td->EXIT_STATUS => 0}, $td->NORMALIZE_NEWLINES); $td->runtest("check output", - {$td->FILE => "a.pdf"}, - {$td->FILE => "generalized.pdf"}); + {$td->COMMAND => "qpdf-test-compare a.pdf generalized.pdf"}, + {$td->FILE => "generalized.pdf", $td->EXIT_STATUS => 0}); $td->runtest("custom filter, decode specialized", {$td->COMMAND => @@ -34,8 +34,8 @@ $td->runtest("custom filter, decode specialized", $td->EXIT_STATUS => 0}, $td->NORMALIZE_NEWLINES); $td->runtest("check output", - {$td->FILE => "a.pdf"}, - {$td->FILE => "specialized.pdf"}); + {$td->COMMAND => "qpdf-test-compare a.pdf specialized.pdf"}, + {$td->FILE => "specialized.pdf", $td->EXIT_STATUS => 0}); cleanup(); diff --git a/examples/qtest/extend-c-api.test b/examples/qtest/extend-c-api.test new file mode 100644 index 00000000..3dd82193 --- /dev/null +++ b/examples/qtest/extend-c-api.test @@ -0,0 +1,30 @@ +#!/usr/bin/env perl +require 5.008; +use warnings; +use strict; + +chdir("extend-c-api") or die "chdir testdir failed: $!\n"; + +require TestDriver; + +cleanup(); + +my $td = new TestDriver('extend-c-api'); + +$td->runtest("extend C API (good)", + {$td->COMMAND => "extend-c-api good.pdf"}, + {$td->FILE => "good.out", $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); +$td->runtest("extend C API (bad)", + {$td->COMMAND => "extend-c-api bad.pdf"}, + {$td->FILE => "bad.out", $td->EXIT_STATUS => 2}, + $td->NORMALIZE_NEWLINES); + +cleanup(); + +$td->report(2); + +sub cleanup +{ + unlink "a.pdf"; +} diff --git a/examples/qtest/extend-c-api/bad.out b/examples/qtest/extend-c-api/bad.out new file mode 100644 index 00000000..51f1d56b --- /dev/null +++ b/examples/qtest/extend-c-api/bad.out @@ -0,0 +1,5 @@ +WARNING: bad.pdf: can't find PDF header +WARNING: bad.pdf: file is damaged +WARNING: bad.pdf: can't find startxref +WARNING: bad.pdf: Attempting to reconstruct cross-reference table +error: bad.pdf: unable to find trailer dictionary while recovering damaged file diff --git a/examples/qtest/extend-c-api/bad.pdf b/examples/qtest/extend-c-api/bad.pdf new file mode 100644 index 00000000..a3d2d925 --- /dev/null +++ b/examples/qtest/extend-c-api/bad.pdf @@ -0,0 +1 @@ +not even a pdf file diff --git a/examples/qtest/extend-c-api/good.out b/examples/qtest/extend-c-api/good.out new file mode 100644 index 00000000..98205fae --- /dev/null +++ b/examples/qtest/extend-c-api/good.out @@ -0,0 +1 @@ +num pages = 1 diff --git a/examples/qtest/extend-c-api/good.pdf b/examples/qtest/extend-c-api/good.pdf new file mode 100644 index 00000000..42867b96 --- /dev/null +++ b/examples/qtest/extend-c-api/good.pdf @@ -0,0 +1,64 @@ +%PDF-2.0 +1 0 obj +<< + /Pages 2 0 R + /Type /Catalog +>> +endobj +2 0 obj +<< + /Count 1 + /Kids [ + 3 0 R + ] + /Type /Pages +>> +endobj +3 0 obj +<< + /Contents 4 0 R + /MediaBox [ 0 0 612 792 ] + /Parent 2 0 R + /Resources << + /Font << /F1 5 0 R >> + >> + /Type /Page +>> +endobj +4 0 obj +<< + /Length 44 +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Potato) Tj +ET +endstream +endobj +5 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Subtype /Type1 + /Type /Font +>> +endobj + +xref +0 6 +0000000000 65535 f +0000000009 00000 n +0000000062 00000 n +0000000133 00000 n +0000000277 00000 n +0000000372 00000 n +trailer << + /Root 1 0 R + /Size 6 + /ID [<42841c13bbf709d79a200fa1691836f8><b1d8b5838eeafe16125317aa78e666aa>] +>> +startxref +478 +%%EOF diff --git a/examples/qtest/invert-images.test b/examples/qtest/invert-images.test index d1e3c939..7986d0fd 100644 --- a/examples/qtest/invert-images.test +++ b/examples/qtest/invert-images.test @@ -20,8 +20,8 @@ $td->runtest("invert images", $td->NORMALIZE_NEWLINES); $td->runtest("check output", - {$td->FILE => "a.pdf"}, - {$td->FILE => "out.pdf"}); + {$td->COMMAND => "qpdf-test-compare a.pdf out.pdf"}, + {$td->FILE => "out.pdf", $td->EXIT_STATUS => 0}); cleanup(); diff --git a/examples/qtest/overlay-page.test b/examples/qtest/overlay-page.test index be9bcb10..6440a367 100644 --- a/examples/qtest/overlay-page.test +++ b/examples/qtest/overlay-page.test @@ -15,15 +15,15 @@ $td->runtest("overlay-page", {$td->COMMAND => "pdf-overlay-page in.pdf stamp.pdf a.pdf"}, {$td->STRING => "", $td->EXIT_STATUS => 0}); $td->runtest("compare files", - {$td->FILE => "a.pdf"}, - {$td->FILE => "out.pdf"}); + {$td->COMMAND => "qpdf-test-compare a.pdf out.pdf"}, + {$td->FILE => "out.pdf", $td->EXIT_STATUS => 0}); $td->runtest("overlay-page with fields/ annotations", {$td->COMMAND => "pdf-overlay-page in.pdf annotations.pdf a.pdf"}, {$td->STRING => "", $td->EXIT_STATUS => 0}); $td->runtest("compare files", - {$td->FILE => "a.pdf"}, - {$td->FILE => "annotations-out.pdf"}); + {$td->COMMAND => "qpdf-test-compare a.pdf annotations-out.pdf"}, + {$td->FILE => "annotations-out.pdf", $td->EXIT_STATUS => 0}); cleanup(); diff --git a/examples/qtest/qpdf-job/out.pdf b/examples/qtest/qpdf-job/out.pdf Binary files differindex c432ac59..d8ac1509 100644 --- a/examples/qtest/qpdf-job/out.pdf +++ b/examples/qtest/qpdf-job/out.pdf diff --git a/examples/qtest/qpdfjob-remove-annotations.test b/examples/qtest/qpdfjob-remove-annotations.test index 32abf3ef..06f8f07a 100644 --- a/examples/qtest/qpdfjob-remove-annotations.test +++ b/examples/qtest/qpdfjob-remove-annotations.test @@ -15,8 +15,8 @@ $td->runtest("remove-annotations", {$td->COMMAND => "qpdfjob-remove-annotations --static-id annotations.pdf out.pdf"}, {$td->STRING => "", $td->EXIT_STATUS => 0}); $td->runtest("compare files", - {$td->FILE => "out.pdf"}, - {$td->FILE => "annotations-out.pdf"}); + {$td->COMMAND => "qpdf-test-compare out.pdf annotations-out.pdf"}, + {$td->FILE => "annotations-out.pdf", $td->EXIT_STATUS => 0}); cleanup(); diff --git a/examples/qtest/set-form-values.test b/examples/qtest/set-form-values.test index 8c103379..8d2fd2c8 100644 --- a/examples/qtest/set-form-values.test +++ b/examples/qtest/set-form-values.test @@ -15,8 +15,8 @@ $td->runtest("set form values", {$td->COMMAND => "pdf-set-form-values form-in.pdf a.pdf soup"}, {$td->STRING => "", $td->EXIT_STATUS => 0}); $td->runtest("compare files", - {$td->FILE => "a.pdf"}, - {$td->FILE => "form-out.pdf"}); + {$td->COMMAND => "qpdf-test-compare a.pdf form-out.pdf"}, + {$td->FILE => "form-out.pdf", $td->EXIT_STATUS => 0}); cleanup(); |