.. _using:

Running QPDF
============

This chapter describes how to run the qpdf program from the command
line.

.. _invocation:

Basic Invocation
----------------

When running qpdf, the basic invocation is as follows:

::

   qpdf [ options ] { infilename | --empty } outfilename

This converts PDF file :samp:`infilename` to PDF file
:samp:`outfilename`. The output file is functionally
identical to the input file but may have been structurally reorganized.
Also, orphaned objects will be removed from the file. Many
transformations are available as controlled by the options below. In
place of :samp:`infilename`, the parameter
:samp:`--empty` may be specified. This causes qpdf to
use a dummy input file that contains zero pages. The only normal use
case for using :samp:`--empty` would be if you were
going to add pages from another source, as discussed in :ref:`page-selection`.

If :samp:`@filename` appears as a word anywhere in the
command-line, it will be read line by line, and each line will be
treated as a command-line argument. Leading and trailing whitespace is
intentionally not removed from lines, which makes it possible to handle
arguments that start or end with spaces. The :samp:`@-`
option allows arguments to be read from standard input. This allows qpdf
to be invoked with an arbitrary number of arbitrarily long arguments. It
is also very useful for avoiding having to pass passwords on the command
line. Note that the :samp:`@filename` can't appear in
the middle of an argument, so constructs such as
:samp:`--arg=@option` will not work. You would have to
include the argument and its options together in the arguments file.

:samp:`outfilename` does not have to be seekable, even
when generating linearized files. Specifying ":samp:`-`"
as :samp:`outfilename` means to write to standard
output. If you want to overwrite the input file with the output, use the
option :samp:`--replace-input` and omit the output file
name. You can't specify the same file as both the input and the output.
If you do this, qpdf will tell you about the
:samp:`--replace-input` option.

Most options require an output file, but some testing or inspection
commands do not. These are specifically noted.

.. _exit-status:

Exit Status
~~~~~~~~~~~

The exit status of :command:`qpdf` may be interpreted as
follows:

- ``0``: no errors or warnings were found. The file may still have
  problems qpdf can't detect. If
  :samp:`--warning-exit-0` was specified, exit status 0
  is used even if there are warnings.

- ``2``: errors were found. qpdf was not able to fully process the
  file.

- ``3``: qpdf encountered problems that it was able to recover from. In
  some cases, the resulting file may still be damaged. Note that qpdf
  still exits with status ``3`` if it finds warnings even when
  :samp:`--no-warn` is specified. With
  :samp:`--warning-exit-0`, warnings without errors
  exit with status 0 instead of 3.

Note that :command:`qpdf` never exists with status ``1``.
If you get an exit status of ``1``, it was something else, like the
shell not being able to find or execute :command:`qpdf`.

.. _shell-completion:

Shell Completion
----------------

Starting in qpdf version 8.3.0, qpdf provides its own completion support
for zsh and bash. You can enable bash completion with :command:`eval
$(qpdf --completion-bash)` and zsh completion with
:command:`eval $(qpdf --completion-zsh)`. If
:command:`qpdf` is not in your path, you should invoke it
above with an absolute path. If you invoke it with a relative path, it
will warn you, and the completion won't work if you're in a different
directory.

qpdf will use ``argv[0]`` to figure out where its executable is. This
may produce unwanted results in some cases, especially if you are trying
to use completion with copy of qpdf that is built from source. You can
specify a full path to the qpdf you want to use for completion in the
``QPDF_EXECUTABLE`` environment variable.

.. _basic-options:

Basic Options
-------------

The following options are the most common ones and perform commonly
needed transformations.

:samp:`--help`
   Display command-line invocation help.

:samp:`--version`
   Display the current version of qpdf.

:samp:`--copyright`
   Show detailed copyright information.

:samp:`--show-crypto`
   Show a list of available crypto providers, each on a line by itself.
   The default provider is always listed first. See :ref:`crypto` for more information about crypto
   providers.

:samp:`--completion-bash`
   Output a completion command you can eval to enable shell completion
   from bash.

:samp:`--completion-zsh`
   Output a completion command you can eval to enable shell completion
   from zsh.

:samp:`--password={password}`
   Specifies a password for accessing encrypted files. To read the
   password from a file or standard input, you can use
   :samp:`--password-file`, added in qpdf 10.2. Note
   that you can also use :samp:`@filename` or
   :samp:`@-` as described above to put the password in
   a file or pass it via standard input, but you would do so by
   specifying the entire
   :samp:`--password={password}`
   option in the file. Syntax such as
   :samp:`--password=@filename` won't work since
   :samp:`@filename` is not recognized in the middle of
   an argument.

:samp:`--password-file={filename}`
   Reads the first line from the specified file and uses it as the
   password for accessing encrypted files.
   :samp:`{filename}`
   may be ``-`` to read the password from standard input. Note that, in
   this case, the password is echoed and there is no prompt, so use with
   caution.

:samp:`--is-encrypted`
   Silently exit with status 0 if the file is encrypted or status 2 if
   the file is not encrypted. This is useful for shell scripts. Other
   options are ignored if this is given. This option is mutually
   exclusive with :samp:`--requires-password`. Both this
   option and :samp:`--requires-password` exit with
   status 2 for non-encrypted files.

:samp:`--requires-password`
   Silently exit with status 0 if a password (other than as supplied) is
   required. Exit with status 2 if the file is not encrypted. Exit with
   status 3 if the file is encrypted but requires no password or the
   correct password has been supplied. This is useful for shell scripts.
   Note that any supplied password is used when opening the file. When
   used with a :samp:`--password` option, this option
   can be used to check the correctness of the password. In that case,
   an exit status of 3 means the file works with the supplied password.
   This option is mutually exclusive with
   :samp:`--is-encrypted`. Both this option and
   :samp:`--is-encrypted` exit with status 2 for
   non-encrypted files.

:samp:`--verbose`
   Increase verbosity of output. For now, this just prints some
   indication of any file that it creates.

:samp:`--progress`
   Indicate progress while writing files.

:samp:`--no-warn`
   Suppress writing of warnings to stderr. If warnings were detected and
   suppressed, :command:`qpdf` will still exit with exit
   code 3. See also :samp:`--warning-exit-0`.

:samp:`--warning-exit-0`
   If warnings are found but no errors, exit with exit code 0 instead 3.
   When combined with :samp:`--no-warn`, the effect is
   for :command:`qpdf` to completely ignore warnings.

:samp:`--linearize`
   Causes generation of a linearized (web-optimized) output file.

:samp:`--replace-input`
   If specified, the output file name should be omitted. This option
   tells qpdf to replace the input file with the output. It does this by
   writing to
   :file:`{infilename}.~qpdf-temp#`
   and, when done, overwriting the input file with the temporary file.
   If there were any warnings, the original input is saved as
   :file:`{infilename}.~qpdf-orig`.

:samp:`--copy-encryption=file`
   Encrypt the file using the same encryption parameters, including user
   and owner password, as the specified file. Use
   :samp:`--encryption-file-password` to specify a
   password if one is needed to open this file. Note that copying the
   encryption parameters from a file also copies the first half of
   ``/ID`` from the file since this is part of the encryption
   parameters.

:samp:`--encryption-file-password=password`
   If the file specified with :samp:`--copy-encryption`
   requires a password, specify the password using this option. Note
   that only one of the user or owner password is required. Both
   passwords will be preserved since QPDF does not distinguish between
   the two passwords. It is possible to preserve encryption parameters,
   including the owner password, from a file even if you don't know the
   file's owner password.

:samp:`--allow-weak-crypto`
   Starting with version 10.4, qpdf issues warnings when requested to
   create files using RC4 encryption. This option suppresses those
   warnings. In future versions of qpdf, qpdf will refuse to create
   files with weak cryptography when this flag is not given. See :ref:`weak-crypto` for additional details.

:samp:`--encrypt options --`
   Causes generation an encrypted output file. Please see :ref:`encryption-options` for details on how to specify
   encryption parameters.

