Commit 84ec83e92589461e6da68029ed7148ba48198215

Authored by Jay Berkenbilt
1 parent 02333ba1

basic implementation of C API

git-svn-id: svn+q:///qpdf/trunk@725 71b93d88-0707-0410-a8cf-f5a4172ac649
@@ -23,9 +23,6 @@ @@ -23,9 +23,6 @@
23 * See if it is possible to support rewriting a file in place or at 23 * See if it is possible to support rewriting a file in place or at
24 least to detect and block this 24 least to detect and block this
25 25
26 - * Spell check to fix typos in messages and comments. Known typo in  
27 - "damanged".  
28 -  
29 26
30 General 27 General
31 ======= 28 =======
include/qpdf/QPDF.hh
@@ -41,7 +41,7 @@ class QPDF @@ -41,7 +41,7 @@ class QPDF
41 // Prior to calling this, the only methods that are allowed are 41 // Prior to calling this, the only methods that are allowed are
42 // those that set parameters. 42 // those that set parameters.
43 DLL_EXPORT 43 DLL_EXPORT
44 - void processFile(char const* filename, char const* password = ""); 44 + void processFile(char const* filename, char const* password = 0);
45 45
46 // Parameter settings 46 // Parameter settings
47 47
include/qpdf/qpdf-c.h
@@ -6,9 +6,59 @@ @@ -6,9 +6,59 @@
6 * a subset of the QPDF library's capabilities to make them accessible 6 * a subset of the QPDF library's capabilities to make them accessible
7 * to callers who can't handle calling C++ functions or working with 7 * to callers who can't handle calling C++ functions or working with
8 * C++ classes. This may be especially useful to Windows users who 8 * C++ classes. This may be especially useful to Windows users who
9 - * are accessing the qpdflib DLL directly or to other people  
10 - * programming in non-C/C++ languages that can call C code but not C++  
11 - * code. 9 + * are accessing the qpdf DLL directly or to other people programming
  10 + * in non-C/C++ languages that can call C code but not C++ code.
  11 + *
  12 + * There are several things to keep in mind when using the C API.
  13 + *
  14 + * The C API is not as rich as the C++ API. For any operations
  15 + * that involve actually manipulating PDF objects, you must use
  16 + * the C++ API. The C API is primarily useful for doing basic
  17 + * transformations on PDF files similar to what you might do with
  18 + * the qpdf command-line tool.
  19 + *
  20 + * These functions store their state in a qpdf_data object.
  21 + * Individual instances of qpdf_data are not thread-safe: although
  22 + * you may access different qpdf_data objects from different
  23 + * threads, you may not access one qpdf_data simultaneously from
  24 + * multiple threads.
  25 + *
  26 + * All dynamic memory, except for that of the qpdf_data object
  27 + * itself, is managed by the library. You must create a qpdf_data
  28 + * object using qpdf_init and free it using qpdf_cleanup.
  29 + *
  30 + * Many functions return char*. In all cases, the char* values
  31 + * returned are pointers to data inside the qpdf_data object. As
  32 + * such, they are always freed by qpdf_cleanup. In most cases,
  33 + * strings returned by functions here may be invalidated by
  34 + * subsequent function calls, sometimes even to different
  35 + * functions. If you want a string to last past the next qpdf
  36 + * call or after a call to qpdf_cleanup, you should make a copy of
  37 + * it.
  38 + *
  39 + * Many functions defined here merely set parameters and therefore
  40 + * never return error conditions. Functions that may cause PDF
  41 + * files to be read or written may return error conditions. Such
  42 + * functions return an error code. If there were no errors or
  43 + * warnings, they return QPDF_SUCCESS. If there were warnings,
  44 + * the return value has the QPDF_WARNINGS bit set. If there
  45 + * errors, the QPDF_ERRORS bit is set. In other words, if there
  46 + * are both warnings and errors, then the return status will be
  47 + * QPDF_WARNINGS | QPDF_ERRORS. You may also call the
  48 + * qpdf_more_warnings and qpdf_more_errors functions to test
  49 + * whether there are unseen warning or error conditions. By
  50 + * default, warnings are written to stderr when detected, but this
  51 + * behavior can be suppressed. In all cases, errors and warnings
  52 + * may be retrieved by calling qpdf_next_warning and
  53 + * qpdf_next_error. All exceptions thrown by the C++ interface
  54 + * are caught and converted into error messages by the C
  55 + * interface.
  56 + *
  57 + * Most functions defined here have obvious counterparts that are
  58 + * methods to either QPDF or QPDFWriter. Please see comments in
  59 + * QPDF.hh and QPDFWriter.hh for details on their use. In order
  60 + * to avoid duplication of information, comments here focus
  61 + * primarily on differences between the C and C++ API.
