2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-12-22 10:58:58 +00:00

Merge pull request #1208 from m-holger/manual

Standardize on "qpdf"
This commit is contained in:
Jay Berkenbilt 2024-06-10 15:40:57 -04:00 committed by GitHub
commit 9106a5e308
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 237 additions and 120 deletions

View File

@ -1,9 +1,15 @@
# Using the QPDF AppImage bundle (for Linux x86_64 systems only)
# Using the qpdf AppImage bundle (for Linux x86_64 systems only)
Tips:
* After downloading, you have to set the executable bit for any AppImage (for security reasons this is disabled by default): `chmod +x <name-of-application>.AppImage`
* After downloading, you have to set the executable bit for any AppImage (for security reasons this is disabled by
default): `chmod +x <name-of-application>.AppImage`
* Run the QPDF AppImage with the `--ai-usage` parameter to start learning some useful details about built-in features of this specific AppImage.
* Run the qpdf AppImage with the `--ai-usage` parameter to start learning some useful details about built-in features of
this specific AppImage.
* You can rename the AppImage to any name allowed for file names on Linux. The `.AppImage` suffix is not required for it to function. It will also work as expected if you invoke it from a symlink. Using `qpdf` as its filename or symlink name is OK. However, you may want to continue using the QPDF package provided by your system's package manager side by side with the AppImage bundle: in this case it is recommended to use `qpdf.ai` as a short name for (or as the symlink name to) the qpdf-<version>.AppImage.
* You can rename the AppImage to any name allowed for file names on Linux. The `.AppImage` suffix is not required for it
to function. It will also work as expected if you invoke it from a symlink. Using `qpdf` as its filename or symlink
name is OK. However, you may want to continue using the qpdf package provided by your system's package manager side by
side with the AppImage bundle: in this case it is recommended to use `qpdf.ai` as a short name for (or as the symlink
name to) the qpdf-<version>.AppImage.

View File

@ -1,4 +1,4 @@
WHERE TO FIND THE QPDF DOCUMENTATION
WHERE TO FIND THE qpdf DOCUMENTATION
Complete documentation for qpdf can be found online here:
https://qpdf.readthedocs.io

View File

