Commit 1b937716dc7311487bfb1f9dabcd61e2b33a2884

Authored by Peter M. Groen
1 parent 6aba1882

Added Doxygen Tags

include/qpdf/Buffer.hh
... ... @@ -33,15 +33,17 @@ class Buffer
33 33 QPDF_DLL
34 34 Buffer();
35 35  
36   - // Create a Buffer object whose memory is owned by the class and will be freed when the Buffer
37   - // object is destroyed.
  36 + /*! \brief Create a Buffer object whose memory is owned by the class and will be freed when the Buffer
  37 + * object is destroyed.
  38 + */
38 39 QPDF_DLL
39 40 Buffer(size_t size);
40 41 QPDF_DLL
41 42 Buffer(std::string&& content);
42 43  
43   - // Create a Buffer object whose memory is owned by the caller and will not be freed when the
44   - // Buffer is destroyed.
  44 + /*! \brief Create a Buffer object whose memory is owned by the caller and will not be freed when the
  45 + * Buffer is destroyed.
  46 + */
45 47 QPDF_DLL
46 48 Buffer(unsigned char* buf, size_t size);
47 49 QPDF_DLL
... ... @@ -63,21 +65,23 @@ class Buffer
63 65 QPDF_DLL
64 66 unsigned char* getBuffer();
65 67  
66   - // Create a new copy of the Buffer. The new Buffer owns an independent copy of the data.
  68 + /*! \brief Create a new copy of the Buffer. The new Buffer owns an independent copy of the data. */
67 69 QPDF_DLL
68 70 Buffer copy() const;
69 71  
70   - // Move the content of the Buffer. After calling this method, the Buffer will be empty if the
71   - // buffer owns its memory. Otherwise, the Buffer will be unchanged.
  72 + /*! \brief Move the content of the Buffer. After calling this method, the Buffer will be empty if the
  73 + * buffer owns its memory. Otherwise, the Buffer will be unchanged.
  74 + */
72 75 QPDF_DLL
73 76 std::string move();
74 77  
75   - // Return a string_view to the data.
  78 + /*! \brief Return a string_view to the data. */
76 79 QPDF_DLL
77 80 std::string_view view() const;
78 81  
79   - // Return a pointer to the data. NB: Unlike getBuffer, this method returns a valid pointer even
80   - // if the Buffer is empty.
  82 + /*! \return a pointer to the data. NB: Unlike getBuffer, this method returns a valid pointer even
  83 + * if the Buffer is empty.
  84 + */
