2022-02-04 21:36:22 +00:00
|
|
|
// Copyright (c) 2005-2022 Jay Berkenbilt
|
2022-01-03 15:16:28 +00:00
|
|
|
//
|
|
|
|
// This file is part of qpdf.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
//
|
|
|
|
// Versions of qpdf prior to version 7 were released under the terms
|
|
|
|
// of version 2.0 of the Artistic License. At your option, you may
|
|
|
|
// continue to consider qpdf to be licensed under those terms. Please
|
|
|
|
// see the manual for additional information.
|
|
|
|
|
|
|
|
#ifndef QPDFJOB_HH
|
|
|
|
#define QPDFJOB_HH
|
|
|
|
|
2022-01-05 21:13:43 +00:00
|
|
|
#include <qpdf/Constants.h>
|
2022-04-02 21:14:10 +00:00
|
|
|
#include <qpdf/DLL.h>
|
|
|
|
#include <qpdf/PDFVersion.hh>
|
2022-01-03 15:16:28 +00:00
|
|
|
#include <qpdf/QPDF.hh>
|
2022-05-07 11:53:45 +00:00
|
|
|
#include <qpdf/QPDFOutlineObjectHelper.hh>
|
2022-01-05 21:13:43 +00:00
|
|
|
#include <qpdf/QPDFPageObjectHelper.hh>
|
2022-01-03 15:16:28 +00:00
|
|
|
|
2022-04-02 21:14:10 +00:00
|
|
|
#include <functional>
|
|
|
|
#include <iostream>
|
2022-01-03 15:16:28 +00:00
|
|
|
#include <list>
|
|
|
|
#include <map>
|
2022-01-22 21:29:13 +00:00
|
|
|
#include <memory>
|
2022-04-02 21:14:10 +00:00
|
|
|
#include <set>
|
2022-01-25 21:40:35 +00:00
|
|
|
#include <stdexcept>
|
2022-04-02 21:14:10 +00:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2022-01-03 15:16:28 +00:00
|
|
|
|
|
|
|
class QPDFWriter;
|
2022-05-06 20:37:37 +00:00
|
|
|
class Pipeline;
|
2022-06-05 17:30:42 +00:00
|
|
|
class QPDFLogger;
|
2022-01-03 15:16:28 +00:00
|
|
|
|
|
|
|
class QPDFJob
|
|
|
|
{
|
|
|
|
public:
|
2022-07-31 12:03:18 +00:00
|
|
|
static int constexpr LATEST_JOB_JSON = 1;
|
|
|
|
|
2022-02-01 12:28:26 +00:00
|
|
|
// Exit codes -- returned by getExitCode() after calling run()
|
2022-06-18 15:36:11 +00:00
|
|
|
static int constexpr EXIT_ERROR = qpdf_exit_error;
|
|
|
|
static int constexpr EXIT_WARNING = qpdf_exit_warning;
|
2022-02-01 12:28:26 +00:00
|
|
|
// For is-encrypted and requires-password
|
2022-06-18 15:36:11 +00:00
|
|
|
static int constexpr EXIT_IS_NOT_ENCRYPTED = qpdf_exit_is_not_encrypted;
|
|
|
|
static int constexpr EXIT_CORRECT_PASSWORD = qpdf_exit_correct_password;
|
2022-02-01 12:28:26 +00:00
|
|
|
|
2022-01-28 12:46:04 +00:00
|
|
|
// QPDFUsage is thrown if there are any usage-like errors when
|
|
|
|
// calling Config methods.
|
2022-01-03 15:16:28 +00:00
|
|
|
QPDF_DLL
|
|
|
|
QPDFJob();
|
|
|
|
|
2022-01-23 14:46:02 +00:00
|
|
|
// SETUP FUNCTIONS
|
|
|
|
|
2022-02-01 18:49:11 +00:00
|
|
|
// Initialize a QPDFJob object from argv, which must be a
|
|
|
|
// null-terminated array of null-terminated UTF-8-encoded C
|
|
|
|
// strings. The progname_env argument is the name of an
|
|
|
|
// environment variable which, if set, overrides the name of the
|
|
|
|
// executable for purposes of generating the --completion options.
|
|
|
|
// See QPDFArgParser for details. If a null pointer is passed in,
|
|
|
|
// the default value of "QPDF_EXECUTABLE" is used. This is used by
|
|
|
|
// the QPDF cli, which just initializes a QPDFJob from argv, calls
|
|
|
|
// run(), and handles errors and exit status issues. You can
|
|
|
|
// perform much of the cli functionality programmatically in this
|
|
|
|
// way rather than using the regular API. This is exposed in the C
|
|
|
|
// API, which makes it easier to get certain high-level qpdf
|
|
|
|
// functionality from other languages. If there are any
|
|
|
|
// command-line errors, this method will throw QPDFUsage which is
|
|
|
|
// derived from std::runtime_error. Other exceptions may be thrown
|
|
|
|
// in some cases. Note that argc, and argv should be UTF-8
|
|
|
|
// encoded. If you are calling this from a Windows Unicode-aware
|
|
|
|
// main (wmain), see QUtil::call_main_from_wmain for information
|
|
|
|
// about converting arguments to UTF-8. This method will mutate
|
|
|
|
// arguments that are passed to it.
|
2022-01-05 22:20:20 +00:00
|
|
|
QPDF_DLL
|
2022-04-02 21:14:10 +00:00
|
|
|
void initializeFromArgv(
|
|
|
|
char const* const argv[], char const* progname_env = nullptr);
|
2022-01-05 22:20:20 +00:00
|
|
|
|
2022-01-30 19:39:38 +00:00
|
|
|
// Initialize a QPDFJob from json. Passing partial = true prevents
|
|
|
|
// this method from doing the final checks (calling
|
|
|
|
// checkConfiguration) after processing the json file. This makes
|
2022-02-01 12:18:23 +00:00
|
|
|
// it possible to initialize QPDFJob in stages using multiple json
|
2022-01-30 19:39:38 +00:00
|
|
|
// files or to have a json file that can be processed from the CLI
|
|
|
|
// with --job-json-file and be combined with other arguments. For
|
|
|
|
// example, you might include only encryption parameters, leaving
|
|
|
|
// it up to the rest of the command-line arguments to provide
|
|
|
|
// input and output files. initializeFromJson is called with
|
|
|
|
// partial = true when invoked from the command line. To make sure
|
|
|
|
// that the json file is fully valid on its own, just don't
|
2022-02-01 12:18:23 +00:00
|
|
|
// specify any other command-line flags. If there are any
|
|
|
|
// configuration errors, QPDFUsage is thrown. Some error messages
|
|
|
|
// may be CLI-centric. If an an exception tells you to use the
|
|
|
|
// "--some-option" option, set the "someOption" key in the JSON
|
|
|
|
// object instead.
|
2022-01-22 21:29:13 +00:00
|
|
|
QPDF_DLL
|
2022-01-30 19:39:38 +00:00
|
|
|
void initializeFromJson(std::string const& json, bool partial = false);
|
2022-01-22 21:29:13 +00:00
|
|
|
|
2022-01-03 17:16:16 +00:00
|
|
|
// Set name that is used to prefix verbose messages, progress
|
|
|
|
// messages, and other things that the library writes to output
|
|
|
|
// and error streams on the caller's behalf. Defaults to "qpdf".
|
|
|
|
QPDF_DLL
|
|
|
|
void setMessagePrefix(std::string const&);
|
2022-06-19 12:20:43 +00:00
|
|
|
QPDF_DLL
|
|
|
|
std::string getMessagePrefix() const;
|
2022-01-03 17:16:16 +00:00
|
|
|
|
2022-06-05 17:30:42 +00:00
|
|
|
// To capture or redirect output, configure the logger returned by
|
|
|
|
// getLogger(). By default, all QPDF and QPDFJob objects share the
|
|
|
|
// global logger. If you need a private logger for some reason,
|
|
|
|
// pass a new one to setLogger(). See comments in QPDFLogger.hh
|
|
|
|
// for details on configuring the logger.
|
|
|
|
//
|
|
|
|
// If you set a custom logger here, the logger will be passed to
|
|
|
|
// all subsequent QPDF objects created by this QPDFJob object.
|
|
|
|
QPDF_DLL
|
|
|
|
std::shared_ptr<QPDFLogger> getLogger();
|
2022-01-03 15:16:28 +00:00
|
|
|
QPDF_DLL
|
2022-06-05 17:30:42 +00:00
|
|
|
void setLogger(std::shared_ptr<QPDFLogger>);
|
|
|
|
|
|
|
|
// This deprecated method is the old way to capture output, but it
|
|
|
|
// didn't capture all output. See comments above for getLogger and
|
|
|
|
// setLogger. This will be removed in QPDF 12. For now, it
|
|
|
|
// configures a private logger, separating this object from the
|
|
|
|
// default logger, and calls setOutputStreams on that logger. See
|
|
|
|
// QPDFLogger.hh for additional details.
|
|
|
|
[[deprecated(
|
|
|
|
"configure logger from getLogger() or call setLogger()")]] QPDF_DLL void
|
|
|
|
setOutputStreams(std::ostream* out_stream, std::ostream* err_stream);
|
2022-01-03 15:16:28 +00:00
|
|
|
|
2022-06-19 00:44:44 +00:00
|
|
|
// You can register a custom progress reporter to be called by
|
|
|
|
// QPDFWriter (see QPDFWriter::registerProgressReporter). This is
|
|
|
|
// only called if you also request progress reporting through
|
|
|
|
// normal configuration methods (e.g., pass --progress, call
|
|
|
|
// config()->progress, etc.)
|
|
|
|
QPDF_DLL
|
|
|
|
void registerProgressReporter(std::function<void(int)>);
|
|
|
|
|
2022-01-23 18:11:46 +00:00
|
|
|
// Check to make sure no contradictory options have been
|
|
|
|
// specified. This is called automatically after initializing from
|
|
|
|
// argv or json and is also called by run, but you can call it
|
2022-01-29 14:01:20 +00:00
|
|
|
// manually as well. It throws a QPDFUsage exception if there are
|
|
|
|
// any errors. This Config object (see CONFIGURATION) also has a
|
|
|
|
// checkConfiguration method which calls this one.
|
2022-01-23 18:11:46 +00:00
|
|
|
QPDF_DLL
|
|
|
|
void checkConfiguration();
|
|
|
|
|
2022-01-23 18:04:08 +00:00
|
|
|
// Returns true if output is created by the specified job.
|
|
|
|
QPDF_DLL
|
|
|
|
bool createsOutput() const;
|
|
|
|
|
2022-01-26 22:31:31 +00:00
|
|
|
// SEE BELOW FOR MORE PUBLIC METHODS AND CLASSES
|
2022-01-25 16:07:53 +00:00
|
|
|
private:
|
2022-01-26 22:31:31 +00:00
|
|
|
// These structures are private but we need to define them before
|
|
|
|
// the public Config classes.
|
2022-01-25 16:07:53 +00:00
|
|
|
struct CopyAttachmentFrom
|
|
|
|
{
|
|
|
|
std::string path;
|
|
|
|
std::string password;
|
|
|
|
std::string prefix;
|
|
|
|
};
|
|
|
|
|
2022-01-25 21:37:17 +00:00
|
|
|
struct AddAttachment
|
|
|
|
{
|
|
|
|
AddAttachment() :
|
|
|
|
replace(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string path;
|
|
|
|
std::string key;
|
|
|
|
std::string filename;
|
|
|
|
std::string creationdate;
|
|
|
|
std::string moddate;
|
|
|
|
std::string mimetype;
|
|
|
|
std::string description;
|
|
|
|
bool replace;
|
|
|
|
};
|
|
|
|
|
2022-01-26 00:01:10 +00:00
|
|
|
struct PageSpec
|
|
|
|
{
|
2022-04-02 21:14:10 +00:00
|
|
|
PageSpec(
|
|
|
|
std::string const& filename,
|
|
|
|
char const* password,
|
|
|
|
std::string const& range);
|
2022-01-26 00:01:10 +00:00
|
|
|
|
|
|
|
std::string filename;
|
|
|
|
std::shared_ptr<char> password;
|
|
|
|
std::string range;
|
|
|
|
};
|
|
|
|
|
2022-01-25 16:07:53 +00:00
|
|
|
public:
|
2022-01-26 22:31:31 +00:00
|
|
|
// CONFIGURATION
|
|
|
|
|
|
|
|
// Configuration classes are implemented in QPDFJob_config.cc.
|
|
|
|
|
|
|
|
// The config() method returns a shared pointer to a Config
|
|
|
|
// object. The Config object contains methods that correspond with
|
|
|
|
// qpdf command-line arguments. You can use a fluent interface to
|
|
|
|
// configure a QPDFJob object that would do exactly the same thing
|
2022-02-01 12:18:23 +00:00
|
|
|
// as a specific qpdf command. The example qpdf-job.cc contains an
|
2022-01-26 22:31:31 +00:00
|
|
|
// example of this usage. You can also use initializeFromJson or
|
|
|
|
// initializeFromArgv to initialize a QPDFJob object.
|
|
|
|
|
|
|
|
// Notes about the Config methods:
|
|
|
|
//
|
|
|
|
// * Most of the method declarations are automatically generated
|
|
|
|
// in header files that are included within the class
|
|
|
|
// definitions. They correspond in predictable ways to the
|
|
|
|
// command-line arguments and are generated from the same code
|
|
|
|
// that generates the command-line argument parsing code.
|
|
|
|
//
|
|
|
|
// * Methods return pointers, rather than references, to
|
|
|
|
// configuration objects. References might feel more familiar to
|
|
|
|
// users of fluent interfaces, so why do we use pointers? The
|
|
|
|
// main methods that create them return smart pointers so that
|
|
|
|
// users can initialize them when needed, which you can't do
|
|
|
|
// with references. Returning pointers instead of references
|
|
|
|
// makes for a more uniform interface.
|
|
|
|
|
2022-02-01 12:18:23 +00:00
|
|
|
// Maintainer documentation: see the section in README-maintainer
|
|
|
|
// called "HOW TO ADD A COMMAND-LINE ARGUMENT", which contains
|
|
|
|
// references to additional places in the documentation.
|
|
|
|
|
2022-01-25 16:07:53 +00:00
|
|
|
class Config;
|
2022-01-25 21:37:17 +00:00
|
|
|
|
|
|
|
class AttConfig
|
|
|
|
{
|
|
|
|
friend class QPDFJob;
|
|
|
|
friend class Config;
|
2022-04-02 21:14:10 +00:00
|
|
|
|
2022-01-25 21:37:17 +00:00
|
|
|
public:
|
2022-01-26 22:02:30 +00:00
|
|
|
QPDF_DLL
|
2022-01-26 22:18:03 +00:00
|
|
|
Config* endAddAttachment();
|
2022-01-26 18:41:45 +00:00
|
|
|
QPDF_DLL
|
2022-02-01 18:37:31 +00:00
|
|
|
AttConfig* file(std::string const& parameter);
|
2022-01-25 21:37:17 +00:00
|
|
|
|
2022-04-02 21:14:10 +00:00
|
|
|
#include <qpdf/auto_job_c_att.hh>
|
2022-01-25 21:37:17 +00:00
|
|
|
|
|
|
|
private:
|
2022-01-26 22:18:03 +00:00
|
|
|
AttConfig(Config*);
|
2022-01-25 21:37:17 +00:00
|
|
|
AttConfig(AttConfig const&) = delete;
|
|
|
|
|
2022-01-26 22:18:03 +00:00
|
|
|
Config* config;
|
2022-01-25 21:37:17 +00:00
|
|
|
AddAttachment att;
|
|
|
|
};
|
|
|
|
|
2022-01-25 16:07:53 +00:00
|
|
|
class CopyAttConfig
|
|
|
|
{
|
|
|
|
friend class QPDFJob;
|
|
|
|
friend class Config;
|
2022-04-02 21:14:10 +00:00
|
|
|
|
2022-01-25 16:07:53 +00:00
|
|
|
public:
|
2022-01-26 22:02:30 +00:00
|
|
|
QPDF_DLL
|
2022-01-26 22:18:03 +00:00
|
|
|
Config* endCopyAttachmentsFrom();
|
2022-01-26 18:41:45 +00:00
|
|
|
QPDF_DLL
|
2022-02-01 18:37:31 +00:00
|
|
|
CopyAttConfig* file(std::string const& parameter);
|
2022-01-25 20:46:32 +00:00
|
|
|
|
2022-04-02 21:14:10 +00:00
|
|
|
#include <qpdf/auto_job_c_copy_att.hh>
|
2022-01-25 16:07:53 +00:00
|
|
|
|
|
|
|
private:
|
2022-01-26 22:18:03 +00:00
|
|
|
CopyAttConfig(Config*);
|
2022-01-25 16:07:53 +00:00
|
|
|
CopyAttConfig(CopyAttConfig const&) = delete;
|
|
|
|
|
2022-01-26 22:18:03 +00:00
|
|
|
Config* config;
|
2022-01-25 16:07:53 +00:00
|
|
|
CopyAttachmentFrom caf;
|
|
|
|
};
|
|
|
|
|
2022-01-26 00:01:10 +00:00
|
|
|
class PagesConfig
|
|
|
|
{
|
|
|
|
friend class QPDFJob;
|
|
|
|
friend class Config;
|
2022-04-02 21:14:10 +00:00
|
|
|
|
2022-01-26 00:01:10 +00:00
|
|
|
public:
|
2022-01-26 22:02:30 +00:00
|
|
|
QPDF_DLL
|
2022-01-26 22:18:03 +00:00
|
|
|
Config* endPages();
|
2022-01-26 18:41:45 +00:00
|
|
|
QPDF_DLL
|
2022-04-02 21:14:10 +00:00
|
|
|
PagesConfig* pageSpec(
|
|
|
|
std::string const& filename,
|
|
|
|
std::string const& range,
|
|
|
|
char const* password = nullptr);
|
2022-01-26 00:01:10 +00:00
|
|
|
|
2022-04-02 21:14:10 +00:00
|
|
|
#include <qpdf/auto_job_c_pages.hh>
|
2022-01-26 00:01:10 +00:00
|
|
|
|
|
|
|
private:
|
2022-01-26 22:18:03 +00:00
|
|
|
PagesConfig(Config*);
|
2022-01-26 00:01:10 +00:00
|
|
|
PagesConfig(PagesConfig const&) = delete;
|
|
|
|
|
2022-01-26 22:18:03 +00:00
|
|
|
Config* config;
|
2022-01-26 00:01:10 +00:00
|
|
|
};
|
|
|
|
|
2022-01-26 14:38:34 +00:00
|
|
|
class UOConfig
|
|
|
|
{
|
|
|
|
friend class QPDFJob;
|
|
|
|
friend class Config;
|
2022-04-02 21:14:10 +00:00
|
|
|
|
2022-01-26 14:38:34 +00:00
|
|
|
public:
|
2022-01-26 22:02:30 +00:00
|
|
|
QPDF_DLL
|
2022-01-26 22:18:03 +00:00
|
|
|
Config* endUnderlayOverlay();
|
2022-01-26 18:41:45 +00:00
|
|
|
QPDF_DLL
|
2022-02-01 18:37:31 +00:00
|
|
|
UOConfig* file(std::string const& parameter);
|
2022-01-26 14:38:34 +00:00
|
|
|
|
2022-04-02 21:14:10 +00:00
|
|
|
#include <qpdf/auto_job_c_uo.hh>
|
2022-01-26 14:38:34 +00:00
|
|
|
|
|
|
|
private:
|
2022-01-26 22:18:03 +00:00
|
|
|
UOConfig(Config*);
|
2022-01-26 14:38:34 +00:00
|
|
|
UOConfig(PagesConfig const&) = delete;
|
|
|
|
|
2022-01-26 22:18:03 +00:00
|
|
|
Config* config;
|
2022-01-26 14:38:34 +00:00
|
|
|
};
|
|
|
|
|
2022-01-26 18:17:57 +00:00
|
|
|
class EncConfig
|
|
|
|
{
|
|
|
|
friend class QPDFJob;
|
|
|
|
friend class Config;
|
2022-04-02 21:14:10 +00:00
|
|
|
|
2022-01-26 18:17:57 +00:00
|
|
|
public:
|
2022-01-26 22:02:30 +00:00
|
|
|
QPDF_DLL
|
2022-01-26 22:18:03 +00:00
|
|
|
Config* endEncrypt();
|
2022-01-26 18:41:45 +00:00
|
|
|
QPDF_DLL
|
2022-02-01 18:37:31 +00:00
|
|
|
EncConfig* file(std::string const& parameter);
|
2022-01-26 18:17:57 +00:00
|
|
|
|
2022-04-02 21:14:10 +00:00
|
|
|
#include <qpdf/auto_job_c_enc.hh>
|
2022-01-26 18:17:57 +00:00
|
|
|
|
|
|
|
private:
|
2022-01-26 22:18:03 +00:00
|
|
|
EncConfig(Config*);
|
2022-01-26 18:17:57 +00:00
|
|
|
EncConfig(PagesConfig const&) = delete;
|
|
|
|
|
2022-01-26 22:18:03 +00:00
|
|
|
Config* config;
|
2022-01-26 18:17:57 +00:00
|
|
|
};
|
|
|
|
|
2022-01-24 00:29:18 +00:00
|
|
|
class Config
|
|
|
|
{
|
|
|
|
friend class QPDFJob;
|
2022-04-02 21:14:10 +00:00
|
|
|
|
2022-01-24 00:29:18 +00:00
|
|
|
public:
|
2022-01-29 14:01:20 +00:00
|
|
|
// Proxy to QPDFJob::checkConfiguration()
|
|
|
|
QPDF_DLL
|
|
|
|
void checkConfiguration();
|
|
|
|
|
2022-01-26 18:56:13 +00:00
|
|
|
QPDF_DLL
|
2022-02-01 18:37:31 +00:00
|
|
|
Config* inputFile(std::string const& filename);
|
2022-01-26 18:56:13 +00:00
|
|
|
QPDF_DLL
|
2022-01-26 22:18:03 +00:00
|
|
|
Config* emptyInput();
|
2022-01-26 18:56:13 +00:00
|
|
|
QPDF_DLL
|
2022-02-01 18:37:31 +00:00
|
|
|
Config* outputFile(std::string const& filename);
|
2022-01-26 18:56:13 +00:00
|
|
|
QPDF_DLL
|
2022-01-26 22:18:03 +00:00
|
|
|
Config* replaceInput();
|
2022-01-26 18:56:13 +00:00
|
|
|
|
2022-01-25 16:07:53 +00:00
|
|
|
QPDF_DLL
|
|
|
|
std::shared_ptr<CopyAttConfig> copyAttachmentsFrom();
|
2022-01-26 18:41:45 +00:00
|
|
|
QPDF_DLL
|
2022-01-25 21:37:17 +00:00
|
|
|
std::shared_ptr<AttConfig> addAttachment();
|
2022-01-26 18:41:45 +00:00
|
|
|
QPDF_DLL
|
2022-01-26 00:01:10 +00:00
|
|
|
std::shared_ptr<PagesConfig> pages();
|
2022-01-26 18:41:45 +00:00
|
|
|
QPDF_DLL
|
2022-01-26 14:38:34 +00:00
|
|
|
std::shared_ptr<UOConfig> overlay();
|
2022-01-26 18:41:45 +00:00
|
|
|
QPDF_DLL
|
2022-01-26 14:38:34 +00:00
|
|
|
std::shared_ptr<UOConfig> underlay();
|
2022-01-26 18:41:45 +00:00
|
|
|
QPDF_DLL
|
2022-01-26 18:17:57 +00:00
|
|
|
std::shared_ptr<EncConfig> encrypt(
|
|
|
|
int keylen,
|
|
|
|
std::string const& user_password,
|
|
|
|
std::string const& owner_password);
|
2022-01-25 16:07:53 +00:00
|
|
|
|
2022-04-02 21:14:10 +00:00
|
|
|
#include <qpdf/auto_job_c_main.hh>
|
2022-01-24 00:29:18 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
Config() = delete;
|
2022-01-25 16:07:53 +00:00
|
|
|
Config(Config const&) = delete;
|
2022-01-24 00:29:18 +00:00
|
|
|
Config(QPDFJob& job) :
|
|
|
|
o(job)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
QPDFJob& o;
|
|
|
|
};
|
|
|
|
friend class Config;
|
|
|
|
|
2022-01-26 22:31:31 +00:00
|
|
|
// Return a top-level configuration item. See CONFIGURATION above
|
2022-01-28 12:46:04 +00:00
|
|
|
// for details. If an invalid configuration is created (such as
|
|
|
|
// supplying contradictory options, omitting an input file, etc.),
|
2022-02-01 12:18:23 +00:00
|
|
|
// QPDFUsage is thrown. Note that error messages are CLI-centric,
|
|
|
|
// but you can map them into config calls. For example, if an
|
|
|
|
// exception tells you to use the --some-option flag, you should
|
|
|
|
// call config()->someOption() instead.
|
2022-01-24 00:29:18 +00:00
|
|
|
QPDF_DLL
|
2022-01-25 16:07:53 +00:00
|
|
|
std::shared_ptr<Config> config();
|
2022-01-24 00:29:18 +00:00
|
|
|
|
2022-01-23 14:46:02 +00:00
|
|
|
// Execute the job
|
2022-01-05 22:20:20 +00:00
|
|
|
QPDF_DLL
|
2022-01-23 14:46:02 +00:00
|
|
|
void run();
|
|
|
|
|
|
|
|
// CHECK STATUS -- these methods provide information known after
|
|
|
|
// run() is called.
|
2022-01-05 22:20:20 +00:00
|
|
|
|
2022-01-03 15:16:28 +00:00
|
|
|
QPDF_DLL
|
2022-02-01 12:28:26 +00:00
|
|
|
bool hasWarnings() const;
|
|
|
|
|
|
|
|
// Return one of the EXIT_* constants defined at the top of the
|
|
|
|
// class declaration. This may be called after run() when run()
|
|
|
|
// did not throw an exception. Takes into consideration whether
|
|
|
|
// isEncrypted or requiresPassword was called. Note that this
|
|
|
|
// function does not know whether run() threw an exception, so
|
|
|
|
// code that uses this to determine how to exit should explicitly
|
|
|
|
// use EXIT_ERROR if run() threw an exception.
|
|
|
|
QPDF_DLL
|
|
|
|
int getExitCode() const;
|
2022-01-03 15:16:28 +00:00
|
|
|
|
|
|
|
// Return value is bitwise OR of values from qpdf_encryption_status_e
|
|
|
|
QPDF_DLL
|
|
|
|
unsigned long getEncryptionStatus();
|
|
|
|
|
2022-01-23 14:46:02 +00:00
|
|
|
// HELPER FUNCTIONS -- methods useful for calling in handlers that
|
|
|
|
// interact with QPDFJob during run or initialization.
|
|
|
|
|
|
|
|
// If in verbose mode, call the given function, passing in the
|
|
|
|
// output stream and message prefix.
|
|
|
|
QPDF_DLL
|
2022-06-05 17:30:42 +00:00
|
|
|
void
|
|
|
|
doIfVerbose(std::function<void(Pipeline&, std::string const& prefix)> fn);
|
2022-01-23 14:46:02 +00:00
|
|
|
|
2022-01-26 21:40:14 +00:00
|
|
|
// Provide a string that is the help information ("schema" for the
|
2022-07-31 12:03:18 +00:00
|
|
|
// qpdf-specific JSON object) for the specified version of JSON
|
|
|
|
// output.
|
|
|
|
QPDF_DLL
|
|
|
|
static std::string json_out_schema(int version);
|
|
|
|
|
2022-07-31 21:10:55 +00:00
|
|
|
[[deprecated("use json_out_schema(version)")]] static std::string QPDF_DLL
|
2022-07-31 12:03:18 +00:00
|
|
|
json_out_schema_v1();
|
|
|
|
|
|
|
|
// Provide a string that is the help information for specified
|
|
|
|
// version of JSON format for QPDFJob.
|
2022-01-03 15:16:28 +00:00
|
|
|
QPDF_DLL
|
2022-07-31 12:03:18 +00:00
|
|
|
static std::string job_json_schema(int version);
|
2022-01-03 15:16:28 +00:00
|
|
|
|
2022-07-31 21:10:55 +00:00
|
|
|
[[deprecated("use job_json_schema(version)")]] static std::string QPDF_DLL
|
2022-07-31 12:03:18 +00:00
|
|
|
job_json_schema_v1();
|
2022-01-26 21:48:18 +00:00
|
|
|
|
2022-01-26 21:40:14 +00:00
|
|
|
private:
|
2022-01-03 15:16:28 +00:00
|
|
|
struct RotationSpec
|
|
|
|
{
|
|
|
|
RotationSpec(int angle = 0, bool relative = false) :
|
|
|
|
angle(angle),
|
|
|
|
relative(relative)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
int angle;
|
|
|
|
bool relative;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum password_mode_e { pm_bytes, pm_hex_bytes, pm_unicode, pm_auto };
|
|
|
|
|
|
|
|
struct UnderOverlay
|
|
|
|
{
|
|
|
|
UnderOverlay(char const* which) :
|
|
|
|
which(which),
|
|
|
|
to_nr("1-z"),
|
|
|
|
from_nr("1-z"),
|
|
|
|
repeat_nr("")
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string which;
|
2022-01-22 23:49:05 +00:00
|
|
|
std::string filename;
|
|
|
|
std::shared_ptr<char> password;
|
2022-01-22 23:46:46 +00:00
|
|
|
std::string to_nr;
|
|
|
|
std::string from_nr;
|
|
|
|
std::string repeat_nr;
|
2022-01-22 22:37:51 +00:00
|
|
|
std::shared_ptr<QPDF> pdf;
|
2022-01-03 15:16:28 +00:00
|
|
|
std::vector<int> to_pagenos;
|
|
|
|
std::vector<int> from_pagenos;
|
|
|
|
std::vector<int> repeat_pagenos;
|
|
|
|
};
|
|
|
|
|
2022-01-26 14:38:34 +00:00
|
|
|
// Helper functions
|
2022-01-28 12:46:04 +00:00
|
|
|
static void usage(std::string const& msg);
|
2022-05-07 15:38:04 +00:00
|
|
|
static JSON json_schema(int json_version, std::set<std::string>* keys = 0);
|
2022-01-26 21:40:14 +00:00
|
|
|
static void parse_object_id(
|
|
|
|
std::string const& objspec, bool& trailer, int& obj, int& gen);
|
2022-01-26 14:38:34 +00:00
|
|
|
void parseRotationParameter(std::string const&);
|
|
|
|
std::vector<int> parseNumrange(char const* range, int max);
|
2022-01-26 14:09:29 +00:00
|
|
|
|
2022-01-05 21:50:18 +00:00
|
|
|
// Basic file processing
|
2022-01-22 22:37:51 +00:00
|
|
|
std::shared_ptr<QPDF> processFile(
|
2022-05-18 22:22:57 +00:00
|
|
|
char const* filename,
|
|
|
|
char const* password,
|
|
|
|
bool used_for_input,
|
|
|
|
bool main_input);
|
2022-01-22 22:37:51 +00:00
|
|
|
std::shared_ptr<QPDF> processInputSource(
|
2022-04-09 18:35:56 +00:00
|
|
|
std::shared_ptr<InputSource> is,
|
2022-04-02 21:14:10 +00:00
|
|
|
char const* password,
|
2022-02-08 18:38:03 +00:00
|
|
|
bool used_for_input);
|
2022-01-22 22:37:51 +00:00
|
|
|
std::shared_ptr<QPDF> doProcess(
|
2022-01-05 21:50:18 +00:00
|
|
|
std::function<void(QPDF*, char const*)> fn,
|
2022-04-02 21:14:10 +00:00
|
|
|
char const* password,
|
|
|
|
bool empty,
|
2022-05-18 22:22:57 +00:00
|
|
|
bool used_for_input,
|
|
|
|
bool main_input);
|
2022-01-22 22:37:51 +00:00
|
|
|
std::shared_ptr<QPDF> doProcessOnce(
|
2022-01-05 21:50:18 +00:00
|
|
|
std::function<void(QPDF*, char const*)> fn,
|
2022-04-02 21:14:10 +00:00
|
|
|
char const* password,
|
|
|
|
bool empty,
|
2022-05-18 22:22:57 +00:00
|
|
|
bool used_for_input,
|
|
|
|
bool main_input);
|
2022-01-05 21:50:18 +00:00
|
|
|
|
|
|
|
// Transformations
|
|
|
|
void setQPDFOptions(QPDF& pdf);
|
|
|
|
void handlePageSpecs(
|
2022-04-02 21:14:10 +00:00
|
|
|
QPDF& pdf,
|
|
|
|
bool& warnings,
|
2022-01-22 22:37:51 +00:00
|
|
|
std::vector<std::shared_ptr<QPDF>>& page_heap);
|
2022-01-05 21:50:18 +00:00
|
|
|
bool shouldRemoveUnreferencedResources(QPDF& pdf);
|
|
|
|
void handleRotations(QPDF& pdf);
|
2022-04-02 21:14:10 +00:00
|
|
|
void
|
|
|
|
getUOPagenos(UnderOverlay& uo, std::map<int, std::vector<int>>& pagenos);
|
2022-01-05 21:50:18 +00:00
|
|
|
void handleUnderOverlay(QPDF& pdf);
|
|
|
|
void doUnderOverlayForPage(
|
|
|
|
QPDF& pdf,
|
2022-01-26 21:40:14 +00:00
|
|
|
UnderOverlay& uo,
|
2022-04-02 21:14:10 +00:00
|
|
|
std::map<int, std::vector<int>>& pagenos,
|
2022-01-05 21:50:18 +00:00
|
|
|
size_t page_idx,
|
|
|
|
std::map<int, QPDFObjectHandle>& fo,
|
|
|
|
std::vector<QPDFPageObjectHelper>& pages,
|
|
|
|
QPDFPageObjectHelper& dest_page,
|
|
|
|
bool before);
|
2022-01-26 21:40:14 +00:00
|
|
|
void validateUnderOverlay(QPDF& pdf, UnderOverlay* uo);
|
2022-01-05 21:50:18 +00:00
|
|
|
void handleTransformations(QPDF& pdf);
|
|
|
|
void addAttachments(QPDF& pdf);
|
|
|
|
void copyAttachments(QPDF& pdf);
|
|
|
|
|
|
|
|
// Inspection
|
|
|
|
void doInspection(QPDF& pdf);
|
|
|
|
void doCheck(QPDF& pdf);
|
|
|
|
void showEncryption(QPDF& pdf);
|
|
|
|
void doShowObj(QPDF& pdf);
|
|
|
|
void doShowPages(QPDF& pdf);
|
|
|
|
void doListAttachments(QPDF& pdf);
|
|
|
|
void doShowAttachment(QPDF& pdf);
|
|
|
|
|
|
|
|
// Output generation
|
|
|
|
void doSplitPages(QPDF& pdf, bool& warnings);
|
|
|
|
void setWriterOptions(QPDF& pdf, QPDFWriter& w);
|
|
|
|
void setEncryptionOptions(QPDF&, QPDFWriter&);
|
|
|
|
void maybeFixWritePassword(int R, std::string& password);
|
|
|
|
void writeOutfile(QPDF& pdf);
|
2022-07-31 14:34:05 +00:00
|
|
|
void writeJSON(QPDF& pdf);
|
2022-01-05 21:50:18 +00:00
|
|
|
|
|
|
|
// JSON
|
2022-05-06 20:37:37 +00:00
|
|
|
void doJSON(QPDF& pdf, Pipeline*);
|
2022-01-05 21:50:18 +00:00
|
|
|
std::set<QPDFObjGen> getWantedJSONObjects();
|
2022-05-18 22:22:57 +00:00
|
|
|
void doJSONObject(
|
|
|
|
Pipeline* p, bool& first, std::string const& key, QPDFObjectHandle&);
|
Top-level json: write incrementally
This commit just changes the order in which fields are written to the
json without changing their content. All the json files in the test
suite were modified with this script to ensure that we didn't get any
changes other than ordering.
----------
#!/usr/bin/env python3
import json
import sys
def json_dumps(data):
return json.dumps(data, ensure_ascii=False,
indent=2, separators=(',', ': '))
for filename in sys.argv[1:]:
with open(filename, 'r') as f:
data = json.loads(f.read())
newdata = {}
for i in ('version', 'parameters', 'pages', 'pagelabels',
'acroform', 'attachments', 'encrypt', 'outlines',
'objects', 'objectinfo'):
if i in data:
newdata[i] = data[i]
print(json_dumps(newdata))
----------
2022-05-06 22:25:59 +00:00
|
|
|
void doJSONObjects(Pipeline* p, bool& first, QPDF& pdf);
|
|
|
|
void doJSONObjectinfo(Pipeline* p, bool& first, QPDF& pdf);
|
|
|
|
void doJSONPages(Pipeline* p, bool& first, QPDF& pdf);
|
|
|
|
void doJSONPageLabels(Pipeline* p, bool& first, QPDF& pdf);
|
|
|
|
void doJSONOutlines(Pipeline* p, bool& first, QPDF& pdf);
|
|
|
|
void doJSONAcroform(Pipeline* p, bool& first, QPDF& pdf);
|
|
|
|
void doJSONEncrypt(Pipeline* p, bool& first, QPDF& pdf);
|
|
|
|
void doJSONAttachments(Pipeline* p, bool& first, QPDF& pdf);
|
2022-05-07 11:53:45 +00:00
|
|
|
void addOutlinesToJson(
|
|
|
|
std::vector<QPDFOutlineObjectHelper> outlines,
|
|
|
|
JSON& j,
|
|
|
|
std::map<QPDFObjGen, int>& page_numbers);
|
2022-01-05 21:50:18 +00:00
|
|
|
|
2022-01-26 19:56:24 +00:00
|
|
|
enum remove_unref_e { re_auto, re_yes, re_no };
|
|
|
|
|
2022-01-03 15:16:28 +00:00
|
|
|
class Members
|
|
|
|
{
|
|
|
|
friend class QPDFJob;
|
|
|
|
|
|
|
|
public:
|
|
|
|
QPDF_DLL
|
|
|
|
~Members() = default;
|
|
|
|
|
|
|
|
private:
|
|
|
|
Members();
|
|
|
|
Members(Members const&) = delete;
|
|
|
|
|
2022-06-05 17:30:42 +00:00
|
|
|
std::shared_ptr<QPDFLogger> log;
|
2022-01-05 20:01:35 +00:00
|
|
|
std::string message_prefix;
|
2022-01-03 15:16:28 +00:00
|
|
|
bool warnings;
|
|
|
|
unsigned long encryption_status;
|
2022-01-24 00:29:18 +00:00
|
|
|
bool verbose;
|
2022-01-26 19:56:24 +00:00
|
|
|
std::shared_ptr<char> password;
|
|
|
|
bool linearize;
|
|
|
|
bool decrypt;
|
|
|
|
int split_pages;
|
|
|
|
bool progress;
|
2022-06-19 00:44:44 +00:00
|
|
|
std::function<void(int)> progress_handler;
|
2022-01-26 19:56:24 +00:00
|
|
|
bool suppress_warnings;
|
|
|
|
bool warnings_exit_zero;
|
|
|
|
bool copy_encryption;
|
|
|
|
std::string encryption_file;
|
|
|
|
std::shared_ptr<char> encryption_file_password;
|
|
|
|
bool encrypt;
|
|
|
|
bool password_is_hex_key;
|
|
|
|
bool suppress_password_recovery;
|
|
|
|
password_mode_e password_mode;
|
|
|
|
bool allow_insecure;
|
|
|
|
bool allow_weak_crypto;
|
|
|
|
std::string user_password;
|
|
|
|
std::string owner_password;
|
|
|
|
int keylen;
|
|
|
|
bool r2_print;
|
|
|
|
bool r2_modify;
|
|
|
|
bool r2_extract;
|
|
|
|
bool r2_annotate;
|
|
|
|
bool r3_accessibility;
|
|
|
|
bool r3_extract;
|
|
|
|
bool r3_assemble;
|
|
|
|
bool r3_annotate_and_form;
|
|
|
|
bool r3_form_filling;
|
|
|
|
bool r3_modify_other;
|
|
|
|
qpdf_r3_print_e r3_print;
|
|
|
|
bool force_V4;
|
|
|
|
bool force_R5;
|
|
|
|
bool cleartext_metadata;
|
|
|
|
bool use_aes;
|
|
|
|
bool stream_data_set;
|
|
|
|
qpdf_stream_data_e stream_data_mode;
|
|
|
|
bool compress_streams;
|
|
|
|
bool compress_streams_set;
|
|
|
|
bool recompress_flate;
|
|
|
|
bool recompress_flate_set;
|
|
|
|
int compression_level;
|
|
|
|
qpdf_stream_decode_level_e decode_level;
|
|
|
|
bool decode_level_set;
|
|
|
|
bool normalize_set;
|
|
|
|
bool normalize;
|
|
|
|
bool suppress_recovery;
|
|
|
|
bool object_stream_set;
|
|
|
|
qpdf_object_stream_e object_stream_mode;
|
|
|
|
bool ignore_xref_streams;
|
|
|
|
bool qdf_mode;
|
|
|
|
bool preserve_unreferenced_objects;
|
|
|
|
remove_unref_e remove_unreferenced_page_resources;
|
|
|
|
bool keep_files_open;
|
|
|
|
bool keep_files_open_set;
|
|
|
|
size_t keep_files_open_threshold;
|
|
|
|
bool newline_before_endstream;
|
|
|
|
std::string linearize_pass1;
|
|
|
|
bool coalesce_contents;
|
|
|
|
bool flatten_annotations;
|
|
|
|
int flatten_annotations_required;
|
|
|
|
int flatten_annotations_forbidden;
|
|
|
|
bool generate_appearances;
|
2022-02-08 16:27:38 +00:00
|
|
|
PDFVersion max_input_version;
|
2022-01-26 19:56:24 +00:00
|
|
|
std::string min_version;
|
|
|
|
std::string force_version;
|
|
|
|
bool show_npages;
|
|
|
|
bool deterministic_id;
|
|
|
|
bool static_id;
|
|
|
|
bool static_aes_iv;
|
|
|
|
bool suppress_original_object_id;
|
|
|
|
bool show_encryption;
|
|
|
|
bool show_encryption_key;
|
|
|
|
bool check_linearization;
|
|
|
|
bool show_linearization;
|
|
|
|
bool show_xref;
|
|
|
|
bool show_trailer;
|
|
|
|
int show_obj;
|
|
|
|
int show_gen;
|
|
|
|
bool show_raw_stream_data;
|
|
|
|
bool show_filtered_stream_data;
|
|
|
|
bool show_pages;
|
|
|
|
bool show_page_images;
|
|
|
|
size_t collate;
|
|
|
|
bool flatten_rotation;
|
|
|
|
bool list_attachments;
|
|
|
|
std::string attachment_to_show;
|
|
|
|
std::list<std::string> attachments_to_remove;
|
|
|
|
std::list<AddAttachment> attachments_to_add;
|
|
|
|
std::list<CopyAttachmentFrom> attachments_to_copy;
|
2022-01-31 19:20:06 +00:00
|
|
|
int json_version;
|
2022-01-26 19:56:24 +00:00
|
|
|
std::set<std::string> json_keys;
|
|
|
|
std::set<std::string> json_objects;
|
2022-05-07 17:33:45 +00:00
|
|
|
qpdf_json_stream_data_e json_stream_data;
|
2022-05-18 22:22:57 +00:00
|
|
|
bool json_stream_data_set;
|
2022-05-07 17:33:45 +00:00
|
|
|
std::string json_stream_prefix;
|
2022-05-06 21:29:22 +00:00
|
|
|
bool test_json_schema;
|
2022-01-26 19:56:24 +00:00
|
|
|
bool check;
|
|
|
|
bool optimize_images;
|
|
|
|
bool externalize_inline_images;
|
|
|
|
bool keep_inline_images;
|
|
|
|
bool remove_page_labels;
|
2022-01-26 21:40:14 +00:00
|
|
|
size_t oi_min_width;
|
|
|
|
size_t oi_min_height;
|
|
|
|
size_t oi_min_area;
|
2022-01-26 19:56:24 +00:00
|
|
|
size_t ii_min_bytes;
|
|
|
|
UnderOverlay underlay;
|
|
|
|
UnderOverlay overlay;
|
|
|
|
UnderOverlay* under_overlay;
|
|
|
|
std::vector<PageSpec> page_specs;
|
|
|
|
std::map<std::string, RotationSpec> rotations;
|
|
|
|
bool require_outfile;
|
|
|
|
bool replace_input;
|
|
|
|
bool check_is_encrypted;
|
|
|
|
bool check_requires_password;
|
|
|
|
std::shared_ptr<char> infilename;
|
|
|
|
std::shared_ptr<char> outfilename;
|
2022-05-18 22:22:57 +00:00
|
|
|
bool json_input;
|
2022-07-31 00:53:30 +00:00
|
|
|
bool json_output;
|
2022-05-08 17:42:16 +00:00
|
|
|
std::string update_from_json;
|
2022-08-31 17:51:58 +00:00
|
|
|
bool report_mem_usage;
|
2022-01-03 15:16:28 +00:00
|
|
|
};
|
2022-01-22 22:37:51 +00:00
|
|
|
std::shared_ptr<Members> m;
|
2022-01-03 15:16:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // QPDFOBJECT_HH
|