@ -1,31 +1,59 @@
To build from source for Linux or other UNIX/UNIX-like systems, it is generally sufficient to download just the source `qpdf-<version>.tar.gz` file.
To build from source for Linux or other UNIX/UNIX-like systems, it is generally sufficient to download just the
source `qpdf-<version>.tar.gz` file.
Windows Binaries
You can download Windows binaries that are statically linked with qpdf's external dependencies and use the OpenSSL crypto provider. There are several options:
You can download Windows binaries that are statically linked with qpdf's external dependencies and use the OpenSSL
crypto provider. There are several options:
* For Windows installers, you can download the `.exe` file for a traditional installer that allows relocation, or you can download the `.zip` file which you can unzip to any location. Note that the `msvc` executables perform slightly better than the `mingw` executables.
* For Windows installers, you can download the `.exe` file for a traditional installer that allows relocation, or you
can download the `.zip` file which you can unzip to any location. Note that the `msvc` executables perform slightly
better than the `mingw` executables.
* `qpdf-<version>-bin-msvc64.exe` - Use this for 64-bit Windows systems. This is the highest performance Windows release. It is usually the best choice for using qpdf from the command line. It is also the right choice if you are building non-Debug code for 64-bit systems using a recent version of Microsoft Visual C++.
* `qpdf-<version>-bin-msvc64.exe` - Use this for 64-bit Windows systems. This is the highest performance Windows
release. It is usually the best choice for using qpdf from the command line. It is also the right choice if you are
building non-Debug code for 64-bit systems using a recent version of Microsoft Visual C++.
* `qpdf-<version>-bin-mingw64.exe` - This is a 64-bit version built with mingw. Use this for 64-bit Windows systems if you want development libraries that work with the 64-bit version of mingw. If you are dynamically loading qpdf from the DLL, this version has fewer DLLs than the msvc version and does not require a Visual C++ runtime DLL. Unlike with the MSVC releases, it is possible to link a debugging build with mingw against non-debugging libraries built with mingw.
* `qpdf-<version>-bin-mingw64.exe` - This is a 64-bit version built with mingw. Use this for 64-bit Windows systems if
you want development libraries that work with the 64-bit version of mingw. If you are dynamically loading qpdf from
the DLL, this version has fewer DLLs than the msvc version and does not require a Visual C++ runtime DLL. Unlike with
the MSVC releases, it is possible to link a debugging build with mingw against non-debugging libraries built with
mingw.
* `qpdf-<version>-bin-msvc32.exe` - This is a 32-bit version built with MSVC. Use this if you need to run qpdf on a 32-bit system or if you are building 32-bit executables in non-Debug mode with Microsoft Visual C++. The 32-bit executables will work on 64-bit systems as well and are capable of working with files larger than 2 GB.
* `qpdf-<version>-bin-msvc32.exe` - This is a 32-bit version built with MSVC. Use this if you need to run qpdf on a
32-bit system or if you are building 32-bit executables in non-Debug mode with Microsoft Visual C++. The 32-bit
executables will work on 64-bit systems as well and are capable of working with files larger than 2 GB.
* `qpdf-<version>-bin-mingw32.exe` - This is a 32-bit version built with mingw. It will work on 32-bit or 64-bit systems and can handle files larger than 2 GB.
* `qpdf-<version>-bin-mingw32.exe` - This is a 32-bit version built with mingw. It will work on 32-bit or 64-bit systems
and can handle files larger than 2 GB.
Linux Binaries
Virtually all Linux distributions include packages for qpdf. There is also a PPA for Ubuntu at https://launchpad.net/~qpdf/+archive/ubuntu/qpdf that includes the latest version of qpdf for recent versions of Ubuntu. However, there are some downloads available for Linux as well.
Virtually all Linux distributions include packages for qpdf. There is also a PPA for Ubuntu
at https://launchpad.net/~qpdf/+archive/ubuntu/qpdf that includes the latest version of qpdf for recent versions of
Ubuntu. However, there are some downloads available for Linux as well.
* `qpdf-<version>-x86_64.AppImage` - If you'd like to run the latest version of qpdf as an [AppImage](https://appimage.org/), you can download this. This is a self-contained executable that you make symlink `qpdf` to and run on most reasonably recent Linux distributions. See README-appimage.md in the qpdf source distribution for additional details, or run the AppImage with the `--ai-usage` argument to get help specific to the AppImage.
* `qpdf-<version>-x86_64.AppImage` - If you'd like to run the latest version of qpdf as
an [AppImage](https://appimage.org/), you can download this. This is a self-contained executable that you make
symlink `qpdf` to and run on most reasonably recent Linux distributions. See README-appimage.md in the qpdf source
distribution for additional details, or run the AppImage with the `--ai-usage` argument to get help specific to the
AppImage.
* `qpdf-<version>-bin-linux-x86_64.zip` - This is not intended to be an end-user distribution. It is a (nearly) stand-alone Linux binary, built using an Ubuntu LTS release. It contains the qpdf executables and shared libraries as well as dependent shared libraries that would not typically be present on a minimal system. This can be used to include qpdf in a minimal environment such as a docker container. It is also known to work as a layer in AWS Lambda and was initially created for that purpose. The executables have their runpath set to looks for the qpdf library in `../lib` relative to the location of the executables, which makes this distribution relocatable.
* `qpdf-<version>-bin-linux-x86_64.zip` - This is not intended to be an end-user distribution. It is a (nearly)
stand-alone Linux binary, built using an Ubuntu LTS release. It contains the qpdf executables and shared libraries as
well as dependent shared libraries that would not typically be present on a minimal system. This can be used to
include qpdf in a minimal environment such as a docker container. It is also known to work as a layer in AWS Lambda
and was initially created for that purpose. The executables have their runpath set to looks for the qpdf library
in `../lib` relative to the location of the executables, which makes this distribution relocatable.
Windows Build Support
If you are building on Windows and want to use pre-built external static libraries, you should obtain current versions from https://github.com/qpdf/external-libs/releases. The `external-libs` directory contains older versions that will not work with qpdf versions >= 10.0.2. Please see README-windows.md in the qpdf source distribution. The libraries from this distribution will not work with a Debug build with MSVC.
If you are building on Windows and want to use pre-built external static libraries, you should obtain current versions
from https://github.com/qpdf/external-libs/releases. The `external-libs` directory contains older versions that will not
work with qpdf versions >= 10.0.2. Please see README-windows.md in the qpdf source distribution. The libraries from this
distribution will not work with a Debug build with MSVC.
Documentation
* `qpdf-<version>-doc.zip` - This is a downloadable version of the QPDF manual. An online version is hosted at https://qpdf.readthedocs.io.
* `qpdf-<version>-doc.zip` - This is a downloadable version of the qpdf manual. An online version is hosted
at https://qpdf.readthedocs.io.

155
README.md
View File

@ -1,37 +1,49 @@
# QPDF
[![qpdf](logo/qpdf.svg)](https://qpdf.sourceforge.io)
[![QPDF](logo/qpdf.svg)](https://qpdf.sourceforge.io)
[![QPDF Build](https://github.com/qpdf/qpdf/workflows/QPDF%20Build/badge.svg)](https://github.com/qpdf/qpdf/actions)
[![qpdf Build](https://github.com/qpdf/qpdf/workflows/QPDF%20Build/badge.svg)](https://github.com/qpdf/qpdf/actions)
[![Documentation Status](https://readthedocs.org/projects/qpdf/badge/?version=latest)](https://qpdf.readthedocs.io/en/latest/?badge=latest)
QPDF is a command-line tool and C++ library that performs content-preserving transformations on PDF files. It supports linearization, encryption, and numerous other features. It can also be used for splitting and merging files, creating PDF files (but you have to supply all the content yourself), and inspecting files for study or analysis. QPDF does not render PDFs or perform text extraction, and it does not contain higher-level interfaces for working with page contents. It is a low-level tool for working with the structure of PDF files and can be a valuable tool for anyone who wants to do programmatic or command-line-based manipulation of PDF files.
qpdf is a command-line tool and C++ library that performs content-preserving transformations on PDF files. It supports
linearization, encryption, and numerous other features. It can also be used for splitting and merging files, creating
PDF files (but you have to supply all the content yourself), and inspecting files for study or analysis. qpdf does not
render PDFs or perform text extraction, and it does not contain higher-level interfaces for working with page contents.
It is a low-level tool for working with the structure of PDF files and can be a valuable tool for anyone who wants to do
programmatic or command-line-based manipulation of PDF files.
The [QPDF Manual](https://qpdf.readthedocs.io) is hosted online at https://qpdf.readthedocs.io. The project website is https://qpdf.sourceforge.io. The source code repository is hosted at GitHub: https://github.com/qpdf/qpdf.
The [qpdf Manual](https://qpdf.readthedocs.io) is hosted online at https://qpdf.readthedocs.io. The project website
is https://qpdf.sourceforge.io. The source code repository is hosted at GitHub: https://github.com/qpdf/qpdf.
# Verifying Distributions
The public key used to sign qpdf source distributions has fingerprint `C2C9 6B10 011F E009 E6D1 DF82 8A75 D109 9801 2C7E` and can be found at https://q.ql.org/pubkey.asc or downloaded from a public key server.
The public key used to sign qpdf source distributions has
fingerprint `C2C9 6B10 011F E009 E6D1 DF82 8A75 D109 9801 2C7E` and can be found at https://q.ql.org/pubkey.asc or
downloaded from a public key server.
# Copyright, License
QPDF is copyright (c) 2005-2024 Jay Berkenbilt
qpdf is copyright (c) 2005-2024 Jay Berkenbilt
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
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
https://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.
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.
You may also see the license in the file [LICENSE.txt](LICENSE.txt) in the source distribution.
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. The Artistic License appears in the file [Artistic-2.0](Artistic-2.0) in the source distribution.
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. The Artistic License appears in the file [Artistic-2.0](Artistic-2.0) in the source distribution.
# Prerequisites
QPDF requires a C++ compiler that supports C++-17.
qpdf requires a C++ compiler that supports C++-17.
To compile and link something with qpdf, you can use `pkg-config` with package name `libqpdf` or `cmake` with package name `qpdf`. Here's an example of a `CMakeLists.txt` file that builds a program with the qpdf library:
To compile and link something with qpdf, you can use `pkg-config` with package name `libqpdf` or `cmake` with package
name `qpdf`. Here's an example of a `CMakeLists.txt` file that builds a program with the qpdf library:
```
cmake_minimum_required(VERSION 3.16)
@ -41,50 +53,76 @@ add_executable(some-application some-application.cc)
target_link_libraries(some-application qpdf::libqpdf)
```
QPDF depends on the external libraries [zlib](https://www.zlib.net/) and [jpeg](https://www.ijg.org/files/). The [libjpeg-turbo](https://libjpeg-turbo.org/) library is also known to work since it is compatible with the regular jpeg library, and QPDF doesn't use any interfaces that aren't present in the straight jpeg8 API. These are part of every Linux distribution and are readily available. Download information appears in the documentation. For Windows, you can download pre-built binary versions of these libraries for some compilers; see [README-windows.md](README-windows.md) for additional details.
qpdf depends on the external libraries [zlib](https://www.zlib.net/) and [jpeg](https://www.ijg.org/files/).
The [libjpeg-turbo](https://libjpeg-turbo.org/) library is also known to work since it is compatible with the regular
jpeg library, and qpdf doesn't use any interfaces that aren't present in the straight jpeg8 API. These are part of every
Linux distribution and are readily available. Download information appears in the documentation. For Windows, you can
download pre-built binary versions of these libraries for some compilers; see [README-windows.md](README-windows.md) for
additional details.
Depending on which crypto providers are enabled, then [GnuTLS](https://www.gnutls.org/) and [OpenSSL](https://openssl.org) may also be required. This is discussed more in [Crypto providers](#crypto-providers) below.
Depending on which crypto providers are enabled, then [GnuTLS](https://www.gnutls.org/)
and [OpenSSL](https://openssl.org) may also be required. This is discussed more in [Crypto providers](#crypto-providers)
below.
Detailed information appears in the [manual](https://qpdf.readthedocs.io/en/latest/installation.html).
# Licensing terms of embedded software
QPDF makes use of zlib and jpeg libraries for its functionality. These packages can be downloaded separately from their own download locations. If the optional GnuTLS or OpenSSL crypto providers are enabled, then GnuTLS and/or OpenSSL are also required.
qpdf makes use of zlib and jpeg libraries for its functionality. These packages can be downloaded separately from their
own download locations. If the optional GnuTLS or OpenSSL crypto providers are enabled, then GnuTLS and/or OpenSSL are
also required.
Please see the [NOTICE](NOTICE.md) file for information on licenses of embedded software.
# Crypto providers
qpdf can use different crypto implementations. These can be selected at compile time or at runtime. The native crypto implementations that were used in all versions prior to 9.1.0 are still present, but they are not built into qpdf by default if any external providers are available at build time.
qpdf can use different crypto implementations. These can be selected at compile time or at runtime. The native crypto
implementations that were used in all versions prior to 9.1.0 are still present, but they are not built into qpdf by
default if any external providers are available at build time.
The following providers are available:
* `gnutls`: an implementation that uses the GnuTLS library to provide crypto; causes libqpdf to link with the GnuTLS library
* `openssl`: an implementation that can use the OpenSSL (or BoringSSL) libraries to provide crypto; causes libqpdf to link with the OpenSSL library
* `gnutls`: an implementation that uses the GnuTLS library to provide crypto; causes libqpdf to link with the GnuTLS
library
* `openssl`: an implementation that can use the OpenSSL (or BoringSSL) libraries to provide crypto; causes libqpdf to
link with the OpenSSL library
* `native`: a native implementation where all the source is embedded in qpdf and no external dependencies are required
The default behavior is for cmake to discover which other crypto providers can be supported based on available external libraries, to build all available external crypto providers, and to use an external provider as the default over the native one. By default, the native crypto provider will be used only if no external providers are available. This behavior can be changed with various cmake options as [described in the manual](https://qpdf.readthedocs.io/en/latest/installation.html#build-time-crypto-selection).
The default behavior is for cmake to discover which other crypto providers can be supported based on available external
libraries, to build all available external crypto providers, and to use an external provider as the default over the
native one. By default, the native crypto provider will be used only if no external providers are available. This
behavior can be changed with various cmake options
as [described in the manual](https://qpdf.readthedocs.io/en/latest/installation.html#build-time-crypto-selection).
## Note about weak cryptographic algorithms
The PDF file format used to rely on RC4 for encryption. Using 256-bit keys always uses AES instead, and with 128-bit keys, you can elect to use AES. qpdf does its best to warn when someone is writing a file with weak cryptographic algorithms, but qpdf must always retain support for being able to read and even write files with weak encryption to be able to fully support older PDF files and older PDF readers.
The PDF file format used to rely on RC4 for encryption. Using 256-bit keys always uses AES instead, and with 128-bit
keys, you can elect to use AES. qpdf does its best to warn when someone is writing a file with weak cryptographic
algorithms, but qpdf must always retain support for being able to read and even write files with weak encryption to be
able to fully support older PDF files and older PDF readers.
# Building from source distribution on UNIX/Linux
Starting with version 11, qpdf builds with cmake. The default configuration with cmake works on most systems. On Windows, you can build qpdf with Visual Studio using cmake without having any additional tools installed. However, to run the test suite, you need MSYS2, and you also need MSYS2 to build with mingw.
Starting with version 11, qpdf builds with cmake. The default configuration with cmake works on most systems. On
Windows, you can build qpdf with Visual Studio using cmake without having any additional tools installed. However, to
run the test suite, you need MSYS2, and you also need MSYS2 to build with mingw.
Example UNIX/Linux build:
```
cmake -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build
```
Example mingw build from an MSYS2 mingw shell:
```
cmake -S . -B build -G 'MSYS Makefiles' -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build
```
Example MSVC build from an MSYS shell or from a Windows command shell with Visual Studio command-line tools in the path:
```
cmake -S . -B build
cmake --build build --config Release
@ -92,40 +130,85 @@ cmake --build build --config Release
Installation can be done with `cmake --install`. Packages can be made with `cpack`.
The tests use `qtest`, and the test driver is invoked by `ctest`. To see the real underlying tests, run `ctest --verbose` so that you can see `qtest`'s output. If you need to turn off qtest's color output, pass `-DQTEST_COLOR=0` to cmake.
The tests use `qtest`, and the test driver is invoked by `ctest`. To see the real underlying tests,
run `ctest --verbose` so that you can see `qtest`'s output. If you need to turn off qtest's color output,
pass `-DQTEST_COLOR=0` to cmake.
For additional information, please refer to the [manual](https://qpdf.readthedocs.io/en/latest/installation.html).
# Building on Windows
qpdf is known to build and pass its test suite with mingw and Microsoft Visual C++. Both 32-bit and 64-bit versions work. In addition to the manual, see [README-windows.md](README-windows.md) for more details on how to build under Windows.
qpdf is known to build and pass its test suite with mingw and Microsoft Visual C++. Both 32-bit and 64-bit versions
work. In addition to the manual, see [README-windows.md](README-windows.md) for more details on how to build under
Windows.
# Building Documentation
The QPDF manual is written in reStructured Text format and is build with [sphinx](https://www.sphinx-doc.org). The sources to the user manual can be found in the `manual` directory. For more detailed information, consult the [Building and Installing QPDF section of the manual](https://qpdf.readthedocs.io/en/latest/installation.html) or consult the [build-doc script](build-scripts/build-doc).
The qpdf manual is written in reStructured Text format and is build with [sphinx](https://www.sphinx-doc.org). The
sources to the user manual can be found in the `manual` directory. For more detailed information, consult
the [Building and Installing qpdf section of the manual](https://qpdf.readthedocs.io/en/latest/installation.html) or
consult the [build-doc script](build-scripts/build-doc).
# Additional Notes on Build
qpdf provides cmake configuration files and pkg-config files. They support static and dynamic linking. In general, you do not need the header files from qpdf's dependencies to be available to builds that _use_ qpdf. The only exception to this is that, if you include `Pl_DCT.hh`, you need header files from `libjpeg`. Since this is a rare case, qpdf's cmake and pkg-config files do not automatically add a JPEG include path to the build. If you are using `Pl_DCT` explicitly, you probably already have that configured in your build.
qpdf provides cmake configuration files and pkg-config files. They support static and dynamic linking. In general, you
do not need the header files from qpdf's dependencies to be available to builds that _use_ qpdf. The only exception to
this is that, if you include `Pl_DCT.hh`, you need header files from `libjpeg`. Since this is a rare case, qpdf's cmake
and pkg-config files do not automatically add a JPEG include path to the build. If you are using `Pl_DCT` explicitly,
you probably already have that configured in your build.
To learn about using the library, please read comments in the header files in [include/qpdf](include/qpdf/), especially [QPDF.hh](include/qpdf/QPDF.hh), [QPDFObjectHandle.hh](include/qpdf/QPDFObjectHandle.hh), and
[QPDFWriter.hh](include/qpdf/QPDFWriter.hh). These are the best sources of documentation on the API. You can also study the code of [QPDFJob.cc](libqpdf/QPDFJob.cc), which exercises most of the public interface. There are additional example programs in the [examples](examples/) directory.
To learn about using the library, please read comments in the header files in [include/qpdf](include/qpdf/),
especially [QPDF.hh](include/qpdf/QPDF.hh), [QPDFObjectHandle.hh](include/qpdf/QPDFObjectHandle.hh), and
[QPDFWriter.hh](include/qpdf/QPDFWriter.hh). These are the best sources of documentation on the API. You can also study
the code of [QPDFJob.cc](libqpdf/QPDFJob.cc), which exercises most of the public interface. There are additional example
programs in the [examples](examples/) directory.
# Additional Notes on Test Suite
By default, slow tests and tests that require dependencies beyond those needed to build qpdf are disabled. Slow tests include image comparison tests and large file tests. Image comparison tests can be enabled by setting the `QPDF_TEST_COMPARE_IMAGES` environment variable to `1`. Large file tests can be enabled setting the `QPDF_LARGE_FILE_TEST_PATH` environment variable to the absolute path of a directory with at least 11 GB of free space that can handle files over 4 GB in size. On Windows, this should be a Windows path (e.g. `C:\LargeFileTemp` even if the build is being run from an MSYS2 environment. The test suite provides nearly full coverage even without these tests. Unless you are making deep changes to the library that would impact the contents of the generated PDF files or testing this on a new platform for the first time, there is no real reason to run these tests. If you're just running the test suite to make sure that qpdf works for your build, the default tests are adequate.
By default, slow tests and tests that require dependencies beyond those needed to build qpdf are disabled. Slow tests
include image comparison tests and large file tests. Image comparison tests can be enabled by setting
the `QPDF_TEST_COMPARE_IMAGES` environment variable to `1`. Large file tests can be enabled setting
the `QPDF_LARGE_FILE_TEST_PATH` environment variable to the absolute path of a directory with at least 11 GB of free
space that can handle files over 4 GB in size. On Windows, this should be a Windows path (e.g. `C:\LargeFileTemp` even
if the build is being run from an MSYS2 environment. The test suite provides nearly full coverage even without these
tests. Unless you are making deep changes to the library that would impact the contents of the generated PDF files or
testing this on a new platform for the first time, there is no real reason to run these tests. If you're just running
the test suite to make sure that qpdf works for your build, the default tests are adequate.
If you are packaging qpdf for a distribution and preparing a build that is run by an autobuilder, you may want to pass `-DSHOW_FAILED_TEST_OUTPUT=1` to `cmake` and run `ctest` with the `--verbose` or `--output-on-failure` option. This way, if the test suite fails, test failure detail will be included in the build output. Otherwise, you will have to have access to the `qtest.log` file from the build to view test failures. The Debian packages for qpdf enable this option. More notes for packagers can be found in [the manual](https://qpdf.readthedocs.io/en/latest/packaging.html).
If you are packaging qpdf for a distribution and preparing a build that is run by an autobuilder, you may want to
pass `-DSHOW_FAILED_TEST_OUTPUT=1` to `cmake` and run `ctest` with the `--verbose` or `--output-on-failure` option. This
way, if the test suite fails, test failure detail will be included in the build output. Otherwise, you will have to have
access to the `qtest.log` file from the build to view test failures. The Debian packages for qpdf enable this option.
More notes for packagers can be found in [the manual](https://qpdf.readthedocs.io/en/latest/packaging.html).
# Random Number Generation
By default, qpdf uses the crypto provider for generating random numbers. The rest of this applies only if you are using the native crypto provider.
By default, qpdf uses the crypto provider for generating random numbers. The rest of this applies only if you are using
the native crypto provider.
If the native crypto provider is in use, then, when `qpdf` detects either the Windows cryptography API or the existence of `/dev/urandom`, `/dev/arandom`, or `/dev/random`, it uses them to generate cryptographically secure random numbers. If none of these conditions are true, the build will fail with an error. This behavior can be modified in several ways:
* If you use the cmake option `SKIP_OS_SECURE_RANDOM` or define the `SKIP_OS_SECURE_RANDOM` preprocessor symbol, qpdf will not attempt to use Windows cryptography or the random device. You must either supply your own random data provider or allow use of insecure random numbers.
* If you turn on the cmake option `USE_INSECURE_RANDOM` or define the `USE_INSECURE_RANDOM` preprocessor symbol, qpdf will try insecure random numbers if OS-provided secure random numbers are disabled. This is not a fallback. In order for insecure random numbers to be used, you must also disable OS secure random numbers since, otherwise, failure to find OS secure random numbers is a compile error. The insecure random number source is stdlib's `random()` or `rand()` calls. These random numbers are not cryptography secure, but the qpdf library is fully functional using them. Using non-secure random numbers means that it's easier in some cases to guess encryption keys.
* In all cases, you may supply your own random data provider. To do this, derive a class from `qpdf/RandomDataProvider` (since version 5.1.0) and call `QUtil::setRandomDataProvider` before you create any `QPDF` objects. If you supply your own random data provider, it will always be used even if support for one of the other random data providers is compiled in. If you wish to avoid any possibility of your build of qpdf from using anything but a user-supplied random data provider, you can define `SKIP_OS_SECURE_RANDOM` and not `USE_INSECURE_RANDOM`. In this case, qpdf will throw a runtime error if any attempt is made to generate random numbers and no random data provider has been supplied.
If the native crypto provider is in use, then, when `qpdf` detects either the Windows cryptography API or the existence
of `/dev/urandom`, `/dev/arandom`, or `/dev/random`, it uses them to generate cryptographically secure random numbers.
If none of these conditions are true, the build will fail with an error. This behavior can be modified in several ways:
* If you use the cmake option `SKIP_OS_SECURE_RANDOM` or define the `SKIP_OS_SECURE_RANDOM` preprocessor symbol, qpdf
will not attempt to use Windows cryptography or the random device. You must either supply your own random data
provider or allow use of insecure random numbers.
* If you turn on the cmake option `USE_INSECURE_RANDOM` or define the `USE_INSECURE_RANDOM` preprocessor symbol, qpdf
will try insecure random numbers if OS-provided secure random numbers are disabled. This is not a fallback. In order
for insecure random numbers to be used, you must also disable OS secure random numbers since, otherwise, failure to
find OS secure random numbers is a compile error. The insecure random number source is stdlib's `random()` or `rand()`
calls. These random numbers are not cryptography secure, but the qpdf library is fully functional using them. Using
non-secure random numbers means that it's easier in some cases to guess encryption keys.
* In all cases, you may supply your own random data provider. To do this, derive a class
from `qpdf/RandomDataProvider` (since version 5.1.0) and call `QUtil::setRandomDataProvider` before you create
any `QPDF` objects. If you supply your own random data provider, it will always be used even if support for one of the
other random data providers is compiled in. If you wish to avoid any possibility of your build of qpdf from using
anything but a user-supplied random data provider, you can define `SKIP_OS_SECURE_RANDOM` and
not `USE_INSECURE_RANDOM`. In this case, qpdf will throw a runtime error if any attempt is made to generate random
numbers and no random data provider has been supplied.
# Acknowledgments
The qpdf project has a JetBrains license through their [Open Source Program](https://www.jetbrains.com/community/opensource/#support). We are grateful for this program and have been enjoying the benefits of their high-quality products.
The qpdf project has a JetBrains license through
their [Open Source Program](https://www.jetbrains.com/community/opensource/#support). We are grateful for this program
and have been enjoying the benefits of their high-quality products.

View File

@ -6,7 +6,7 @@ to another (or back to the same PDF). A secondary goal is to add more flexibilit
which documents can be split and combined (flexible assembly).
This is a work in progress. As implementation proceeds, details will become more solid. Comments are
encouraged. Please make comments in the [QPDF pages epic
encouraged. Please make comments in the [qpdf pages epic
discussion](https://github.com/qpdf/qpdf/discussions/1104). As ideas are refined, they will be
updated in this document.

View File

@ -99,7 +99,7 @@ Documentation
* Do a full pass through the documentation.
* Make sure `qpdf` is consistent. Use QPDF when just referring to the package.
* Make sure `qpdf` is consistent. Use qpdf when just referring to the package.
* Make sure markup is consistent
* Autogenerate where possible
* Consider which parts might be good candidates for moving to the wiki.
@ -337,7 +337,7 @@ so, I find it useful to make reference to them in this list.
an object. I think qpdf must handle generations correctly, but make sure to test this carefully.
Note that there's nothing that says an indirect object in one update can't refer to an object that
doesn't appear until a later update. This means that QPDF has to hang onto indirect nulls,
doesn't appear until a later update. This means that qpdf has to hang onto indirect nulls,
including when they appear as dictionary values. In this case, QPDF_Dictionary::getKeys() ignores
all keys with null values, and hasKey() returns false for keys that have null values. QPDF_Dictionary
already handles the special case of keys that are indirect nulls, which is used to reserve foreign
@ -431,7 +431,7 @@ so, I find it useful to make reference to them in this list.
* Support for handling file names with Unicode characters in Windows is incomplete. qpdf seems to
support them okay from a functionality standpoint, and the right thing happens if you pass in
UTF-8 encoded filenames to QPDF library routines in Windows (they are converted internally to
UTF-8 encoded filenames to qpdf library routines in Windows (they are converted internally to
wchar_t*), but file names are encoded in UTF-8 on output, which doesn't produce nice error
messages or output on Windows in some cases.
@ -658,7 +658,7 @@ Rejected Ideas
QPDFObjectHandle::getOwningQPDF() return a std::weak_ptr<QPDF>. Prior to #726 (
QPDFObject/QPDFValue split, released in qpdf 11.0.0), getOwningQPDF() could return an invalid
pointer if the owning QPDF disappeared, but this is no longer the case, which removes the main
motivation. QPDF 11 added QPDF::create() anyway though.
motivation. qpdf 11 added QPDF::create() anyway though.
Removing raw QPDF* would look something like this. Note that you can't use std::make_shared<T>
unless T has a public constructor.

View File

@ -3,7 +3,7 @@
Acknowledgments
===============
QPDF was originally created in 2001 and modified periodically between
qpdf was originally created in 2001 and modified periodically between
2001 and 2005 during my employment at `Apex CoVantage
<https://apexcovantage.com/>`__. Upon my departure from Apex, the
company graciously allowed me to take ownership of the software and
@ -14,5 +14,5 @@ such a decision. This work would not have been possible without their
support.
In 2020, I joined `Advent Health Partners <https://adventhp.com/>`__,
which has sponsored some previous QPDF work and generously allows me
to spend some "company time" maintaining QPDF.
which has sponsored some previous qpdf work and generously allows me
to spend some "company time" maintaining qpdf.

View File

@ -154,7 +154,7 @@ request as submitted.
Personal Comments
-----------------
QPDF started as a work project in 2002. The first open source release
qpdf started as a work project in 2002. The first open source release
was in 2008. While there have been a handful of contributors, the vast
majority of the code was written by one person over many years as a
side project.

View File

@ -133,7 +133,7 @@ certain document constructions. These are discussed in :ref:`helper-classes`.
Helper Classes
--------------
QPDF version 8.1 introduced the concept of helper classes. Helper
qpdf version 8.1 introduced the concept of helper classes. Helper
classes are intended to contain higher level APIs that allow developers
to work with certain document constructs at an abstraction level above
that of ``QPDFObjectHandle`` while staying true to qpdf's philosophy of
@ -232,7 +232,7 @@ using helper classes.
Implementation Notes
--------------------
This section contains a few notes about QPDF's internal implementation,
This section contains a few notes about qpdf's internal implementation,
particularly around what it does when it first processes a file. This
section is a bit of a simplification of what it actually does, but it
could serve as a starting point to someone trying to understand the
@ -281,7 +281,7 @@ object stream contents is discarded. In this way, the first time an
object in an object stream is requested, all objects in the stream are
cached.
The following example should clarify how ``QPDF`` processes a simple
The following example should clarify how ``qpdf`` processes a simple
file.
- Client constructs ``QPDF`` ``pdf`` and calls
@ -336,11 +336,11 @@ file.
.. _object_internals:
QPDF Object Internals
qpdf Object Internals
---------------------
The internals of ``QPDFObjectHandle`` and how qpdf stores objects were
significantly rewritten for QPDF 11. Here are some additional details.
significantly rewritten for qpdf 11. Here are some additional details.
Object Internals
~~~~~~~~~~~~~~~~
@ -456,7 +456,7 @@ move between different integer types because of incompatible integer
types used in interoperable interfaces. Some are unavoidable, such as
moving between sizes and offsets, and others are there because of old
code that is too in entrenched to be fixable without breaking source
compatibility and causing pain for users. QPDF is compiled with extra
compatibility and causing pain for users. qpdf is compiled with extra
warnings to detect conversions with potential data loss, and all such
cases should be fixed by either using a function from ``QIntC`` or a
``static_cast``.
@ -478,7 +478,7 @@ packed together in some integer type. Also note that ``size_t`` and
so sometimes an explicit cast may not be needed to avoid warnings on one
platform but may be needed on another. A conversion with ``QIntC``
should always be used when the types are different even if the
underlying size is the same. QPDF's automatic build builds on 32-bit
underlying size is the same. qpdf's automatic build builds on 32-bit
and 64-bit platforms, and the test suite is very thorough, so it is
hard to make any of the potential errors here without being caught in
build or test.
@ -538,14 +538,14 @@ is opened by an ordinary reader without specification of password, the
restrictions specified in the encryption dictionary can be enforced.
Most users wouldn't even realize such a file was encrypted. Since qpdf
always ignores the restrictions (except for the purpose of reporting
what they are), qpdf doesn't care which password you use. QPDF will
what they are), qpdf doesn't care which password you use. qpdf will
allow you to create PDF files with non-empty user passwords and empty
owner passwords. Some readers will require a password when you open
these files, and others will open the files without a password and not
enforce restrictions. Having a non-empty user password and an empty
owner password doesn't really make sense because it would mean that
opening the file with the user password would be more restrictive than
not supplying a password at all. QPDF also allows you to create PDF
not supplying a password at all. qpdf also allows you to create PDF
files with the same password as both the user and owner password. Some
readers will not ever allow such files to be accessed without
restrictions because they never try the password as the owner password
@ -564,7 +564,7 @@ you do it by mistake.
Random Number Generation
------------------------
QPDF generates random numbers to support generation of encrypted data.
qpdf generates random numbers to support generation of encrypted data.
Starting in qpdf 10.0.0, qpdf uses the crypto provider as its source of
random numbers. Older versions used the OS-provided source of secure
random numbers or, if allowed at build time, insecure random numbers
@ -757,7 +757,7 @@ something like store its output to a file or a memory buffer ignoring a
successor. For additional details, look at
:file:`Pipeline.hh`.
``QPDF`` can read raw or filtered streams. When reading a filtered
``qpdf`` can read raw or filtered streams. When reading a filtered
stream, the ``QPDF`` class creates a ``Pipeline`` object for one of each
appropriate filter object and chains them together. The last filter
should write to whatever type of output is required. The ``QPDF`` class

View File

@ -1,9 +1,9 @@
.. _download:
Downloading QPDF
Downloading qpdf
================
QPDF is included in most Linux distributions. Native packages are
qpdf is included in most Linux distributions. Native packages are
available for many other operating systems as well.
Other resources:
@ -12,4 +12,4 @@ Other resources:
- `GitHub project <https://github.com/qpdf/qpdf>`__
- `QPDF project web site <https://qpdf.sourceforge.io>`__
- `qpdf project web site <https://qpdf.sourceforge.io>`__

View File

@ -2,14 +2,14 @@
Directives documentation:
https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html
QPDF version |release|
qpdf version |release|
======================
..
Include the actual text of the link to readthedocs so it shows up in
the PDF when printed.
Welcome to the QPDF documentation! For the latest version of this
Welcome to the qpdf documentation! For the latest version of this
documentation, please visit `https://qpdf.readthedocs.io
<https://qpdf.readthedocs.io>`__.

View File

@ -1,6 +1,6 @@
.. _installing:
Building and Installing QPDF
Building and Installing qpdf
============================
This chapter describes how to build and install qpdf.
@ -283,7 +283,7 @@ FUTURE
breaking and are subject to change, which means code linked against
a qpdf built with this option may not be binary compatible with
installed qpdf libraries. Set this if you want to test your code
with proposed QPDF API changes and provide feedback prior to the
with proposed qpdf API changes and provide feedback prior to the
inclusion of those changes in a release. Packagers should never
distribute packages built with this option.

View File

@ -325,7 +325,7 @@ unreferenced objects, encryption, decryption, linearization, QDF
mode, etc. See :ref:`rewriting` for a more in-depth discussion. This
has a few noteworthy implications:
- Decryption is handled transparently by qpdf. As there are no QPDF
- Decryption is handled transparently by qpdf. As there are no qpdf
APIs, even internal to the library, that allow retrieval of
encrypted data in its raw, encrypted form, qpdf JSON always includes
decrypted data. It is possible that a future version of qpdf may
@ -653,7 +653,7 @@ JSON Compatibility Guarantees
The qpdf JSON representation includes a JSON serialization of the raw
objects in the PDF file as well as some computed information in a more
easily extracted format. QPDF provides some guarantees about its JSON
easily extracted format. qpdf provides some guarantees about its JSON
format. These guarantees are designed to simplify the experience of a
developer working with the JSON format.

View File

@ -1,11 +1,11 @@
.. _using-library:
Using the QPDF Library
Using the qpdf Library
======================
.. _using.from-cxx:
Using QPDF from C++
Using qpdf from C++
-------------------
The source tree for the qpdf package has an
@ -39,14 +39,14 @@ single-file executable that links with qpdf:
The qpdf library is safe to use in a multithreaded program, but no
individual ``QPDF`` object instance (including ``QPDF``,
individual ``qpdf`` object instance (including ``QPDF``,
``QPDFObjectHandle``, or ``QPDFWriter``) can be used in more than one
thread at a time. Multiple threads may simultaneously work with
different instances of these and all other QPDF objects.
different instances of these and all other qpdf objects.
.. _using.other-languages:
Using QPDF from other languages
Using qpdf from other languages
-------------------------------
The qpdf library is implemented in C++, which makes it hard to use

View File

@ -3,7 +3,7 @@
License
=======
QPDF is licensed under `the Apache License, Version 2.0
qpdf is licensed under `the Apache License, Version 2.0
<http://www.apache.org/licenses/LICENSE-2.0>`__ (the "License").
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,

View File

@ -1,33 +1,33 @@
.. _overview:
What is QPDF?
What is qpdf?
=============
QPDF is a program and C++ library for structural, content-preserving
transformations on PDF files. QPDF's website is located at
https://qpdf.sourceforge.io/. QPDF's source code is hosted on github
qpdf is a program and C++ library for structural, content-preserving
transformations on PDF files. qpdf's website is located at
https://qpdf.sourceforge.io/. qpdf's source code is hosted on github
at https://github.com/qpdf/qpdf. You can find the latest version of
this documentation at https://qpdf.readthedocs.io/.
QPDF provides many useful capabilities to developers of PDF-producing
qpdf provides many useful capabilities to developers of PDF-producing
software or for people who just want to look at the innards of a PDF
file to learn more about how they work. With QPDF, it is possible to
file to learn more about how they work. With qpdf, it is possible to
copy objects from one PDF file into another and to manipulate the list
of pages in a PDF file. This makes it possible to merge and split PDF
files. The QPDF library also makes it possible for you to create PDF
files. The qpdf library also makes it possible for you to create PDF
files from scratch. In this mode, you are responsible for supplying
all the contents of the file, while the QPDF library takes care of all
all the contents of the file, while the qpdf library takes care of all
the syntactical representation of the objects, creation of cross
references tables and, if you use them, object streams, encryption,
linearization, and other syntactic details. You are still responsible
for generating PDF content on your own.
QPDF has been designed with very few external dependencies, and it is
intentionally very lightweight. QPDF is *not* a PDF content creation
qpdf has been designed with very few external dependencies, and it is
intentionally very lightweight. qpdf is *not* a PDF content creation
library, a PDF viewer, or a program capable of converting PDF into other
formats. In particular, QPDF knows nothing about the semantics of PDF
formats. In particular, qpdf knows nothing about the semantics of PDF
content streams. If you are looking for something that can do that, you
should look elsewhere. However, once you have a valid PDF file, QPDF can
should look elsewhere. However, once you have a valid PDF file, qpdf can
be used to transform that file in ways that perhaps your original PDF
creation tool can't handle. For example, many programs generate simple PDF
files but can't password-protect them, web-optimize them, or perform

View File

@ -128,14 +128,14 @@ Planned changes for future 12.x (subject to change):
reference streams, linearization hint streams, and object
streams. This has been fixed.
- Fix to QPDF JSON: the syntax ``"n:/pdf-syntax"`` is now accepted
- Fix to qpdf JSON: the syntax ``"n:/pdf-syntax"`` is now accepted
as an alternative way to represent names. This can be used for
any name (e.g. ``"n:/text#2fplain"``), but it is necessary when
the name contains binary characters. For example, ``/one#a0two``
must be represented as ``"n:/one#a0two"`` since the single byte
``a0`` is not valid in JSON.
- QPDF JSON will convert floating numbers that appear in the JSON
- qpdf JSON will convert floating numbers that appear in the JSON
in scientific notation to fixed-point notation since PDF doesn't
accept scientific notation.
@ -1531,7 +1531,7 @@ Planned changes for future 12.x (subject to change):
environment, such as a docker container. The zip file is also
known to work as a layer in AWS Lambda.
- QPDF's automated build has been migrated from Azure Pipelines
- qpdf's automated build has been migrated from Azure Pipelines
to GitHub Actions.
- Windows-specific Changes
@ -1916,7 +1916,7 @@ Planned changes for future 12.x (subject to change):
tell ``QPDFWriter`` to uncompress and recompress streams
already compressed with ``/FlateDecode``.
- The underlying implementation of QPDF arrays has been enhanced
- The underlying implementation of qpdf arrays has been enhanced
to be much more memory efficient when dealing with arrays with
lots of nulls. This enables qpdf to use drastically less memory
for certain types of files.
@ -1979,11 +1979,11 @@ Planned changes for future 12.x (subject to change):
If you see this, please report a bug at
https://github.com/qpdf/qpdf/issues/.
- QPDF is now compiled with integer conversion and sign
- qpdf is now compiled with integer conversion and sign
conversion warnings enabled. Numerous changes were made to the
library to make this safe.
- QPDF's :command:`make install` target explicitly
- qpdf's :command:`make install` target explicitly
specifies the mode to use when installing files instead of
relying the user's umask. It was previously doing this for some
files but not others.
@ -1995,7 +1995,7 @@ Planned changes for future 12.x (subject to change):
- Other Notes
- QPDF has been fully integrated into `Google's OSS-Fuzz
- qpdf has been fully integrated into `Google's OSS-Fuzz
project <https://github.com/google/oss-fuzz>`__. This project
exercises code with randomly mutated inputs and is great for
discovering hidden security crashes and security issues.
@ -2179,7 +2179,7 @@ Planned changes for future 12.x (subject to change):
- Add method ``QUtil::possible_repaired_encodings()`` to generate
a list of strings that represent other ways the given string
could have been encoded. This is the method the QPDF CLI uses
could have been encoded. This is the method the qpdf CLI uses
to generate the strings it tries when recovering incorrectly
encoded Unicode passwords.
@ -2344,7 +2344,7 @@ Planned changes for future 12.x (subject to change):
- Bug Fixes and Enhancements
- QPDF now automatically detects and recovers from dangling
- qpdf now automatically detects and recovers from dangling
references. If a PDF file contained an indirect reference to a
non-existent object, which is valid, when adding a new object
to the file, it was possible for the new object to take the
@ -2662,7 +2662,7 @@ Planned changes for future 12.x (subject to change):
8.0.0: February 25, 2018
- Packaging and Distribution Changes
- QPDF is now distributed as an
- qpdf is now distributed as an
`AppImage <https://appimage.org/>`__ in addition to all the
other ways it is distributed. The AppImage can be found in the
download area with the other packages. Thanks to Kurt Pfeifle
@ -2752,14 +2752,14 @@ Planned changes for future 12.x (subject to change):
7.0.0: September 15, 2017
- Packaging and Distribution Changes
- QPDF's primary license is now `version 2.0 of the Apache
- qpdf's primary license is now `version 2.0 of the Apache
License <http://www.apache.org/licenses/LICENSE-2.0>`__ rather
than version 2.0 of the Artistic License. You may still, at
your option, consider qpdf to be licensed with version 2.0 of
the Artistic license.
- QPDF no longer has a dependency on the PCRE (Perl-Compatible
Regular Expression) library. QPDF now has an added dependency
- qpdf no longer has a dependency on the PCRE (Perl-Compatible
Regular Expression) library. qpdf now has an added dependency
on the JPEG library.
- Bug Fixes
@ -2771,7 +2771,7 @@ Planned changes for future 12.x (subject to change):
- New Features
- QPDF now supports reading and writing streams encoded with JPEG
- qpdf now supports reading and writing streams encoded with JPEG
or RunLength encoding. Library API enhancements and
command-line options have been added to control this behavior.
See command-line options
@ -2780,9 +2780,9 @@ Planned changes for future 12.x (subject to change):
``QPDFWriter::setCompressStreams`` and
``QPDFWriter::setDecodeLevel``.
- QPDF is much better at recovering from broken files. In most
- qpdf is much better at recovering from broken files. In most
cases, qpdf will skip invalid objects and will preserve broken
stream data by not attempting to filter broken streams. QPDF is
stream data by not attempting to filter broken streams. qpdf is
now able to recover or at least not crash on dozens of broken
test files I have received over the past few years.
@ -3390,7 +3390,7 @@ Planned changes for future 12.x (subject to change):
and ``std::cerr`` with other streams for generation of diagnostic
messages and error messages. This can be useful for GUIs or other
applications that want to capture any output generated by the
library to present to the user in some other way. Note that QPDF
library to present to the user in some other way. Note that qpdf
does not write to ``std::cout`` (or the specified output stream)
except where explicitly mentioned in
:file:`QPDF.hh`, and that the only use of the
@ -3533,7 +3533,7 @@ Planned changes for future 12.x (subject to change):
- *Non-compatible API changes:*
- QPDF's exception handling mechanism now uses
- qpdf's exception handling mechanism now uses
``std::logic_error`` for internal errors and
``std::runtime_error`` for runtime errors in favor of the now
removed ``QEXC`` classes used in previous versions. The ``QEXC``

View File

@ -105,7 +105,7 @@ original encryption, *if any*. Also, one may have a template used for
encryption that one may apply to a variety of output files, and it
would be annoying to be warned about it for every output file.
Uses of Weak Hashing In QPDF
Uses of Weak Hashing In qpdf
----------------------------
The PDF specification makes use the weak *MD5* hashing algorithm in