81 85 QPDF_DLL
82 86 char const* data() const;
83 87  
... ...
include/qpdf/BufferInputSource.hh
... ... @@ -28,8 +28,9 @@
28 28 class QPDF_DLL_CLASS BufferInputSource: public InputSource
29 29 {
30 30 public:
31   - // If own_memory is true, BufferInputSource will delete the buffer when finished with it.
32   - // Otherwise, the caller owns the memory.
  31 + /*! \brief If own_memory is true, BufferInputSource will delete the buffer when finished with it.
  32 + * Otherwise, the caller owns the memory.
  33 + */
33 34 QPDF_DLL
34 35 BufferInputSource(std::string const& description, Buffer* buf, bool own_memory = false);
35 36  
... ...
include/qpdf/ClosedFileInputSource.hh
... ... @@ -26,10 +26,11 @@
26 26  
27 27 class FileInputSource;
28 28  
29   -// This is an input source that reads from files, like FileInputSource, except that it opens and
30   -// closes the file surrounding every operation. This decreases efficiency, but it allows many more
31   -// of these to exist at once than the maximum number of open file descriptors. This is used for
32   -// merging large numbers of files.
  29 +/*! \brief This is an input source that reads from files, like FileInputSource, except that it opens and
  30 + * closes the file surrounding every operation. This decreases efficiency, but it allows many more
  31 + * of these to exist at once than the maximum number of open file descriptors. This is used for
  32 + * merging large numbers of files.
  33 + */
33 34 class QPDF_DLL_CLASS ClosedFileInputSource: public InputSource
34 35 {
35 36 public:
... ... @@ -56,9 +57,10 @@ class QPDF_DLL_CLASS ClosedFileInputSource: public InputSource
56 57 QPDF_DLL
57 58 void unreadCh(char ch) override;
58 59  
59   - // The file stays open between calls to stayOpen(true) and stayOpen(false). You can use this to
60   - // surround multiple operations on a single ClosedFileInputSource to reduce the overhead of a
61   - // separate open/close on each call.
  60 + /*! \brief The file stays open between calls to stayOpen(true) and stayOpen(false). You can use this to
  61 + * surround multiple operations on a single ClosedFileInputSource to reduce the overhead of a
  62 + * separate open/close on each call.
  63 + */
62 64 QPDF_DLL
63 65 void stayOpen(bool);
64 66  
... ...
include/qpdf/Constants.h
... ... @@ -31,42 +31,41 @@
31 31 * interfaces.
32 32 */
33 33  
34   -/* ****************************** NOTE ******************************
35   -
36   -Tl;Dr: new values must be added to the end such that no constant's
37   -numerical value changes, even across major releases.
38   -
39   -Details:
40   -
41   -As new values are added to existing enumerated types in this file,
42   -it is important not to change the actual values of any constants.
43   -This means that, in the absence of explicit assignment of values,
44   -the order of entries can't change even across major releases. Why?
45   -Here are the reasons:
46   -
47   -* Many of these constants are used by the C API. The C API is used
48   - through foreign function call interfaces by users of other languages
49   - who may not have access to or the ability to parse a C header file.
50   - As such, users are likely to hard-code numerical values or create
51   - their own constants whose values match. If we change values here,
52   - their code would break, and there would be no way to detect it short
53   - of noticing a bug. Furthermore, it would be difficult to write code
54   - that properly handled more than one version of the qpdf shared
55   - object (e.g. DLL) since the information about what version of qpdf
56   - is involved is only available at runtime.
57   -
58   -- It has happened from time to time that a user builds an application
59   - with an incorrectly installed qpdf, such as having mismatched header
60   - files and library files. In the event that they are only using qpdf
61   - interfaces that have been stable across the versions in question,
62   - this turns out to be harmless. If they happen to use non-compatible
63   - interfaces, this results usually in a failure to load or an obvious
64   - runtime error. If we change values of constants, it is possible that
65   - code that links and runs may have mismatched values for constants.
66   - This would create a bug that would be extremely difficult to track
67   - down and impossible for qpdf maintainers to reproduce.
68   -
69   -*/
  34 +/*! \note ****************************** NOTE ******************************
  35 + *
  36 + * Tl;Dr: new values must be added to the end such that no constant's
  37 + * numerical value changes, even across major releases.
  38 + *
  39 + * Details:
  40 + *
  41 + * As new values are added to existing enumerated types in this file,
  42 + * it is important not to change the actual values of any constants.
  43 + * This means that, in the absence of explicit assignment of values,
  44 + * the order of entries can't change even across major releases. Why?
  45 + * Here are the reasons:
  46 + *
  47 + * * Many of these constants are used by the C API. The C API is used
  48 + * through foreign function call interfaces by users of other languages
  49 + * who may not have access to or the ability to parse a C header file.
  50 + * As such, users are likely to hard-code numerical values or create
  51 + * their own constants whose values match. If we change values here,
  52 + * their code would break, and there would be no way to detect it short
  53 + * of noticing a bug. Furthermore, it would be difficult to write code
  54 + * that properly handled more than one version of the qpdf shared
  55 + * object (e.g. DLL) since the information about what version of qpdf
  56 + * is involved is only available at runtime.
  57 + *
  58 + * - It has happened from time to time that a user builds an application
  59 + * with an incorrectly installed qpdf, such as having mismatched header
  60 + * files and library files. In the event that they are only using qpdf
  61 + * interfaces that have been stable across the versions in question,
  62 + * this turns out to be harmless. If they happen to use non-compatible
  63 + * interfaces, this results usually in a failure to load or an obvious
  64 + * runtime error. If we change values of constants, it is possible that
  65 + * code that links and runs may have mismatched values for constants.
  66 + * This would create a bug that would be extremely difficult to track
  67 + * down and impossible for qpdf maintainers to reproduce.
  68 + */
70 69  
71 70 /* Exit Codes from QPDFJob and the qpdf CLI */
72 71  
... ... @@ -97,7 +96,7 @@ enum qpdf_error_code_e {
97 96  
98 97 /* Object Types */
99 98  
100   -/* PDF objects represented by QPDFObjectHandle or, in the C API, by
  99 +/*! \brief PDF objects represented by QPDFObjectHandle or, in the C API, by
101 100 * qpdf_oh, have a unique type code that has one of the values in the
102 101 * list below. As new object types are added to qpdf, additional items
103 102 * may be added to the list, so code that switches on these values
... ... @@ -171,7 +170,7 @@ enum qpdf_r3_print_e {
171 170 qpdf_r3p_none /* allow no printing */
172 171 };
173 172  
174   -/* qpdf_r3_modify_e doesn't allow the full flexibility of the spec. It
  173 +/*! \brief qpdf_r3_modify_e doesn't allow the full flexibility of the spec. It
175 174 * corresponds to options in Acrobat 5's menus. The new interface in
176 175 * QPDFWriter offers more granularity and no longer uses this type.
177 176 */
... ...
include/qpdf/DLL.h
... ... @@ -35,8 +35,7 @@
35 35 # define QPDF_VERSION "12.3.3"
36 36 #endif
37 37  
38   -/*
39   - * This file defines symbols that control the which functions,
  38 +/*! \brief This file defines symbols that control the which functions,
40 39 * classes, and methods are exposed to the public ABI (application
41 40 * binary interface). See below for a detailed explanation.
42 41 */
... ... @@ -61,7 +60,7 @@
61 60 # define QPDF_DLL_CLASS
62 61 #endif
63 62  
64   -/*
  63 +/*! \brief
65 64  
66 65 Here's what's happening. See also https://gcc.gnu.org/wiki/Visibility
67 66 for a more in-depth discussion.
... ...
include/qpdf/QPDFJob.hh
... ... @@ -59,78 +59,83 @@ class QPDFJob
59 59  
60 60 // SETUP FUNCTIONS
61 61  
62   - // Initialize a QPDFJob object from argv, which must be a null-terminated array of
63   - // null-terminated UTF-8-encoded C strings. The progname_env argument is the name of an
64   - // environment variable which, if set, overrides the name of the executable for purposes of
65   - // generating the --completion options. See QPDFArgParser for details. If a null pointer is
66   - // passed in, the default value of "QPDF_EXECUTABLE" is used. This is used by the QPDF cli,
67   - // which just initializes a QPDFJob from argv, calls run(), and handles errors and exit status
68   - // issues. You can perform much of the cli functionality programmatically in this way rather
69   - // than using the regular API. This is exposed in the C API, which makes it easier to get
70   - // certain high-level qpdf functionality from other languages. If there are any command-line
71   - // errors, this method will throw QPDFUsage which is derived from std::runtime_error. Other
72   - // exceptions may be thrown in some cases. Note that argc, and argv should be UTF-8 encoded. If
73   - // you are calling this from a Windows Unicode-aware main (wmain), see
74   - // QUtil::call_main_from_wmain for information about converting arguments to UTF-8. This method
75   - // will mutate arguments that are passed to it.
  62 + /*! \brief Initialize a QPDFJob object from argv, which must be a null-terminated array of
  63 + * null-terminated UTF-8-encoded C strings. The progname_env argument is the name of an
  64 + * environment variable which, if set, overrides the name of the executable for purposes of
  65 + * generating the --completion options. See QPDFArgParser for details. If a null pointer is
  66 + * passed in, the default value of "QPDF_EXECUTABLE" is used. This is used by the QPDF cli,
  67 + * which just initializes a QPDFJob from argv, calls run(), and handles errors and exit status
  68 + * issues. You can perform much of the cli functionality programmatically in this way rather
  69 + * than using the regular API. This is exposed in the C API, which makes it easier to get
  70 + * certain high-level qpdf functionality from other languages. If there are any command-line
  71 + * errors, this method will throw QPDFUsage which is derived from std::runtime_error. Other
  72 + * exceptions may be thrown in some cases. Note that argc, and argv should be UTF-8 encoded. If
  73 + * you are calling this from a Windows Unicode-aware main (wmain), see
  74 + * QUtil::call_main_from_wmain for information about converting arguments to UTF-8. This method
  75 + * will mutate arguments that are passed to it.
  76 + */
76 77 QPDF_DLL
77 78 void initializeFromArgv(char const* const argv[], char const* progname_env = nullptr);
78 79  
79   - // Initialize a QPDFJob from json. Passing partial = true prevents this method from doing the
80   - // final checks (calling checkConfiguration) after processing the json file. This makes it
81   - // possible to initialize QPDFJob in stages using multiple json files or to have a json file
82   - // that can be processed from the CLI with --job-json-file and be combined with other arguments.
83   - // For example, you might include only encryption parameters, leaving it up to the rest of the
84   - // command-line arguments to provide input and output files. initializeFromJson is called with
85   - // partial = true when invoked from the command line. To make sure that the json file is fully
86   - // valid on its own, just don't specify any other command-line flags. If there are any
87   - // configuration errors, QPDFUsage is thrown. Some error messages may be CLI-centric. If an
88   - // exception tells you to use the "--some-option" option, set the "someOption" key in the JSON
89   - // object instead.
  80 + /*! \brief Initialize a QPDFJob from json. Passing partial = true prevents this method from doing the
  81 + * final checks (calling checkConfiguration) after processing the json file. This makes it
  82 + * possible to initialize QPDFJob in stages using multiple json files or to have a json file
  83 + * that can be processed from the CLI with --job-json-file and be combined with other arguments.
  84 + * For example, you might include only encryption parameters, leaving it up to the rest of the
  85 + * command-line arguments to provide input and output files. initializeFromJson is called with
  86 + * partial = true when invoked from the command line. To make sure that the json file is fully
  87 + * valid on its own, just don't specify any other command-line flags. If there are any
  88 + * configuration errors, QPDFUsage is thrown. Some error messages may be CLI-centric. If an
  89 + * exception tells you to use the "--some-option" option, set the "someOption" key in the JSON
  90 + * object instead.
  91 + */
90 92 QPDF_DLL
91 93 void initializeFromJson(std::string const& json, bool partial = false);
92 94  
93   - // Set name that is used to prefix verbose messages, progress messages, and other things that
94   - // the library writes to output and error streams on the caller's behalf. Defaults to "qpdf".
  95 + /*! \brief Set name that is used to prefix verbose messages, progress messages, and other things that
  96 + * the library writes to output and error streams on the caller's behalf. Defaults to "qpdf".
  97 + */
95 98 QPDF_DLL
96 99 void setMessagePrefix(std::string const&);
97 100 QPDF_DLL
98 101 std::string getMessagePrefix() const;
99 102  
100   - // To capture or redirect output, configure the logger returned by getLogger(). By default, all
101   - // QPDF and QPDFJob objects share the global logger. If you need a private logger for some
102   - // reason, pass a new one to setLogger(). See comments in QPDFLogger.hh for details on
103   - // configuring the logger.
104   - //
105   - // If you set a custom logger here, the logger will be passed to all subsequent QPDF objects
106   - // created by this QPDFJob object.
107   - QPDF_DLL
108   - std::shared_ptr<QPDFLogger> getLogger();
109   - QPDF_DLL
110   - void setLogger(std::shared_ptr<QPDFLogger>);
111   -
112   - // This deprecated method is the old way to capture output, but it didn't capture all output.
113   - // See comments above for getLogger and setLogger. This will be removed in QPDF 12. For now, it
114   - // configures a private logger, separating this object from the default logger, and calls
115   - // setOutputStreams on that logger. See QPDFLogger.hh for additional details.
116   - [[deprecated("configure logger from getLogger() or call setLogger()")]] QPDF_DLL void
117   - setOutputStreams(std::ostream* out_stream, std::ostream* err_stream);
118   -
119   - // You can register a custom progress reporter to be called by QPDFWriter (see
120   - // QPDFWriter::registerProgressReporter). This is only called if you also request progress
121   - // reporting through normal configuration methods (e.g., pass --progress, call
122   - // config()->progress, etc.)
  103 + /*! \brief To capture or redirect output, configure the logger returned by getLogger(). By default, all
  104 + * QPDF and QPDFJob objects share the global logger. If you need a private logger for some
  105 + * reason, pass a new one to setLogger(). See comments in QPDFLogger.hh for details on
  106 + * configuring the logger.
  107 + *
  108 + * If you set a custom logger here, the logger will be passed to all subsequent QPDF objects
  109 + * created by this QPDFJob object.
  110 + */
  111 + QPDF_DLL std::shared_ptr<QPDFLogger> getLogger();
  112 + QPDF_DLL void setLogger(std::shared_ptr<QPDFLogger>);
  113 +
  114 + /*! \brief This deprecated method is the old way to capture output, but it didn't capture all output.
  115 + * See comments above for getLogger and setLogger. This will be removed in QPDF 12. For now, it
  116 + * configures a private logger, separating this object from the default logger, and calls
  117 + * setOutputStreams on that logger. See QPDFLogger.hh for additional details.
  118 + */
  119 + [[deprecated("configure logger from getLogger() or call setLogger()")]]
  120 + QPDF_DLL void setOutputStreams(std::ostream* out_stream, std::ostream* err_stream);
  121 +
  122 + /*! \brief You can register a custom progress reporter to be called by QPDFWriter (see
  123 + * QPDFWriter::registerProgressReporter). This is only called if you also request progress
  124 + * reporting through normal configuration methods (e.g., pass --progress, call
  125 + * config()->progress, etc.)
  126 + */
123 127 QPDF_DLL
124 128 void registerProgressReporter(std::function<void(int)>);
125 129  
126   - // Check to make sure no contradictory options have been specified. This is called automatically
127   - // after initializing from argv or json and is also called by run, but you can call it manually
128   - // as well. It throws a QPDFUsage exception if there are any errors. This Config object (see
129   - // CONFIGURATION) also has a checkConfiguration method which calls this one.
  130 + /*! \brief Check to make sure no contradictory options have been specified. This is called automatically
  131 + * after initializing from argv or json and is also called by run, but you can call it manually
  132 + * as well. It throws a QPDFUsage exception if there are any errors. This Config object (see
  133 + * CONFIGURATION) also has a checkConfiguration method which calls this one.
  134 + */
130 135 QPDF_DLL
131 136 void checkConfiguration();
132 137  
133   - // Returns true if output is created by the specified job.
  138 + /*! \brief Returns true if output is created by the specified job. */
134 139 QPDF_DLL
135 140 bool createsOutput() const;
136 141  
... ... @@ -161,27 +166,28 @@ class QPDFJob
161 166  
162 167 // Configuration classes are implemented in QPDFJob_config.cc.
163 168  
164   - // The config() method returns a shared pointer to a Config object. The Config object contains
165   - // methods that correspond with qpdf command-line arguments. You can use a fluent interface to
166   - // configure a QPDFJob object that would do exactly the same thing as a specific qpdf command.
167   - // The example qpdf-job.cc contains an example of this usage. You can also use
168   - // initializeFromJson or initializeFromArgv to initialize a QPDFJob object.
169   -
170   - // Notes about the Config methods:
171   - //
172   - // * Most of the method declarations are automatically generated in header files that are
173   - // included within the class definitions. They correspond in predictable ways to the
174   - // command-line arguments and are generated from the same code that generates the command-line
175   - // argument parsing code.
176   - //
177   - // * Methods return pointers, rather than references, to configuration objects. References
178   - // might feel more familiar to users of fluent interfaces, so why do we use pointers? The
179   - // main methods that create them return smart pointers so that users can initialize them when
180   - // needed, which you can't do with references. Returning pointers instead of references makes
181   - // for a more uniform interface.
182   -
183   - // Maintainer documentation: see the section in README-developer called "HOW TO ADD A
184   - // COMMAND-LINE ARGUMENT", which contains references to additional places in the documentation.
  169 + /*! \brief The config() method returns a shared pointer to a Config object. The Config object contains
  170 + * methods that correspond with qpdf command-line arguments. You can use a fluent interface to
  171 + * configure a QPDFJob object that would do exactly the same thing as a specific qpdf command.
  172 + * The example qpdf-job.cc contains an example of this usage. You can also use
  173 + * initializeFromJson or initializeFromArgv to initialize a QPDFJob object.
  174 + *
  175 + * \note About the Config methods:
  176 + *
  177 + * * Most of the method declarations are automatically generated in header files that are
  178 + * included within the class definitions. They correspond in predictable ways to the
  179 + * command-line arguments and are generated from the same code that generates the command-line
  180 + * argument parsing code.
  181 + *
  182 + * * Methods return pointers, rather than references, to configuration objects. References
  183 + * might feel more familiar to users of fluent interfaces, so why do we use pointers? The
  184 + * main methods that create them return smart pointers so that users can initialize them when
  185 + * needed, which you can't do with references. Returning pointers instead of references makes
  186 + * for a more uniform interface.
  187 + *
  188 + * Maintainer documentation: see the section in README-developer called "HOW TO ADD A
  189 + * COMMAND-LINE ARGUMENT", which contains references to additional places in the documentation.
  190 + */
185 191  
186 192 class Config;
187 193  
... ... @@ -235,8 +241,10 @@ class QPDFJob
235 241 public:
236 242 QPDF_DLL
237 243 Config* endPages();
238   - // From qpdf 11.9.0, you can call file(), range(), and password(). Each call to file()
239   - // starts a new page spec.
  244 +
  245 + /*! \brief From qpdf 11.9.0, you can call file(), range(), and password(). Each call to file()
  246 + * starts a new page spec.
  247 + */
240 248 QPDF_DLL
241 249 PagesConfig* pageSpec(
242 250 std::string const& filename, std::string const& range, char const* password = nullptr);
... ... @@ -372,11 +380,12 @@ class QPDFJob
372 380 QPDFJob& o;
373 381 };
374 382  
375   - // Return a top-level configuration item. See CONFIGURATION above for details. If an invalid
376   - // configuration is created (such as supplying contradictory options, omitting an input file,
377   - // etc.), QPDFUsage is thrown. Note that error messages are CLI-centric, but you can map them
378   - // into config calls. For example, if an exception tells you to use the --some-option flag, you
379   - // should call config()->someOption() instead.
  383 + /*! \return a top-level configuration item. See CONFIGURATION above for details. If an invalid
  384 + * configuration is created (such as supplying contradictory options, omitting an input file,
  385 + * etc.), QPDFUsage is thrown. Note that error messages are CLI-centric, but you can map them
  386 + * into config calls. For example, if an exception tells you to use the --some-option flag, you
  387 + * should call config()->someOption() instead.
  388 + */
380 389 QPDF_DLL
381 390 std::shared_ptr<Config> config();
382 391  
... ... @@ -384,15 +393,16 @@ class QPDFJob
384 393 QPDF_DLL
385 394 void run();
386 395  
387   - // The following two methods allow a job to be run in two stages - creation of a QPDF object and
388   - // writing of the QPDF object. This allows the QPDF object to be modified prior to writing it
389   - // out. See examples/qpdfjob-remove-annotations for an illustration of its use.
  396 + /*! \brief The following two methods allow a job to be run in two stages - creation of a QPDF object and
  397 + * writing of the QPDF object. This allows the QPDF object to be modified prior to writing it
  398 + * out. See examples/qpdfjob-remove-annotations for an illustration of its use.
  399 + */
390 400  
391   - // Run the first stage of the job. Return a nullptr if the configuration is not valid.
  401 + /*! \brief Run the first stage of the job. Return a nullptr if the configuration is not valid. */
392 402 QPDF_DLL
393 403 std::unique_ptr<QPDF> createQPDF();
394 404  
395   - // Run the second stage of the job. Do nothing if a nullptr is passed as parameter.
  405 + /*! \brief Run the second stage of the job. Do nothing if a nullptr is passed as parameter. */
396 406 QPDF_DLL
397 407 void writeQPDF(QPDF& qpdf);
398 408  
... ... @@ -401,34 +411,37 @@ class QPDFJob
401 411 QPDF_DLL
402 412 bool hasWarnings() const;
403 413  
404   - // Return one of the EXIT_* constants defined at the top of the class declaration. This may be
405   - // called after run() when run() did not throw an exception. Takes into consideration whether
406   - // isEncrypted or requiresPassword was called. Note that this function does not know whether
407   - // run() threw an exception, so code that uses this to determine how to exit should explicitly
408   - // use EXIT_ERROR if run() threw an exception.
  414 + /*! \brief Return one of the EXIT_* constants defined at the top of the class declaration. This may be
  415 + * called after run() when run() did not throw an exception. Takes into consideration whether
  416 + * isEncrypted or requiresPassword was called. Note that this function does not know whether
  417 + * run() threw an exception, so code that uses this to determine how to exit should explicitly
  418 + * use EXIT_ERROR if run() threw an exception.
  419 + */
409 420 QPDF_DLL
410 421 int getExitCode() const;
411 422  
412   - // Return value is bitwise OR of values from qpdf_encryption_status_e
  423 + /*! \return value is bitwise OR of values from qpdf_encryption_status_e */
413 424 QPDF_DLL
414 425 unsigned long getEncryptionStatus();
415 426  
416 427 // HELPER FUNCTIONS -- methods useful for calling in handlers that interact with QPDFJob during
417 428 // run or initialization.
418 429  
419   - // If in verbose mode, call the given function, passing in the output stream and message prefix.
  430 + /*! \brief If in verbose mode, call the given function, passing in the output stream and message prefix. */
420 431 QPDF_DLL
421 432 void doIfVerbose(std::function<void(Pipeline&, std::string const& prefix)> fn);
422 433  
423   - // Provide a string that is the help information ("schema" for the qpdf-specific JSON object)
424   - // for the specified version of JSON output.
  434 + /*! \brief Provide a string that is the help information ("schema" for the qpdf-specific JSON object)
  435 + * for the specified version of JSON output.
  436 + */
425 437 QPDF_DLL
426 438 static std::string json_out_schema(int version);
427 439  
428 440 [[deprecated("use json_out_schema(version)")]] static std::string QPDF_DLL json_out_schema_v1();
429 441  
430   - // Provide a string that is the help information for specified version of JSON format for
431   - // QPDFJob.
  442 + /*! \brief Provide a string that is the help information for specified version of JSON format for
  443 + * QPDFJob.
  444 + */
432 445 QPDF_DLL
433 446 static std::string job_json_schema(int version);
434 447  
... ...
include/qpdf/QPDFObjectHandle.hh
... ... @@ -71,9 +71,10 @@ class QPDFObjectHandle: public qpdf::BaseHandle
71 71 friend class qpdf::impl::Parser;
72 72  
73 73 public:
74   - // This class is used by replaceStreamData. It provides an alternative way of associating
75   - // stream data with a stream. See comments on replaceStreamData and newStream for additional
76   - // details.
  74 + /*! \brief This class is used by replaceStreamData. It provides an alternative way of associating
  75 + * stream data with a stream. See comments on replaceStreamData and newStream for additional
  76 + * details.
  77 + */
77 78 class QPDF_DLL_CLASS StreamDataProvider
78 79 {
79 80 public:
... ... @@ -82,40 +83,41 @@ class QPDFObjectHandle: public qpdf::BaseHandle
82 83  
83 84 QPDF_DLL
84 85 virtual ~StreamDataProvider();
85   - // The implementation of this function must write stream data to the given pipeline. The
86   - // stream data must conform to whatever filters are explicitly associated with the stream.
87   - // QPDFWriter may, in some cases, add compression, but if it does, it will update the
88   - // filters as needed. Every call to provideStreamData for a given stream must write the same
89   - // data. Note that, when writing linearized files, qpdf will call your provideStreamData
90   - // twice, and if it generates different output, you risk generating invalid output or having
91   - // qpdf throw an exception. The object ID and generation passed to this method are those
92   - // that belong to the stream on behalf of which the provider is called. They may be ignored
93   - // or used by the implementation for indexing or other purposes. This information is made
94   - // available just to make it more convenient to use a single StreamDataProvider object to
95   - // provide data for multiple streams.
96   -
97   - // A few things to keep in mind:
98   - //
99   - // * Stream data providers must not modify any objects since they may be called after some
100   - // parts of the file have already been written.
101   - //
102   - // * Since qpdf may call provideStreamData multiple times when writing linearized files, if
103   - // the work done by your stream data provider is slow or computationally intensive, you
104   - // might want to implement your own cache.
105   - //
106   - // * Once you have called replaceStreamData, the original stream data is no longer directly
107   - // accessible from the stream, but this is easy to work around by copying the stream to
108   - // a separate QPDF object. The qpdf library implements this very efficiently without
109   - // actually making a copy of the stream data. You can find examples of this pattern in
110   - // some of the examples, including pdf-custom-filter.cc and pdf-invert-images.cc.
111   -
112   - // Prior to qpdf 10.0.0, it was not possible to handle errors the way pipeStreamData does or
113   - // to pass back success. Starting in qpdf 10.0.0, those capabilities have been added by
114   - // allowing an alternative provideStreamData to be implemented. You must implement at least
115   - // one of the versions of provideStreamData below. If you implement the version that
116   - // supports retry and returns a value, you should pass true as the value of supports_retry
117   - // in the base class constructor. This will cause the library to call that version of the
118   - // method, which should also return a boolean indicating whether it ran without errors.
  86 + /*! \brief The implementation of this function must write stream data to the given pipeline. The
  87 + * stream data must conform to whatever filters are explicitly associated with the stream.
  88 + * QPDFWriter may, in some cases, add compression, but if it does, it will update the
  89 + * filters as needed. Every call to provideStreamData for a given stream must write the same
  90 + * data. Note that, when writing linearized files, qpdf will call your provideStreamData
  91 + * twice, and if it generates different output, you risk generating invalid output or having
  92 + * qpdf throw an exception. The object ID and generation passed to this method are those
  93 + * that belong to the stream on behalf of which the provider is called. They may be ignored
  94 + * or used by the implementation for indexing or other purposes. This information is made
  95 + * available just to make it more convenient to use a single StreamDataProvider object to
  96 + * provide data for multiple streams.
  97 + *
  98 + * A few things to keep in mind:
  99 + *
  100 + * * Stream data providers must not modify any objects since they may be called after some
  101 + * parts of the file have already been written.
  102 + *
  103 + * * Since qpdf may call provideStreamData multiple times when writing linearized files, if
  104 + * the work done by your stream data provider is slow or computationally intensive, you
  105 + * might want to implement your own cache.
  106 + *
  107 + * * Once you have called replaceStreamData, the original stream data is no longer directly
  108 + * accessible from the stream, but this is easy to work around by copying the stream to
  109 + * a separate QPDF object. The qpdf library implements this very efficiently without
  110 + * actually making a copy of the stream data. You can find examples of this pattern in
  111 + * some of the examples, including pdf-custom-filter.cc and pdf-invert-images.cc.
  112 + *
  113 + * Prior to qpdf 10.0.0, it was not possible to handle errors the way pipeStreamData does or
  114 + * to pass back success. Starting in qpdf 10.0.0, those capabilities have been added by
  115 + * allowing an alternative provideStreamData to be implemented. You must implement at least
  116 + * one of the versions of provideStreamData below. If you implement the version that
  117 + * supports retry and returns a value, you should pass true as the value of supports_retry
  118 + * in the base class constructor. This will cause the library to call that version of the
  119 + * method, which should also return a boolean indicating whether it ran without errors.
  120 + */
119 121 QPDF_DLL
120 122 virtual void provideStreamData(QPDFObjGen const& og, Pipeline* pipeline);
121 123 QPDF_DLL
... ... @@ -131,31 +133,32 @@ class QPDFObjectHandle: public qpdf::BaseHandle
131 133 bool supports_retry;
132 134 };
133 135  
134   - // The TokenFilter class provides a way to filter content streams in a lexically aware fashion.
135   - // TokenFilters can be attached to streams using the addTokenFilter or addContentTokenFilter
136   - // methods or can be applied on the spot by filterPageContents. You may also use
137   - // Pl_QPDFTokenizer directly if you need full control.
138   - //
139   - // The handleToken method is called for each token, including the eof token, and then handleEOF
140   - // is called at the very end. Handlers may call write (or writeToken) to pass data downstream.
141   - // Please see examples/pdf-filter-tokens.cc and examples/pdf-count-strings.cc for examples of
142   - // using TokenFilters.
143   - //
144   - // Please note that when you call token.getValue() on a token of type tt_string or tt_name, you
145   - // get the canonical, "parsed" representation of the token. For a string, this means that there
146   - // are no delimiters, and for a name, it means that all escaping (# followed by two hex digits)
147   - // has been resolved. qpdf's internal representation of a name includes the leading slash. As
148   - // such, you can't write the value of token.getValue() directly to output that is supposed to be
149   - // valid PDF syntax. If you want to do that, you need to call writeToken() instead, or you can
150   - // retrieve the token as it appeared in the input with token.getRawValue(). To construct a new
151   - // string or name token from a canonical representation, use
152   - // QPDFTokenizer::Token(QPDFTokenizer::tt_string, "parsed-str") or
153   - // QPDFTokenizer::Token(QPDFTokenizer::tt_name,
154   - // "/Canonical-Name"). Tokens created this way won't have a PDF-syntax raw value, but you can
155   - // still write them with writeToken(). Example:
156   - // writeToken(QPDFTokenizer::Token(QPDFTokenizer::tt_name, "/text/plain"))
157   - // would write `/text#2fplain`, and
158   - // writeToken(QPDFTokenizer::Token(QPDFTokenizer::tt_string, "a\\(b")) would write `(a\(b)`.
  136 + /*! \brief The TokenFilter class provides a way to filter content streams in a lexically aware fashion.
  137 + * TokenFilters can be attached to streams using the addTokenFilter or addContentTokenFilter
  138 + * methods or can be applied on the spot by filterPageContents. You may also use
  139 + * Pl_QPDFTokenizer directly if you need full control.
  140 + *
  141 + * The handleToken method is called for each token, including the eof token, and then handleEOF
  142 + * is called at the very end. Handlers may call write (or writeToken) to pass data downstream.
  143 + * Please see examples/pdf-filter-tokens.cc and examples/pdf-count-strings.cc for examples of
  144 + * using TokenFilters.
  145 + *
  146 + * Please note that when you call token.getValue() on a token of type tt_string or tt_name, you
  147 + * get the canonical, "parsed" representation of the token. For a string, this means that there
  148 + * are no delimiters, and for a name, it means that all escaping (# followed by two hex digits)
  149 + * has been resolved. qpdf's internal representation of a name includes the leading slash. As
  150 + * such, you can't write the value of token.getValue() directly to output that is supposed to be
  151 + * valid PDF syntax. If you want to do that, you need to call writeToken() instead, or you can
  152 + * retrieve the token as it appeared in the input with token.getRawValue(). To construct a new
  153 + * string or name token from a canonical representation, use
  154 + * QPDFTokenizer::Token(QPDFTokenizer::tt_string, "parsed-str") or
  155 + * QPDFTokenizer::Token(QPDFTokenizer::tt_name,
  156 + * "/Canonical-Name"). Tokens created this way won't have a PDF-syntax raw value, but you can
  157 + * still write them with writeToken(). Example:
  158 + * writeToken(QPDFTokenizer::Token(QPDFTokenizer::tt_name, "/text/plain"))
  159 + * would write `/text#2fplain`, and
  160 + * writeToken(QPDFTokenizer::Token(QPDFTokenizer::tt_string, "a\\(b")) would write `(a\(b)`.
  161 + */
159 162 class QPDF_DLL_CLASS TokenFilter
160 163 {
161 164 public:
... ... @@ -192,8 +195,9 @@ class QPDFObjectHandle: public qpdf::BaseHandle
192 195 Pipeline* pipeline;
193 196 };
194 197  
195   - // This class is used by parse to decrypt strings when reading an object that contains encrypted
196   - // strings.
  198 + /*! \brief This class is used by parse to decrypt strings when reading an object that contains encrypted
  199 + * strings.
  200 + */
197 201 class StringDecrypter
198 202 {
199 203 public:
... ... @@ -201,12 +205,14 @@ class QPDFObjectHandle: public qpdf::BaseHandle
201 205 virtual void decryptString(std::string& val) = 0;
202 206 };
203 207  
204   - // This class is used by parsePageContents. Callers must instantiate a subclass of this with
205   - // handlers defined to accept QPDFObjectHandles that are parsed from the stream.
  208 + /*! \brief This class is used by parsePageContents. Callers must instantiate a subclass of this with
  209 + * handlers defined to accept QPDFObjectHandles that are parsed from the stream.
  210 + */
206 211 class QPDF_DLL_CLASS ParserCallbacks
207 212 {
208 213 public:
209 214 virtual ~ParserCallbacks() = default;
  215 +
210 216 // One of the handleObject methods must be overridden.
211 217 QPDF_DLL
212 218 virtual void handleObject(QPDFObjectHandle);
... ... @@ -215,14 +221,16 @@ class QPDFObjectHandle: public qpdf::BaseHandle
215 221  
216 222 virtual void handleEOF() = 0;
217 223  
218   - // Override this if you want to know the full size of the contents, possibly after
219   - // concatenation of multiple streams. This is called before the first call to handleObject.
  224 + /*! \brief Override this if you want to know the full size of the contents, possibly after
  225 + * concatenation of multiple streams. This is called before the first call to handleObject.
  226 + */
220 227 QPDF_DLL
221 228 virtual void contentSize(size_t);
222 229  
223 230 protected:
224   - // Implementors may call this method during parsing to terminate parsing early. This method
225   - // throws an exception that is caught by parsePageContents, so its effect is immediate.
  231 + /*! \brief Implementors may call this method during parsing to terminate parsing early. This method
  232 + * throws an exception that is caught by parsePageContents, so its effect is immediate.
  233 + */
226 234 QPDF_DLL
227 235 void terminateParsing();
228 236 };
... ... @@ -238,6 +246,7 @@ class QPDFObjectHandle: public qpdf::BaseHandle
238 246 ury(0.0)
239 247 {
240 248 }
  249 +
241 250 Rectangle(double llx, double lly, double urx, double ury) :
242 251 llx(llx),
243 252 lly(lly),
... ... @@ -252,9 +261,10 @@ class QPDFObjectHandle: public qpdf::BaseHandle
252 261 double ury;
253 262 };
254 263  
255   - // Convenience object for transformation matrices. See also QPDFMatrix. Unfortunately we can't
256   - // replace this with QPDFMatrix because QPDFMatrix's default constructor creates the identity
257   - // transform matrix and this one is all zeroes.
  264 + /*! \brief Convenience object for transformation matrices. See also QPDFMatrix. Unfortunately we can't
  265 + * replace this with QPDFMatrix because QPDFMatrix's default constructor creates the identity
  266 + * transform matrix and this one is all zeroes.
  267 + */