:samp:`--decrypt`
   Removes any encryption on the file. A password must be supplied if
   the file is password protected.

:samp:`--password-is-hex-key`
   Overrides the usual computation/retrieval of the PDF file's
   encryption key from user/owner password with an explicit
   specification of the encryption key. When this option is specified,
   the argument to the :samp:`--password` option is
   interpreted as a hexadecimal-encoded key value. This only applies to
   the password used to open the main input file. It does not apply to
   other files opened by :samp:`--pages` or other
   options or to files being written.

   Most users will never have a need for this option, and no standard
   viewers support this mode of operation, but it can be useful for
   forensic or investigatory purposes. For example, if a PDF file is
   encrypted with an unknown password, a brute-force attack using the
   key directly is sometimes more efficient than one using the password.
   Also, if a file is heavily damaged, it may be possible to derive the
   encryption key and recover parts of the file using it directly. To
   expose the encryption key used by an encrypted file that you can open
   normally, use the :samp:`--show-encryption-key`
   option.

:samp:`--suppress-password-recovery`
   Ordinarily, qpdf attempts to automatically compensate for passwords
   specified in the wrong character encoding. This option suppresses
   that behavior. Under normal conditions, there are no reasons to use
   this option. See :ref:`unicode-passwords` for a
   discussion

:samp:`--password-mode={mode}`
   This option can be used to fine-tune how qpdf interprets Unicode
   (non-ASCII) password strings passed on the command line. With the
   exception of the :samp:`hex-bytes` mode, these only
   apply to passwords provided when encrypting files. The
   :samp:`hex-bytes` mode also applies to passwords
   specified for reading files. For additional discussion of the
   supported password modes and when you might want to use them, see
   :ref:`unicode-passwords`. The following modes
   are supported:

   - :samp:`auto`: Automatically determine whether the
     specified password is a properly encoded Unicode (UTF-8) string,
     and transcode it as required by the PDF spec based on the type
     encryption being applied. On Windows starting with version 8.4.0,
     and on almost all other modern platforms, incoming passwords will
     be properly encoded in UTF-8, so this is almost always what you
     want.

   - :samp:`unicode`: Tells qpdf that the incoming
     password is UTF-8, overriding whatever its automatic detection
     determines. The only difference between this mode and
     :samp:`auto` is that qpdf will fail with an error
     message if the password is not valid UTF-8 instead of falling back
     to :samp:`bytes` mode with a warning.

   - :samp:`bytes`: Interpret the password as a literal
     byte string. For non-Windows platforms, this is what versions of
     qpdf prior to 8.4.0 did. For Windows platforms, there is no way to
     specify strings of binary data on the command line directly, but
     you can use the :samp:`@filename` option to do it,
     in which case this option forces qpdf to respect the string of
     bytes as provided. This option will allow you to encrypt PDF files
     with passwords that will not be usable by other readers.

   - :samp:`hex-bytes`: Interpret the password as a
     hex-encoded string. This provides a way to pass binary data as a
     password on all platforms including Windows. As with
     :samp:`bytes`, this option may allow creation of
     files that can't be opened by other readers. This mode affects
     qpdf's interpretation of passwords specified for decrypting files
     as well as for encrypting them. It makes it possible to specify
     strings that are encoded in some manner other than the system's
     default encoding.

:samp:`--rotate=[+|-]angle[:page-range]`
   Apply rotation to specified pages. The
   :samp:`page-range` portion of the option value has
   the same format as page ranges in :ref:`page-selection`. If the page range is omitted, the
   rotation is applied to all pages. The :samp:`angle`
   portion of the parameter may be either 0, 90, 180, or 270. If
   preceded by :samp:`+` or :samp:`-`,
   the angle is added to or subtracted from the specified pages'
   original rotations. This is almost always what you want. Otherwise
   the pages' rotations are set to the exact value, which may cause the
   appearances of the pages to be inconsistent, especially for scans.
   For example, the command :command:`qpdf in.pdf out.pdf
   --rotate=+90:2,4,6 --rotate=180:7-8` would rotate pages
   2, 4, and 6 90 degrees clockwise from their original rotation and
   force the rotation of pages 7 through 8 to 180 degrees regardless of
   their original rotation, and the command :command:`qpdf in.pdf
   out.pdf --rotate=+180` would rotate all pages by 180
   degrees.

:samp:`--keep-files-open={[yn]}`
   This option controls whether qpdf keeps individual files open while
   merging. Prior to version 8.1.0, qpdf always kept all files open, but
   this meant that the number of files that could be merged was limited
   by the operating system's open file limit. Version 8.1.0 opened files
   as they were referenced and closed them after each read, but this
   caused a major performance impact. Version 8.2.0 optimized the
   performance but did so in a way that, for local file systems, there
   was a small but unavoidable performance hit, but for networked file
   systems, the performance impact could be very high. Starting with
   version 8.2.1, the default behavior is that files are kept open if no
   more than 200 files are specified, but this default behavior can be
   explicitly overridden with the
   :samp:`--keep-files-open` flag. If you are merging
   more than 200 files but less than the operating system's max open
   files limit, you may want to use
   :samp:`--keep-files-open=y`, especially if working
   over a networked file system. If you are using a local file system
   where the overhead is low and you might sometimes merge more than the
   OS limit's number of files from a script and are not worried about a
   few seconds additional processing time, you may want to specify
   :samp:`--keep-files-open=n`. The threshold for
   switching may be changed from the default 200 with the
   :samp:`--keep-files-open-threshold` option.

:samp:`--keep-files-open-threshold={count}`
   If specified, overrides the default value of 200 used as the
   threshold for qpdf deciding whether or not to keep files open. See
   :samp:`--keep-files-open` for details.

:samp:`--pages options --`
   Select specific pages from one or more input files. See :ref:`page-selection` for details on how to do
   page selection (splitting and merging).

:samp:`--collate={n}`
   When specified, collate rather than concatenate pages from files
   specified with :samp:`--pages`. With a numeric
   argument, collate in groups of :samp:`{n}`.
   The default is 1. See :ref:`page-selection` for additional details.

:samp:`--flatten-rotation`
   For each page that is rotated using the ``/Rotate`` key in the page's
   dictionary, remove the ``/Rotate`` key and implement the identical
   rotation semantics by modifying the page's contents. This option can
   be useful to prepare files for buggy PDF applications that don't
   properly handle rotated pages.

:samp:`--split-pages=[n]`
   Write each group of :samp:`n` pages to a separate
   output file. If :samp:`n` is not specified, create
   single pages. Output file names are generated as follows:

   - If the string ``%d`` appears in the output file name, it is
     replaced with a range of zero-padded page numbers starting from 1.

   - Otherwise, if the output file name ends in
     :file:`.pdf` (case insensitive), a zero-padded
     page range, preceded by a dash, is inserted before the file
     extension.

   - Otherwise, the file name is appended with a zero-padded page range
     preceded by a dash.

   Page ranges are a single number in the case of single-page groups or
   two numbers separated by a dash otherwise. For example, if
   :file:`infile.pdf` has 12 pages

   - :command:`qpdf --split-pages infile.pdf %d-out`
     would generate files :file:`01-out` through
     :file:`12-out`

   - :command:`qpdf --split-pages=2 infile.pdf
     outfile.pdf` would generate files
     :file:`outfile-01-02.pdf` through
     :file:`outfile-11-12.pdf`

   - :command:`qpdf --split-pages infile.pdf
     something.else` would generate files
     :file:`something.else-01` through
     :file:`something.else-12`

   Note that outlines, threads, and other global features of the
   original PDF file are not preserved. For each page of output, this
   option creates an empty PDF and copies a single page from the output
   into it. If you require the global data, you will have to run
   :command:`qpdf` with the
   :samp:`--pages` option once for each file. Using
   :samp:`--split-pages` is much faster if you don't
   require the global data.