12 */ 62 */
13 63
14 #include <qpdf/DLL.hh> 64 #include <qpdf/DLL.hh>
@@ -20,34 +70,26 @@ extern &quot;C&quot; { @@ -20,34 +70,26 @@ extern &quot;C&quot; {
20 typedef struct _qpdf_data* qpdf_data; 70 typedef struct _qpdf_data* qpdf_data;
21 71
22 /* Many functions return an integer error code. Codes are defined 72 /* Many functions return an integer error code. Codes are defined
23 - * below. See ERROR REPORTING below. 73 + * below. See comments at the top of the file for details. Note
  74 + * that the values below can be logically orred together.
24 */ 75 */
25 typedef int QPDF_ERROR_CODE; 76 typedef int QPDF_ERROR_CODE;
26 # define QPDF_SUCCESS 0 77 # define QPDF_SUCCESS 0
27 -# define QPDF_WARNINGS 1  
28 -# define QPDF_ERRORS 2 78 +# define QPDF_WARNINGS 1 << 0
  79 +# define QPDF_ERRORS 1 << 1
29 80
30 typedef int QPDF_BOOL; 81 typedef int QPDF_BOOL;
31 # define QPDF_TRUE 1 82 # define QPDF_TRUE 1
32 # define QPDF_FALSE 0 83 # define QPDF_FALSE 0
33 84
34 /* Returns dynamically allocated qpdf_data pointer; must be freed 85 /* Returns dynamically allocated qpdf_data pointer; must be freed
35 - * by calling qpdf_cleanup. Note that qpdf_data is not  
36 - * thread-safe: although you may access different qpdf_data  
37 - * objects from different threads, you may not access one  
38 - * qpdf_data simultaneously from multiple threads. Many functions  
39 - * defined below return char*. In all cases, the char* values  
40 - * returned are pointers to data inside the qpdf_data object. As  
41 - * such, they are always freed by qpdf_cleanup. In some cases,  
42 - * strings returned by functions here may be overwritten by  
43 - * additional function calls, so if you really want a string to  
44 - * last past the next qpdf call, you should make a copy of it. 86 + * by calling qpdf_cleanup.
45 */ 87 */
46 DLL_EXPORT 88 DLL_EXPORT
47 qpdf_data qpdf_init(); 89 qpdf_data qpdf_init();
48 90
49 /* Pass a pointer to the qpdf_data pointer created by qpdf_init to 91 /* Pass a pointer to the qpdf_data pointer created by qpdf_init to
50 - * clean up resoures. 92 + * clean up resources.
51 */ 93 */
52 DLL_EXPORT 94 DLL_EXPORT
53 void qpdf_cleanup(qpdf_data* qpdf); 95 void qpdf_cleanup(qpdf_data* qpdf);
@@ -59,40 +101,45 @@ extern &quot;C&quot; { @@ -59,40 +101,45 @@ extern &quot;C&quot; {
59 */ 101 */
60 DLL_EXPORT 102 DLL_EXPORT
61 QPDF_BOOL qpdf_more_errors(qpdf_data qpdf); 103 QPDF_BOOL qpdf_more_errors(qpdf_data qpdf);
62 -  
63 - /* If there are any errors, returns a pointer to the next error.  
64 - * Otherwise returns a null pointer. The error value returned is  
65 - * a pointer to data inside the qpdf_data object. It will become  
66 - * valid the next time a qpdf function that returns a string is  
67 - * called or after a call to qpdf_cleanup.  
68 - */  
69 DLL_EXPORT 104 DLL_EXPORT
70 - char const* qpdf_next_error(qpdf_data qpdf); 105 + QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf);
71 106
72 - /* These functions are analogous to the "error" counterparts but  
73 - * apply to warnings. 107 + /* If there are any errors/warnings, returns a pointer to the next
  108 + * error or warning. Otherwise returns a null pointer.
74 */ 109 */
75 -  
76 DLL_EXPORT 110 DLL_EXPORT
77 - QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf); 111 + char const* qpdf_next_error(qpdf_data qpdf);
78 DLL_EXPORT 112 DLL_EXPORT
79 char const* qpdf_next_warning(qpdf_data qpdf); 113 char const* qpdf_next_warning(qpdf_data qpdf);
80 114
81 - /* READ PARAMETER FUNCTIONS */  
82 -  
83 /* By default, warnings are written to stderr. Passing true to 115 /* By default, warnings are written to stderr. Passing true to
84 - this function will prevent warnings from being written to stderr.  
85 - They will still be available by calls to qpdf_next_warning.  
86 - */ 116 + * this function will prevent warnings from being written to
  117 + * stderr. They will still be available by calls to
  118 + * qpdf_next_warning.
  119 + */
87 DLL_EXPORT 120 DLL_EXPORT
88 - void qpdf_set_suppress_warnings(qpdf_data qpdf, QPDF_BOOL val); 121 + void qpdf_set_suppress_warnings(qpdf_data qpdf, QPDF_BOOL value);
89 122
90 /* READ FUNCTIONS */ 123 /* READ FUNCTIONS */
91 124
92 - /* POST-READ QUERY FUNCTIONS */ 125 + /* READ PARAMETER FUNCTIONS -- must be called before qpdf_read */
93 126
94 - /* These functions are invalid until after qpdf_read has been  
95 - * called. */ 127 + DLL_EXPORT
  128 + void qpdf_set_ignore_xref_streams(qpdf_data qpdf, QPDF_BOOL value);
  129 +
  130 + DLL_EXPORT
  131 + void qpdf_set_attempt_recovery(qpdf_data qpdf, QPDF_BOOL value);
  132 +
  133 + /* Calling qpdf_read causes processFile to be called in the C++
  134 + * API. Basic parsing is performed, but data from the file is
  135 + * only read as needed. For files without passwords, pass a null
  136 + * pointer as the password.
  137 + */
  138 + DLL_EXPORT
  139 + QPDF_ERROR_CODE qpdf_read(qpdf_data qpdf, char const* filename,
  140 + char const* password);
  141 +
  142 + /* Read functions below must be called after qpdf_read. */
96 143
97 /* Return the version of the PDF file. */ 144 /* Return the version of the PDF file. */
98 DLL_EXPORT 145 DLL_EXPORT
@@ -126,13 +173,73 @@ extern &quot;C&quot; { @@ -126,13 +173,73 @@ extern &quot;C&quot; {
126 * until the call to qpdf_write. 173 * until the call to qpdf_write.
127 */ 174 */
128 DLL_EXPORT 175 DLL_EXPORT
129 - QPDF_ERROR_CODE qpdf_init_write(qpdf_data data, char const* filename); 176 + QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename);
  177 +
  178 +# define QPDF_OBJECT_STREAM_DISABLE 0
  179 +# define QPDF_OBJECT_STREAM_PRESERVE 1
  180 +# define QPDF_OBJECT_STREAM_GENERATE 2
  181 +
  182 + /* For mode, pass one of the QPDF_OBJECT_STREAM constants. */
  183 + DLL_EXPORT
  184 + void qpdf_set_object_stream_mode(qpdf_data qpdf, int mode);
130 185
131 - /* XXX Get public interface from QPDFWriter */ 186 +# define QPDF_STREAM_DATA_UNCOMPRESS 0
  187 +# define QPDF_STREAM_DATA_PRESERVE 1
  188 +# define QPDF_STREAM_DATA_COMPRESS 2
  189 + /* For mode, pass one of the QPDF_STREAM_DATA constants. */
  190 + DLL_EXPORT
  191 + void qpdf_set_stream_data_mode(qpdf_data qpdf, int mode);
  192 +
  193 + DLL_EXPORT
  194 + void qpdf_set_content_normalization(qpdf_data qpdf, QPDF_BOOL value);
  195 +
  196 + DLL_EXPORT
  197 + void qpdf_set_qdf_mode(qpdf_data qpdf, QPDF_BOOL value);
  198 +
  199 + /* Never use qpdf_set_static_ID except in test suites to suppress
  200 + * generation of a random /ID.
  201 + */
  202 + DLL_EXPORT
  203 + void qpdf_set_static_ID(qpdf_data qpdf, QPDF_BOOL value);
  204 +
  205 + DLL_EXPORT
  206 + void qpdf_set_suppress_original_object_IDs(
  207 + qpdf_data qpdf, QPDF_BOOL value);
  208 +
  209 + DLL_EXPORT
  210 + void qpdf_set_preserve_encryption(qpdf_data qpdf, QPDF_BOOL value);
  211 +
  212 + DLL_EXPORT
  213 + void qpdf_set_r2_encryption_parameters(
  214 + qpdf_data qpdf, char const* user_password, char const* owner_password,
  215 + QPDF_BOOL allow_print, QPDF_BOOL allow_modify,
  216 + QPDF_BOOL allow_extract, QPDF_BOOL allow_annotate);
  217 +
  218 +# define QPDF_R3_PRINT_FULL 0
  219 +# define QPDF_R3_PRINT_LOW 1
  220 +# define QPDF_R3_PRINT_NONE 2
  221 +
  222 +# define QPDF_R3_MODIFY_ALL 0
  223 +# define QPDF_R3_MODIFY_ANNOTATE 1
  224 +# define QPDF_R3_MODIFY_FORM 2
  225 +# define QPDF_R3_MODIFY_ASSEMBLY 3
  226 +# define QPDF_R3_MODIFY_NONE 4
  227 +
  228 + /* Value of print should be one of the QPDF_R3_PRINT constants.
  229 + * Value of modify should be one of the QPDF_R3_MODIFY constants.
  230 + */
  231 + DLL_EXPORT
  232 + void qpdf_set_r3_encryption_parameters(
  233 + qpdf_data qpdf, char const* user_password, char const* owner_password,
  234 + QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
  235 + int print, int modify);
  236 +
  237 + DLL_EXPORT
  238 + void qpdf_set_linearization(qpdf_data qpdf, QPDF_BOOL value);
132 239
133 - /* Perform the actual write operation. */ 240 + /* Do actual write operation. */
134 DLL_EXPORT 241 DLL_EXPORT
135 - QPDF_ERROR_CODE qpdf_write(); 242 + QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf);
136 243
137 #ifdef __cplusplus 244 #ifdef __cplusplus
138 } 245 }
libqpdf/QPDF.cc
@@ -271,7 +271,10 @@ void @@ -271,7 +271,10 @@ void
271 QPDF::processFile(char const* filename, char const* password) 271 QPDF::processFile(char const* filename, char const* password)
272 { 272 {
273 this->file.setFilename(filename); 273 this->file.setFilename(filename);
274 - this->provided_password = password; 274 + if (password)
  275 + {
  276 + this->provided_password = password;
  277 + }
275 parse(); 278 parse();
276 } 279 }
277 280
libqpdf/qpdf-c.cc
1 #include <qpdf/qpdf-c.h> 1 #include <qpdf/qpdf-c.h>
2 2
3 -class _qpdf_data 3 +#include <qpdf/QPDF.hh>
  4 +#include <qpdf/QPDFWriter.hh>
  5 +#include <qpdf/QTC.hh>
  6 +
  7 +#include <list>
  8 +#include <string>
  9 +#include <stdexcept>
  10 +
  11 +struct _qpdf_data