258 268 class Matrix
259 269 {
260 270 public:
... ... @@ -267,6 +277,7 @@ class QPDFObjectHandle: public qpdf::BaseHandle
267 277 f(0.0)
268 278 {
269 279 }
  280 +
270 281 Matrix(double a, double b, double c, double d, double e, double f) :
271 282 a(a),
272 283 b(b),
... ... @@ -291,26 +302,30 @@ class QPDFObjectHandle: public qpdf::BaseHandle
291 302 QPDFObjectHandle(QPDFObjectHandle&&) = default;
292 303 QPDFObjectHandle& operator=(QPDFObjectHandle&&) = default;
293 304  
294   - // This method is provided for backward compatibility only. New code should convert to bool
295   - // instead.
  305 + /*! \brief This method is provided for backward compatibility only. New code should convert to bool
  306 + * instead.
  307 + */
296 308 inline bool isInitialized() const;
297 309  
298   - // This method returns true if the QPDFObjectHandle objects point to exactly the same underlying
299   - // object, meaning that changes to one are reflected in the other, or "if you paint one, the
300   - // other one changes color." This does not perform a structural comparison of the contents of
301   - // the objects.
  310 + /*! \brief This method returns true if the QPDFObjectHandle objects point to exactly the same underlying
  311 + * object, meaning that changes to one are reflected in the other, or "if you paint one, the
  312 + * other one changes color." This does not perform a structural comparison of the contents of
  313 + * the objects.
  314 + */
302 315 QPDF_DLL
303 316 bool isSameObjectAs(QPDFObjectHandle const&) const;
304 317  
305   - // Return type code and type name of underlying object. These are useful for doing rapid type
306   - // tests (like switch statements) or for testing and debugging.
  318 + /*! \brief Return type code and type name of underlying object. These are useful for doing rapid type
  319 + * tests (like switch statements) or for testing and debugging.
  320 + */
307 321 QPDF_DLL
308 322 qpdf_object_type_e getTypeCode() const;
309 323 QPDF_DLL
310 324 char const* getTypeName() const;
311 325  
312   - // Exactly one of these will return true for any initialized object. Operator and InlineImage
313   - // are only allowed in content streams.
  326 + /*! \brief Exactly one of these will return true for any initialized object. Operator and InlineImage
  327 + * are only allowed in content streams.
  328 + */
314 329 QPDF_DLL
315 330 bool isBool() const;
316 331 QPDF_DLL
... ... @@ -336,68 +351,73 @@ class QPDFObjectHandle: public qpdf::BaseHandle
336 351 QPDF_DLL
337 352 bool isReserved() const;
338 353  
339   - // True for objects that are direct nulls. Does not attempt to resolve objects. This is intended
340   - // for internal use, but it can be used as an efficient way to check for nulls that are not
341   - // indirect objects.
  354 + /*! \brief True for objects that are direct nulls. Does not attempt to resolve objects. This is intended
  355 + * for internal use, but it can be used as an efficient way to check for nulls that are not
  356 + * indirect objects.
342 357 QPDF_DLL
343 358 bool isDirectNull() const;
344 359  
345   - // This returns true in addition to the query for the specific type for indirect objects.
  360 + /*! \brief This returns true in addition to the query for the specific type for indirect objects. */
346 361 QPDF_DLL
347 362 bool isIndirect() const;
348 363  
349   - // This returns true for indirect objects from a QPDF that has been destroyed. Trying unparse
350   - // such an object will throw a logic_error.
  364 + /*! \brief This returns true for indirect objects from a QPDF that has been destroyed. Trying unparse
  365 + * such an object will throw a logic_error.
  366 + */
351 367 QPDF_DLL
352 368 bool isDestroyed() const;
353 369  
354   - // True for everything except array, dictionary, stream, word, and inline image.
  370 + /*! \brief True for everything except array, dictionary, stream, word, and inline image. */
355 371 QPDF_DLL
356 372 bool isScalar() const;
357 373  
358   - // True if the object is a name object representing the provided name.
  374 + /*! \brief True if the object is a name object representing the provided name. */
359 375 QPDF_DLL
360 376 bool isNameAndEquals(std::string const& name) const;
361 377  
362   - // True if the object is a dictionary of the specified type and subtype, if any.
  378 + /*! \brief True if the object is a dictionary of the specified type and subtype, if any. */
363 379 QPDF_DLL
364 380 bool isDictionaryOfType(std::string const& type, std::string const& subtype = "") const;
365 381  
366   - // True if the object is a stream of the specified type and subtype, if any.
  382 + /*! \brief True if the object is a stream of the specified type and subtype, if any. */
367 383 QPDF_DLL
368 384 bool isStreamOfType(std::string const& type, std::string const& subtype = "") const;
369 385  
370 386 // Public factory methods
371 387  
372   - // Wrap an object in an array if it is not already an array. This is a helper for cases in which
373   - // something in a PDF may either be a single item or an array of items, which is a common idiom.
  388 + /*! \brief Wrap an object in an array if it is not already an array. This is a helper for cases in which
  389 + * something in a PDF may either be a single item or an array of items, which is a common idiom.
  390 + */
374 391 QPDF_DLL
375 392 QPDFObjectHandle wrapInArray();
376 393  
377   - // Construct an object of any type from a string representation of the object. Throws QPDFExc
378   - // with an empty filename and an offset into the string if there is an error. Any indirect
379   - // object syntax (obj gen R) will cause a logic_error exception to be thrown. If
380   - // object_description is provided, it will appear in the message of any QPDFExc exception thrown
381   - // for invalid syntax. See also the global `operator ""_qpdf` defined below.
  394 + /*! \brief Construct an object of any type from a string representation of the object. Throws QPDFExc
  395 + * with an empty filename and an offset into the string if there is an error. Any indirect
  396 + * object syntax (obj gen R) will cause a logic_error exception to be thrown. If
  397 + * object_description is provided, it will appear in the message of any QPDFExc exception thrown
  398 + * for invalid syntax. See also the global `operator ""_qpdf` defined below.
  399 + */
382 400 QPDF_DLL
383 401 static QPDFObjectHandle
384 402 parse(std::string const& object_str, std::string const& object_description = "");
385 403  
386   - // Construct an object of any type from a string representation of the object. Indirect object
387   - // syntax (obj gen R) is allowed and will create indirect references within the passed-in
388   - // context. If object_description is provided, it will appear in the message of any QPDFExc
389   - // exception thrown for invalid syntax. Note that you can't parse an indirect object reference
390   - // all by itself as parse will stop at the end of the first complete object, which will just be
391   - // the first number and will report that there is trailing data at the end of the string.
  404 + /*! \brief Construct an object of any type from a string representation of the object. Indirect object
  405 + * syntax (obj gen R) is allowed and will create indirect references within the passed-in
  406 + * context. If object_description is provided, it will appear in the message of any QPDFExc
  407 + * exception thrown for invalid syntax. Note that you can't parse an indirect object reference
  408 + * all by itself as parse will stop at the end of the first complete object, which will just be
  409 + * the first number and will report that there is trailing data at the end of the string.
  410 + */
392 411 QPDF_DLL
393 412 static QPDFObjectHandle
394 413 parse(QPDF* context, std::string const& object_str, std::string const& object_description = "");
395 414  
396   - // Construct an object as above by reading from the given InputSource at its current position
397   - // and using the tokenizer you supply. Indirect objects and encrypted strings are permitted.
398   - // This method was intended to be called by QPDF for parsing objects that are read from the
399   - // object's input stream. To be removed in qpdf 13. See
400   - // <https:manual.qpdf.org/release-notes.html#r12-0-0-deprecate>.
  415 + /*! \brief Construct an object as above by reading from the given InputSource at its current position
  416 + * and using the tokenizer you supply. Indirect objects and encrypted strings are permitted.
  417 + * This method was intended to be called by QPDF for parsing objects that are read from the
  418 + * object's input stream. To be removed in qpdf 13. See
  419 + * <https:manual.qpdf.org/release-notes.html#r12-0-0-deprecate>.
  420 + */
401 421 [[deprecated("to be removed in qpdf 13")]] QPDF_DLL static QPDFObjectHandle parse(
402 422 std::shared_ptr<InputSource> input,
403 423 std::string const& object_description,
... ... @@ -406,63 +426,71 @@ class QPDFObjectHandle: public qpdf::BaseHandle
406 426 StringDecrypter* decrypter,
407 427 QPDF* context);
408 428  
409   - // Return the offset where the object was found when parsed. A negative value means that the
410   - // object was created without parsing. If the object is in a stream, the offset is from the
411   - // beginning of the stream. Otherwise, the offset is from the beginning of the file.
  429 + /*! \brief Return the offset where the object was found when parsed. A negative value means that the
  430 + * object was created without parsing. If the object is in a stream, the offset is from the
  431 + * beginning of the stream. Otherwise, the offset is from the beginning of the file.
  432 + */
412 433 QPDF_DLL
413 434 qpdf_offset_t getParsedOffset() const;
414 435  
415   - // Older method: stream_or_array should be the value of /Contents from a page object. It's more
416   - // convenient to just call QPDFPageObjectHelper::parsePageContents on the page object, and error
417   - // messages will also be more useful because the page object information will be known.
  436 + /*! \brief Older method: stream_or_array should be the value of /Contents from a page object. It's more
  437 + * convenient to just call QPDFPageObjectHelper::parsePageContents on the page object, and error
  438 + * messages will also be more useful because the page object information will be known.
  439 + */
418 440 QPDF_DLL
419 441 static void parseContentStream(QPDFObjectHandle stream_or_array, ParserCallbacks* callbacks);
420 442  
421   - // When called on a stream or stream array that is some page's content streams, do the same as
422   - // pipePageContents. This method is a lower level way to do what
423   - // QPDFPageObjectHelper::pipePageContents does, but it allows you to perform this operation on a
424   - // contents object that is disconnected from a page object. The description argument should
425   - // describe the containing page and is used in error messages. The all_description argument is
426   - // initialized to something that could be used to describe the result of the pipeline. It is the
427   - // description amended with the identifiers of the underlying objects. Please note that if there
428   - // is an array of content streams, p->finish() is called after each stream. If you pass a
429   - // pipeline that doesn't allow write() to be called after finish(), you can wrap it in an
430   - // instance of Pl_Concatenate and then call manualFinish() on the Pl_Concatenate pipeline at the
431   - // end.
  443 + /*! \brief When called on a stream or stream array that is some page's content streams, do the same as
  444 + * pipePageContents. This method is a lower level way to do what
  445 + * QPDFPageObjectHelper::pipePageContents does, but it allows you to perform this operation on a
  446 + * contents object that is disconnected from a page object. The description argument should
  447 + * describe the containing page and is used in error messages. The all_description argument is
  448 + * initialized to something that could be used to describe the result of the pipeline. It is the
  449 + * description amended with the identifiers of the underlying objects. Please note that if there
  450 + * is an array of content streams, p->finish() is called after each stream. If you pass a
  451 + * pipeline that doesn't allow write() to be called after finish(), you can wrap it in an
  452 + * instance of Pl_Concatenate and then call manualFinish() on the Pl_Concatenate pipeline at the
  453 + * end.
  454 + */
432 455 QPDF_DLL
433 456 void
434 457 pipeContentStreams(Pipeline* p, std::string const& description, std::string& all_description);
435 458  
436   - // As of qpdf 8, it is possible to add custom token filters to a stream. The tokenized stream
437   - // data is passed through the token filter after all original filters but before content stream
438   - // normalization if requested. This is a low-level interface to add it to a stream. You will
439   - // usually want to call QPDFPageObjectHelper::addContentTokenFilter instead, which can be
440   - // applied to a page object, and which will automatically handle the case of pages whose
441   - // contents are split across multiple streams.
  459 + /*! \brief As of qpdf 8, it is possible to add custom token filters to a stream. The tokenized stream
  460 + * data is passed through the token filter after all original filters but before content stream
  461 + * normalization if requested. This is a low-level interface to add it to a stream. You will
  462 + * usually want to call QPDFPageObjectHelper::addContentTokenFilter instead, which can be
  463 + * applied to a page object, and which will automatically handle the case of pages whose
  464 + * contents are split across multiple streams.
  465 + */
442 466 QPDF_DLL
443 467 void addTokenFilter(std::shared_ptr<TokenFilter> token_filter);
444 468  
445   - // Legacy helpers for parsing content streams. These methods are not going away, but newer code
446   - // should call the correspond methods in QPDFPageObjectHelper instead. The specification and
447   - // behavior of these methods are the same as the identically named methods in that class, but
448   - // newer functionality will be added there.
  469 + /*! \brief Legacy helpers for parsing content streams. These methods are not going away, but newer code
  470 + * should call the correspond methods in QPDFPageObjectHelper instead. The specification and
  471 + * behavior of these methods are the same as the identically named methods in that class, but
  472 + * newer functionality will be added there.
  473 + */
449 474 QPDF_DLL
450 475 void parsePageContents(ParserCallbacks* callbacks);
  476 +
451 477 QPDF_DLL
452 478 void filterPageContents(TokenFilter* filter, Pipeline* next = nullptr);
453   - // See comments for QPDFPageObjectHelper::pipeContents.
454   - QPDF_DLL
455   - void pipePageContents(Pipeline* p);
456   - QPDF_DLL
457   - void addContentTokenFilter(std::shared_ptr<TokenFilter> token_filter);
  479 +
  480 + /*! \brief See comments for QPDFPageObjectHelper::pipeContents. */
  481 + QPDF_DLL void pipePageContents(Pipeline* p);
  482 + QPDF_DLL void addContentTokenFilter(std::shared_ptr<TokenFilter> token_filter);
458 483 // End legacy content stream helpers
459 484  
460   - // Called on a stream to filter the stream as if it were page contents. This can be used to
461   - // apply a TokenFilter to a form XObject, whose data is in the same format as a content stream.
  485 + /*! \brief Called on a stream to filter the stream as if it were page contents. This can be used to
  486 + * apply a TokenFilter to a form XObject, whose data is in the same format as a content stream.
  487 + */
462 488 QPDF_DLL
463 489 void filterAsContents(TokenFilter* filter, Pipeline* next = nullptr);
464   - // Called on a stream to parse the stream as page contents. This can be used to parse a form
465   - // XObject.
  490 +
  491 + /*! \brief Called on a stream to parse the stream as page contents. This can be used to parse a form
  492 + * XObject.
  493 + */
466 494 QPDF_DLL
467 495 void parseAsContents(ParserCallbacks* callbacks);
468 496  
... ... @@ -478,25 +506,29 @@ class QPDFObjectHandle: public qpdf::BaseHandle
478 506 QPDF_DLL
479 507 static QPDFObjectHandle
480 508 newReal(double value, int decimal_places = 0, bool trim_trailing_zeroes = true);
481   - // Note about name objects: qpdf's internal representation of a PDF name is a sequence of bytes,
482   - // excluding the NUL character, and starting with a slash. Name objects as represented in the
483   - // PDF specification can contain characters escaped with #, but such escaping is not of concern
484   - // when calling QPDFObjectHandle methods not directly relating to parsing. For example,
485   - // newName("/text/plain").getName() and parse("/text#2fplain").getName() both return
486   - // "/text/plain", while newName("/text/plain").unparse() and parse("/text#2fplain").unparse()
487   - // both return "/text#2fplain". When working with the qpdf API for creating, retrieving, and
488   - // modifying objects, you want to work with the internal, canonical representation. For names
489   - // containing alphanumeric characters, dashes, and underscores, there is no difference between
490   - // the two representations. For a lengthy discussion, see
491   - // https://github.com/qpdf/qpdf/discussions/625.
  509 +
  510 + /*! \brief Note about name objects: qpdf's internal representation of a PDF name is a sequence of bytes,
  511 + * excluding the NUL character, and starting with a slash. Name objects as represented in the
  512 + * PDF specification can contain characters escaped with #, but such escaping is not of concern
  513 + * when calling QPDFObjectHandle methods not directly relating to parsing. For example,
  514 + * newName("/text/plain").getName() and parse("/text#2fplain").getName() both return
  515 + * "/text/plain", while newName("/text/plain").unparse() and parse("/text#2fplain").unparse()
  516 + * both return "/text#2fplain". When working with the qpdf API for creating, retrieving, and
  517 + * modifying objects, you want to work with the internal, canonical representation. For names
  518 + * containing alphanumeric characters, dashes, and underscores, there is no difference between
  519 + * the two representations. For a lengthy discussion, see
  520 + * https://github.com/qpdf/qpdf/discussions/625.
  521 + */
492 522 QPDF_DLL
493 523 static QPDFObjectHandle newName(std::string const& name);
494 524 QPDF_DLL
495 525 static QPDFObjectHandle newString(std::string const& str);
496   - // Create a string encoded from the given utf8-encoded string appropriately encoded to appear in
497   - // PDF files outside of content streams, such as in document metadata form field values, page
498   - // labels, outlines, and similar locations. We try ASCII first, then PDFDocEncoding, then UTF-16
499   - // as needed to successfully encode all the characters.
  526 +
  527 + /*! \brief Create a string encoded from the given utf8-encoded string appropriately encoded to appear in
  528 + * PDF files outside of content streams, such as in document metadata form field values, page
  529 + * labels, outlines, and similar locations. We try ASCII first, then PDFDocEncoding, then UTF-16
  530 + * as needed to successfully encode all the characters.
  531 + */
500 532 QPDF_DLL
501 533 static QPDFObjectHandle newUnicodeString(std::string const& utf8_str);
502 534 QPDF_DLL
... ... @@ -518,67 +550,73 @@ class QPDFObjectHandle: public qpdf::BaseHandle
518 550 QPDF_DLL
519 551 static QPDFObjectHandle newDictionary(std::map<std::string, QPDFObjectHandle> const& items);
520 552  
521   - // Create an array from a rectangle. Equivalent to the rectangle form of newArray.
  553 + /*! \brief Create an array from a rectangle. Equivalent to the rectangle form of newArray. */
522 554 QPDF_DLL
523 555 static QPDFObjectHandle newFromRectangle(Rectangle const&);
524   - // Create an array from a matrix. Equivalent to the matrix form of newArray.
  556 +
  557 + /*! \brief Create an array from a matrix. Equivalent to the matrix form of newArray. */
525 558 QPDF_DLL
526 559 static QPDFObjectHandle newFromMatrix(Matrix const&);
527 560 QPDF_DLL
528 561 static QPDFObjectHandle newFromMatrix(QPDFMatrix const&);
529 562  
530   - // Note: new stream creation methods have were added to the QPDF class starting with
531   - // version 11.2.0. The ones in this class are here for backward compatibility.
532   -
533   - // Create a new stream and associate it with the given qpdf object. A subsequent call must be
534   - // made to replaceStreamData() to provide data for the stream. The stream's dictionary may be
535   - // retrieved by calling getDict(), and the resulting dictionary may be modified. Alternatively,
536   - // you can create a new dictionary and call replaceDict to install it. From QPDF 11.2, you can
537   - // call QPDF::newStream() instead.
  563 + /*! \note: new stream creation methods have were added to the QPDF class starting with
  564 + * version 11.2.0. The ones in this class are here for backward compatibility.
  565 + *
  566 + * \brief Create a new stream and associate it with the given qpdf object. A subsequent call must be
  567 + * made to replaceStreamData() to provide data for the stream. The stream's dictionary may be
  568 + * retrieved by calling getDict(), and the resulting dictionary may be modified. Alternatively,
  569 + * you can create a new dictionary and call replaceDict to install it. From QPDF 11.2, you can
  570 + * call QPDF::newStream() instead.
  571 + */
538 572 QPDF_DLL
539 573 static QPDFObjectHandle newStream(QPDF* qpdf);
540 574  
541   - // Create a new stream and associate it with the given qpdf object. Use the given buffer as the
542   - // stream data. The stream dictionary's /Length key will automatically be set to the size of the
543   - // data buffer. If additional keys are required, the stream's dictionary may be retrieved by
544   - // calling getDict(), and the resulting dictionary may be modified. This method is just a
545   - // convenient wrapper around the newStream() and replaceStreamData(). It is a convenience
546   - // methods for streams that require no parameters beyond the stream length. Note that you don't
547   - // have to deal with compression yourself if you use QPDFWriter. By default, QPDFWriter will
548   - // automatically compress uncompressed stream data. Example programs are provided that
549   - // illustrate this. From QPDF 11.2, you can call QPDF::newStream()
550   - // instead.
  575 + /*! \brief Create a new stream and associate it with the given qpdf object. Use the given buffer as the
  576 + * stream data. The stream dictionary's /Length key will automatically be set to the size of the
  577 + * data buffer. If additional keys are required, the stream's dictionary may be retrieved by
  578 + * calling getDict(), and the resulting dictionary may be modified. This method is just a
  579 + * convenient wrapper around the newStream() and replaceStreamData(). It is a convenience
  580 + * methods for streams that require no parameters beyond the stream length. Note that you don't
  581 + * have to deal with compression yourself if you use QPDFWriter. By default, QPDFWriter will
  582 + * automatically compress uncompressed stream data. Example programs are provided that
  583 + * illustrate this. From QPDF 11.2, you can call QPDF::newStream()
  584 + * instead.
  585 + */
551 586 QPDF_DLL
552 587 static QPDFObjectHandle newStream(QPDF* qpdf, std::shared_ptr<Buffer> data);
553 588  
554   - // Create new stream with data from string. This method will create a copy of the data rather
555   - // than using the user-provided buffer as in the std::shared_ptr<Buffer> version of newStream.
556   - // From QPDF 11.2, you can call QPDF::newStream() instead.
  589 + /*! \brief Create new stream with data from string. This method will create a copy of the data rather
  590 + * than using the user-provided buffer as in the std::shared_ptr<Buffer> version of newStream.
  591 + * From QPDF 11.2, you can call QPDF::newStream() instead.
  592 + */
557 593 QPDF_DLL
558 594 static QPDFObjectHandle newStream(QPDF* qpdf, std::string const& data);
559 595  
560   - // A reserved object is a special sentinel used for qpdf to reserve a spot for an object that is
561   - // going to be added to the QPDF object. Normally you don't have to use this type since you can
562   - // just call QPDF::makeIndirectObject. However, in some cases, if you have to create objects
563   - // with circular references, you may need to create a reserved object so that you can have a
564   - // reference to it and then replace the object later. Reserved objects have the special
565   - // property that they can't be resolved to direct objects. This makes it possible to replace a
566   - // reserved object with a new object while preserving existing references to them. When you are
567   - // ready to replace a reserved object with its replacement, use QPDF::replaceReserved for this
568   - // purpose rather than the more general QPDF::replaceObject. It is an error to try to write a
569   - // QPDF with QPDFWriter if it has any reserved objects in it. From QPDF 11.4, you can call
570   - // QPDF::newReserved() instead.
  596 + /*! \brief A reserved object is a special sentinel used for qpdf to reserve a spot for an object that is
  597 + * going to be added to the QPDF object. Normally you don't have to use this type since you can
  598 + * just call QPDF::makeIndirectObject. However, in some cases, if you have to create objects
  599 + * with circular references, you may need to create a reserved object so that you can have a
  600 + * reference to it and then replace the object later. Reserved objects have the special
  601 + * property that they can't be resolved to direct objects. This makes it possible to replace a
  602 + * reserved object with a new object while preserving existing references to them. When you are
  603 + * ready to replace a reserved object with its replacement, use QPDF::replaceReserved for this
  604 + * purpose rather than the more general QPDF::replaceObject. It is an error to try to write a
  605 + * QPDF with QPDFWriter if it has any reserved objects in it. From QPDF 11.4, you can call
  606 + * QPDF::newReserved() instead.
  607 + */
571 608 QPDF_DLL
572 609 static QPDFObjectHandle newReserved(QPDF* qpdf);
573 610  
574   - // Provide an owning qpdf and object description. The library does this automatically with
575   - // objects that are read from the input PDF and with objects that are created programmatically
576   - // and inserted into the QPDF as a new indirect object. Most end user code will not need to call
577   - // this. If an object has an owning qpdf and object description, it enables qpdf to give
578   - // warnings with proper context in some cases where it would otherwise raise exceptions. It is
579   - // okay to add objects without an owning_qpdf to objects that have one, but it is an error to
580   - // have a QPDF contain objects with owning_qpdf set to something else. To add objects from
581   - // another qpdf, use copyForeignObject instead.
  611 + /*! \brief Provide an owning qpdf and object description. The library does this automatically with
  612 + * objects that are read from the input PDF and with objects that are created programmatically
  613 + * and inserted into the QPDF as a new indirect object. Most end user code will not need to call
  614 + * this. If an object has an owning qpdf and object description, it enables qpdf to give
  615 + * warnings with proper context in some cases where it would otherwise raise exceptions. It is
  616 + * okay to add objects without an owning_qpdf to objects that have one, but it is an error to
  617 + * have a QPDF contain objects with owning_qpdf set to something else. To add objects from
  618 + * another qpdf, use copyForeignObject instead.
  619 + */
582 620 QPDF_DLL
583 621 void setObjectDescription(QPDF* owning_qpdf, std::string const& object_description);
584 622 QPDF_DLL
... ... @@ -636,10 +674,11 @@ class QPDFObjectHandle: public qpdf::BaseHandle
636 674 QPDF_DLL
637 675 bool getValueAsBool(bool&) const;
638 676  
639   - // Methods for integer objects. Note: if an integer value is too big (too far away from zero in
640   - // either direction) to fit in the requested return type, the maximum or minimum value for that
641   - // return type may be returned. For example, on a system with 32-bit int, a numeric object with
642   - // a value of 2^40 (or anything too big for 32 bits) will be returned as INT_MAX.
  677 + /*! \brief Methods for integer objects. Note: if an integer value is too big (too far away from zero in
  678 + * either direction) to fit in the requested return type, the maximum or minimum value for that
  679 + * return type may be returned. For example, on a system with 32-bit int, a numeric object with
  680 + * a value of 2^40 (or anything too big for 32 bits) will be returned as INT_MAX.
  681 + */
643 682 QPDF_DLL
644 683 long long getIntValue() const;
645 684 QPDF_DLL
... ... @@ -671,30 +710,30 @@ class QPDFObjectHandle: public qpdf::BaseHandle
671 710 QPDF_DLL
672 711 bool getValueAsNumber(double&) const;
673 712  
674   - // Methods for name objects. The returned name value is in qpdf's canonical form with all
675   - // escaping resolved. See comments for newName() for details.
  713 + /*! \brief Methods for name objects. The returned name value is in qpdf's canonical form with all
  714 + * escaping resolved. See comments for newName() for details.
  715 + */
676 716 QPDF_DLL
677 717 std::string getName() const;
678 718 QPDF_DLL
679 719 bool getValueAsName(std::string&) const;
680 720  
681   - // Methods for string objects
  721 + /*! \brief Methods for string objects */
682 722 QPDF_DLL
683 723 std::string getStringValue() const;
684 724 QPDF_DLL
685 725 bool getValueAsString(std::string&) const;
686 726  
687   - // If a string starts with the UTF-16 marker, it is converted from UTF-16 to UTF-8. Otherwise,
688   - // it is treated as a string encoded with PDF Doc Encoding. PDF Doc Encoding is identical to
689   - // ISO-8859-1 except in the range from 0200 through 0240, where there is a mapping of characters
690   - // to Unicode. QPDF versions prior to version 8.0.0 erroneously left characters in that range
691   - // unmapped.
692   - QPDF_DLL
693   - std::string getUTF8Value() const;
694   - QPDF_DLL
695   - bool getValueAsUTF8(std::string&) const;
  727 + /*! \brief If a string starts with the UTF-16 marker, it is converted from UTF-16 to UTF-8. Otherwise,
  728 + * it is treated as a string encoded with PDF Doc Encoding. PDF Doc Encoding is identical to
  729 + * ISO-8859-1 except in the range from 0200 through 0240, where there is a mapping of characters
  730 + * to Unicode. QPDF versions prior to version 8.0.0 erroneously left characters in that range
  731 + * unmapped.
  732 + */
  733 + QPDF_DLL std::string getUTF8Value() const;
  734 + QPDF_DLL bool getValueAsUTF8(std::string&) const;
696 735  
697   - // Methods for content stream objects
  736 + /*! \brief Methods for content stream objects */
698 737 QPDF_DLL
699 738 std::string getOperatorValue() const;
700 739 QPDF_DLL
... ... @@ -704,14 +743,14 @@ class QPDFObjectHandle: public qpdf::BaseHandle
704 743 QPDF_DLL
705 744 bool getValueAsInlineImage(std::string&) const;
706 745  
707   - // Methods for array objects; see also name and array objects.
708   -
709   - // Return an object that enables iteration over members. You can do
710   - //
711   - // for (auto iter: obj.aitems())
712   - // {
713   - // // iter is an array element
714   - // }
  746 + /*! \brief Methods for array objects; see also name and array objects.
  747 + * Return an object that enables iteration over members. You can do
  748 + *
  749 + * for (auto iter: obj.aitems())
  750 + * {
  751 + * // iter is an array element
  752 + * }
  753 + */
715 754 class QPDFArrayItems;
716 755 QPDF_DLL
717 756 QPDFArrayItems aitems();
... ... @@ -720,195 +759,220 @@ class QPDFObjectHandle: public qpdf::BaseHandle
720 759 int getArrayNItems() const;
721 760 QPDF_DLL
722 761 QPDFObjectHandle getArrayItem(int n) const;
723   - // Note: QPDF arrays internally optimize memory for arrays containing lots of nulls. Calling
724   - // getArrayAsVector may cause a lot of memory to be allocated for very large arrays with lots of
725   - // nulls.
  762 +
  763 + /*! \note: QPDF arrays internally optimize memory for arrays containing lots of nulls. Calling
  764 + * getArrayAsVector may cause a lot of memory to be allocated for very large arrays with lots of
  765 + * nulls.
  766 + */
726 767 QPDF_DLL
727 768 std::vector<QPDFObjectHandle> getArrayAsVector() const;
728 769 QPDF_DLL
729 770 bool isRectangle() const;
730   - // If the array is an array of four numeric values, return as a rectangle. Otherwise, return the
731   - // rectangle [0, 0, 0, 0]
  771 +
  772 + /*! \brief If the array is an array of four numeric values, return as a rectangle. Otherwise, return the
  773 + * rectangle [0, 0, 0, 0]
  774 + */
732 775 QPDF_DLL
733 776 Rectangle getArrayAsRectangle() const;
734 777 QPDF_DLL
735 778 bool isMatrix() const;
736   - // If the array is an array of six numeric values, return as a matrix. Otherwise, return the
737   - // matrix [1, 0, 0, 1, 0, 0]
  779 +
  780 + /*! \brief If the array is an array of six numeric values, return as a matrix. Otherwise, return the
  781 + * matrix [1, 0, 0, 1, 0, 0]
  782 + */
738 783 QPDF_DLL
739 784 Matrix getArrayAsMatrix() const;
740 785  
741   - // Methods for dictionary objects. In all dictionary methods, keys are specified/represented as
742   - // canonical name strings starting with a leading slash and not containing any PDF syntax
743   - // escaping. See comments for getName() for details.
744   -
745   - // Return an object that enables iteration over members. You can do
746   - //
747   - // for (auto iter: obj.ditems())
748   - // {
749   - // // iter.first is the key
750   - // // iter.second is the value
751   - // }
  786 + /*! \brief Methods for dictionary objects. In all dictionary methods, keys are specified/represented as
  787 + * canonical name strings starting with a leading slash and not containing any PDF syntax
  788 + * escaping. See comments for getName() for details.
  789 + *
  790 + * Return an object that enables iteration over members. You can do
  791 + *
  792 + * for (auto iter: obj.ditems())
  793 + * {
  794 + * // iter.first is the key
  795 + * // iter.second is the value
  796 + * }
  797 + */
752 798 class QPDFDictItems;
753 799 QPDF_DLL
754 800 QPDFDictItems ditems();
755 801  
756   - // Return true if key is present. Keys with null values are treated as if they are not present.
757   - // This is as per the PDF spec.
  802 + /*! \return true if key is present. Keys with null values are treated as if they are not present.
  803 + * This is as per the PDF spec.
  804 + */
758 805 QPDF_DLL
759 806 bool hasKey(std::string const&) const;
760   - // Return the value for the key. If the key is not present, null is returned.
  807 +
  808 + /*! \return the value for the key. If the key is not present, null is returned. */
761 809 QPDF_DLL
762 810 QPDFObjectHandle getKey(std::string const&) const;
763   - // If the object is null, return null. Otherwise, call getKey(). This makes it easier to access
764   - // lower-level dictionaries, as in
765   - // auto font = page.getKeyIfDict("/Resources").getKeyIfDict("/Font");
  811 +
  812 + /*! \brief If the object is null, return null. Otherwise, call getKey(). This makes it easier to access
  813 + * lower-level dictionaries, as in
  814 + * auto font = page.getKeyIfDict("/Resources").getKeyIfDict("/Font");
  815 + */
766 816 QPDF_DLL
767 817 QPDFObjectHandle getKeyIfDict(std::string const&) const;
768   - // Return all keys. Keys with null values are treated as if they are not present. This is as
769   - // per the PDF spec.
  818 +
  819 + /*! \brief Return all keys. Keys with null values are treated as if they are not present. This is as
  820 + * per the PDF spec.
  821 + */
770 822 QPDF_DLL
771 823 std::set<std::string> getKeys() const;
772   - // Return dictionary as a map. Entries with null values are included.
  824 +
  825 + /*! \return dictionary as a map. Entries with null values are included. */
773 826 QPDF_DLL
774 827 std::map<std::string, QPDFObjectHandle> getDictAsMap() const;
775 828  
776   - // Methods for name and array objects. The name value is in qpdf's canonical form with all
777   - // escaping resolved. See comments for newName() for details.
  829 + /*! \brief Methods for name and array objects. The name value is in qpdf's canonical form with all
  830 + * escaping resolved. See comments for newName() for details.
  831 + */
778 832 QPDF_DLL
779 833 bool isOrHasName(std::string const&) const;
780 834  
781   - // Make all resources in a resource dictionary indirect. This just goes through all entries of
782   - // top-level subdictionaries and converts any direct objects to indirect objects. This can be
783   - // useful to call before mergeResources if it is going to be called multiple times to prevent
784   - // resources from being copied multiple times.
  835 + /*! \brief Make all resources in a resource dictionary indirect. This just goes through all entries of
  836 + * top-level subdictionaries and converts any direct objects to indirect objects. This can be
  837 + * useful to call before mergeResources if it is going to be called multiple times to prevent
  838 + * resources from being copied multiple times.
  839 + */
785 840 QPDF_DLL
786 841 void makeResourcesIndirect(QPDF& owning_qpdf);
787 842  
788   - // Merge resource dictionaries. If the "conflicts" parameter is provided, conflicts in
789   - // dictionary subitems are resolved, and "conflicts" is initialized to a map such that
790   - // conflicts[resource_type][old_key] == [new_key]
791   - //
792   - // See also makeResourcesIndirect, which can be useful to call before calling this.
793   - //
794   - // This method does nothing if both this object and the other object are not dictionaries.
795   - // Otherwise, it has following behavior, where "object" refers to the object whose method is
796   - // invoked, and "other" refers to the argument:
797   - //
798   - // * For each key in "other" whose value is an array:
799   - // * If "object" does not have that entry, shallow copy it.
800   - // * Otherwise, if "object" has an array in the same place, append to that array any objects
801   - // in "other"'s array that are not already present.
802   - // * For each key in "other" whose value is a dictionary:
803   - // * If "object" does not have that entry, shallow copy it.
804   - // * Otherwise, for each key in the subdictionary:
805   - // * If key is not present in "object"'s entry, shallow copy it if direct or just add it if
806   - // indirect.
807   - // * Otherwise, if conflicts are being detected:
808   - // * If there is a key (oldkey) already in the dictionary that points to the same indirect
809   - // destination as key, indicate that key was replaced by oldkey. This would happen if
810   - // these two resource dictionaries have previously been merged.
811   - // * Otherwise pick a new key (newkey) that is unique within the resource dictionary,
812   - // store that in the resource dictionary with key's destination as its destination, and
813   - // indicate that key was replaced by newkey.
814   - //
815   - // The primary purpose of this method is to facilitate merging of resource dictionaries that are
816   - // supposed to have the same scope as each other. For example, this can be used to merge a form
817   - // XObject's /Resources dictionary with a form field's /DR or to merge two /DR dictionaries. The
818   - // "conflicts" parameter may be previously initialized. This method adds to whatever is already
819   - // there, which can be useful when merging with multiple things.
  843 + /*! \brief Merge resource dictionaries. If the "conflicts" parameter is provided, conflicts in
  844 + * dictionary subitems are resolved, and "conflicts" is initialized to a map such that
  845 + * conflicts[resource_type][old_key] == [new_key]
  846 + *
  847 + * See also makeResourcesIndirect, which can be useful to call before calling this.
  848 + *
  849 + * This method does nothing if both this object and the other object are not dictionaries.
  850 + * Otherwise, it has following behavior, where "object" refers to the object whose method is
  851 + * invoked, and "other" refers to the argument:
  852 + *
  853 + * * For each key in "other" whose value is an array:
  854 + * * If "object" does not have that entry, shallow copy it.
  855 + * * Otherwise, if "object" has an array in the same place, append to that array any objects
  856 + * in "other"'s array that are not already present.
  857 + * * For each key in "other" whose value is a dictionary:
  858 + * * If "object" does not have that entry, shallow copy it.
  859 + * * Otherwise, for each key in the subdictionary:
  860 + * * If key is not present in "object"'s entry, shallow copy it if direct or just add it if
  861 + * indirect.
  862 + * * Otherwise, if conflicts are being detected:
  863 + * * If there is a key (oldkey) already in the dictionary that points to the same indirect
  864 + * destination as key, indicate that key was replaced by oldkey. This would happen if
  865 + * these two resource dictionaries have previously been merged.
  866 + * * Otherwise pick a new key (newkey) that is unique within the resource dictionary,
  867 + * store that in the resource dictionary with key's destination as its destination, and
  868 + * indicate that key was replaced by newkey.
  869 + *
  870 + * The primary purpose of this method is to facilitate merging of resource dictionaries that are
  871 + * supposed to have the same scope as each other. For example, this can be used to merge a form
  872 + * XObject's /Resources dictionary with a form field's /DR or to merge two /DR dictionaries. The
  873 + * "conflicts" parameter may be previously initialized. This method adds to whatever is already
  874 + * there, which can be useful when merging with multiple things.
  875 + */
820 876 QPDF_DLL
821 877 void mergeResources(
822 878 QPDFObjectHandle other,
823 879 std::map<std::string, std::map<std::string, std::string>>* conflicts = nullptr);
824 880  
825   - // Get all resource names from a resource dictionary. If this object is a dictionary, this
826   - // method returns a set of all the keys in all top-level subdictionaries. For resources
827   - // dictionaries, this is the collection of names that may be referenced in the content stream.
  881 + /*! \brief Get all resource names from a resource dictionary. If this object is a dictionary, this
  882 + * method returns a set of all the keys in all top-level subdictionaries. For resources
  883 + * dictionaries, this is the collection of names that may be referenced in the content stream.
  884 + */
828 885 QPDF_DLL
829 886 std::set<std::string> getResourceNames() const;
830 887  
831   - // Find a unique name within a resource dictionary starting with a given prefix. This method
832   - // works by appending a number to the given prefix. It searches starting with min_suffix and
833   - // sets min_suffix to selected value upon return. This can be used to increase efficiency if
834   - // adding multiple items with the same prefix. (Why doesn't it set min_suffix to the next
835   - // number? Well, maybe you aren't going to actually use the name it returns.) If you are calling
836   - // this multiple times on the same resource dictionary, you can initialize resource_names by
837   - // calling getResourceNames(), incrementally update it as you add resources, and keep passing it
838   - // in so that getUniqueResourceName doesn't have to traverse the resource dictionary each time
839   - // it's called.
  888 + /*! \brief Find a unique name within a resource dictionary starting with a given prefix. This method
  889 + * works by appending a number to the given prefix. It searches starting with min_suffix and
  890 + * sets min_suffix to selected value upon return. This can be used to increase efficiency if
  891 + * adding multiple items with the same prefix. (Why doesn't it set min_suffix to the next
  892 + * number? Well, maybe you aren't going to actually use the name it returns.) If you are calling
  893 + * this multiple times on the same resource dictionary, you can initialize resource_names by
  894 + * calling getResourceNames(), incrementally update it as you add resources, and keep passing it
  895 + * in so that getUniqueResourceName doesn't have to traverse the resource dictionary each time
  896 + * it's called.
  897 + */
840 898 QPDF_DLL
841 899 std::string getUniqueResourceName(
842 900 std::string const& prefix,
843 901 int& min_suffix,
844 902 std::set<std::string>* resource_names = nullptr) const;
845 903  
846   - // A QPDFObjectHandle has an owning QPDF if it is associated with ("owned by") a specific QPDF
847   - // object. Indirect objects always have an owning QPDF. Direct objects that are read from the
848   - // input source will also have an owning QPDF. Programmatically created objects will only have
849   - // one if setObjectDescription was called.
850   - //
851   - // When the QPDF object that owns an object is destroyed, the object is changed into a null, and
852   - // its owner is cleared. Therefore you should not retain the value of an owning QPDF beyond the
853   - // life of the QPDF. If in doubt, ask for it each time you need it.
854   -
855   - // getOwningQPDF returns a pointer to the owning QPDF is the object has one. Otherwise, it
856   - // returns a null pointer. Use this when you are able to handle the case of an object that
857   - // doesn't have an owning QPDF.
  904 + /*! \brief A QPDFObjectHandle has an owning QPDF if it is associated with ("owned by") a specific QPDF
  905 + * object. Indirect objects always have an owning QPDF. Direct objects that are read from the
  906 + * input source will also have an owning QPDF. Programmatically created objects will only have
  907 + * one if setObjectDescription was called.
  908 + *
  909 + * When the QPDF object that owns an object is destroyed, the object is changed into a null, and
  910 + * its owner is cleared. Therefore you should not retain the value of an owning QPDF beyond the
  911 + * life of the QPDF. If in doubt, ask for it each time you need it.
  912 + *
  913 + * getOwningQPDF returns a pointer to the owning QPDF is the object has one. Otherwise, it
  914 + * returns a null pointer. Use this when you are able to handle the case of an object that
  915 + * doesn't have an owning QPDF.
  916 + */
858 917 QPDF_DLL
859 918 QPDF* getOwningQPDF() const;
860   - // getQPDF, new in qpdf 11, returns a reference owning QPDF. If there is none, it throws a
861   - // runtime_error. Use this when you know the object has to have an owning QPDF, such as when
862   - // it's a known indirect object. Since streams are always indirect objects, this method can be
863   - // used safely for streams. If error_msg is specified, it will be used at the contents of the
864   - // runtime_error if there is now owner.
  919 + /*! \brief getQPDF, new in qpdf 11, returns a reference owning QPDF. If there is none, it throws a
  920 + * runtime_error. Use this when you know the object has to have an owning QPDF, such as when
  921 + * it's a known indirect object. Since streams are always indirect objects, this method can be
  922 + * used safely for streams. If error_msg is specified, it will be used at the contents of the
  923 + * runtime_error if there is now owner.
  924 + */
865 925 QPDF_DLL
866 926 QPDF& getQPDF(std::string const& error_msg = "") const;
867 927  
868   - // Create a shallow copy of an object as a direct object, but do not traverse across indirect
869   - // object boundaries. That means that, for dictionaries and arrays, any keys or items that were
870   - // indirect objects will still be indirect objects that point to the same place. In the
871   - // strictest sense, this is not a shallow copy because it recursively descends arrays and
872   - // dictionaries; it just doesn't cross over indirect objects. See also unsafeShallowCopy(). You
873   - // can't copy a stream this way. See copyStream() instead.
  928 + /*! \brief Create a shallow copy of an object as a direct object, but do not traverse across indirect
  929 + * object boundaries. That means that, for dictionaries and arrays, any keys or items that were
  930 + * indirect objects will still be indirect objects that point to the same place. In the
  931 + * strictest sense, this is not a shallow copy because it recursively descends arrays and
  932 + * dictionaries; it just doesn't cross over indirect objects. See also unsafeShallowCopy(). You
  933 + * can't copy a stream this way. See copyStream() instead.
  934 + */
874 935 QPDF_DLL
875 936 QPDFObjectHandle shallowCopy();
876 937  
877   - // Create a true shallow copy of an array or dictionary, just copying the immediate items
878   - // (array) or keys (dictionary). This is "unsafe" because, if you *modify* any of the items in
879   - // the copy, you are modifying the original, which is almost never what you want. However, if
880   - // your intention is merely to *replace* top-level items or keys and not to modify lower-level
881   - // items in the copy, this method is much faster than shallowCopy().
  938 + /*! \brief Create a true shallow copy of an array or dictionary, just copying the immediate items
  939 + * (array) or keys (dictionary). This is "unsafe" because, if you *modify* any of the items in
  940 + * the copy, you are modifying the original, which is almost never what you want. However, if
  941 + * your intention is merely to *replace* top-level items or keys and not to modify lower-level
  942 + * items in the copy, this method is much faster than shallowCopy().
  943 + */
882 944 QPDF_DLL
883 945 QPDFObjectHandle unsafeShallowCopy();
884 946  
885   - // Create a copy of this stream. The new stream and the old stream are independent: after the
886   - // copy, either the original or the copy's dictionary or data can be modified without affecting
887   - // the other. This uses StreamDataProvider internally, so no unnecessary copies of the stream's
888   - // data are made. If the source stream's data is already being provided by a StreamDataProvider,
889   - // the new stream will use the same one, so you have to make sure your StreamDataProvider can
890   - // handle that case. But if you're already using a StreamDataProvider, you probably don't need
891   - // to call this method.
  947 + /*! \brief Create a copy of this stream. The new stream and the old stream are independent: after the
  948 + * copy, either the original or the copy's dictionary or data can be modified without affecting
  949 + * the other. This uses StreamDataProvider internally, so no unnecessary copies of the stream's
  950 + * data are made. If the source stream's data is already being provided by a StreamDataProvider,
  951 + * the new stream will use the same one, so you have to make sure your StreamDataProvider can
  952 + * handle that case. But if you're already using a StreamDataProvider, you probably don't need
  953 + * to call this method.
  954 + */
892 955 QPDF_DLL
893 956 QPDFObjectHandle copyStream();
894 957  
895 958 // Mutator methods.
896 959  
897   - // Since qpdf 11: for mutators that may add or remove an item, there are additional versions
898   - // whose names contain "AndGet" that return the added or removed item. For example:
899   - //
900   - // auto new_dict = dict.replaceKeyAndGetNew(
901   - // "/New", QPDFObjectHandle::newDictionary());
902   - //
903   - // auto old_value = dict.replaceKeyAndGetOld(
904   - // "/New", "(something)"_qpdf);
905   -
906   - // Recursively copy this object, making it direct. An exception is thrown if a loop is detected.
907   - // With allow_streams true, keep indirect object references to streams. Otherwise, throw an
908   - // exception if any sub-object is a stream. Note that, when allow_streams is true and a stream
909   - // is found, the resulting object is still associated with the containing qpdf. When
910   - // allow_streams is false, the object will no longer be connected to the original QPDF object
911   - // after this call completes successfully.
  960 + /*! \brief Since qpdf 11: for mutators that may add or remove an item, there are additional versions
  961 + * whose names contain "AndGet" that return the added or removed item. For example:
  962 + *
  963 + * auto new_dict = dict.replaceKeyAndGetNew(
  964 + * "/New", QPDFObjectHandle::newDictionary());
  965 + *
  966 + * auto old_value = dict.replaceKeyAndGetOld(
  967 + * "/New", "(something)"_qpdf);
  968 + *
  969 + * Recursively copy this object, making it direct. An exception is thrown if a loop is detected.
  970 + * With allow_streams true, keep indirect object references to streams. Otherwise, throw an
  971 + * exception if any sub-object is a stream. Note that, when allow_streams is true and a stream
  972 + * is found, the resulting object is still associated with the containing qpdf. When
  973 + * allow_streams is false, the object will no longer be connected to the original QPDF object
  974 + * after this call completes successfully.
  975 + */
912 976 QPDF_DLL
913 977 void makeDirect(bool allow_streams = false);
914 978  
... ... @@ -917,41 +981,52 @@ class QPDFObjectHandle: public qpdf::BaseHandle
917 981 void setArrayItem(int, QPDFObjectHandle const&);
918 982 QPDF_DLL
919 983 void setArrayFromVector(std::vector<QPDFObjectHandle> const& items);
920   - // Insert an item before the item at the given position ("at") so that it has that position
921   - // after insertion. If "at" is equal to the size of the array, insert the item at the end.
  984 +
  985 + /*! \brief Insert an item before the item at the given position ("at") so that it has that position
  986 + * after insertion. If "at" is equal to the size of the array, insert the item at the end.
  987 + */
922 988 QPDF_DLL
923 989 void insertItem(int at, QPDFObjectHandle const& item);
924   - // Like insertItem but return the item that was inserted.
  990 +
  991 + /*! \brief Like insertItem but return the item that was inserted. */
925 992 QPDF_DLL
926 993 QPDFObjectHandle insertItemAndGetNew(int at, QPDFObjectHandle const& item);
927   - // Append an item to an array.
  994 +
  995 + /*! \brief Append an item to an array. */
928 996 QPDF_DLL
929 997 void appendItem(QPDFObjectHandle const& item);
930   - // Append an item, and return the newly added item.
  998 +
  999 + /*! \brief Append an item, and return the newly added item. */
931 1000 QPDF_DLL
932 1001 QPDFObjectHandle appendItemAndGetNew(QPDFObjectHandle const& item);
933   - // Remove the item at that position, reducing the size of the array by one.
  1002 +
  1003 + /*! \brief Remove the item at that position, reducing the size of the array by one. */
934 1004 QPDF_DLL
935 1005 void eraseItem(int at);
936   - // Erase and item and return the item that was removed.
  1006 +
  1007 + /*! \brief Erase and item and return the item that was removed. */
937 1008 QPDF_DLL
938 1009 QPDFObjectHandle eraseItemAndGetOld(int at);
939 1010  
940 1011 // Mutator methods for dictionary objects
941 1012  
942   - // Replace value of key, adding it if it does not exist. If value is null, remove the key.
  1013 + /*! \brief Replace value of key, adding it if it does not exist. If value is null, remove the key. */
943 1014 QPDF_DLL
944 1015 void replaceKey(std::string const& key, QPDFObjectHandle const& value);
945   - // Replace value of key and return the value.
  1016 +
  1017 + /*! \brief Replace value of key and return the value. */
946 1018 QPDF_DLL
947 1019 QPDFObjectHandle replaceKeyAndGetNew(std::string const& key, QPDFObjectHandle const& value);
948   - // Replace value of key and return the old value, or null if the key was previously not present.
  1020 +
  1021 + /*! \brief Replace value of key and return the old value, or null if the key was previously not present. */
949 1022 QPDF_DLL
950 1023 QPDFObjectHandle replaceKeyAndGetOld(std::string const& key, QPDFObjectHandle const& value);
951   - // Remove key, doing nothing if key does not exist.
  1024 +
  1025 + /*! \brief Remove key, doing nothing if key does not exist. */
952 1026 QPDF_DLL
953 1027 void removeKey(std::string const& key);
954   - // Remove key and return the old value. If the old value didn't exist, return a null object.
  1028 +
  1029 + /*! \brief Remove key and return the old value. If the old value didn't exist, return a null object. */
955 1030 QPDF_DLL
956 1031 QPDFObjectHandle removeKeyAndGetOld(std::string const& key);
957 1032  
... ... @@ -959,76 +1034,80 @@ class QPDFObjectHandle: public qpdf::BaseHandle
959 1034 QPDF_DLL
960 1035 QPDFObjectHandle getDict() const;
961 1036  
962   - // By default, or if true passed, QPDFWriter will attempt to filter a stream based on decode
963   - // level, whether compression is enabled, and its ability to filter. Passing false will prevent
964   - // QPDFWriter from attempting to filter the stream even if it can. This includes both decoding
965   - // and compressing. This makes it possible for you to prevent QPDFWriter from uncompressing and
966   - // recompressing a stream that it knows how to operate on for any application-specific reason,
967   - // such as that you have already optimized its filtering. Note that this doesn't affect any
968   - // other ways to get the stream's data, such as pipeStreamData or getStreamData.
  1037 + /*! \brief By default, or if true passed, QPDFWriter will attempt to filter a stream based on decode
  1038 + * level, whether compression is enabled, and its ability to filter. Passing false will prevent
  1039 + * QPDFWriter from attempting to filter the stream even if it can. This includes both decoding
  1040 + * and compressing. This makes it possible for you to prevent QPDFWriter from uncompressing and
  1041 + * recompressing a stream that it knows how to operate on for any application-specific reason,
  1042 + * such as that you have already optimized its filtering. Note that this doesn't affect any
  1043 + * other ways to get the stream's data, such as pipeStreamData or getStreamData.
  1044 + */
969 1045 QPDF_DLL
970 1046 void setFilterOnWrite(bool);
971 1047 QPDF_DLL
972 1048 bool getFilterOnWrite();
973 1049  
974   - // If addTokenFilter has been called for this stream, then the original data should be
975   - // considered to be modified. This means we should avoid optimizations such as not filtering a
976   - // stream that is already compressed.
  1050 + /*! \brief If addTokenFilter has been called for this stream, then the original data should be
  1051 + * considered to be modified. This means we should avoid optimizations such as not filtering a
  1052 + * stream that is already compressed.
  1053 + */
977 1054 QPDF_DLL
978 1055 bool isDataModified();
979 1056  
980   - // Returns filtered (uncompressed) stream data. Throws an exception if the stream is filtered
981   - // and we can't decode it.
  1057 + /*! \brief Returns filtered (uncompressed) stream data. Throws an exception if the stream is filtered
  1058 + * and we can't decode it.
  1059 + */
982 1060 QPDF_DLL
983 1061 std::shared_ptr<Buffer> getStreamData(qpdf_stream_decode_level_e level = qpdf_dl_generalized);
984 1062  
985   - // Returns unfiltered (raw) stream data.
  1063 + /*! \brief Returns unfiltered (raw) stream data. */
986 1064 QPDF_DLL
987 1065 std::shared_ptr<Buffer> getRawStreamData();
988 1066  
989   - // Write stream data through the given pipeline. A null pipeline value may be used if all you
990   - // want to do is determine whether a stream is filterable and would be filtered based on the
991   - // provided flags. If flags is 0, write raw stream data and return false. Otherwise, the flags
992   - // alter the behavior in the following way:
993   - //
994   - // encode_flags:
995   - //
996   - // qpdf_sf_compress -- compress data with /FlateDecode if no other compression filters are
997   - // applied.
998   - //
999   - // qpdf_sf_normalize -- tokenize as content stream and normalize tokens
1000   - //
1001   - // decode_level:
1002   - //
1003   - // qpdf_dl_none -- do not decode any streams.
1004   - //
1005   - // qpdf_dl_generalized -- decode supported general-purpose filters. This includes
1006   - // /ASCIIHexDecode, /ASCII85Decode, /LZWDecode, and /FlateDecode.
1007   - //
1008   - // qpdf_dl_specialized -- in addition to generalized filters, also decode supported non-lossy
1009   - // specialized filters. This includes /RunLengthDecode.
1010   - //
1011   - // qpdf_dl_all -- in addition to generalized and non-lossy specialized filters, decode supported
1012   - // lossy filters. This includes /DCTDecode.
1013   - //
1014   - // If, based on the flags and the filters and decode parameters, we determine that we know how
1015   - // to apply all requested filters, do so and return true if we are successful.
1016   - //
1017   - // The exact meaning of the return value differs the different versions of this function, but
1018   - // for any version, the meaning has been the same. For the main version, added in qpdf 10, the
1019   - // return value indicates whether the overall operation succeeded. The filter parameter, if
1020   - // specified, will be set to whether or not filtering was attempted. If filtering was not
1021   - // requested, this value will be false even if the overall operation succeeded.
1022   - //
1023   - // If filtering is requested but this method returns false, it means there was some error in the
1024   - // filtering, in which case the resulting data is likely partially filtered and/or incomplete
1025   - // and may not be consistent with the configured filters. QPDFWriter handles this by attempting
1026   - // to get the stream data without filtering, but callers should consider a false return value
1027   - // when decode_level is not qpdf_dl_none to be a potential loss of data. If you intend to retry
1028   - // in that case, pass true as the value of will_retry. This changes the warning issued by the
1029   - // library to indicate that the operation will be retried without filtering to avoid data loss.
1030   -
1031   - // Return value is overall success, even if filtering is not requested.
  1067 + /*! \brief Write stream data through the given pipeline. A null pipeline value may be used if all you
  1068 + * want to do is determine whether a stream is filterable and would be filtered based on the
  1069 + * provided flags. If flags is 0, write raw stream data and return false. Otherwise, the flags
  1070 + * alter the behavior in the following way:
  1071 + *
  1072 + * encode_flags:
  1073 + *
  1074 + * qpdf_sf_compress -- compress data with /FlateDecode if no other compression filters are
  1075 + * applied.
  1076 + *
  1077 + * qpdf_sf_normalize -- tokenize as content stream and normalize tokens
  1078 + *
  1079 + * decode_level:
  1080 + *
  1081 + * qpdf_dl_none -- do not decode any streams.
  1082 + *
  1083 + * qpdf_dl_generalized -- decode supported general-purpose filters. This includes
  1084 + * /ASCIIHexDecode, /ASCII85Decode, /LZWDecode, and /FlateDecode.
  1085 + *
  1086 + * qpdf_dl_specialized -- in addition to generalized filters, also decode supported non-lossy
  1087 + * specialized filters. This includes /RunLengthDecode.
  1088 + *
  1089 + * qpdf_dl_all -- in addition to generalized and non-lossy specialized filters, decode supported
  1090 + * lossy filters. This includes /DCTDecode.
  1091 + *
  1092 + * If, based on the flags and the filters and decode parameters, we determine that we know how
  1093 + * to apply all requested filters, do so and return true if we are successful.
  1094 + *
  1095 + * The exact meaning of the return value differs the different versions of this function, but
  1096 + * for any version, the meaning has been the same. For the main version, added in qpdf 10, the
  1097 + * return value indicates whether the overall operation succeeded. The filter parameter, if
  1098 + * specified, will be set to whether or not filtering was attempted. If filtering was not
  1099 + * requested, this value will be false even if the overall operation succeeded.
  1100 + *
  1101 + * If filtering is requested but this method returns false, it means there was some error in the
  1102 + * filtering, in which case the resulting data is likely partially filtered and/or incomplete
  1103 + * and may not be consistent with the configured filters. QPDFWriter handles this by attempting
  1104 + * to get the stream data without filtering, but callers should consider a false return value
  1105 + * when decode_level is not qpdf_dl_none to be a potential loss of data. If you intend to retry
  1106 + * in that case, pass true as the value of will_retry. This changes the warning issued by the
  1107 + * library to indicate that the operation will be retried without filtering to avoid data loss.
  1108 +
  1109 + * Return value is overall success, even if filtering is not requested.
  1110 + */
1032 1111 QPDF_DLL
1033 1112 bool pipeStreamData(
1034 1113 Pipeline*,
... ... @@ -1038,8 +1117,9 @@ class QPDFObjectHandle: public qpdf::BaseHandle
1038 1117 bool suppress_warnings = false,
1039 1118 bool will_retry = false);
1040 1119  
1041   - // Legacy version. Return value is whether filtering was attempted. There is no way to determine
1042   - // success if filtering was not attempted.
  1120 + /*! \brief Legacy version. Return value is whether filtering was attempted. There is no way to determine
  1121 + * success if filtering was not attempted.
  1122 + */
1043 1123 QPDF_DLL
1044 1124 bool pipeStreamData(
1045 1125 Pipeline*,
... ... @@ -1048,99 +1128,107 @@ class QPDFObjectHandle: public qpdf::BaseHandle
1048 1128 bool suppress_warnings = false,
1049 1129 bool will_retry = false);
1050 1130  
1051   - // Legacy pipeStreamData. This maps to the the flags-based pipeStreamData as follows:
1052   - // filter = false -> encode_flags = 0
1053   - // filter = true -> decode_level = qpdf_dl_generalized
1054   - // normalize = true -> encode_flags |= qpdf_sf_normalize
1055   - // compress = true -> encode_flags |= qpdf_sf_compress
1056   - // Return value is whether filtering was attempted.
  1131 + /*! \brief Legacy pipeStreamData. This maps to the the flags-based pipeStreamData as follows:
  1132 + * filter = false -> encode_flags = 0
  1133 + * filter = true -> decode_level = qpdf_dl_generalized
  1134 + * normalize = true -> encode_flags |= qpdf_sf_normalize
  1135 + * compress = true -> encode_flags |= qpdf_sf_compress
  1136 + * Return value is whether filtering was attempted.
  1137 + */
1057 1138 QPDF_DLL
1058 1139 bool pipeStreamData(Pipeline*, bool filter, bool normalize, bool compress);
1059 1140  
1060   - // Replace a stream's dictionary. The new dictionary must be consistent with the stream's data.
1061   - // This is most appropriately used when creating streams from scratch that will use a stream
1062   - // data provider and therefore start with an empty dictionary. It may be more convenient in
1063   - // this case than calling getDict and modifying it for each key. The pdf-create example does
1064   - // this.
  1141 + /*! \brief Replace a stream's dictionary. The new dictionary must be consistent with the stream's data.
  1142 + * This is most appropriately used when creating streams from scratch that will use a stream
  1143 + * data provider and therefore start with an empty dictionary. It may be more convenient in
  1144 + * this case than calling getDict and modifying it for each key. The pdf-create example does
  1145 + * this.
  1146 + */
1065 1147 QPDF_DLL
1066 1148 void replaceDict(QPDFObjectHandle const&);
1067 1149  
1068   - // Test whether a stream is the root XMP /Metadata object of its owning QPDF.
  1150 + /*! \brief Test whether a stream is the root XMP /Metadata object of its owning QPDF. */
1069 1151 QPDF_DLL
1070 1152 bool isRootMetadata() const;
1071 1153  
1072 1154 // REPLACING STREAM DATA
1073 1155  
1074   - // Note about all replaceStreamData methods: whatever values are passed as filter and
1075   - // decode_parms will overwrite /Filter and /DecodeParms in the stream. Passing a null object
1076   - // (QPDFObjectHandle::newNull()) will remove those values from the stream dictionary. From qpdf
1077   - // 11, passing an *uninitialized* QPDFObjectHandle (QPDFObjectHandle()) will leave any existing
1078   - // values untouched.
  1156 + /*! \note About all replaceStreamData methods: whatever values are passed as filter and
  1157 + * decode_parms will overwrite /Filter and /DecodeParms in the stream. Passing a null object
  1158 + * (QPDFObjectHandle::newNull()) will remove those values from the stream dictionary. From qpdf
  1159 + * 11, passing an *uninitialized* QPDFObjectHandle (QPDFObjectHandle()) will leave any existing
  1160 + * values untouched.
  1161 + */
1079 1162  
1080   - // Replace this stream's stream data with the given data buffer. The stream's /Length key is
1081   - // replaced with the length of the data buffer. The stream is interpreted as if the data read
1082   - // from the file, after any decryption filters have been applied, is as presented.
  1163 + /*! \brief Replace this stream's stream data with the given data buffer. The stream's /Length key is
  1164 + * replaced with the length of the data buffer. The stream is interpreted as if the data read
  1165 + * from the file, after any decryption filters have been applied, is as presented.
  1166 + */
1083 1167 QPDF_DLL
1084 1168 void replaceStreamData(
1085 1169 std::shared_ptr<Buffer> data,
1086 1170 QPDFObjectHandle const& filter,
1087 1171 QPDFObjectHandle const& decode_parms);
1088 1172  
1089   - // Replace the stream's stream data with the given string. This method will create a copy of the
1090   - // data rather than using the user-provided buffer as in the std::shared_ptr<Buffer> version of
1091   - // replaceStreamData.
  1173 + /*! \brief Replace the stream's stream data with the given string. This method will create a copy of the
  1174 + * data rather than using the user-provided buffer as in the std::shared_ptr<Buffer> version of
  1175 + * replaceStreamData.
  1176 + */
1092 1177 QPDF_DLL
1093 1178 void replaceStreamData(
1094 1179 std::string const& data,
1095 1180 QPDFObjectHandle const& filter,
1096 1181 QPDFObjectHandle const& decode_parms);
1097 1182  
1098   - // As above, replace this stream's stream data. Instead of directly providing a buffer with the
1099   - // stream data, call the given provider's provideStreamData method. See comments on the
1100   - // StreamDataProvider class (defined above) for details on the method. The data must be
1101   - // consistent with filter and decode_parms as provided. Although it is more complex to use this
1102   - // form of replaceStreamData than the one that takes a buffer, it makes it possible to avoid
1103   - // allocating memory for the stream data. Example programs are provided that use both forms of
1104   - // replaceStreamData.
1105   -
1106   - // Note about stream length: for any given stream, the provider must provide the same amount of
1107   - // data each time it is called. This is critical for making linearization work properly.
1108   - // Versions of qpdf before 3.0.0 required a length to be specified here. Starting with
1109   - // version 3.0.0, this is no longer necessary (or permitted). The first time the stream data
1110   - // provider is invoked for a given stream, the actual length is stored. Subsequent times, it is
1111   - // enforced that the length be the same as the first time.
1112   -
1113   - // If you have gotten a compile error here while building code that worked with older versions
1114   - // of qpdf, just omit the length parameter. You can also simplify your code by not having to
1115   - // compute the length in advance.
  1183 + /*! \brief As above, replace this stream's stream data. Instead of directly providing a buffer with the
  1184 + * stream data, call the given provider's provideStreamData method. See comments on the
  1185 + * StreamDataProvider class (defined above) for details on the method. The data must be
  1186 + * consistent with filter and decode_parms as provided. Although it is more complex to use this
  1187 + * form of replaceStreamData than the one that takes a buffer, it makes it possible to avoid
  1188 + * allocating memory for the stream data. Example programs are provided that use both forms of
  1189 + * replaceStreamData.
  1190 + *
  1191 + * Note about stream length: for any given stream, the provider must provide the same amount of
  1192 + * data each time it is called. This is critical for making linearization work properly.
  1193 + * Versions of qpdf before 3.0.0 required a length to be specified here. Starting with
  1194 + * version 3.0.0, this is no longer necessary (or permitted). The first time the stream data
  1195 + * provider is invoked for a given stream, the actual length is stored. Subsequent times, it is
  1196 + * enforced that the length be the same as the first time.
  1197 + *
  1198 + * If you have gotten a compile error here while building code that worked with older versions
  1199 + * of qpdf, just omit the length parameter. You can also simplify your code by not having to
  1200 + * compute the length in advance.
  1201 + */
1116 1202 QPDF_DLL
1117 1203 void replaceStreamData(
1118 1204 std::shared_ptr<StreamDataProvider> provider,
1119 1205 QPDFObjectHandle const& filter,
1120 1206 QPDFObjectHandle const& decode_parms);
1121 1207  
1122   - // Starting in qpdf 10.2, you can use C++-11 function objects instead of StreamDataProvider.
1123   -
1124   - // The provider should write the stream data to the pipeline. For a one-liner to replace stream
1125   - // data with the contents of a file, pass QUtil::file_provider(filename) as provider.
  1208 + /*! \brief Starting in qpdf 10.2, you can use C++-11 function objects instead of StreamDataProvider.
  1209 + * The provider should write the stream data to the pipeline. For a one-liner to replace stream
  1210 + * data with the contents of a file, pass QUtil::file_provider(filename) as provider.
  1211 + */
1126 1212 QPDF_DLL
1127 1213 void replaceStreamData(
1128 1214 std::function<void(Pipeline*)> provider,
1129 1215 QPDFObjectHandle const& filter,
1130 1216 QPDFObjectHandle const& decode_parms);
1131   - // The provider should write the stream data to the pipeline, returning true if it succeeded
1132   - // without errors.
  1217 +
  1218 + /*! \brief The provider should write the stream data to the pipeline, returning true if it succeeded
  1219 + * without errors.
  1220 + */
1133 1221 QPDF_DLL
1134 1222 void replaceStreamData(
1135 1223 std::function<bool(Pipeline*, bool suppress_warnings, bool will_retry)> provider,
1136 1224 QPDFObjectHandle const& filter,
1137 1225 QPDFObjectHandle const& decode_parms);
1138 1226  
1139   - // Access object ID and generation. For direct objects, return object ID 0.
1140   -
1141   - // NOTE: Be careful about calling getObjectID() and getGeneration() directly as this can lead to
1142   - // the pattern of depending on object ID or generation without the other. In general, when
1143   - // keeping track of object IDs, it's better to use QPDFObjGen instead.
  1227 + /*! \brief Access object ID and generation. For direct objects, return object ID 0.
  1228 + * \note: Be careful about calling getObjectID() and getGeneration() directly as this can lead to
  1229 + * the pattern of depending on object ID or generation without the other. In general, when
  1230 + * keeping track of object IDs, it's better to use QPDFObjGen instead.
  1231 + */
1144 1232  
1145 1233 QPDF_DLL
1146 1234 QPDFObjGen getObjGen() const;
... ... @@ -1153,73 +1241,77 @@ class QPDFObjectHandle: public qpdf::BaseHandle
1153 1241 std::string unparse() const;
1154 1242 QPDF_DLL
1155 1243 std::string unparseResolved() const;
1156   - // For strings only, force binary representation. Otherwise, same as unparse.
  1244 +
  1245 + /*! \brief For strings only, force binary representation. Otherwise, same as unparse. */
1157 1246 QPDF_DLL
1158 1247 std::string unparseBinary() const;
1159 1248  
1160   - // Return encoded as JSON. The constant JSON::LATEST can be used to specify the latest available
1161   - // JSON version. The JSON is generated as follows:
1162   - // * Arrays, dictionaries, booleans, nulls, integers, and real numbers are represented by their
1163   - // native JSON types.
1164   - // * Names are encoded as strings representing the canonical representation (after parsing #xx)
1165   - // and preceded by a slash, just as unparse() returns. For example, the JSON for the
1166   - // PDF-syntax name /Text#2fPlain would be "/Text/Plain".
1167   - // * Indirect references are encoded as strings containing "obj gen R"
1168   - // * Strings
1169   - // * JSON v1: Strings are encoded as UTF-8 strings with unrepresentable binary characters
1170   - // encoded as \uHHHH. Characters in PDF Doc encoding that don't have bidirectional unicode
1171   - // mappings are not reversible. There is no way to tell the difference between a string that
1172   - // looks like a name or indirect object from an actual name or indirect object.
1173   - // * JSON v2:
1174   - // * Unicode strings and strings encoded with PDF Doc encoding that can be bidirectionally
1175   - // mapped to Unicode (which is all strings without undefined characters) are represented
1176   - // as "u:" followed by the UTF-8 encoded string. Example:
1177   - // "u:potato".
1178   - // * All other strings are represented as "b:" followed by a hexadecimal encoding of the
1179   - // string. Example: "b:0102cacb"
1180   - // * Streams
1181   - // * JSON v1: Only the stream's dictionary is encoded. There is no way to tell a stream from a
1182   - // dictionary other than context.
1183   - // * JSON v2: A stream is encoded as {"dict": {...}} with the value being the encoding of the
1184   - // stream's dictionary. Since "dict" does not otherwise represent anything, this is
1185   - // unambiguous. The getStreamJSON() call can be used to add encoding of the stream's data.
1186   - // * Object types that are only valid in content streams (inline image, operator) are serialized
1187   - // as "null". Attempting to serialize a "reserved" object is an error.
1188   - // If dereference_indirect is true and this is an indirect object, show the actual contents of
1189   - // the object. The effect of dereference_indirect applies only to this object. It is not
1190   - // recursive.
  1249 + /*! \brief Return encoded as JSON. The constant JSON::LATEST can be used to specify the latest available
  1250 + * JSON version. The JSON is generated as follows:
  1251 + * * Arrays, dictionaries, booleans, nulls, integers, and real numbers are represented by their
  1252 + * native JSON types.
  1253 + * * Names are encoded as strings representing the canonical representation (after parsing #xx)
  1254 + * and preceded by a slash, just as unparse() returns. For example, the JSON for the
  1255 + * PDF-syntax name /Text#2fPlain would be "/Text/Plain".
  1256 + * * Indirect references are encoded as strings containing "obj gen R"
  1257 + * * Strings
  1258 + * * JSON v1: Strings are encoded as UTF-8 strings with unrepresentable binary characters
  1259 + * encoded as \uHHHH. Characters in PDF Doc encoding that don't have bidirectional unicode
  1260 + * mappings are not reversible. There is no way to tell the difference between a string that
  1261 + * looks like a name or indirect object from an actual name or indirect object.
  1262 + * * JSON v2:
  1263 + * * Unicode strings and strings encoded with PDF Doc encoding that can be bidirectionally
  1264 + * mapped to Unicode (which is all strings without undefined characters) are represented
  1265 + * as "u:" followed by the UTF-8 encoded string. Example:
  1266 + * "u:potato".
  1267 + * * All other strings are represented as "b:" followed by a hexadecimal encoding of the
  1268 + * string. Example: "b:0102cacb"
  1269 + * * Streams
  1270 + * * JSON v1: Only the stream's dictionary is encoded. There is no way to tell a stream from a
  1271 + * dictionary other than context.
  1272 + * * JSON v2: A stream is encoded as {"dict": {...}} with the value being the encoding of the
  1273 + * stream's dictionary. Since "dict" does not otherwise represent anything, this is
  1274 + * unambiguous. The getStreamJSON() call can be used to add encoding of the stream's data.
  1275 + * * Object types that are only valid in content streams (inline image, operator) are serialized
  1276 + * as "null". Attempting to serialize a "reserved" object is an error.
  1277 + * If dereference_indirect is true and this is an indirect object, show the actual contents of
  1278 + * the object. The effect of dereference_indirect applies only to this object. It is not
  1279 + * recursive.
  1280 + */
1191 1281 QPDF_DLL
1192 1282 JSON getJSON(int json_version, bool dereference_indirect = false) const;
1193 1283  
1194   - // Write the object encoded as JSON to a pipeline. This is equivalent to, but more efficient
1195   - // than, calling getJSON(json_version, dereference_indirect).write(p, depth). See the
1196   - // documentation for getJSON and JSON::write for further detail.
  1284 + /*! \brief Write the object encoded as JSON to a pipeline. This is equivalent to, but more efficient
  1285 + * than, calling getJSON(json_version, dereference_indirect).write(p, depth). See the
  1286 + * documentation for getJSON and JSON::write for further detail.
  1287 + */
1197 1288 QPDF_DLL
1198 1289 void writeJSON(
1199 1290 int json_version, Pipeline* p, bool dereference_indirect = false, size_t depth = 0) const;
1200 1291  
1201   - // This method can be called on a stream to get a more extended JSON representation of the
1202   - // stream that includes the stream's data. The JSON object returned is always a dictionary whose
1203   - // "dict" key is an encoding of the stream's dictionary. The representation of the data is
1204   - // determined by the json_data field.
1205   - //
1206   - // The json_data field may have the value qpdf_sj_none, qpdf_sj_inline, or qpdf_sj_file.
1207   - //
1208   - // If json_data is qpdf_sj_none, stream data is not represented.
1209   - //
1210   - // If json_data is qpdf_sj_inline or qpdf_sj_file, then stream data is filtered or not based on
1211   - // the value of decode_level, which has the same meaning as with pipeStreamData.
1212   - //
1213   - // If json_data is qpdf_sj_inline, the base64-encoded stream data is included in the "data"
1214   - // field of the dictionary that is returned.
1215   - //
1216   - // If json_data is qpdf_sj_file, then the Pipeline ("p") and data_filename argument must be
1217   - // supplied. The value of data_filename is stored in the resulting json in the "datafile" key
1218   - // but is not otherwise use. The stream data itself (raw or filtered depending on decode level),
1219   - // is written to the pipeline via pipeStreamData().
1220   - //
1221   - // NOTE: When json_data is qpdf_sj_inline, the QPDF object from which the stream originates must
1222   - // remain valid until after the JSON object is written.
  1292 + /*! \brief This method can be called on a stream to get a more extended JSON representation of the
  1293 + * stream that includes the stream's data. The JSON object returned is always a dictionary whose
  1294 + * "dict" key is an encoding of the stream's dictionary. The representation of the data is
  1295 + * determined by the json_data field.
  1296 + *
  1297 + * The json_data field may have the value qpdf_sj_none, qpdf_sj_inline, or qpdf_sj_file.
  1298 + *
  1299 + * If json_data is qpdf_sj_none, stream data is not represented.
  1300 + *
  1301 + * If json_data is qpdf_sj_inline or qpdf_sj_file, then stream data is filtered or not based on
  1302 + * the value of decode_level, which has the same meaning as with pipeStreamData.
  1303 + *
  1304 + * If json_data is qpdf_sj_inline, the base64-encoded stream data is included in the "data"
  1305 + * field of the dictionary that is returned.
  1306 + *
  1307 + * If json_data is qpdf_sj_file, then the Pipeline ("p") and data_filename argument must be
  1308 + * supplied. The value of data_filename is stored in the resulting json in the "datafile" key
  1309 + * but is not otherwise use. The stream data itself (raw or filtered depending on decode level),
  1310 + * is written to the pipeline via pipeStreamData().
  1311 + *
  1312 + * \note : When json_data is qpdf_sj_inline, the QPDF object from which the stream originates must
  1313 + * remain valid until after the JSON object is written.
  1314 + */
1223 1315 QPDF_DLL
1224 1316 JSON getStreamJSON(
1225 1317 int json_version,
... ... @@ -1228,9 +1320,10 @@ class QPDFObjectHandle: public qpdf::BaseHandle
1228 1320 Pipeline* p,
1229 1321 std::string const& data_filename);
1230 1322  
1231   - // Legacy helper methods for commonly performed operations on pages. Newer code should use
1232   - // QPDFPageObjectHelper instead. The specification and behavior of these methods are the same as
1233   - // the identically named methods in that class, but newer functionality will be added there.
  1323 + /*! \brief Legacy helper methods for commonly performed operations on pages. Newer code should use
  1324 + * QPDFPageObjectHelper instead. The specification and behavior of these methods are the same as
  1325 + * the identically named methods in that class, but newer functionality will be added there.
  1326 + */
1234 1327 QPDF_DLL
1235 1328 std::map<std::string, QPDFObjectHandle> getPageImages();
1236 1329 QPDF_DLL
... ... @@ -1257,58 +1350,40 @@ class QPDFObjectHandle: public qpdf::BaseHandle
1257 1350 QPDF_DLL
1258 1351 void assertInitialized() const;
1259 1352  
1260   - QPDF_DLL
1261   - void assertNull() const;
1262   - QPDF_DLL
1263   - void assertBool() const;
1264   - QPDF_DLL
1265   - void assertInteger() const;
1266   - QPDF_DLL
1267   - void assertReal() const;
1268   - QPDF_DLL
1269   - void assertName() const;
1270   - QPDF_DLL
1271   - void assertString() const;
1272   - QPDF_DLL
1273   - void assertOperator() const;
1274   - QPDF_DLL
1275   - void assertInlineImage() const;
1276   - QPDF_DLL
1277   - void assertArray() const;
1278   - QPDF_DLL
1279   - void assertDictionary() const;
1280   - QPDF_DLL
1281   - void assertStream() const;
1282   - QPDF_DLL
1283   - void assertReserved() const;
1284   -
1285   - QPDF_DLL
1286   - void assertIndirect() const;
1287   - QPDF_DLL
1288   - void assertScalar() const;
1289   - QPDF_DLL
1290   - void assertNumber() const;
1291   -
1292   - // The isPageObject method checks the /Type key of the object. This is not completely reliable
1293   - // as there are some otherwise valid files whose /Type is wrong for page objects. qpdf is
1294   - // slightly more accepting but may still return false here when treating the object as a page
1295   - // would work. Use this sparingly.
1296   - QPDF_DLL
1297   - bool isPageObject() const;
1298   - QPDF_DLL
1299   - bool isPagesObject() const;
1300   - QPDF_DLL
1301   - void assertPageObject() const;
1302   -
1303   - QPDF_DLL
1304   - bool isFormXObject() const;
1305   -
1306   - // Indicate if this is an image. If exclude_imagemask is true, don't count image masks as
1307   - // images.
1308   - QPDF_DLL
1309   - bool isImage(bool exclude_imagemask = true) const;
1310   -
1311   - // The following methods do not form part of the public API and are for internal use only.
  1353 + QPDF_DLL void assertNull() const;
  1354 + QPDF_DLL void assertBool() const;
  1355 + QPDF_DLL void assertInteger() const;
  1356 + QPDF_DLL void assertReal() const;
  1357 + QPDF_DLL void assertName() const;
  1358 + QPDF_DLL void assertString() const;
  1359 + QPDF_DLL void assertOperator() const;
  1360 + QPDF_DLL void assertInlineImage() const;
  1361 + QPDF_DLL void assertArray() const;
  1362 + QPDF_DLL void assertDictionary() const;
  1363 + QPDF_DLL void assertStream() const;
  1364 + QPDF_DLL void assertReserved() const;
  1365 +
  1366 + QPDF_DLL void assertIndirect() const;
  1367 + QPDF_DLL void assertScalar() const;
  1368 + QPDF_DLL void assertNumber() const;
  1369 +
  1370 + /*! \brief The isPageObject method checks the /Type key of the object. This is not completely reliable
  1371 + * as there are some otherwise valid files whose /Type is wrong for page objects. qpdf is
  1372 + * slightly more accepting but may still return false here when treating the object as a page
  1373 + * would work. Use this sparingly.
  1374 + */
  1375 + QPDF_DLL bool isPageObject() const;
  1376 + QPDF_DLL bool isPagesObject() const;
  1377 + QPDF_DLL void assertPageObject() const;
  1378 +
  1379 + QPDF_DLL bool isFormXObject() const;
  1380 +
  1381 + /*! \brief Indicate if this is an image. If exclude_imagemask is true, don't count image masks as
  1382 + * images.
  1383 + */
  1384 + QPDF_DLL bool isImage(bool exclude_imagemask = true) const;
  1385 +
  1386 + /*! \brief The following methods do not form part of the public API and are for internal use only. */
1312 1387  
1313 1388 QPDFObjectHandle(std::shared_ptr<QPDFObject> const& obj) :
1314 1389 qpdf::BaseHandle(obj)
... ... @@ -1348,17 +1423,18 @@ class QPDFObjectHandle: public qpdf::BaseHandle
1348 1423 };
1349 1424  
1350 1425 #ifndef QPDF_NO_QPDF_STRING
1351   -// This is short for QPDFObjectHandle::parse, so you can do
1352   -
1353   -// auto oh = "<< /Key (value) >>"_qpdf;
1354   -
1355   -// If this is causing problems in your code, define QPDF_NO_QPDF_STRING to prevent the declaration
1356   -// from being here.
1357   -
1358   -/* clang-format off */
1359   - // Disable formatting for this declaration: emacs font-lock in cc-mode (as of 28.1) treats the rest
1360   - // of the file as a string if clang-format removes the space after "operator", and as of
1361   - // clang-format 15, there's no way to prevent it from doing so.
  1426 +/*! \brief This is short for QPDFObjectHandle::parse, so you can do
  1427 + *
  1428 + * auto oh = "<< /Key (value) >>"_qpdf;
  1429 + *
  1430 + * If this is causing problems in your code, define QPDF_NO_QPDF_STRING to prevent the declaration
  1431 + * from being here.
  1432 + *
  1433 + * clang-format off
  1434 + * Disable formatting for this declaration: emacs font-lock in cc-mode (as of 28.1) treats the rest
  1435 + * of the file as a string if clang-format removes the space after "operator", and as of
  1436 + * clang-format 15, there's no way to prevent it from doing so.
  1437 + */