:samp:`--overlay options --`
   Overlay pages from another file onto the output pages. See :ref:`overlay-underlay` for details on
   overlay/underlay.

:samp:`--underlay options --`
   Overlay pages from another file onto the output pages. See :ref:`overlay-underlay` for details on
   overlay/underlay.

Password-protected files may be opened by specifying a password. By
default, qpdf will preserve any encryption data associated with a file.
If :samp:`--decrypt` is specified, qpdf will attempt to
remove any encryption information. If :samp:`--encrypt`
is specified, qpdf will replace the document's encryption parameters
with whatever is specified.

Note that qpdf does not obey encryption restrictions already imposed on
the file. Doing so would be meaningless since qpdf can be used to remove
encryption from the file entirely. This functionality is not intended to
be used for bypassing copyright restrictions or other restrictions
placed on files by their producers.

Prior to 8.4.0, in the case of passwords that contain characters that
fall outside of 7-bit US-ASCII, qpdf left the burden of supplying
properly encoded encryption and decryption passwords to the user.
Starting in qpdf 8.4.0, qpdf does this automatically in most cases. For
an in-depth discussion, please see :ref:`unicode-passwords`. Previous versions of this manual
described workarounds using the :command:`iconv` command.
Such workarounds are no longer required or recommended with qpdf 8.4.0.
However, for backward compatibility, qpdf attempts to detect those
workarounds and do the right thing in most cases.

.. _encryption-options:

Encryption Options
------------------

To change the encryption parameters of a file, use the --encrypt flag.
The syntax is

::

   --encrypt user-password owner-password key-length [ restrictions ] --

Note that ":samp:`--`" terminates parsing of encryption
flags and must be present even if no restrictions are present.

Either or both of the user password and the owner password may be empty
strings. Starting in qpdf 10.2, qpdf defaults to not allowing creation
of PDF files with a non-empty user password, an empty owner password,
and a 256-bit key since such files can be opened with no password. If
you want to create such files, specify the encryption option
:samp:`--allow-insecure`, as described below.

The value for
:samp:`{key-length}` may
be 40, 128, or 256. The restriction flags are dependent upon key length.
When no additional restrictions are given, the default is to be fully
permissive.

If :samp:`{key-length}`
is 40, the following restriction options are available:

:samp:`--print=[yn]`
   Determines whether or not to allow printing.

:samp:`--modify=[yn]`
   Determines whether or not to allow document modification.

:samp:`--extract=[yn]`
   Determines whether or not to allow text/image extraction.

:samp:`--annotate=[yn]`
   Determines whether or not to allow comments and form fill-in and
   signing.

If :samp:`{key-length}`
is 128, the following restriction options are available:

:samp:`--accessibility=[yn]`
   Determines whether or not to allow accessibility to visually
   impaired. The qpdf library disregards this field when AES is used or
   when 256-bit encryption is used. You should really never disable
   accessibility, but qpdf lets you do it in case you need to configure
   a file this way for testing purposes. The PDF spec says that
   conforming readers should disregard this permission and always allow
   accessibility.

:samp:`--extract=[yn]`
   Determines whether or not to allow text/graphic extraction.

:samp:`--assemble=[yn]`
   Determines whether document assembly (rotation and reordering of
   pages) is allowed.

:samp:`--annotate=[yn]`
   Determines whether modifying annotations is allowed. This includes
   adding comments and filling in form fields. Also allows editing of
   form fields if :samp:`--modify-other=y` is given.

:samp:`--form=[yn]`
   Determines whether filling form fields is allowed.

:samp:`--modify-other=[yn]`
   Allow all document editing except those controlled separately by the
   :samp:`--assemble`,
   :samp:`--annotate`, and
   :samp:`--form` options.

:samp:`--print={print-opt}`
   Controls printing access.
   :samp:`{print-opt}`
   may be one of the following:

   - :samp:`full`: allow full printing

   - :samp:`low`: allow low-resolution printing only

   - :samp:`none`: disallow printing

:samp:`--modify={modify-opt}`
   Controls modify access. This way of controlling modify access has
   less granularity than new options added in qpdf 8.4.
   :samp:`{modify-opt}`
   may be one of the following:

   - :samp:`all`: allow full document modification

   - :samp:`annotate`: allow comment authoring, form
     operations, and document assembly

   - :samp:`form`: allow form field fill-in and signing
     and document assembly

   - :samp:`assembly`: allow document assembly only

   - :samp:`none`: allow no modifications

   Using the :samp:`--modify` option does not allow you
   to create certain combinations of permissions such as allowing form
   filling but not allowing document assembly. Starting with qpdf 8.4,
   you can either just use the other options to control fields
   individually, or you can use something like :samp:`--modify=form
   --assembly=n` to fine tune.

:samp:`--cleartext-metadata`
   If specified, any metadata stream in the document will be left
   unencrypted even if the rest of the document is encrypted. This also
   forces the PDF version to be at least 1.5.

:samp:`--use-aes=[yn]`
   If :samp:`--use-aes=y` is specified, AES encryption
   will be used instead of RC4 encryption. This forces the PDF version
   to be at least 1.6.

:samp:`--allow-insecure`
   From qpdf 10.2, qpdf defaults to not allowing creation of PDF files
   where the user password is non-empty, the owner password is empty,
   and a 256-bit key is in use. Files created in this way are insecure
   since they can be opened without a password. Users would ordinarily
   never want to create such files. If you are using qpdf to
   intentionally created strange files for testing (a definite valid use
   of qpdf!), this option allows you to create such insecure files.

:samp:`--force-V4`
   Use of this option forces the ``/V`` and ``/R`` parameters in the
   document's encryption dictionary to be set to the value ``4``. As
   qpdf will automatically do this when required, there is no reason to
   ever use this option. It exists primarily for use in testing qpdf
   itself. This option also forces the PDF version to be at least 1.5.

If :samp:`{key-length}`
is 256, the minimum PDF version is 1.7 with extension level 8, and the
AES-based encryption format used is the PDF 2.0 encryption method
supported by Acrobat X. the same options are available as with 128 bits
with the following exceptions:

:samp:`--use-aes`
   This option is not available with 256-bit keys. AES is always used
   with 256-bit encryption keys.

:samp:`--force-V4`
   This option is not available with 256 keys.

:samp:`--force-R5`
   If specified, qpdf sets the minimum version to 1.7 at extension level
   3 and writes the deprecated encryption format used by Acrobat version
   IX. This option should not be used in practice to generate PDF files
   that will be in general use, but it can be useful to generate files
   if you are trying to test proper support in another application for
   PDF files encrypted in this way.

The default for each permission option is to be fully permissive.

.. _page-selection:

Page Selection Options
----------------------

Starting with qpdf 3.0, it is possible to split and merge PDF files by
selecting pages from one or more input files. Whatever file is given as
the primary input file is used as the starting point, but its pages are
replaced with pages as specified.

::

   --pages input-file [ --password=password ] [ page-range ] [ ... ] --

Multiple input files may be specified. Each one is given as the name of
the input file, an optional password (if required to open the file), and
the range of pages. Note that ":samp:`--`" terminates
parsing of page selection flags.

Starting with qpf 8.4, the special input file name
":file:`.`" can be used as a shortcut for the
primary input filename.

For each file that pages should be taken from, specify the file, a
password needed to open the file (if any), and a page range. The
password needs to be given only once per file. If any of the input files
are the same as the primary input file or the file used to copy
encryption parameters (if specified), you do not need to repeat the
password here. The same file can be repeated multiple times. If a file
that is repeated has a password, the password only has to be given the
first time. All non-page data (info, outlines, page numbers, etc.) are
taken from the primary input file. To discard these, use
:samp:`--empty` as the primary input.

Starting with qpdf 5.0.0, it is possible to omit the page range. If qpdf
sees a value in the place where it expects a page range and that value
is not a valid range but is a valid file name, qpdf will implicitly use
the range ``1-z``, meaning that it will include all pages in the file.
This makes it possible to easily combine all pages in a set of files
with a command like :command:`qpdf --empty out.pdf --pages \*.pdf
--`.