4 { 12 {
  13 + _qpdf_data();
  14 + ~_qpdf_data();
  15 +
  16 + QPDF* qpdf;
  17 + QPDFWriter* qpdf_writer;
  18 +
  19 + std::string error;
  20 + std::list<std::string> warnings;
  21 + std::string tmp_string;
5 }; 22 };
6 23
  24 +_qpdf_data::_qpdf_data() :
  25 + qpdf(0),
  26 + qpdf_writer(0)
  27 +{
  28 +}
  29 +
  30 +_qpdf_data::~_qpdf_data()
  31 +{
  32 + delete qpdf_writer;
  33 + delete qpdf;
  34 +}
  35 +
7 DLL_EXPORT 36 DLL_EXPORT
8 qpdf_data qpdf_init() 37 qpdf_data qpdf_init()
9 { 38 {
10 - return new _qpdf_data(); 39 + QTC::TC("qpdf", "qpdf-c called qpdf_init");
  40 + qpdf_data qpdf = new _qpdf_data();
  41 + qpdf->qpdf = new QPDF();
  42 + return qpdf;
11 } 43 }
12 44
13 DLL_EXPORT 45 DLL_EXPORT
14 void qpdf_cleanup(qpdf_data* qpdf) 46 void qpdf_cleanup(qpdf_data* qpdf)
15 { 47 {
  48 + QTC::TC("qpdf", "qpdf-c called qpdf_cleanup");
16 delete *qpdf; 49 delete *qpdf;
17 *qpdf = 0; 50 *qpdf = 0;
18 } 51 }
  52 +
  53 +DLL_EXPORT
  54 +QPDF_BOOL qpdf_more_errors(qpdf_data qpdf)
  55 +{
  56 + QTC::TC("qpdf", "qpdf-c called qpdf_more_errors");
  57 + return (qpdf->error.empty() ? QPDF_FALSE : QPDF_TRUE);
  58 +}
  59 +
  60 +DLL_EXPORT
  61 +QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf)
  62 +{
  63 + QTC::TC("qpdf", "qpdf-c called qpdf_more_warnings");
  64 +
  65 + if (qpdf->warnings.empty())
  66 + {
  67 + std::vector<std::string> w = qpdf->qpdf->getWarnings();
  68 + if (! w.empty())
  69 + {
  70 + qpdf->warnings.assign(w.begin(), w.end());
  71 + }
  72 + }
  73 + if (qpdf->warnings.empty())
  74 + {
  75 + return QPDF_FALSE;
  76 + }
  77 + else
  78 + {
  79 + return QPDF_TRUE;
  80 + }
  81 +}
  82 +
  83 +DLL_EXPORT
  84 +char const* qpdf_next_error(qpdf_data qpdf)
  85 +{
  86 + QTC::TC("qpdf", "qpdf-c called qpdf_next_error");
  87 + if (qpdf_more_errors(qpdf))
  88 + {
  89 + qpdf->tmp_string = qpdf->error;
  90 + qpdf->error.clear();
  91 + return qpdf->tmp_string.c_str();
  92 + }
  93 + else
  94 + {
  95 + return 0;
  96 + }
  97 +}
  98 +
  99 +DLL_EXPORT
  100 +char const* qpdf_next_warning(qpdf_data qpdf)
  101 +{
  102 + QTC::TC("qpdf", "qpdf-c called qpdf_next_warning");
  103 + if (qpdf_more_warnings(qpdf))
  104 + {
  105 + qpdf->tmp_string = qpdf->warnings.front();
  106 + qpdf->warnings.pop_front();
  107 + return qpdf->tmp_string.c_str();
  108 + }
  109 + else
  110 + {
  111 + return 0;
  112 + }
  113 +}
  114 +
  115 +DLL_EXPORT
  116 +void qpdf_set_suppress_warnings(qpdf_data qpdf, QPDF_BOOL value)
  117 +{
  118 + QTC::TC("qpdf", "qpdf-c called qpdf_set_suppress_warnings");
  119 + qpdf->qpdf->setSuppressWarnings(value);
  120 +}
  121 +
  122 +DLL_EXPORT
  123 +void qpdf_set_ignore_xref_streams(qpdf_data qpdf, QPDF_BOOL value)
  124 +{
  125 + QTC::TC("qpdf", "qpdf-c called qpdf_set_ignore_xref_streams");
  126 + qpdf->qpdf->setIgnoreXRefStreams(value);
  127 +}
  128 +
  129 +DLL_EXPORT
  130 +void qpdf_set_attempt_recovery(qpdf_data qpdf, QPDF_BOOL value)
  131 +{
  132 + QTC::TC("qpdf", "qpdf-c called qpdf_set_attempt_recovery");
  133 + qpdf->qpdf->setAttemptRecovery(value);
  134 +}
  135 +
  136 +DLL_EXPORT
  137 +QPDF_ERROR_CODE qpdf_read(qpdf_data qpdf, char const* filename,
  138 + char const* password)
  139 +{
  140 + QPDF_ERROR_CODE status = QPDF_SUCCESS;
  141 + try
  142 + {
  143 + qpdf->qpdf->processFile(filename, password);
  144 + }
  145 + catch (std::exception& e)
  146 + {
  147 + qpdf->error = e.what();
  148 + status |= QPDF_ERRORS;
  149 + }
  150 + if (qpdf_more_warnings(qpdf))
  151 + {
  152 + status |= QPDF_WARNINGS;
  153 + }
  154 + QTC::TC("qpdf", "qpdf-c called qpdf_read", status);
  155 + return status;
  156 +}
  157 +
  158 +DLL_EXPORT
  159 +char const* qpdf_get_pdf_version(qpdf_data qpdf)
  160 +{
  161 + QTC::TC("qpdf", "qpdf-c called qpdf_get_pdf_version");
  162 + qpdf->tmp_string = qpdf->qpdf->getPDFVersion();
  163 + return qpdf->tmp_string.c_str();
  164 +}
  165 +
  166 +DLL_EXPORT
  167 +char const* qpdf_get_user_password(qpdf_data qpdf)
  168 +{
  169 + QTC::TC("qpdf", "qpdf-c called qpdf_get_user_password");
  170 + qpdf->tmp_string = qpdf->qpdf->getTrimmedUserPassword();
  171 + return qpdf->tmp_string.c_str();
  172 +}
  173 +
  174 +DLL_EXPORT
  175 +QPDF_BOOL qpdf_is_linearized(qpdf_data qpdf)
  176 +{
  177 + QTC::TC("qpdf", "qpdf-c called qpdf_is_linearized");
  178 + return (qpdf->qpdf->isLinearized() ? QPDF_TRUE : QPDF_FALSE);
  179 +}
  180 +
  181 +DLL_EXPORT
  182 +QPDF_BOOL qpdf_is_encrypted(qpdf_data qpdf)
  183 +{
  184 + QTC::TC("qpdf", "qpdf-c called qpdf_is_encrypted");
  185 + return (qpdf->qpdf->isEncrypted() ? QPDF_TRUE : QPDF_FALSE);
  186 +}
  187 +
  188 +DLL_EXPORT
  189 +QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename)
  190 +{
  191 + QPDF_ERROR_CODE status = QPDF_SUCCESS;
  192 + try
  193 + {
  194 + qpdf->qpdf_writer = new QPDFWriter(*(qpdf->qpdf), filename);
  195 + }
  196 + catch (std::exception& e)
  197 + {
  198 + qpdf->error = e.what();
  199 + status |= QPDF_ERRORS;
  200 + }
  201 + if (qpdf_more_warnings(qpdf))
  202 + {
  203 + status |= QPDF_WARNINGS;
  204 + }
  205 + QTC::TC("qpdf", "qpdf-c called qpdf_init_write", status);
  206 + return status;
  207 +}
  208 +
  209 +DLL_EXPORT
  210 +void qpdf_set_object_stream_mode(qpdf_data qpdf, int mode)
  211 +{
  212 + QTC::TC("qpdf", "qpdf-c called qpdf_set_object_stream_mode");
  213 + QPDFWriter::object_stream_e omode = QPDFWriter::o_preserve;
  214 + switch (mode)
  215 + {
  216 + case QPDF_OBJECT_STREAM_DISABLE:
  217 + omode = QPDFWriter::o_disable;
  218 + break;
  219 +
  220 + case QPDF_OBJECT_STREAM_GENERATE:
  221 + omode = QPDFWriter::o_generate;
  222 + break;
  223 +
  224 + default:
  225 + // already set to o_preserve; treate out of range values as
  226 + // the default.
  227 + break;
  228 + }
  229 +
  230 + qpdf->qpdf_writer->setObjectStreamMode(omode);
  231 +}
  232 +
  233 +DLL_EXPORT
  234 +void qpdf_set_stream_data_mode(qpdf_data qpdf, int mode)
  235 +{
  236 + QTC::TC("qpdf", "qpdf-c called qpdf_set_stream_data_mode");
  237 + QPDFWriter::stream_data_e smode = QPDFWriter::s_preserve;
  238 + switch (mode)
  239 + {
  240 + case QPDF_STREAM_DATA_UNCOMPRESS:
  241 + smode = QPDFWriter::s_uncompress;
  242 + break;
  243 +
  244 + case QPDF_STREAM_DATA_COMPRESS:
  245 + smode = QPDFWriter::s_compress;
  246 + break;
  247 +
  248 + default:
  249 + // Treat anything else as default
  250 + break;
  251 + }
  252 + qpdf->qpdf_writer->setStreamDataMode(smode);
  253 +}
  254 +
  255 +DLL_EXPORT
  256 +void qpdf_set_content_normalization(qpdf_data qpdf, QPDF_BOOL value)
  257 +{
  258 + QTC::TC("qpdf", "qpdf-c called qpdf_set_content_normalization");
  259 + qpdf->qpdf_writer->setContentNormalization(value);
  260 +}
  261 +
  262 +DLL_EXPORT
  263 +void qpdf_set_qdf_mode(qpdf_data qpdf, QPDF_BOOL value)
  264 +{
  265 + QTC::TC("qpdf", "qpdf-c called qpdf_set_qdf_mode");
  266 + qpdf->qpdf_writer->setQDFMode(value);
  267 +}
  268 +
  269 +DLL_EXPORT
  270 +void qpdf_set_static_ID(qpdf_data qpdf, QPDF_BOOL value)
  271 +{
  272 + QTC::TC("qpdf", "qpdf-c called qpdf_set_static_ID");
  273 + qpdf->qpdf_writer->setStaticID(value);
  274 +}
  275 +
  276 +DLL_EXPORT
  277 +void qpdf_set_suppress_original_object_IDs(
  278 + qpdf_data qpdf, QPDF_BOOL value)
  279 +{
  280 + QTC::TC("qpdf", "qpdf-c called qpdf_set_suppress_original_object_IDs");
  281 + qpdf->qpdf_writer->setSuppressOriginalObjectIDs(value);
  282 +}
  283 +
  284 +DLL_EXPORT
  285 +void qpdf_set_preserve_encryption(qpdf_data qpdf, QPDF_BOOL value)
  286 +{
  287 + QTC::TC("qpdf", "qpdf-c called qpdf_set_preserve_encryption");
  288 + qpdf->qpdf_writer->setPreserveEncryption(value);
  289 +}
  290 +
  291 +DLL_EXPORT
  292 +void qpdf_set_r2_encryption_parameters(
  293 + qpdf_data qpdf, char const* user_password, char const* owner_password,
  294 + QPDF_BOOL allow_print, QPDF_BOOL allow_modify,
  295 + QPDF_BOOL allow_extract, QPDF_BOOL allow_annotate)
  296 +{
  297 + QTC::TC("qpdf", "qpdf-c called qpdf_set_r2_encryption_parameters");
  298 + qpdf->qpdf_writer->setR2EncryptionParameters(
  299 + user_password, owner_password,
  300 + allow_print, allow_modify, allow_extract, allow_annotate);
  301 +}
  302 +
  303 +DLL_EXPORT
  304 +void qpdf_set_r3_encryption_parameters(
  305 + qpdf_data qpdf, char const* user_password, char const* owner_password,
  306 + QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
  307 + int print, int modify)
  308 +{
  309 + QTC::TC("qpdf", "qpdf-c called qpdf_set_r3_encryption_parameters");
  310 + qpdf->qpdf_writer->setR3EncryptionParameters(
  311 + user_password, owner_password,
  312 + allow_accessibility, allow_extract,
  313 + ((print == QPDF_R3_PRINT_LOW) ? QPDFWriter::r3p_low :
  314 + (print == QPDF_R3_PRINT_NONE) ? QPDFWriter::r3p_none :
  315 + QPDFWriter::r3p_full),
  316 + ((print == QPDF_R3_MODIFY_ANNOTATE) ? QPDFWriter::r3m_annotate :
  317 + (print == QPDF_R3_MODIFY_FORM) ? QPDFWriter::r3m_form :
  318 + (print == QPDF_R3_MODIFY_ASSEMBLY) ? QPDFWriter::r3m_assembly :
  319 + (print == QPDF_R3_MODIFY_NONE) ? QPDFWriter::r3m_none :
  320 + QPDFWriter::r3m_all));
  321 +}
  322 +
  323 +DLL_EXPORT
  324 +void qpdf_set_linearization(qpdf_data qpdf, QPDF_BOOL value)
  325 +{
  326 + QTC::TC("qpdf", "qpdf-c called qpdf_set_linearization");
  327 + qpdf->qpdf_writer->setLinearization(value);
  328 +}
  329 +
  330 +DLL_EXPORT
  331 +QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf)
  332 +{
  333 + QPDF_ERROR_CODE status = QPDF_SUCCESS;
  334 + try
  335 + {
  336 + qpdf->qpdf_writer->write();
  337 + }
  338 + catch (std::exception& e)
  339 + {
  340 + qpdf->error = e.what();
  341 + status |= QPDF_ERRORS;
  342 + }
  343 + if (qpdf_more_warnings(qpdf))
  344 + {
  345 + status |= QPDF_WARNINGS;
  346 + }
  347 + QTC::TC("qpdf", "qpdf-c called qpdf_write", status);
  348 + return status;
  349 +}