1362 1438 QPDF_DLL
1363 1439 QPDFObjectHandle operator ""_qpdf(char const* v, size_t len);
1364 1440 /* clang-format on */
... ... @@ -1367,16 +1443,17 @@ class QPDFObjectHandle: public qpdf::BaseHandle
1367 1443  
1368 1444 class QPDFObjectHandle::QPDFDictItems
1369 1445 {
1370   - // This class allows C++-style iteration, including range-for iteration, around dictionaries.
1371   - // You can write
1372   -
1373   - // for (auto iter: QPDFDictItems(dictionary_obj))
1374   - // {
1375   - // // iter.first is a string
1376   - // // iter.second is a QPDFObjectHandle
1377   - // }
1378   -
1379   - // See examples/pdf-name-number-tree.cc for a demonstration of using this API.
  1446 + /*! \brief This class allows C++-style iteration, including range-for iteration, around dictionaries.
  1447 + * You can write
  1448 + *
  1449 + * for (auto iter: QPDFDictItems(dictionary_obj))
  1450 + * {
  1451 + * // iter.first is a string
  1452 + * // iter.second is a QPDFObjectHandle
  1453 + * }
  1454 + *
  1455 + * See examples/pdf-name-number-tree.cc for a demonstration of using this API.
  1456 + */
1380 1457  
1381 1458 public:
1382 1459 QPDF_DLL
... ... @@ -1459,17 +1536,20 @@ class QPDFObjectHandle::QPDFDictItems
1459 1536 QPDFObjectHandle oh;
1460 1537 };
1461 1538  
  1539 +/*!
  1540 + * \class QPDFArrayItems
  1541 + * \brief This class allows C++-style iteration, including range-for iteration, around arrays. You can
  1542 + * write
  1543 + *
  1544 + * for (auto iter: QPDFArrayItems(array_obj))
  1545 + * {
  1546 + * // iter is a QPDFObjectHandle
  1547 + * }
  1548 + *
  1549 + * See examples/pdf-name-number-tree.cc for a demonstration of using this API.
  1550 + */