The page range is a set of numbers separated by commas, ranges of
numbers separated dashes, or combinations of those. The character "z"
represents the last page. A number preceded by an "r" indicates to count
from the end, so ``r3-r1`` would be the last three pages of the
document. Pages can appear in any order. Ranges can appear with a high
number followed by a low number, which causes the pages to appear in
reverse. Numbers may be repeated in a page range. A page range may be
optionally appended with ``:even`` or ``:odd`` to indicate only the even
or odd pages in the given range. Note that even and odd refer to the
positions within the specified, range, not whether the original number
is even or odd.

Example page ranges:

- ``1,3,5-9,15-12``: pages 1, 3, 5, 6, 7, 8, 9, 15, 14, 13, and 12 in
  that order.

- ``z-1``: all pages in the document in reverse

- ``r3-r1``: the last three pages of the document

- ``r1-r3``: the last three pages of the document in reverse order

- ``1-20:even``: even pages from 2 to 20

- ``5,7-9,12:odd``: pages 5, 8, and, 12, which are the pages in odd
  positions from among the original range, which represents pages 5, 7,
  8, 9, and 12.

Starting in qpdf version 8.3, you can specify the
:samp:`--collate` option. Note that this option is
specified outside of :samp:`--pages ... --`. When
:samp:`--collate` is specified, it changes the meaning
of :samp:`--pages` so that the specified files, as
modified by page ranges, are collated rather than concatenated. For
example, if you add the files :file:`odd.pdf` and
:file:`even.pdf` containing odd and even pages of a
document respectively, you could run :command:`qpdf --collate odd.pdf
--pages odd.pdf even.pdf -- all.pdf` to collate the pages.
This would pick page 1 from odd, page 1 from even, page 2 from odd, page
2 from even, etc. until all pages have been included. Any number of
files and page ranges can be specified. If any file has fewer pages,
that file is just skipped when its pages have all been included. For
example, if you ran :command:`qpdf --collate --empty --pages a.pdf
1-5 b.pdf 6-4 c.pdf r1 -- out.pdf`, you would get the
following pages in this order:

- a.pdf page 1

- b.pdf page 6

- c.pdf last page

- a.pdf page 2

- b.pdf page 5

- a.pdf page 3

- b.pdf page 4

- a.pdf page 4

- a.pdf page 5

Starting in qpdf version 10.2, you may specify a numeric argument to
:samp:`--collate`. With
:samp:`--collate={n}`,
pull groups of :samp:`{n}` pages from each file,
again, stopping when there are no more pages. For example, if you ran
:command:`qpdf --collate=2 --empty --pages a.pdf 1-5 b.pdf 6-4 c.pdf
r1 -- out.pdf`, you would get the following pages in this
order:

- a.pdf page 1

- a.pdf page 2

- b.pdf page 6

- b.pdf page 5

- c.pdf last page

- a.pdf page 3

- a.pdf page 4

- b.pdf page 4

- a.pdf page 5

Starting in qpdf version 8.3, when you split and merge files, any page
labels (page numbers) are preserved in the final file. It is expected
that more document features will be preserved by splitting and merging.
In the mean time, semantics of splitting and merging vary across
features. For example, the document's outlines (bookmarks) point to
actual page objects, so if you select some pages and not others,
bookmarks that point to pages that are in the output file will work, and
remaining bookmarks will not work. A future version of
:command:`qpdf` may do a better job at handling these
issues. (Note that the qpdf library already contains all of the APIs
required in order to implement this in your own application if you need
it.) In the mean time, you can always use
:samp:`--empty` as the primary input file to avoid
copying all of that from the first file. For example, to take pages 1
through 5 from a :file:`infile.pdf` while preserving
all metadata associated with that file, you could use

::

   qpdf infile.pdf --pages . 1-5 -- outfile.pdf

If you wanted pages 1 through 5 from
:file:`infile.pdf` but you wanted the rest of the
metadata to be dropped, you could instead run

::

   qpdf --empty --pages infile.pdf 1-5 -- outfile.pdf

If you wanted to take pages 1 through 5 from
:file:`file1.pdf` and pages 11 through 15 from
:file:`file2.pdf` in reverse, taking document-level
metadata from :file:`file2.pdf`, you would run

::

   qpdf file2.pdf --pages file1.pdf 1-5 . 15-11 -- outfile.pdf

If, for some reason, you wanted to take the first page of an encrypted
file called :file:`encrypted.pdf` with password
``pass`` and repeat it twice in an output file, and if you wanted to
drop document-level metadata but preserve encryption, you would use

::

   qpdf --empty --copy-encryption=encrypted.pdf \
        --encryption-file-password=pass \
        --pages encrypted.pdf --password=pass 1 \
              ./encrypted.pdf --password=pass 1 -- \
        outfile.pdf

Note that we had to specify the password all three times because giving
a password as :samp:`--encryption-file-password` doesn't
count for page selection, and as far as qpdf is concerned,
:file:`encrypted.pdf` and
:file:`./encrypted.pdf` are separated files. These
are all corner cases that most users should hopefully never have to be
bothered with.

Prior to version 8.4, it was not possible to specify the same page from
the same file directly more than once, and the workaround of specifying
the same file in more than one way was required. Version 8.4 removes
this limitation, but there is still a valid use case. When you specify
the same page from the same file more than once, qpdf will share objects
between the pages. If you are going to do further manipulation on the
file and need the two instances of the same original page to be deep
copies, then you can specify the file in two different ways. For example
:command:`qpdf in.pdf --pages . 1 ./in.pdf 1 -- out.pdf`
would create a file with two copies of the first page of the input, and
the two copies would share any objects in common. This includes fonts,
images, and anything else the page references.

.. _overlay-underlay:

Overlay and Underlay Options
----------------------------

Starting with qpdf 8.4, it is possible to overlay or underlay pages from
other files onto the output generated by qpdf. Specify overlay or
underlay as follows:

::

   { --overlay | --underlay } file [ options ] --

Overlay and underlay options are processed late, so they can be combined
with other like merging and will apply to the final output. The
:samp:`--overlay` and :samp:`--underlay`
options work the same way, except underlay pages are drawn underneath
the page to which they are applied, possibly obscured by the original
page, and overlay files are drawn on top of the page to which they are
applied, possibly obscuring the page. You can combine overlay and
underlay.

The default behavior of overlay and underlay is that pages are taken
from the overlay/underlay file in sequence and applied to corresponding
pages in the output until there are no more output pages. If the overlay
or underlay file runs out of pages, remaining output pages are left
alone. This behavior can be modified by options, which are provided
between the :samp:`--overlay` or
:samp:`--underlay` flag and the
:samp:`--` option. The following options are supported:

- :samp:`--password=password`: supply a password if the
  overlay/underlay file is encrypted.

- :samp:`--to=page-range`: a range of pages in the same
  form at described in :ref:`page-selection`
  indicates which pages in the output should have the overlay/underlay
  applied. If not specified, overlay/underlay are applied to all pages.

- :samp:`--from=[page-range]`: a range of pages that
  specifies which pages in the overlay/underlay file will be used for
  overlay or underlay. If not specified, all pages will be used. This
  can be explicitly specified to be empty if
  :samp:`--repeat` is used.

- :samp:`--repeat=page-range`: an optional range of
  pages that specifies which pages in the overlay/underlay file will be
  repeated after the "from" pages are used up. If you want to repeat a
  range of pages starting at the beginning, you can explicitly use
  :samp:`--from=`.

Here are some examples.

- :command:`--overlay o.pdf --to=1-5 --from=1-3 --repeat=4
  --`: overlay the first three pages from file
  :file:`o.pdf` onto the first three pages of the
  output, then overlay page 4 from :file:`o.pdf`
  onto pages 4 and 5 of the output. Leave remaining output pages
  untouched.