qpdf/qpdf.testcov
@@ -118,3 +118,29 @@ QPDF_String non-trivial UTF-16 0 @@ -118,3 +118,29 @@ QPDF_String non-trivial UTF-16 0
118 QPDF xref overwrite object 0 118 QPDF xref overwrite object 0
119 QPDF decoding error warning 0 119 QPDF decoding error warning 0
120 QPDF_Stream ignore non-dictionary DecodeParms 0 120 QPDF_Stream ignore non-dictionary DecodeParms 0
  121 +qpdf-c called qpdf_init 0
  122 +qpdf-c called qpdf_cleanup 0
  123 +qpdf-c called qpdf_more_errors 0
  124 +qpdf-c called qpdf_more_warnings 0
  125 +qpdf-c called qpdf_next_error 0
  126 +qpdf-c called qpdf_next_warning 0
  127 +qpdf-c called qpdf_set_suppress_warnings 0
  128 +qpdf-c called qpdf_set_ignore_xref_streams 0
  129 +qpdf-c called qpdf_set_attempt_recovery 0
  130 +qpdf-c called qpdf_read 3
  131 +qpdf-c called qpdf_get_pdf_version 0
  132 +qpdf-c called qpdf_get_user_password 0
  133 +qpdf-c called qpdf_is_linearized 0
  134 +qpdf-c called qpdf_is_encrypted 0
  135 +qpdf-c called qpdf_init_write 3
  136 +qpdf-c called qpdf_set_object_stream_mode 0
  137 +qpdf-c called qpdf_set_stream_data_mode 0
  138 +qpdf-c called qpdf_set_content_normalization 0
  139 +qpdf-c called qpdf_set_qdf_mode 0
  140 +qpdf-c called qpdf_set_static_ID 0
  141 +qpdf-c called qpdf_set_suppress_original_object_IDs 0
  142 +qpdf-c called qpdf_set_preserve_encryption 0
  143 +qpdf-c called qpdf_set_r2_encryption_parameters 0
  144 +qpdf-c called qpdf_set_r3_encryption_parameters 0
  145 +qpdf-c called qpdf_set_linearization 0
  146 +qpdf-c called qpdf_write 3