1462 1551 class QPDFObjectHandle::QPDFArrayItems
1463 1552 {
1464   - // This class allows C++-style iteration, including range-for iteration, around arrays. You can
1465   - // write
1466   -
1467   - // for (auto iter: QPDFArrayItems(array_obj))
1468   - // {
1469   - // // iter is a QPDFObjectHandle
1470   - // }
1471   -
1472   - // See examples/pdf-name-number-tree.cc for a demonstration of using this API.
1473 1553  
1474 1554 public:
1475 1555 QPDF_DLL
... ...
include/qpdf/QPDFObjectHelper.hh
... ... @@ -24,13 +24,14 @@
24 24  
25 25 #include <qpdf/QPDFObjectHandle.hh>
26 26  
27   -// This is a base class for QPDF Object Helper classes. Object helpers are classes that provide a
28   -// convenient, higher-level API for working with specific types of QPDF objects. Object helpers are
29   -// always initialized with a QPDFObjectHandle, and the underlying object handle can always be
30   -// retrieved. The intention is that you may freely intermix use of object helpers with the
31   -// underlying QPDF objects unless there is a specific comment in a specific helper method that says
32   -// otherwise. The pattern of using helper objects was introduced to allow creation of higher level
33   -// helper functions without polluting the public interface of QPDFObjectHandle.
  27 +/*! \brief This is a base class for QPDF Object Helper classes. Object helpers are classes that provide a
  28 + * convenient, higher-level API for working with specific types of QPDF objects. Object helpers are
  29 + * always initialized with a QPDFObjectHandle, and the underlying object handle can always be
  30 + * retrieved. The intention is that you may freely intermix use of object helpers with the
  31 + * underlying QPDF objects unless there is a specific comment in a specific helper method that says
  32 + * otherwise. The pattern of using helper objects was introduced to allow creation of higher level
  33 + * helper functions without polluting the public interface of QPDFObjectHandle.
  34 + */
34 35 class QPDF_DLL_CLASS QPDFObjectHelper: public qpdf::BaseHandle
35 36 {
36 37 public:
... ...
include/qpdf/QPDFWriter.hh
... ... @@ -50,25 +50,29 @@ namespace qpdf
50 50  
51 51 class QPDF;
52 52  
53   -// This class implements a simple writer for saving QPDF objects to new PDF files. See comments
54   -// through the header file for additional details.
  53 +/*! \brief This class implements a simple writer for saving QPDF objects to new PDF files. See comments
  54 + * through the header file for additional details.
  55 + */
55 56 class QPDFWriter
56 57 {
57 58 public:
58   - // Construct a QPDFWriter object without specifying output. You must call one of the output
59   - // setting routines defined below.
  59 + /*! \brief Construct a QPDFWriter object without specifying output. You must call one of the output
  60 + * setting routines defined below.
  61 + */
60 62 QPDF_DLL
61 63 QPDFWriter(QPDF& pdf);
62 64  
63   - // Create a QPDFWriter object that writes its output to a file or to stdout. This is equivalent
64   - // to using the previous constructor and then calling setOutputFilename(). See
65   - // setOutputFilename() for details.
  65 + /*! \brief Create a QPDFWriter object that writes its output to a file or to stdout. This is equivalent
  66 + * to using the previous constructor and then calling setOutputFilename(). See
  67 + * setOutputFilename() for details.
  68 + */
66 69 QPDF_DLL
67 70 QPDFWriter(QPDF& pdf, char const* filename);
68 71  
69   - // Create a QPDFWriter object that writes its output to an already open FILE*. This is
70   - // equivalent to calling the first constructor and then calling setOutputFile(). See
71   - // setOutputFile() for details.
  72 + /*! \brief Create a QPDFWriter object that writes its output to an already open FILE*. This is
  73 + * equivalent to calling the first constructor and then calling setOutputFile(). See
  74 + * setOutputFile() for details.
  75 + */
72 76 QPDF_DLL
73 77 QPDFWriter(QPDF& pdf, char const* description, FILE* file, bool close_file);
74 78  
... ... @@ -80,13 +84,15 @@ class QPDFWriter
80 84 QPDF_DLL
81 85 virtual ~ProgressReporter();
82 86  
83   - // This method is called with a value from 0 to 100 to indicate approximate progress through
84   - // the write process. See registerProgressReporter.
  87 + /*! \brief This method is called with a value from 0 to 100 to indicate approximate progress through
  88 + * the write process. See registerProgressReporter.
  89 + */
85 90 virtual void reportProgress(int) = 0;
86 91 };
87 92  
88   - // This is a progress reporter that takes a function. It is used by the C APIs, but it is
89   - // available if you want to just register a C function as a handler.
  93 + /*! \brief This is a progress reporter that takes a function. It is used by the C APIs, but it is
  94 + * available if you want to just register a C function as a handler.
  95 + */
90 96 class QPDF_DLL_CLASS FunctionProgressReporter: public ProgressReporter
91 97 {
92 98 public:
... ... @@ -101,230 +107,253 @@ class QPDFWriter
101 107 std::function<void(int)> handler;
102 108 };
103 109  
104   - // Setting Output. Output may be set only one time. If you don't use the filename version of
105   - // the QPDFWriter constructor, you must call exactly one of these methods.
106   -
107   - // Passing nullptr as filename means write to stdout. QPDFWriter will create a zero-length
108   - // output file upon construction. If write fails, the empty or partially written file will not
109   - // be deleted. This is by design: sometimes the partial file may be useful for tracking down
110   - // problems. If your application doesn't want the partially written file to be left behind, you
111   - // should delete it if the eventual call to write fails.
  110 + /*! \brief Setting Output. Output may be set only one time. If you don't use the filename version of
  111 + * the QPDFWriter constructor, you must call exactly one of these methods.
  112 + *
  113 + * Passing nullptr as filename means write to stdout. QPDFWriter will create a zero-length
  114 + * output file upon construction. If write fails, the empty or partially written file will not
  115 + * be deleted. This is by design: sometimes the partial file may be useful for tracking down
  116 + * problems. If your application doesn't want the partially written file to be left behind, you
  117 + * should delete it if the eventual call to write fails.
  118 + */
112 119 QPDF_DLL
113 120 void setOutputFilename(char const* filename);
114 121  
115   - // Write to the given FILE*, which must be opened by the caller. If close_file is true,
116   - // QPDFWriter will close the file. Otherwise, the caller must close the file. The file does not
117   - // need to be seekable; it will be written to in a single pass. It must be open in binary mode.
  122 + /*! \brief Write to the given FILE*, which must be opened by the caller. If close_file is true,
  123 + * QPDFWriter will close the file. Otherwise, the caller must close the file. The file does not
  124 + * need to be seekable; it will be written to in a single pass. It must be open in binary mode.
  125 + */
118 126 QPDF_DLL
119 127 void setOutputFile(char const* description, FILE* file, bool close_file);
120 128  
121   - // Indicate that QPDFWriter should create a memory buffer to contain the final PDF file. Obtain
122   - // the memory by calling getBuffer().
  129 + /*! \brief Indicate that QPDFWriter should create a memory buffer to contain the final PDF file. Obtain
  130 + * the memory by calling getBuffer().
  131 + */
123 132 QPDF_DLL
124 133 void setOutputMemory();
125 134  
126   - // Return the buffer object containing the PDF file. If setOutputMemory() has been called, this
127   - // method may be called exactly one time after write() has returned. The caller is responsible
128   - // for deleting the buffer when done. See also getBufferSharedPointer().
  135 + /*! \brief Return the buffer object containing the PDF file. If setOutputMemory() has been called, this
  136 + * method may be called exactly one time after write() has returned. The caller is responsible
  137 + * for deleting the buffer when done. See also getBufferSharedPointer().
  138 + */
129 139 QPDF_DLL
130 140 Buffer* getBuffer();
131 141  
132   - // Return getBuffer() in a shared pointer.
  142 + /*! \brief Return getBuffer() in a shared pointer. */
133 143 QPDF_DLL
134 144 std::shared_ptr<Buffer> getBufferSharedPointer();
135 145  
136   - // Supply your own pipeline object. Output will be written to this pipeline, and QPDFWriter
137   - // will call finish() on the pipeline. It is the caller's responsibility to manage the memory
138   - // for the pipeline. The pipeline is never deleted by QPDFWriter, which makes it possible for
139   - // you to call additional methods on the pipeline after the writing is finished.
  146 + /*! \brief Supply your own pipeline object. Output will be written to this pipeline, and QPDFWriter
  147 + * will call finish() on the pipeline. It is the caller's responsibility to manage the memory
  148 + * for the pipeline. The pipeline is never deleted by QPDFWriter, which makes it possible for
  149 + * you to call additional methods on the pipeline after the writing is finished.
  150 + */
140 151 QPDF_DLL
141 152 void setOutputPipeline(Pipeline*);
142 153  
143 154 // Setting Parameters
144 155  
145   - // Set the value of object stream mode. In disable mode, we never generate any object streams.
146   - // In preserve mode, we preserve object stream structure from the original file. In generate
147   - // mode, we generate our own object streams. In all cases, we generate a conventional
148   - // cross-reference table if there are no object streams and a cross-reference stream if there
149   - // are object streams. The default is o_preserve.
  156 + /*! \brief Set the value of object stream mode. In disable mode, we never generate any object streams.
  157 + * In preserve mode, we preserve object stream structure from the original file. In generate
  158 + * mode, we generate our own object streams. In all cases, we generate a conventional
  159 + * cross-reference table if there are no object streams and a cross-reference stream if there
  160 + * are object streams. The default is o_preserve.
  161 + */
150 162 QPDF_DLL
151 163 void setObjectStreamMode(qpdf_object_stream_e);
152 164  
153   - // Set value of stream data mode. This is an older interface. Instead of using this, prefer
154   - // setCompressStreams() and setDecodeLevel(). This method is retained for compatibility, but it
155   - // does not cover the full range of available configurations. The mapping between this and the
156   - // new methods is as follows:
157   - //
158   - // qpdf_s_uncompress:
159   - // setCompressStreams(false)
160   - // setDecodeLevel(qpdf_dl_generalized)
161   - // qpdf_s_preserve:
162   - // setCompressStreams(false)
163   - // setDecodeLevel(qpdf_dl_none)
164   - // qpdf_s_compress:
165   - // setCompressStreams(true)
166   - // setDecodeLevel(qpdf_dl_generalized)
167   - //
168   - // The default is qpdf_s_compress.
  165 + /*! \brief Set value of stream data mode. This is an older interface. Instead of using this, prefer
  166 + * setCompressStreams() and setDecodeLevel(). This method is retained for compatibility, but it
  167 + * does not cover the full range of available configurations. The mapping between this and the
  168 + * new methods is as follows:
  169 + *
  170 + * qpdf_s_uncompress:
  171 + * setCompressStreams(false)
  172 + * setDecodeLevel(qpdf_dl_generalized)
  173 + * qpdf_s_preserve:
  174 + * setCompressStreams(false)
  175 + * setDecodeLevel(qpdf_dl_none)
  176 + * qpdf_s_compress:
  177 + * setCompressStreams(true)
  178 + * setDecodeLevel(qpdf_dl_generalized)
  179 + *
  180 + * The default is qpdf_s_compress.
  181 + */
169 182 QPDF_DLL
170 183 void setStreamDataMode(qpdf_stream_data_e);
171 184  
172   - // If true, compress any uncompressed streams when writing them. Metadata streams are a special
173   - // case and are not compressed even if this is true. This is true by default for QPDFWriter. If
174   - // you want QPDFWriter to leave uncompressed streams uncompressed, pass false to this method.
  185 + /*! \brief If true, compress any uncompressed streams when writing them. Metadata streams are a special
  186 + * case and are not compressed even if this is true. This is true by default for QPDFWriter. If
  187 + * you want QPDFWriter to leave uncompressed streams uncompressed, pass false to this method.
  188 + */
175 189 QPDF_DLL
176 190 void setCompressStreams(bool);
177 191  
178   - // When QPDFWriter encounters streams, this parameter controls the behavior with respect to
179   - // attempting to apply any filters to the streams when copying to the output. The decode levels
180   - // are as follows:
181   - //
182   - // qpdf_dl_none: Do not attempt to apply any filters. Streams remain as they appear in the
183   - // original file. Note that uncompressed streams may still be compressed on output. You can
184   - // disable that by calling setCompressStreams(false).
185   - //
186   - // qpdf_dl_generalized: This is the default. QPDFWriter will apply LZWDecode, ASCII85Decode,
187   - // ASCIIHexDecode, and FlateDecode filters on the input. When combined with
188   - // setCompressStreams(true), which is the default, the effect of this is that streams filtered
189   - // with these older and less efficient filters will be recompressed with the Flate filter. By
190   - // default, as a special case, if a stream is already compressed with FlateDecode and
191   - // setCompressStreams is enabled, the original compressed data will be preserved. This behavior
192   - // can be overridden by calling setRecompressFlate(true).
193   - //
194   - // qpdf_dl_specialized: In addition to uncompressing the generalized compression formats,
195   - // supported non-lossy compression will also be decoded. At present, this includes the
196   - // RunLengthDecode filter.
197   - //
198   - // qpdf_dl_all: In addition to generalized and non-lossy specialized filters, supported lossy
199   - // compression filters will be applied. At present, this includes DCTDecode (JPEG) compression.
200   - // Note that compressing the resulting data with DCTDecode again will accumulate loss, so avoid
201   - // multiple compression and decompression cycles. This is mostly useful for retrieving image
202   - // data.
  192 + /*! \brief When QPDFWriter encounters streams, this parameter controls the behavior with respect to
  193 + * attempting to apply any filters to the streams when copying to the output. The decode levels
  194 + * are as follows:
  195 + *
  196 + * qpdf_dl_none: Do not attempt to apply any filters. Streams remain as they appear in the
  197 + * original file. Note that uncompressed streams may still be compressed on output. You can
  198 + * disable that by calling setCompressStreams(false).
  199 + *
  200 + * qpdf_dl_generalized: This is the default. QPDFWriter will apply LZWDecode, ASCII85Decode,
  201 + * ASCIIHexDecode, and FlateDecode filters on the input. When combined with
  202 + * setCompressStreams(true), which is the default, the effect of this is that streams filtered
  203 + * with these older and less efficient filters will be recompressed with the Flate filter. By
  204 + * default, as a special case, if a stream is already compressed with FlateDecode and
  205 + * setCompressStreams is enabled, the original compressed data will be preserved. This behavior
  206 + * can be overridden by calling setRecompressFlate(true).
  207 + *
  208 + * qpdf_dl_specialized: In addition to uncompressing the generalized compression formats,
  209 + * supported non-lossy compression will also be decoded. At present, this includes the
  210 + * RunLengthDecode filter.
  211 + *
  212 + * qpdf_dl_all: In addition to generalized and non-lossy specialized filters, supported lossy
  213 + * compression filters will be applied. At present, this includes DCTDecode (JPEG) compression.
  214 + * Note that compressing the resulting data with DCTDecode again will accumulate loss, so avoid
  215 + * multiple compression and decompression cycles. This is mostly useful for retrieving image
  216 + * data.
  217 + */
203 218 QPDF_DLL
204 219 void setDecodeLevel(qpdf_stream_decode_level_e);
205 220  
206   - // By default, when both the input and output contents of a stream are compressed with Flate,
207   - // qpdf does not uncompress and recompress the stream. Passing true here causes it to do so.
208   - // This can be useful if recompressing all streams with a higher compression level, which can be
209   - // set by calling the static method Pl_Flate::setCompressionLevel.
  221 + /*! \brief By default, when both the input and output contents of a stream are compressed with Flate,
  222 + * qpdf does not uncompress and recompress the stream. Passing true here causes it to do so.
  223 + * This can be useful if recompressing all streams with a higher compression level, which can be
  224 + * set by calling the static method Pl_Flate::setCompressionLevel.
  225 + */
210 226 QPDF_DLL
211 227 void setRecompressFlate(bool);
212 228  
213   - // Set value of content stream normalization. The default is "false". If true, we attempt to
214   - // normalize newlines inside of content streams. Some constructs such as inline images may
215   - // thwart our efforts. There may be some cases where this can damage the content stream. This
216   - // flag should be used only for debugging and experimenting with PDF content streams. Never use
217   - // it for production files.
  229 + /*! \brief Set value of content stream normalization. The default is "false". If true, we attempt to
  230 + * normalize newlines inside of content streams. Some constructs such as inline images may
  231 + * thwart our efforts. There may be some cases where this can damage the content stream. This
  232 + * flag should be used only for debugging and experimenting with PDF content streams. Never use
  233 + * it for production files.
  234 + */
218 235 QPDF_DLL
219 236 void setContentNormalization(bool);
220 237  
221   - // Set QDF mode. QDF mode causes special "pretty printing" of PDF objects, adds comments for
222   - // easier perusing of files. Resulting PDF files can be edited in a text editor and then run
223   - // through fix-qdf to update cross reference tables and stream lengths.
  238 + /*! \brief Set QDF mode. QDF mode causes special "pretty printing" of PDF objects, adds comments for
  239 + * easier perusing of files. Resulting PDF files can be edited in a text editor and then run
  240 + * through fix-qdf to update cross reference tables and stream lengths.
  241 + */
224 242 QPDF_DLL
225 243 void setQDFMode(bool);
226 244  
227   - // Preserve unreferenced objects. The default behavior is to discard any object that is not
228   - // visited during a traversal of the object structure from the trailer.
  245 + /*! \brief Preserve unreferenced objects. The default behavior is to discard any object that is not
  246 + * visited during a traversal of the object structure from the trailer.
229 247 QPDF_DLL
230 248 void setPreserveUnreferencedObjects(bool);
231 249  
232   - // Always write a newline before the endstream keyword. This helps with PDF/A compliance, though
233   - // it is not sufficient for it.
  250 + /*! \brief Always write a newline before the endstream keyword. This helps with PDF/A compliance, though
  251 + * it is not sufficient for it.
  252 + */
234 253 QPDF_DLL
235 254 void setNewlineBeforeEndstream(bool);
236 255  
237   - // Set the minimum PDF version. If the PDF version of the input file (or previously set minimum
238   - // version) is less than the version passed to this method, the PDF version of the output file
239   - // will be set to this value. If the original PDF file's version or previously set minimum
240   - // version is already this version or later, the original file's version will be used.
241   - // QPDFWriter automatically sets the minimum version to 1.4 when R3 encryption parameters are
242   - // used, and to 1.5 when object streams are used.
  256 + /*! \brief Set the minimum PDF version. If the PDF version of the input file (or previously set minimum
  257 + * version) is less than the version passed to this method, the PDF version of the output file
  258 + * will be set to this value. If the original PDF file's version or previously set minimum
  259 + * version is already this version or later, the original file's version will be used.
  260 + * QPDFWriter automatically sets the minimum version to 1.4 when R3 encryption parameters are
  261 + * used, and to 1.5 when object streams are used.
  262 + */
243 263 QPDF_DLL
244 264 void setMinimumPDFVersion(std::string const&, int extension_level = 0);
245 265 QPDF_DLL
246 266 void setMinimumPDFVersion(PDFVersion const&);
247 267  
248   - // Force the PDF version of the output file to be a given version. Use of this function may
249   - // create PDF files that will not work properly with older PDF viewers. When a PDF version is
250   - // set using this function, qpdf will use this version even if the file contains features that
251   - // are not supported in that version of PDF. In other words, you should only use this function
252   - // if you are sure the PDF file in question has no features of newer versions of PDF or if you
253   - // are willing to create files that old viewers may try to open but not be able to properly
254   - // interpret. If any encryption has been applied to the document either explicitly or by
255   - // preserving the encryption of the source document, forcing the PDF version to a value too low
256   - // to support that type of encryption will explicitly disable decryption. Additionally, forcing
257   - // to a version below 1.5 will disable object streams.
  268 + /*! \brief Force the PDF version of the output file to be a given version. Use of this function may
  269 + * create PDF files that will not work properly with older PDF viewers. When a PDF version is
  270 + * set using this function, qpdf will use this version even if the file contains features that
  271 + * are not supported in that version of PDF. In other words, you should only use this function
  272 + * if you are sure the PDF file in question has no features of newer versions of PDF or if you
  273 + * are willing to create files that old viewers may try to open but not be able to properly
  274 + * interpret. If any encryption has been applied to the document either explicitly or by
  275 + * preserving the encryption of the source document, forcing the PDF version to a value too low
  276 + * to support that type of encryption will explicitly disable decryption. Additionally, forcing
  277 + * to a version below 1.5 will disable object streams.
  278 + */
258 279 QPDF_DLL
259 280 void forcePDFVersion(std::string const&, int extension_level = 0);
260 281  
261   - // Provide additional text to insert in the PDF file somewhere near the beginning of the file.
262   - // This can be used to add comments to the beginning of a PDF file, for example, if those
263   - // comments are to be consumed by some other application. No checks are performed to ensure
264   - // that the text inserted here is valid PDF. If you want to insert multiline comments, you will
265   - // need to include \n in the string yourself and start each line with %. An extra newline will
266   - // be appended if one is not already present at the end of your text.
  282 + /*! \brief Provide additional text to insert in the PDF file somewhere near the beginning of the file.
  283 + * This can be used to add comments to the beginning of a PDF file, for example, if those
  284 + * comments are to be consumed by some other application. No checks are performed to ensure
  285 + * that the text inserted here is valid PDF. If you want to insert multiline comments, you will
  286 + * need to include \n in the string yourself and start each line with %. An extra newline will
  287 + * be appended if one is not already present at the end of your text.
  288 + */
267 289 QPDF_DLL
268 290 void setExtraHeaderText(std::string const&);
269 291  
270   - // Causes a deterministic /ID value to be generated. When this is set, the current time and
271   - // output file name are not used as part of /ID generation. Instead, a digest of all significant
272   - // parts of the output file's contents is included in the /ID calculation. Use of a
273   - // deterministic /ID can be handy when it is desirable for a repeat of the same qpdf operation
274   - // on the same inputs being written to the same outputs with the same parameters to generate
275   - // exactly the same results. This feature is incompatible with encrypted files because, for
276   - // encrypted files, the /ID is generated before any part of the file is written since it is an
277   - // input to the encryption process.
  292 + /*! \brief Causes a deterministic /ID value to be generated. When this is set, the current time and
  293 + * output file name are not used as part of /ID generation. Instead, a digest of all significant
  294 + * parts of the output file's contents is included in the /ID calculation. Use of a
  295 + * deterministic /ID can be handy when it is desirable for a repeat of the same qpdf operation
  296 + * on the same inputs being written to the same outputs with the same parameters to generate
  297 + * exactly the same results. This feature is incompatible with encrypted files because, for
  298 + * encrypted files, the /ID is generated before any part of the file is written since it is an
  299 + * input to the encryption process.
  300 + */
278 301 QPDF_DLL
279 302 void setDeterministicID(bool);
280 303  
281   - // Cause a static /ID value to be generated. Use only in test suites. See also
282   - // setDeterministicID.
  304 + /*! \brief Cause a static /ID value to be generated. Use only in test suites. See also
  305 + * setDeterministicID.
  306 + */
283 307 QPDF_DLL
284 308 void setStaticID(bool);
285 309  
286   - // Use a fixed initialization vector for AES-CBC encryption. This is not secure. It should be
287   - // used only in test suites for creating predictable encrypted output.
  310 + /*! \brief Use a fixed initialization vector for AES-CBC encryption. This is not secure. It should be
  311 + * used only in test suites for creating predictable encrypted output.
  312 + */
288 313 QPDF_DLL
289 314 void setStaticAesIV(bool);
290 315  
291   - // Suppress inclusion of comments indicating original object IDs when writing QDF files. This
292   - // can also be useful for testing, particularly when using comparison of two qdf files to
293   - // determine whether two PDF files have identical content.
  316 + /*! \brief Suppress inclusion of comments indicating original object IDs when writing QDF files. This
  317 + * can also be useful for testing, particularly when using comparison of two qdf files to
  318 + * determine whether two PDF files have identical content.
  319 + */
294 320 QPDF_DLL
295 321 void setSuppressOriginalObjectIDs(bool);
296 322  
297   - // Preserve encryption. The default is true unless prefiltering, content normalization, or qdf
298   - // mode has been selected in which case encryption is never preserved. Encryption is also not
299   - // preserved if we explicitly set encryption parameters.
  323 + /*! \brief Preserve encryption. The default is true unless prefiltering, content normalization, or qdf
  324 + * mode has been selected in which case encryption is never preserved. Encryption is also not
  325 + * preserved if we explicitly set encryption parameters.
  326 + */
300 327 QPDF_DLL
301 328 void setPreserveEncryption(bool);
302 329  
303   - // Copy encryption parameters from another QPDF object. If you want to copy encryption from the
304   - // object you are writing, call setPreserveEncryption(true) instead.
  330 + /*! \brief Copy encryption parameters from another QPDF object. If you want to copy encryption from the
  331 + * object you are writing, call setPreserveEncryption(true) instead.
  332 + */
305 333 QPDF_DLL
306 334 void copyEncryptionParameters(QPDF&);
307 335  
308   - // Set up for encrypted output. User and owner password both must be specified. Either or both
309   - // may be the empty string. Note that qpdf does not apply any special treatment to the empty
310   - // string, which makes it possible to create encrypted files with empty owner passwords and
311   - // non-empty user passwords or with the same password for both user and owner. Some PDF reading
312   - // products don't handle such files very well. Enabling encryption disables stream prefiltering
313   - // and content normalization. Note that setting R2 encryption parameters sets the PDF version
314   - // to at least 1.3, setting R3 encryption parameters pushes the PDF version number to at
315   - // least 1.4, setting R4 parameters pushes the version to at least 1.5, or if AES is used, 1.6,
316   - // and setting R5 or R6 parameters pushes the version to at least 1.7 with extension level 3.
317   - //
318   - // Note about Unicode passwords: the PDF specification requires passwords to be encoded with PDF
319   - // Doc encoding for R <= 4 and UTF-8 for R >= 5. In all cases, these methods take strings of
320   - // bytes as passwords. It is up to the caller to ensure that passwords are properly encoded. The
321   - // qpdf command-line tool tries to do this, as discussed in the manual. If you are doing this
322   - // from your own application, QUtil contains many transcoding functions that could be useful to
323   - // you, most notably utf8_to_pdf_doc.
324   -
325   - // R2 uses RC4, which is a weak cryptographic algorithm. Don't use it unless you have to. See
326   - // "Weak Cryptography" in the manual. This encryption format is deprecated in the PDF 2.0
327   - // specification.
  336 + /*! \brief Set up for encrypted output. User and owner password both must be specified. Either or both
  337 + * may be the empty string. Note that qpdf does not apply any special treatment to the empty
  338 + * string, which makes it possible to create encrypted files with empty owner passwords and
  339 + * non-empty user passwords or with the same password for both user and owner. Some PDF reading
  340 + * products don't handle such files very well. Enabling encryption disables stream prefiltering
  341 + * and content normalization. Note that setting R2 encryption parameters sets the PDF version
  342 + * to at least 1.3, setting R3 encryption parameters pushes the PDF version number to at
  343 + * least 1.4, setting R4 parameters pushes the version to at least 1.5, or if AES is used, 1.6,
  344 + * and setting R5 or R6 parameters pushes the version to at least 1.7 with extension level 3.
  345 + *
  346 + * Note about Unicode passwords: the PDF specification requires passwords to be encoded with PDF
  347 + * Doc encoding for R <= 4 and UTF-8 for R >= 5. In all cases, these methods take strings of
  348 + * bytes as passwords. It is up to the caller to ensure that passwords are properly encoded. The
  349 + * qpdf command-line tool tries to do this, as discussed in the manual. If you are doing this
  350 + * from your own application, QUtil contains many transcoding functions that could be useful to
  351 + * you, most notably utf8_to_pdf_doc.
  352 + *
  353 + * R2 uses RC4, which is a weak cryptographic algorithm. Don't use it unless you have to. See
  354 + * "Weak Cryptography" in the manual. This encryption format is deprecated in the PDF 2.0
  355 + * specification.
  356 + */
328 357 QPDF_DLL
329 358 void setR2EncryptionParametersInsecure(
330 359 char const* user_password,
... ... @@ -333,9 +362,11 @@ class QPDFWriter
333 362 bool allow_modify,
334 363 bool allow_extract,
335 364 bool allow_annotate);
336   - // R3 uses RC4, which is a weak cryptographic algorithm. Don't use it unless you have to. See
337   - // "Weak Cryptography" in the manual. This encryption format is deprecated in the PDF 2.0
338   - // specification.
  365 +
  366 + /*! \brief R3 uses RC4, which is a weak cryptographic algorithm. Don't use it unless you have to. See
  367 + * "Weak Cryptography" in the manual. This encryption format is deprecated in the PDF 2.0
  368 + * specification.
  369 + */
339 370 QPDF_DLL
340 371 void setR3EncryptionParametersInsecure(
341 372 char const* user_password,
... ... @@ -347,10 +378,12 @@ class QPDFWriter
347 378 bool allow_form_filling,
348 379 bool allow_modify_other,
349 380 qpdf_r3_print_e print);
350   - // When use_aes=false, this call enables R4 with RC4, which is a weak cryptographic algorithm.
351   - // Even with use_aes=true, the overall encryption scheme is weak. Don't use it unless you have
352   - // to. See "Weak Cryptography" in the manual. This encryption format is deprecated in the
353   - // PDF 2.0 specification.
  381 +
  382 + /*! \brief When use_aes=false, this call enables R4 with RC4, which is a weak cryptographic algorithm.
  383 + * Even with use_aes=true, the overall encryption scheme is weak. Don't use it unless you have
  384 + * to. See "Weak Cryptography" in the manual. This encryption format is deprecated in the
  385 + * PDF 2.0 specification.
  386 + */
354 387 QPDF_DLL
355 388 void setR4EncryptionParametersInsecure(
356 389 char const* user_password,
... ... @@ -364,8 +397,10 @@ class QPDFWriter
364 397 qpdf_r3_print_e print,
365 398 bool encrypt_metadata,
366 399 bool use_aes);
367   - // R5 is deprecated. Do not use it for production use. Writing R5 is supported by qpdf
368   - // primarily to generate test files for applications that may need to test R5 support.
  400 +
  401 + /*! \brief R5 is deprecated. Do not use it for production use. Writing R5 is supported by qpdf
  402 + * primarily to generate test files for applications that may need to test R5 support.
  403 + */
369 404 QPDF_DLL
370 405 void setR5EncryptionParameters(
371 406 char const* user_password,
... ... @@ -378,7 +413,8 @@ class QPDFWriter
378 413 bool allow_modify_other,
379 414 qpdf_r3_print_e print,
380 415 bool encrypt_metadata);
381   - // This is the only password-based encryption format supported by the PDF specification.
  416 +
  417 + /*! \brief This is the only password-based encryption format supported by the PDF specification. */
382 418 QPDF_DLL
383 419 void setR6EncryptionParameters(
384 420 char const* user_password,
... ... @@ -392,53 +428,59 @@ class QPDFWriter
392 428 qpdf_r3_print_e print,
393 429 bool encrypt_metadata_aes);
394 430  
395   - // Create linearized output. Disables qdf mode, content normalization, and stream prefiltering.
  431 + /*! \brief Create linearized output. Disables qdf mode, content normalization, and stream prefiltering. */
396 432 QPDF_DLL
397 433 void setLinearization(bool);
398 434  
399   - // For debugging QPDF: provide the name of a file to write pass1 of linearization to. The only
400   - // reason to use this is to debug QPDF. To linearize, QPDF writes out the file in two passes.
401   - // Usually the first pass is discarded, but lots of computations are made in pass 1. If a
402   - // linearized file comes out wrong, it can be helpful to look at the first pass.
  435 + /*! \brief For debugging QPDF: provide the name of a file to write pass1 of linearization to. The only
  436 + * reason to use this is to debug QPDF. To linearize, QPDF writes out the file in two passes.
  437 + * Usually the first pass is discarded, but lots of computations are made in pass 1. If a
  438 + * linearized file comes out wrong, it can be helpful to look at the first pass.
  439 + */
403 440 QPDF_DLL
404 441 void setLinearizationPass1Filename(std::string const&);
405 442  
406   - // Create PCLm output. This is only useful for clients that know how to create PCLm files. If a
407   - // file is structured exactly as PCLm requires, this call will tell QPDFWriter to write the PCLm
408   - // header, create certain unreferenced streams required by the standard, and write the objects
409   - // in the required order. Calling this on an ordinary PDF serves no purpose. There is no
410   - // command-line argument that causes this method to be called.
  443 + /*! \brief Create PCLm output. This is only useful for clients that know how to create PCLm files. If a
  444 + * file is structured exactly as PCLm requires, this call will tell QPDFWriter to write the PCLm
  445 + * header, create certain unreferenced streams required by the standard, and write the objects
  446 + * in the required order. Calling this on an ordinary PDF serves no purpose. There is no
  447 + * command-line argument that causes this method to be called.
  448 + */
411 449 QPDF_DLL
412 450 void setPCLm(bool);
413 451  
414   - // If you want to be notified of progress, derive a class from ProgressReporter and override the
415   - // reportProgress method.
  452 + /*! \brief If you want to be notified of progress, derive a class from ProgressReporter and override the
  453 + * reportProgress method.
  454 + */
416 455 QPDF_DLL
417 456 void registerProgressReporter(std::shared_ptr<ProgressReporter>);
418 457  
419   - // Return the PDF version that will be written into the header. Calling this method does all the
420   - // preparation for writing, so it is an error to call any methods that may cause a change to the
421   - // version. Adding new objects to the original file after calling this may also cause problems.
422   - // It is safe to update existing objects or stream contents after calling this method, e.g., to
423   - // include the final version number in metadata.
  458 + /*! \brief Return the PDF version that will be written into the header. Calling this method does all the
  459 + * preparation for writing, so it is an error to call any methods that may cause a change to the
  460 + * version. Adding new objects to the original file after calling this may also cause problems.
  461 + * It is safe to update existing objects or stream contents after calling this method, e.g., to
  462 + * include the final version number in metadata.
  463 + */
424 464 QPDF_DLL
425 465 std::string getFinalVersion();
426 466  
427   - // Write the final file. There is no expectation of being able to call write() more than once.
  467 + /*! \brief Write the final file. There is no expectation of being able to call write() more than once. */
428 468 QPDF_DLL
429 469 void write();
430 470  
431   - // Return renumbered ObjGen that was written into the final file. This method can be used after
432   - // calling write().
  471 + /*! \brief Return renumbered ObjGen that was written into the final file. This method can be used after
  472 + * calling write().
  473 + */
433 474 QPDF_DLL
434 475 QPDFObjGen getRenumberedObjGen(QPDFObjGen);
435 476  
436   - // Return XRef entry that was written into the final file. This method can be used after calling
437   - // write().
  477 + /*! \brief Return XRef entry that was written into the final file. This method can be used after calling
  478 + * write().
  479 + */
438 480 QPDF_DLL
439 481 std::map<QPDFObjGen, QPDFXRefEntry> getWrittenXRefTable();
440 482  
441   - // The following structs / classes are not part of the public API.
  483 + /*! \brief The following structs / classes are not part of the public API. */
442 484 struct Object;
443 485 struct NewObject;
444 486 class ObjTable;
... ...