- :command:`--underlay footer.pdf --from= --repeat=1,2
  --`: Underlay page 1 of
  :file:`footer.pdf` on all odd output pages, and
  underlay page 2 of :file:`footer.pdf` on all even
  output pages.

.. _attachments:

Embedded Files/Attachments Options
----------------------------------

Starting with qpdf 10.2, you can work with file attachments in PDF files
from the command line. The following options are available:

:samp:`--list-attachments`
   Show the "key" and stream number for embedded files. With
   :samp:`--verbose`, additional information, including
   preferred file name, description, dates, and more are also displayed.
   The key is usually but not always equal to the file name, and is
   needed by some of the other options.

:samp:`--show-attachment={key}`
   Write the contents of the specified attachment to standard output as
   binary data. The key should match one of the keys shown by
   :samp:`--list-attachments`. If specified multiple
   times, only the last attachment will be shown.

:samp:`--add-attachment {file} {options} --`
   Add or replace an attachment with the contents of
   :samp:`{file}`. This may be specified more
   than once. The following additional options may appear before the
   ``--`` that ends this option:

   :samp:`--key={key}`
      The key to use to register the attachment in the embedded files
      table. Defaults to the last path element of
      :samp:`{file}`.

   :samp:`--filename={name}`
      The file name to be used for the attachment. This is what is
      usually displayed to the user and is the name most graphical PDF
      viewers will use when saving a file. It defaults to the last path
      element of :samp:`{file}`.

   :samp:`--creationdate={date}`
      The attachment's creation date in PDF format; defaults to the
      current time. The date format is explained below.

   :samp:`--moddate={date}`
      The attachment's modification date in PDF format; defaults to the
      current time. The date format is explained below.

   :samp:`--mimetype={type/subtype}`
      The mime type for the attachment, e.g. ``text/plain`` or
      ``application/pdf``. Note that the mimetype appears in a field
      called ``/Subtype`` in the PDF but actually includes the full type
      and subtype of the mime type.

   :samp:`--description={"text"}`
      Descriptive text for the attachment, displayed by some PDF
      viewers.

   :samp:`--replace`
      Indicates that any existing attachment with the same key should be
      replaced by the new attachment. Otherwise,
      :command:`qpdf` gives an error if an attachment
      with that key is already present.

:samp:`--remove-attachment={key}`
   Remove the specified attachment. This doesn't only remove the
   attachment from the embedded files table but also clears out the file
   specification. That means that any potential internal links to the
   attachment will be broken. This option may be specified multiple
   times. Run with :samp:`--verbose` to see status of
   the removal.

:samp:`--copy-attachments-from {file} {options} --`
   Copy attachments from another file. This may be specified more than
   once. The following additional options may appear before the ``--``
   that ends this option:

   :samp:`--password={password}`
      If required, the password needed to open
      :samp:`{file}`

   :samp:`--prefix={prefix}`
      Only required if the file from which attachments are being copied
      has attachments with keys that conflict with attachments already
      in the file. In this case, the specified prefix will be prepended
      to each key. This affects only the key in the embedded files
      table, not the file name. The PDF specification doesn't preclude
      multiple attachments having the same file name.

When a date is required, the date should conform to the PDF date format
specification, which is
``D:``\ :samp:`{yyyymmddhhmmss<z>}`, where
:samp:`{<z>}` is either ``Z`` for UTC or a
timezone offset in the form :samp:`{-hh'mm'}` or
:samp:`{+hh'mm'}`. Examples:
``D:20210207161528-05'00'``, ``D:20210207211528Z``.

.. _advanced-parsing:

Advanced Parsing Options
------------------------

These options control aspects of how qpdf reads PDF files. Mostly these
are of use to people who are working with damaged files. There is little
reason to use these options unless you are trying to solve specific
problems. The following options are available:

:samp:`--suppress-recovery`
   Prevents qpdf from attempting to recover damaged files.

:samp:`--ignore-xref-streams`
   Tells qpdf to ignore any cross-reference streams.

Ordinarily, qpdf will attempt to recover from certain types of errors in
PDF files. These include errors in the cross-reference table, certain
types of object numbering errors, and certain types of stream length
errors. Sometimes, qpdf may think it has recovered but may not have
actually recovered, so care should be taken when using this option as
some data loss is possible. The
:samp:`--suppress-recovery` option will prevent qpdf
from attempting recovery. In this case, it will fail on the first error
that it encounters.

Ordinarily, qpdf reads cross-reference streams when they are present in
a PDF file. If :samp:`--ignore-xref-streams` is
specified, qpdf will ignore any cross-reference streams for hybrid PDF
files. The purpose of hybrid files is to make some content available to
viewers that are not aware of cross-reference streams. It is almost
never desirable to ignore them. The only time when you might want to use
this feature is if you are testing creation of hybrid PDF files and wish
to see how a PDF consumer that doesn't understand object and
cross-reference streams would interpret such a file.

.. _advanced-transformation:

Advanced Transformation Options
-------------------------------

These transformation options control fine points of how qpdf creates the
output file. Mostly these are of use only to people who are very
familiar with the PDF file format or who are PDF developers. The
following options are available:

:samp:`--compress-streams={[yn]}`
   By default, or with :samp:`--compress-streams=y`,
   qpdf will compress any stream with no other filters applied to it
   with the ``/FlateDecode`` filter when it writes it. To suppress this
   behavior and preserve uncompressed streams as uncompressed, use
   :samp:`--compress-streams=n`.

:samp:`--decode-level={option}`
   Controls which streams qpdf tries to decode. The default is
   :samp:`generalized`. The following options are
   available:

   - :samp:`none`: do not attempt to decode any streams

   - :samp:`generalized`: decode streams filtered with
     supported generalized filters: ``/LZWDecode``, ``/FlateDecode``,
     ``/ASCII85Decode``, and ``/ASCIIHexDecode``. We define generalized
     filters as those to be used for general-purpose compression or
     encoding, as opposed to filters specifically designed for image
     data. Note that, by default, streams already compressed with
     ``/FlateDecode`` are not uncompressed and recompressed unless you
     also specify :samp:`--recompress-flate`.

   - :samp:`specialized`: in addition to generalized,
     decode streams with supported non-lossy specialized filters;
     currently this is just ``/RunLengthDecode``

   - :samp:`all`: in addition to generalized and
     specialized, decode streams with supported lossy filters;
     currently this is just ``/DCTDecode`` (JPEG)

:samp:`--stream-data={option}`
   Controls transformation of stream data. This option predates the
   :samp:`--compress-streams` and
   :samp:`--decode-level` options. Those options can be
   used to achieve the same affect with more control. The value of
   :samp:`{option}` may
   be one of the following:

   - :samp:`compress`: recompress stream data when
     possible (default); equivalent to
     :samp:`--compress-streams=y`
     :samp:`--decode-level=generalized`. Does not
     recompress streams already compressed with ``/FlateDecode`` unless
     :samp:`--recompress-flate` is also specified.

   - :samp:`preserve`: leave all stream data as is;
     equivalent to :samp:`--compress-streams=n`
     :samp:`--decode-level=none`

   - :samp:`uncompress`: uncompress stream data
     compressed with generalized filters when possible; equivalent to
     :samp:`--compress-streams=n`
     :samp:`--decode-level=generalized`

:samp:`--recompress-flate`
   By default, streams already compressed with ``/FlateDecode`` are left
   alone rather than being uncompressed and recompressed. This option
   causes qpdf to uncompress and recompress the streams. There is a
   significant performance cost to using this option, but you probably
   want to use it if you specify
   :samp:`--compression-level`.

:samp:`--compression-level={level}`
   When writing new streams that are compressed with ``/FlateDecode``,
   use the specified compression level. The value of
   :samp:`level` should be a number from 1 to 9 and is
   passed directly to zlib, which implements deflate compression. Note
   that qpdf doesn't uncompress and recompress streams by default. To
   have this option apply to already compressed streams, you should also
   specify :samp:`--recompress-flate`. If your goal is
   to shrink the size of PDF files, you should also use
   :samp:`--object-streams=generate`.

:samp:`--normalize-content=[yn]`
   Enables or disables normalization of content streams. Content
   normalization is enabled by default in QDF mode. Please see :ref:`qdf` for additional discussion of QDF mode.

:samp:`--object-streams={mode}`
   Controls handling of object streams. The value of
   :samp:`{mode}` may be
   one of the following:

   - :samp:`preserve`: preserve original object streams
     (default)

   - :samp:`disable`: don't write any object streams

   - :samp:`generate`: use object streams wherever
     possible

:samp:`--preserve-unreferenced`
   Tells qpdf to preserve objects that are not referenced when writing
   the file. Ordinarily any object that is not referenced in a traversal
   of the document from the trailer dictionary will be discarded. This
   may be useful in working with some damaged files or inspecting files
   with known unreferenced objects.

   This flag is ignored for linearized files and has the effect of
   causing objects in the new file to be written in order by object ID
   from the original file. This does not mean that object numbers will
   be the same since qpdf may create stream lengths as direct or
   indirect differently from the original file, and the original file
   may have gaps in its numbering.

   See also :samp:`--preserve-unreferenced-resources`,
   which does something completely different.

:samp:`--remove-unreferenced-resources={option}`
   The :samp:`{option}` may be ``auto``,
   ``yes``, or ``no``. The default is ``auto``.

   Starting with qpdf 8.1, when splitting pages, qpdf is able to attempt
   to remove images and fonts that are not used by a page even if they
   are referenced in the page's resources dictionary. When shared
   resources are in use, this behavior can greatly reduce the file sizes
   of split pages, but the analysis is very slow. In versions from 8.1
   through 9.1.1, qpdf did this analysis by default. Starting in qpdf
   10.0.0, if ``auto`` is used, qpdf does a quick analysis of the file
   to determine whether the file is likely to have unreferenced objects
   on pages, a pattern that frequently occurs when resource dictionaries
   are shared across multiple pages and rarely occurs otherwise. If it
   discovers this pattern, then it will attempt to remove unreferenced
   resources. Usually this means you get the slower splitting speed only
   when it's actually going to create smaller files. You can suppress
   removal of unreferenced resources altogether by specifying ``no`` or
   force it to do the full algorithm by specifying ``yes``.

   Other than cases in which you don't care about file size and care a
   lot about runtime, there are few reasons to use this option,
   especially now that ``auto`` mode is supported. One reason to use
   this is if you suspect that qpdf is removing resources it shouldn't
   be removing. If you encounter that case, please report it as bug at
   https://github.com/qpdf/qpdf/issues/.

:samp:`--preserve-unreferenced-resources`
   This is a synonym for
   :samp:`--remove-unreferenced-resources=no`.

   See also :samp:`--preserve-unreferenced`, which does
   something completely different.

:samp:`--newline-before-endstream`
   Tells qpdf to insert a newline before the ``endstream`` keyword, not
   counted in the length, after any stream content even if the last
   character of the stream was a newline. This may result in two
   newlines in some cases. This is a requirement of PDF/A. While qpdf
   doesn't specifically know how to generate PDF/A-compliant PDFs, this
   at least prevents it from removing compliance on already compliant
   files.

:samp:`--linearize-pass1={file}`
   Write the first pass of linearization to the named file. The
   resulting file is not a valid PDF file. This option is useful only
   for debugging ``QPDFWriter``'s linearization code. When qpdf
   linearizes files, it writes the file in two passes, using the first
   pass to calculate sizes and offsets that are required for hint tables
   and the linearization dictionary. Ordinarily, the first pass is
   discarded. This option enables it to be captured.

:samp:`--coalesce-contents`
   When a page's contents are split across multiple streams, this option
   causes qpdf to combine them into a single stream. Use of this option
   is never necessary for ordinary usage, but it can help when working
   with some files in some cases. For example, this can also be combined
   with QDF mode or content normalization to make it easier to look at
   all of a page's contents at once.

:samp:`--flatten-annotations={option}`
   This option collapses annotations into the pages' contents with
   special handling for form fields. Ordinarily, an annotation is
   rendered separately and on top of the page. Combining annotations
   into the page's contents effectively freezes the placement of the
   annotations, making them look right after various page
   transformations. The library functionality backing this option was
   added for the benefit of programs that want to create *n-up* page
   layouts and other similar things that don't work well with
   annotations. The :samp:`{option}` parameter
   may be any of the following:

   - :samp:`all`: include all annotations that are not
     marked invisible or hidden

   - :samp:`print`: only include annotations that
     indicate that they should appear when the page is printed

   - :samp:`screen`: omit annotations that indicate
     they should not appear on the screen

   Note that form fields are special because the annotations that are
   used to render filled-in form fields may become out of date from the
   fields' values if the form is filled in by a program that doesn't
   know how to update the appearances. If qpdf detects this case, its
   default behavior is not to flatten those annotations because doing so
   would cause the value of the form field to be lost. This gives you a
   chance to go back and resave the form with a program that knows how
   to generate appearances. QPDF itself can generate appearances with
   some limitations. See the
   :samp:`--generate-appearances` option below.

:samp:`--generate-appearances`
   If a file contains interactive form fields and indicates that the
   appearances are out of date with the values of the form, this flag
   will regenerate appearances, subject to a few limitations. Note that
   there is not usually a reason to do this, but it can be necessary
   before using the :samp:`--flatten-annotations`
   option. Most of these are not a problem with well-behaved PDF files.
   The limitations are as follows:

   - Radio button and checkbox appearances use the pre-set values in
     the PDF file. QPDF just makes sure that the correct appearance is
     displayed based on the value of the field. This is fine for PDF
     files that create their forms properly. Some PDF writers save
     appearances for fields when they change, which could cause some
     controls to have inconsistent appearances.

   - For text fields and list boxes, any characters that fall outside
     of US-ASCII or, if detected, "Windows ANSI" or "Mac Roman"
     encoding, will be replaced by the ``?`` character.

   - Quadding is ignored. Quadding is used to specify whether the
     contents of a field should be left, center, or right aligned with
     the field.

   - Rich text, multi-line, and other more elaborate formatting
     directives are ignored.

   - There is no support for multi-select fields or signature fields.

   If qpdf doesn't do a good enough job with your form, use an external
   application to save your filled-in form before processing it with
   qpdf.

:samp:`--optimize-images`
   This flag causes qpdf to recompress all images that are not
   compressed with DCT (JPEG) using DCT compression as long as doing so
   decreases the size in bytes of the image data and the image does not
   fall below minimum specified dimensions. Useful information is
   provided when used in combination with
   :samp:`--verbose`. See also the
   :samp:`--oi-min-width`,
   :samp:`--oi-min-height`, and
   :samp:`--oi-min-area` options. By default, starting
   in qpdf 8.4, inline images are converted to regular images and
   optimized as well. Use :samp:`--keep-inline-images`
   to prevent inline images from being included.

:samp:`--oi-min-width={width}`
   Avoid optimizing images whose width is below the specified amount. If
   omitted, the default is 128 pixels. Use 0 for no minimum.

:samp:`--oi-min-height={height}`
   Avoid optimizing images whose height is below the specified amount.
   If omitted, the default is 128 pixels. Use 0 for no minimum.

:samp:`--oi-min-area={area-in-pixels}`
   Avoid optimizing images whose pixel count (width × height) is below
   the specified amount. If omitted, the default is 16,384 pixels. Use 0
   for no minimum.

:samp:`--externalize-inline-images`
   Convert inline images to regular images. By default, images whose
   data is at least 1,024 bytes are converted when this option is
   selected. Use :samp:`--ii-min-bytes` to change the
   size threshold. This option is implicitly selected when
   :samp:`--optimize-images` is selected. Use
   :samp:`--keep-inline-images` to exclude inline images
   from image optimization.

:samp:`--ii-min-bytes={bytes}`
   Avoid converting inline images whose size is below the specified
   minimum size to regular images. If omitted, the default is 1,024
   bytes. Use 0 for no minimum.

:samp:`--keep-inline-images`
   Prevent inline images from being included in image optimization. This
   option has no affect when :samp:`--optimize-images`
   is not specified.

:samp:`--remove-page-labels`
   Remove page labels from the output file.

:samp:`--qdf`
   Turns on QDF mode. For additional information on QDF, please see :ref:`qdf`. Note that :samp:`--linearize`
   disables QDF mode.

:samp:`--min-version={version}`
   Forces the PDF version of the output file to be at least
   :samp:`{version}`. In other words, if the
   input file has a lower version than the specified version, the
   specified version will be used. If the input file has a higher
   version, the input file's original version will be used. It is seldom
   necessary to use this option since qpdf will automatically increase
   the version as needed when adding features that require newer PDF
   readers.

   The version number may be expressed in the form
   :samp:`{major.minor.extension-level}`, in
   which case the version is interpreted as
   :samp:`{major.minor}` at extension level
   :samp:`{extension-level}`. For example,
   version ``1.7.8`` represents version 1.7 at extension level 8. Note
   that minimal syntax checking is done on the command line.

:samp:`--force-version={version}`
   This option forces the PDF version to be the exact version specified
   *even when the file may have content that is not supported in that
   version*. The version number is interpreted in the same way as with
   :samp:`--min-version` so that extension levels can be
   set. In some cases, forcing the output file's PDF version to be lower
   than that of the input file will cause qpdf to disable certain
   features of the document. Specifically, 256-bit keys are disabled if
   the version is less than 1.7 with extension level 8 (except R5 is
   disabled if less than 1.7 with extension level 3), AES encryption is
   disabled if the version is less than 1.6, cleartext metadata and
   object streams are disabled if less than 1.5, 128-bit encryption keys
   are disabled if less than 1.4, and all encryption is disabled if less
   than 1.3. Even with these precautions, qpdf won't be able to do
   things like eliminate use of newer image compression schemes,
   transparency groups, or other features that may have been added in
   more recent versions of PDF.

   As a general rule, with the exception of big structural things like
   the use of object streams or AES encryption, PDF viewers are supposed
   to ignore features in files that they don't support from newer
   versions. This means that forcing the version to a lower version may
   make it possible to open your PDF file with an older version, though
   bear in mind that some of the original document's functionality may
   be lost.

By default, when a stream is encoded using non-lossy filters that qpdf
understands and is not already compressed using a good compression
scheme, qpdf will uncompress and recompress streams. Assuming proper
filter implements, this is safe and generally results in smaller files.
This behavior may also be explicitly requested with
:samp:`--stream-data=compress`.

When :samp:`--normalize-content=y` is specified, qpdf
will attempt to normalize whitespace and newlines in page content
streams. This is generally safe but could, in some cases, cause damage
to the content streams. This option is intended for people who wish to
study PDF content streams or to debug PDF content. You should not use
this for "production" PDF files.

When normalizing content, if qpdf runs into any lexical errors, it will
print a warning indicating that content may be damaged. The only
situation in which qpdf is known to cause damage during content
normalization is when a page's contents are split across multiple
streams and streams are split in the middle of a lexical token such as a
string, name, or inline image. Note that files that do this are invalid
since the PDF specification states that content streams are not to be
split in the middle of a token. If you want to inspect the original
content streams in an uncompressed format, you can always run with
:samp:`--qdf --normalize-content=n` for a QDF file
without content normalization, or alternatively
:samp:`--stream-data=uncompress` for a regular non-QDF
mode file with uncompressed streams. These will both uncompress all the
streams but will not attempt to normalize content. Please note that if
you are using content normalization or QDF mode for the purpose of
manually inspecting files, you don't have to care about this.

Object streams, also known as compressed objects, were introduced into
the PDF specification at version 1.5, corresponding to Acrobat 6. Some
older PDF viewers may not support files with object streams. qpdf can be
used to transform files with object streams to files without object
streams or vice versa. As mentioned above, there are three object stream
modes: :samp:`preserve`,
:samp:`disable`, and :samp:`generate`.

In :samp:`preserve` mode, the relationship to objects
and the streams that contain them is preserved from the original file.
In :samp:`disable` mode, all objects are written as
regular, uncompressed objects. The resulting file should be readable by
older PDF viewers. (Of course, the content of the files may include
features not supported by older viewers, but at least the structure will
be supported.) In :samp:`generate` mode, qpdf will
create its own object streams. This will usually result in more compact
PDF files, though they may not be readable by older viewers. In this
mode, qpdf will also make sure the PDF version number in the header is
at least 1.5.

The :samp:`--qdf` flag turns on QDF mode, which changes
some of the defaults described above. Specifically, in QDF mode, by
default, stream data is uncompressed, content streams are normalized,
and encryption is removed. These defaults can still be overridden by
specifying the appropriate options as described above. Additionally, in
QDF mode, stream lengths are stored as indirect objects, objects are
laid out in a less efficient but more readable fashion, and the
documents are interspersed with comments that make it easier for the
user to find things and also make it possible for
:command:`fix-qdf` to work properly. QDF mode is intended
for people, mostly developers, who wish to inspect or modify PDF files
in a text editor. For details, please see :ref:`qdf`.

.. _testing-options:

Testing, Inspection, and Debugging Options
------------------------------------------

These options can be useful for digging into PDF files or for use in
automated test suites for software that uses the qpdf library. When any
of the options in this section are specified, no output file should be
given. The following options are available:

:samp:`--deterministic-id`
   Causes generation of a deterministic value for /ID. This prevents use
   of timestamp and output file name information in the /ID generation.
   Instead, at some slight additional runtime cost, the /ID field is
   generated to include a digest of the significant parts of the content
   of the output PDF file. This means that a given qpdf operation should
   generate the same /ID each time it is run, which can be useful when
   caching results or for generation of some test data. Use of this flag
   is not compatible with creation of encrypted files.

:samp:`--static-id`
   Causes generation of a fixed value for /ID. This is intended for
   testing only. Never use it for production files. If you are trying to
   get the same /ID each time for a given file and you are not
   generating encrypted files, consider using the
   :samp:`--deterministic-id` option.

:samp:`--static-aes-iv`
   Causes use of a static initialization vector for AES-CBC. This is
   intended for testing only so that output files can be reproducible.
   Never use it for production files. This option in particular is not
   secure since it significantly weakens the encryption.

:samp:`--no-original-object-ids`
   Suppresses inclusion of original object ID comments in QDF files.
   This can be useful when generating QDF files for test purposes,
   particularly when comparing them to determine whether two PDF files
   have identical content.

:samp:`--show-encryption`
   Shows document encryption parameters. Also shows the document's user
   password if the owner password is given.

:samp:`--show-encryption-key`
   When encryption information is being displayed, as when
   :samp:`--check` or
   :samp:`--show-encryption` is given, display the
   computed or retrieved encryption key as a hexadecimal string. This
   value is not ordinarily useful to users, but it can be used as the
   argument to :samp:`--password` if the
   :samp:`--password-is-hex-key` is specified. Note
   that, when PDF files are encrypted, passwords and other metadata are
   used only to compute an encryption key, and the encryption key is
   what is actually used for encryption. This enables retrieval of that
   key.

:samp:`--check-linearization`
   Checks file integrity and linearization status.

:samp:`--show-linearization`
   Checks and displays all data in the linearization hint tables.

:samp:`--show-xref`
   Shows the contents of the cross-reference table in a human-readable
   form. This is especially useful for files with cross-reference
   streams which are stored in a binary format.

:samp:`--show-object=trailer|obj[,gen]`
   Show the contents of the given object. This is especially useful for
   inspecting objects that are inside of object streams (also known as
   "compressed objects").

:samp:`--raw-stream-data`
   When used along with the :samp:`--show-object`
   option, if the object is a stream, shows the raw stream data instead
   of object's contents.

:samp:`--filtered-stream-data`
   When used along with the :samp:`--show-object`
   option, if the object is a stream, shows the filtered stream data
   instead of object's contents. If the stream is filtered using filters
   that qpdf does not support, an error will be issued.

:samp:`--show-npages`
   Prints the number of pages in the input file on a line by itself.
   Since the number of pages appears by itself on a line, this option
   can be useful for scripting if you need to know the number of pages
   in a file.

:samp:`--show-pages`
   Shows the object and generation number for each page dictionary
   object and for each content stream associated with the page. Having
   this information makes it more convenient to inspect objects from a
   particular page.

:samp:`--with-images`
   When used along with :samp:`--show-pages`, also shows
   the object and generation numbers for the image objects on each page.
   (At present, information about images in shared resource dictionaries
   are not output by this command. This is discussed in a comment in the
   source code.)

:samp:`--json`
   Generate a JSON representation of the file. This is described in
   depth in :ref:`json`

:samp:`--json-help`
   Describe the format of the JSON output.

:samp:`--json-key=key`
   This option is repeatable. If specified, only top-level keys
   specified will be included in the JSON output. If not specified, all
   keys will be shown.

:samp:`--json-object=trailer|obj[,gen]`
   This option is repeatable. If specified, only specified objects will
   be shown in the "``objects``" key of the JSON output. If absent, all
   objects will be shown.

:samp:`--check`
   Checks file structure and well as encryption, linearization, and
   encoding of stream data. A file for which
   :samp:`--check` reports no errors may still have
   errors in stream data content but should otherwise be structurally
   sound. If :samp:`--check` any errors, qpdf will exit
   with a status of 2. There are some recoverable conditions that
   :samp:`--check` detects. These are issued as warnings
   instead of errors. If qpdf finds no errors but finds warnings, it
   will exit with a status of 3 (as of version 2.0.4). When
   :samp:`--check` is combined with other options,
   checks are always performed before any other options are processed.
   For erroneous files, :samp:`--check` will cause qpdf
   to attempt to recover, after which other options are effectively
   operating on the recovered file. Combining
   :samp:`--check` with other options in this way can be
   useful for manually recovering severely damaged files. Note that
   :samp:`--check` produces no output to standard output
   when everything is valid, so if you are using this to
   programmatically validate files in bulk, it is safe to run without
   output redirected to :file:`/dev/null` and just
   check for a 0 exit code.

The :samp:`--raw-stream-data` and
:samp:`--filtered-stream-data` options are ignored
unless :samp:`--show-object` is given. Either of these
options will cause the stream data to be written to standard output. In
order to avoid commingling of stream data with other output, it is
recommend that these objects not be combined with other test/inspection
options.

If :samp:`--filtered-stream-data` is given and
:samp:`--normalize-content=y` is also given, qpdf will
attempt to normalize the stream data as if it is a page content stream.
This attempt will be made even if it is not a page content stream, in
which case it will produce unusable results.

.. _unicode-passwords:

Unicode Passwords
-----------------

At the library API level, all methods that perform encryption and
decryption interpret passwords as strings of bytes. It is up to the
caller to ensure that they are appropriately encoded. Starting with qpdf
version 8.4.0, qpdf will attempt to make this easier for you when
interact with qpdf via its command line interface. The PDF specification
requires passwords used to encrypt files with 40-bit or 128-bit
encryption to be encoded with PDF Doc encoding. This encoding is a
single-byte encoding that supports ISO-Latin-1 and a handful of other
commonly used characters. It has a large overlap with Windows ANSI but
is not exactly the same. There is generally not a way to provide PDF Doc
encoded strings on the command line. As such, qpdf versions prior to
8.4.0 would often create PDF files that couldn't be opened with other
software when given a password with non-ASCII characters to encrypt a
file with 40-bit or 128-bit encryption. Starting with qpdf 8.4.0, qpdf
recognizes the encoding of the parameter and transcodes it as needed.
The rest of this section provides the details about exactly how qpdf
behaves. Most users will not need to know this information, but it might
be useful if you have been working around qpdf's old behavior or if you
are using qpdf to generate encrypted files for testing other PDF
software.

A note about Windows: when qpdf builds, it attempts to determine what it
has to do to use ``wmain`` instead of ``main`` on Windows. The ``wmain``
function is an alternative entry point that receives all arguments as
UTF-16-encoded strings. When qpdf starts up this way, it converts all
the strings to UTF-8 encoding and then invokes the regular main. This
means that, as far as qpdf is concerned, it receives its command-line
arguments with UTF-8 encoding, just as it would in any modern Linux or
UNIX environment.

If a file is being encrypted with 40-bit or 128-bit encryption and the
supplied password is not a valid UTF-8 string, qpdf will fall back to
the behavior of interpreting the password as a string of bytes. If you
have old scripts that encrypt files by passing the output of
:command:`iconv` to qpdf, you no longer need to do that,
but if you do, qpdf should still work. The only exception would be for
the extremely unlikely case of a password that is encoded with a
single-byte encoding but also happens to be valid UTF-8. Such a password
would contain strings of even numbers of characters that alternate
between accented letters and symbols. In the extremely unlikely event
that you are intentionally using such passwords and qpdf is thwarting
you by interpreting them as UTF-8, you can use
:samp:`--password-mode=bytes` to suppress qpdf's
automatic behavior.

The :samp:`--password-mode` option, as described earlier
in this chapter, can be used to change qpdf's interpretation of supplied
passwords. There are very few reasons to use this option. One would be
the unlikely case described in the previous paragraph in which the
supplied password happens to be valid UTF-8 but isn't supposed to be
UTF-8. Your best bet would be just to provide the password as a valid
UTF-8 string, but you could also use
:samp:`--password-mode=bytes`. Another reason to use
:samp:`--password-mode=bytes` would be to intentionally
generate PDF files encrypted with passwords that are not properly
encoded. The qpdf test suite does this to generate invalid files for the
purpose of testing its password recovery capability. If you were trying
to create intentionally incorrect files for a similar purposes, the
:samp:`bytes` password mode can enable you to do this.

When qpdf attempts to decrypt a file with a password that contains
non-ASCII characters, it will generate a list of alternative passwords
by attempting to interpret the password as each of a handful of
different coding systems and then transcode them to the required format.
This helps to compensate for the supplied password being given in the
wrong coding system, such as would happen if you used the
:command:`iconv` workaround that was previously needed.
It also generates passwords by doing the reverse operation: translating
from correct in incorrect encoding of the password. This would enable
qpdf to decrypt files using passwords that were improperly encoded by
whatever software encrypted the files, including older versions of qpdf
invoked without properly encoded passwords. The combination of these two
recovery methods should make qpdf transparently open most encrypted
files with the password supplied correctly but in the wrong coding
system. There are no real downsides to this behavior, but if you don't
want qpdf to do this, you can use the
:samp:`--suppress-password-recovery` option. One reason
to do that is to ensure that you know the exact password that was used
to encrypt the file.

With these changes, qpdf now generates compliant passwords in most
cases. There are still some exceptions. In particular, the PDF
specification directs compliant writers to normalize Unicode passwords
and to perform certain transformations on passwords with bidirectional
text. Implementing this functionality requires using a real Unicode
library like ICU. If a client application that uses qpdf wants to do
this, the qpdf library will accept the resulting passwords, but qpdf
will not perform these transformations itself. It is possible that this
will be addressed in a future version of qpdf. The ``QPDFWriter``
methods that enable encryption on the output file accept passwords as
strings of bytes.

Please note that the :samp:`--password-is-hex-key`
option is unrelated to all this. This flag bypasses the normal process
of going from password to encryption string entirely, allowing the raw
encryption key to be specified directly. This is useful for forensic
purposes or for brute-force recovery of files with unknown passwords.
