2021-01-05  Jay Berkenbilt  <ejb@ql.org>

	* 10.1.0: release

2021-01-04  Jay Berkenbilt  <ejb@ql.org>

	* When qpdf CLI extracts pages, it now only attempts to remove
	unreferenced resources from the pages that it is keeping. This
	change dramatically reduces the time it takes to extract a small
	number of pages from a large, complex file.

	* Move getNext()->write() calls in some pipelines to ensure that
	state gates properly reset even if the next pipeline's write
	throws an exception (fuzz issue 28262).

2021-01-03  Jay Berkenbilt  <ejb@ql.org>

	* Don't include -o nospace with zsh completion setup so file
	completion works normally. Fixes #473.

2021-01-02  Jay Berkenbilt  <ejb@ql.org>

	* Make QPDFPageObjectHelper methods pipeContents, parseContents,
	and addContentTokenFilter work with form XObjects.

	* Rename some QPDFPageObjectHelper methods and make them support
	form XObjects as well as pages. The old names will be preserved
	from compatibility.
	- pipePageContents -> pipeContents
	- parsePageContents -> parseContents

	* Add QPDFObjectHandle::parseAsContents to apply ParserCallbacks
	to a form XObject.

	* QPDFPageObjectHelper::externalizeInlineImages can be called with
	form XObjects as well as pages.

	* Bug fix: QPDFPageObjectHelper::externalizeInlineImages was not
	descending into form XObjects on a page. It now does this by
	default. In the extremely unlikely event that anyone was actually
	depending on the old behavior, it is available by passing
	shallow=true to the externalizeInlineImages call.

	* Bug fix: QPDFObjectHandle::filterPageContents was broken for
	pages with an array of content streams. This caused
	externalize-inline-images to also be broken for this case.

2021-01-01  Jay Berkenbilt  <ejb@ql.org>

	* Add methods to QPDFPageObjectHelper: forEachXObject,
	forEachImage, forEachFormXObject to call a function on each
	XObject (or image or form XObject) in a page or form XObject,
	possibly recursing into nested form XObjects.

	* Add method QPDFPageObjectHelper::getFormXObjects to return a map
	of keys to form XObjects (non-recursively) from a page or form
	XObject.

	* Add method QPDFObjectHandle::isImage to test whether an object
	is an image.

2020-12-31  Jay Berkenbilt  <ejb@ql.org>

	* QPDFPageObjectHelper::removeUnreferencedResources can now be
	called with a QPDFPageObjectHelper created from a form XObject.
	The method already recursed into form XObjects.

	* Rename some QPDFPageObjectHelper methods and make them support
	form XObjects as well as pages. The old names will be preserved
	from compatibility.
	- getPageImages -> getImages
	- filterPageContents -> filterContents

	* Add QPDFObjectHandle::isFormXObject to test whether an object is
	a form XObject.

2020-12-30  Jay Berkenbilt  <ejb@ql.org>

	* Add QPDFPageObjectHelper::flattenRotation and --flatten-rotation
	option to the qpdf CLI. The flattenRotation method removes any
	/Rotate key from a page dictionary and implements the same
	rotation by modifying the page's contents such that the various
	page boxes are altered and the page renders identically. This can
	be used to work around buggy PDF applications that don't properly
	handle page rotation. The --flatten-rotation option to the qpdf
	CLI calls flattenRotation for every page.

2020-12-26  Jay Berkenbilt  <ejb@ql.org>

	* Add QPDFObjectHandle::setFilterOnWrite, which can be used to
	tell QPDFWriter not to filter a stream on output even if it can.
	You can use this to prevent QPDFWriter from touching a stream
	(either uncompressing or compressing) that you have optimized or
	otherwise ensured looks exactly the way you want it, even if
	decode level or stream compression would otherwise cause
	QPDFWriter to modify the stream.

	* Add ostream << for QPDFObjGen. (Don't ask why it took 7.5 years
	for me to decide to do this.)

2020-12-25  Jay Berkenbilt  <ejb@ql.org>

	* Refactor write code to eliminate an extra full traversal of
	objects in the file and to remove assumptions that preclude stream
	references from appearing in /DecodeParms of filterable streams.
	This results in an approximately 8% performance reduction in write
	times.

2020-12-23  Jay Berkenbilt  <ejb@ql.org>

	* Allow library users to provide their own decoders for stream
	filters by deriving classes from QPDFStreamFilter and registering
	them using QPDF::registerStreamFilter. Registered stream filters
	provide code to validate and interpret /DecodeParms for a specific
	/Filter and also to provide a pipeline that will decode. Note that
	it is possible to encode to a filter type that is not supported
	even without this feature. See examples/pdf-custom-filter.cc for
	an example of using custom stream filters.

2020-12-22  Jay Berkenbilt  <ejb@ql.org>

	* Add QPDFObjectHandle::makeDirect(bool allow_streams) -- if
	allow_streams is true, preserve indirect references to streams
	rather than throwing an exception. This allows the object to be
	made as direct as possible while preserving stream references.

2020-12-20  Jay Berkenbilt  <ejb@ql.org>

	* Add qpdf_register_progress_reporter method to C API,
	corresponding to QPDFWriter::registerProgressReporter. Fixes #487.

2020-11-28  Jay Berkenbilt  <ejb@ql.org>

	* Add new functions to the C API for manipulating
	QPDFObjectHandles. The new functions allow creation and
	modification of objects, which brings a lot of additional power to
	the C API. See include/qpdf/qpdf-c.h for details and
	examples/pdf-c-objects.c for a simple example.

2020-11-21  Jay Berkenbilt  <ejb@ql.org>

	* 10.0.4: release

	* Fix QIntC::range_check to handle negative numbers properly (fuzz
	issue 26994).

2020-11-11  Jay Berkenbilt  <ejb@ql.org>

	* Treat a direct page object as a runtime error rather than a
	logic error since it is actually possible to create a file that
	has this (fuzz issue 27393).

2020-11-09  Jay Berkenbilt  <ejb@ql.org>

	* Handle "." appearing in --pages not preceded by a numeric range
	as a special case in command-line parsing code.

2020-11-04  Jay Berkenbilt  <ejb@ql.org>

	* Ignore the value of the offset/generation field in an xref entry
	for a deleted object. Also attempt file recovery on lower-level
	exceptions thrown while reading the xref table. Fixes #482.

2020-10-31  Jay Berkenbilt  <ejb@ql.org>

	* 10.0.3: release

	* Don't enter extension initialization in QPDFWriter on a direct
	object. Fixes stack overflow in pathological case of /Root being a
	direct object (fuzz issue 26761).

	* My previous fix to #449 (handling foreign streams with indirect
	objects in /Filter and/or /DecodeParms) was incorrect and caused
	other problems. There is a now a correct fix to the original
	problem. Fixes #478.

2020-10-27  Jay Berkenbilt  <ejb@ql.org>

	* 10.0.2: release

2020-10-25  Jay Berkenbilt  <ejb@ql.org>

	* When signing distribution files, generate sha256 checksums
	instead of md5, sha1, and sha512. sha256 seems to be more widely
	used, and there's no reason to use md5 or sha1 anymore.

	* Official Windows releases are now built using the openssl crypto
	provider. The native provider is still available for selection at
	runtime using the QPDF_CRYPTO_PROVIDER environment variable.

	* Bug fix: --no-warn was not suppressing some warnings that might
	be generated by --split-pages.

2020-10-23  Jay Berkenbilt  <ejb@ql.org>

	* Bug fix: when concatenating content streams, insert a newline if
	needed to prevent the last token from the old stream from being
	merged with the first token of the new stream. Qpdf was mistakenly
	concatenating the streams without regard to the specification that
	content streams are to be broken on token boundaries. Fixes #444.

	* fix-qdf: handle empty streams better with ignore newline by
	treating them as empty even though, technically, a blank line
	would be required inside the Stream. This just makes it easier to
	add place-holder empty streams while editing qdf files by hand.

2020-10-22  Jay Berkenbilt  <ejb@ql.org>

	* Fix memory leak that could occur if objects in object streams
	were resolved more than once and the objects within the object
	streams contained circular references. This leak could be
	triggered when qpdf was run with --object-streams=generate on
	files that already had object streams containing circular
	references (fuzz issue 23642).

	* Add QIntC::range_check for checking to see whether adding two
	numbers together will cause an overflow.

	* Fix loop detection problem when traversing page thumbnails
	during optimization (fuzz issue 23172).

2020-10-21  Jay Berkenbilt  <ejb@ql.org>

	* Bug fix: properly handle copying foreign streams that have
	indirect /Filter or /DecodeParms keys when stream data has been
	replaced. The circumstances leading to this bug are very unusual
	but would cause qpdf to either generate an internal error or some
	other kind of warning situation if it would occur. Fixes #449.

	* Qpdf's build and CI has been migrated from Azure Pipelines
	(Azure DevOps) to GitHub Actions.

	* Remove some fuzz files that triggered Mal/PDFEx-H with some
	virus scanners. There's plenty of coverage in the fuzz corpus
	without these files, and it's a nuisance to have virus checkers
	remove them. Fixes #460.

	* Ensure that numeric conversion is not affected by the user's
	global locale setting. Fixes #459.

	* Add qpdf-<version>-linux-x86_64.zip to the list of built
	distributions. This is a simple zip file that contains just the
	qpdf executables and the dependent shared libraries that would not
	ordinarily be present on a base system. This minimal binary
	distribution works as is when used as a Lambda layer in AWS and
	could be suitable for inclusion in a docker image or other
	standalone Linux/x86_64 environment where you want minimal support
	for running the qpdf executable. Fixes #352.

2020-10-20  Jay Berkenbilt  <ejb@ql.org>

	* Add --warning-exit-0 option to the qpdf command line. When
	specified, qpdf will exit with a status of 0 rather than 3 when
	there are warnings without errors. Combine with --no-warn to
	completely ignore warnings.

	* Bug fix: fix further cases in which errors were written to
	stdout. Fixes #438.

	* Build option: add --disable-rpath option to ./configure, which
	disables passing -rpath to the linker when building shared
	libraries with libtool. Fixes #422.

2020-10-16  Jay Berkenbilt  <ejb@ql.org>

	* Accept pull request that improves how the Windows native crypto
	provider is obtained.

	* Accept pull request that improves performance in processing
	files in memory.

	* Accept pull requests that improve openssl configuration and
	error reporting.

	* Build using GitHub Actions. The intention is that this will
	replace Azure Pipelines as the official CI for qpdf for the next
	release.

2020-10-15  Jay Berkenbilt  <ejb@ql.org>

	* Make many minor improvements to the build process and code
	health, including fixing a lgtm warning and compiler warnings from
	newer version of gcc and MSVC toolchains. Add several cosmetic
	improvements to build output in CI.

	* Added LL_FMT to config.h.in. This is populated automatically by
	autoconf, but if build with your own build system, you may need to
	define it as whatever the format string needed by printf for long
	long is. Usually this is "%lld", but it can be "%I64d" for some
	older Windows-based compilers.

2020-04-29  Jay Berkenbilt  <ejb@ql.org>

	* Bug fix: qpdf --check was writing errors and warnings reported
	by checkLinearization to stdout instead of stderr. Fixes #438.

2020-04-09  Jay Berkenbilt  <ejb@ql.org>

	* 10.0.1: release

2020-04-08  Jay Berkenbilt  <ejb@ql.org>

	* Bug fix: qpdf 10.0.0 introduced a bug in which
	QPDFObjectHandle::getStreamData would return the raw data when
	called on an unfilterable stream instead of throwing an exception
	like it's supposed to. Fixes #425.

2020-04-07  Jay Berkenbilt  <ejb@ql.org>

	* Improve pdf-invert-images example to show a pattern of copying
	streams into another QPDF object to enable a stream data provider
	to access the original stream data.

	* Fix error that caused a compilation error with clang. Fixes
	#424.

2020-04-06  Jay Berkenbilt  <ejb@ql.org>

	* 10.0.0: release

	* Move random number generation into the crypto providers. The old
	os-based secure random number generation with fallback to insecure
	random number generation (only if allowed at build time) has moved
	into the native crypto provider. If using other providers
	(currently gnutls or openssl), random number generation will use
	those libraries. The old interfaces for supplying your own random
	number generator are still in place. Fixes #418.

	* Source-level incompatibility: remove QUtil::srandom. There was
	no reason to ever call this, and it didn't do anything unless
	insecure random number generation was compiled in, which it is not
	by default. If you were calling this, just remove the call because
	it wasn't doing anything anyway.

	* Add openssl crypto provider, contributed by Dean Scarff. This
	provider is implemented using OpenSSL and also works with
	BoringSSL.

2020-04-04  Jay Berkenbilt  <ejb@ql.org>

	* Add a new provideStreamData method for StreamDataProvider that
	allows a success code to be returned and that accepts the
	suppress_warnings and will_retry methods. This makes it possible
	to have a StreamDataProvider call pipeStreamData and propagate its
	results back. This change allows better error handling and
	recovery when objects are copied from other files and when
	"immediate copy from" is enabled.

	* When copying foreign streams, the same type of recovery from
	streams with filtering errors is performed as when dealing with
	streams in the original input. This could happen, for example, if
	you are using the --pages option to take pages from another file
	and that file has errors in it.

	* Add a new version of QPDFObjectHandle::pipeStreamData whose
	return value indicates overall success or failure rather than
	whether nor not filtering was attempted. It should have always
	been this way. This change was done in a backward-compatible
	fashion. Previously existing pipeStreamData methods' return values
	mean the same as always.

	* Add "objectinfo" section to json output. In this release,
	information about whether each object is a stream or not is
	provided. There's otherwise no way to tell conclusively from the
	json output. Over time, other computed information about objects
	may be added here.

	* Add new option --remove-unreferenced-resources that takes auto,
	yes, or no as options. This tells qpdf whether to attempt to
	remove unreferenced resources from pages when doing page splitting
	operations. Prior to this change, the default was to attempt to
	remove unreferenced resources, but this operation was very slow,
	especially for large and complex files. The new default is "auto",
	which tells qpdf to analyze the file for shared resources. This is
	a relatively quick test. If no shared resources are found, then we
	don't attempt to remove unreferenced resources, because
	unreferenced resources never occur in files without shared
	resources. To force qpdf to look for and remove unreferenced
	resources, use --remove-unreferenced-resources=yes. The option
	--preserve-unreferenced-resources is now a synonym for
	--remove-unreferenced-resources=no.

	* Use std::atomic for unique ID generation internally within the
	library. This eliminates the already extremely low chance of a
	collision, improves thread safety, and removes a dependency on a
	random number generator. Thanks to Dean Scarff for the
	contribution.

2020-04-03  Jay Berkenbilt  <ejb@ql.org>

	* Allow qpdf to be built on systems without wchar_t. All "normal"
	systems have wchar_t because it is part of the C++ standard, but
	there are some stripped down environments that don't have it. See
	README.md (search for wchar_t) for instructions and a discussion.
	Fixes #406.

	* Add two extra optional arguments to
	QPDFPageObjectHelper::placeFormXObject to control whether the
	placed item is allowed to be shrunk or expanded to fit within or
	maximally fill the destination rectangle. Prior to this change,
	placeFormXObject might shrink it but would never expand it.

	* When calling the C API, accept any non-zero value as TRUE rather
	than just 1. This appears to resolve issues on Windows when
	calling some versions of the DLL directly from other languages.

2020-04-02  Jay Berkenbilt  <ejb@ql.org>

	* Add method QPDFObjectHandle::unsafeShallowCopy for copying only
	top-level dictionary keys or array items. See comments in
	QPDFObjectHandle.hh for when this should be used.

	* Remove Members class indirection for QPDFObjectHandle. Those are
	copied and assigned too often, and that change caused a very
	substantial performance hit.

2020-03-31  Jay Berkenbilt  <ejb@ql.org>

	* When detecting unreferenced images during page splitting, if any
	XObjects are form XObjects, recursively descend into them and
	remove any unreferenced objects from them too. Fixes #373.

	* Add QPDFObjectHandle::filterAsContents, which filters a stream's
	data as if it were page contents. This can be useful to filter
	form XObjects the same way we would filter page contents.

	* If QPDF_EXECUTABLE is set, use it as the path to qpdf for
	purposes of completion. This variable is only read during the
	execution of `qpdf --completion-zsh` and `qpdf
	--completion-bash`. It is not used during the actual evaluation of
	completions.

2020-02-22  Jay Berkenbilt  <ejb@ql.org>

	* Update pdf-set-form-values.cc to use and mention
	generateAppearance, which hadn't been added when the example was
	originally created.

	* Detect, warn, and correct the case of /Pages in the document
	catalog incorrectly pointing to a page or intermediate node
	instead of the root of the pages tree. Fixes #398.

2020-01-26  Jay Berkenbilt  <ejb@ql.org>

	* 9.1.1: release

	* Bug fix: in qdf mode, do not write out any XRef streams that may
	have appeared in the original file. These are usually
	unreferenced, but with --preserve-unreferenced, they could be
	written out, which breaks fix-qdf's assumption that there is at
	most one XRef stream and that it appears at the end of the file.
	Fixes #386.

	* Bug fix: when externalizing inline images, a colorspace value
	that was a lookup key in the page's /Resource -> /ColorSpace
	dictionary was not properly handled. Fixes #392.

	* Add "encrypt" key to the json output. This contains largely the
	same information as given by --show-encryption but in a
	consistent, parseable format.

	* Add options --is-encrypted and --requires-password. These can be
	used with files, including encrypted files with unknown passwords,
	to determine whether or not a file is encrypted and whether a
	password is required to open the file. The --requires-password
	option can also be used to determine whether a supplied password
	is correct. Information is supplied through exit codes, making
	these options particularly useful for shell scripts. Fixes #390.

2020-01-14  Jay Berkenbilt  <ejb@ql.org>

	* Fix for Windows being unable to acquire crypt context with a new
	keyset. Thanks to Cloudmersive for the fix. Fixes #387.

	* Rewrite fix-qdf in C++. This means fix-qdf is a proper
	executable now, and there is no longer a runtime requirement on
	perl.

	* Add QUtil::call_main_from_wmain, a helper function that can be
	called in the body of wmain to convert UTF-16 arguments to UTF-8
	arguments and then call another main function.

2020-01-13  Jay Berkenbilt  <ejb@ql.org>

	* QUtil::read_lines_from_file: add new versions that use FILE*,
	use FILE* instead if std::ifstream internally to support correct
	handling of Unicode filenames in Windows, and add the option to
	preserve line endings.

2019-11-17  Jay Berkenbilt  <ejb@ql.org>

	* 9.1.0: release

	* This is the first version of qpdf that requires C++-11.

2019-11-09  Jay Berkenbilt  <ejb@ql.org>

	* 9.1.rc1: release

	* Improve behavior of wildcard expansion for msvc executable when
	run from the Windows cmd.exe shell. Unlike in UNIX environments,
	Windows leaves it up to the executable to expand its own
	wildcards. Fixes #224.

	* Allow :even or :odd to be appended to numeric ranges for
	--pages, --rotate, and other options that take page ranges.

	* When reading /P from the encryption dictionary, use static_cast
	instead of QIntC to convert the value to a signed integer. The
	value of /P is a bit field, and PDF files have been found in the
	wild where /P is represented as an unsigned integer even though
	the spec states that it is a signed 32-bit value. By using
	static_cast, we allow qpdf to compensate for writers that
	incorrectly represent the correct bit field as an unsigned value.
	Fixes #382.

2019-11-05  Jay Berkenbilt  <ejb@ql.org>

	* Add support for pluggable crypto providers, enabling multiple
	implementations of the cryptographic functions needed by qpdf.
	This feature was added by request of Red Hat, which recognized the
	use of qpdf's native crypto implementations as a potential
	security liability, preferring instead to get all crypto
	functionality from a third-party library that receives a lot of
	scrutiny. However it was also important to me to not impose any
	unnecessary third party dependencies on my users or packagers,
	some of which build qpdf for lots of environments, some of which
	may not easily support gnutls. Starting in qpdf 9.1.0, it is be
	possible to build qpdf with both the native and gnutls crypto
	providers or with either in isolation. In support of this feature,
	new classes QPDFCryptoProvider and QPDFCryptoImpl have been added
	to the public interface. See QPDFCryptoImpl.hh for details about
	adding your own crypto provider and QPDFCryptoProvider.hh for
	details about choosing which one is used. Note that selection of
	crypto providers is invisible to anyone who doesn't explicitly
	care. Neither end users nor developers have to be concerned about
	it.

	* The environment variable QPDF_CRYPTO_PROVIDER can be used to
	override qpdf's default choice of crypto provider. The
	--show-crypto flag to the qpdf CLI can be used to present a list
	of supported crypto providers with the default provider always
	listed first.

	* Add gnutls crypto provider. Thanks to Zdenek Dohnal for
	contributing the code that I ultimately used in the gnutls crypto
	provider and for engaging in an extended discussion about this
	feature. Fixes #218.

2019-10-22  Jay Berkenbilt  <ejb@ql.org>

	* Incorporate changes from Masamichi Hosoda <trueroad@trueroad.jp>
	to properly handle signature in the following ways:
	  - Always represent /Contents in a signature dictionary as a hex
	    string
	  - Do not compress signature dictionaries when generating object
	    streams
	  - Do not encrypt/decrypt the /Contents field of the signature
	    dictionary when creating or reading encrypted files

	* Incorporate changes from Masamichi Hosoda <trueroad@trueroad.jp>
	to add additional methods for making it possible to gain deeper
	insight into cross reference tables and object renumbering. These
	new API calls make it possible for applications to go into PDF
	files created by qpdf and make changes to them that go beyond
	working with the PDF at the object level. The specific use case
	for these changes was to write an external tool to perform digital
	signature, but there could be other uses as well. New methods
	include the following, all of which are described in their
	respective headers:
	  - QPDF::getXRefTable()
	  - QPDFObjectHandle::getParsedOffset()
	  - QPDFWriter::getRenumberedObjGen(QPDFObjGen)
	  - QPDFWriter::getWrittenXRefTable()

2019-10-12  Jay Berkenbilt  <ejb@ql.org>

	* 9.0.2: release

	* Change the name of the temporary file used by --replace-input to
	work with arbitrary absolute or relative paths without requiring
	path splitting logic. Fixes #365.

2019-09-20  Jay Berkenbilt  <ejb@ql.org>

	* 9.0.1: release

2019-09-19  Jay Berkenbilt  <ejb@ql.org>

	* When converting an array to a Rectangle, ensure that llx <= urx
	and lly <= ury. This prevents flatten-annotations from flipping
	fields whose coordinates are messed up in the input. Fixes #363.

	* Warn when duplicated dictionary keys are found during parsing.
	The behavior remains as before: later keys override earlier ones.
	However, this generates a warning now rather than being silently
	ignored. Fixes #345.

2019-09-17  Jay Berkenbilt  <ejb@ql.org>

	* Fix a few integer warnings for big-endian systems.

	* QIntC tests: don't assume char is signed. Fixes #361.

2019-08-31  Jay Berkenbilt  <ejb@ql.org>

	* 9.0.0: release

	* Add QPDF::anyWarnings() method to find out whether there have
	been any warnings without resetting the list.

	* Add QPDF::closeInputSource() method to release the input source
	so the input file can be deleted or renamed.

	* Add methods rename_file and remove_file to QUtil.

2019-08-24  Jay Berkenbilt  <ejb@ql.org>

	* Add QPDF::userPasswordMatched() and QPDF::ownerPasswordMatched()
	methods so it can be determined separately whether the supplied
	password matched the user password, the owner password, or both.
	Fixes #159.

2019-08-23  Jay Berkenbilt  <ejb@ql.org>

	* Add --recompress-streams option to qpdf and
	QPDFWriter::setRecompressFlate to cause QPDFWriter to recompress
	streams that are already compressed with /FlateDecode.

	* Add option Pl_Flate::setCompressionLevel to globally set the
	zlib compression level used by all Pl_Flate pipelines.

	* Add --compression-level flag to qpdf to set the zlib compression
	level. When combined with --recompress-flate, this will cause most
	of qpdf's streams to use the maximum compression level. This
	results in only a very small amount of savings in size that comes
	at a fairly significant performance cost, but it could be useful
	for archival files or other cases where every byte counts and
	creation time doesn't matter so much. Note that using
	--object-streams=generate in combination with these options gives
	you the biggest advantage. Fixes #113.

2019-08-22  Jay Berkenbilt  <ejb@ql.org>

	* In QPDFObjectHandle::ParserCallbacks, in addition to
	handleObject(QPDFObjectHandle), allow developers to override
	handleObject(QPDFObjectHandle, size_t offset, size_t length). If
	this method appears instead, it is called with the offset of the
	object in the content stream (which may be concatenated from an
	array of streams) and the length of the object. Intervening
	whitespace and comments are not included in offset and length.

	* Add method
	QPDFObjectHandle::ParserCallbacks::contentSize(size_t). If
	defined, it is called by the content stream parser before the
	first call to handleObject, and the argument is the total size in
	bytes of the content streams.

	* Add QPDFObjectHandle::isDirectNull() -- a const method that
	allows determining whether an object is a literal null without
	attempting to resolve it.

	* Stop replacing indirect references to null with literal null in
	arrays when writing output with QPDFWriter.

2019-08-19  Jay Berkenbilt  <ejb@ql.org>

	* Accept (and warn for) extraneous whitespace preceding the xref
	table. Fixes #341.

	* Accept (and warn for) extraneous whitespace between the stream
	keyword and newline. Fixes #329.

	* Properly handle name tokens containing # not preceding two
	hexadecimal digits. Such names are invalid in PDF >= 1.2 but valid
	in PDF 1.0 and 1.1. Prior to this fix, qpdf's behavior was to
	treat such tokens as an error for PDF >= 1.2, but for older PDF
	tokens, the name was silently accepted, and when the name token
	was written out, the # was changed to #23, which is the correct
	way to represent a # character. This behavior was problematic for
	several reasons: one is that, ordinarily, content streams are not
	parsed, so this would cause things like image references whose
	names contained # to break. Also, even if the input file was 1.0
	or 1.1, there's no guarantee that the output file wouldn't be
	written at a new version, resulting in invalid name tokens. The
	new behavior is to issue a warning upon encountering such a token
	but to accept it, regardless of the PDF version. Such tokens are
	written out properly as well. Additionally, the warning message
	indicates that the tokens are invalid for PDF >= 1.2. Fixes #332.

	* Non-compatible API change: remove
	QPDFTokenizer::allowPoundAnywhereInName(). There were a lot of
	problems with this. When it was used, any name tokens read would
	always be modified on output, which is never the correct behavior.
	This method used to signal QPDFTokenizer to not treat # specially
	in name tokens, which resulted in the incorrect behavior whose fix
	is described in the preceding item.

2019-08-18  Jay Berkenbilt  <ejb@ql.org>

	* When traversing the pages tree, if an invalid /Type key is
	encountered, fix it. This is not done for all operations, but it
	will be done for any case in which getAllPages is called. This
	includes all page-based CLI operations. (Hopefully) Fixes #349.

2019-08-17  Jay Berkenbilt  <ejb@ql.org>

	* Change internal implementation of QPDF arrays to use sparse
	arrays, which results in using much less memory for arrays with
	large numbers of nulls. Various files have been encountered in the
	wild that contains thousands of arrays with millions of nulls.
	Fixes #305, #311.

2019-07-03  Jay Berkenbilt  <ejb@ql.org>

	* Non-compatible API change: change
	QPDFOutlineDocumentHelper::getTopLevelOutlines and
	QPDFOutlineObjectHelper::getKids to return a std::vector instead
	of a std::list of QPDFOutlineObjectHelper objects. This is to work
	around bugs with some compilers' STL implementations that are
	choking with list here. There's no deep reason for these to be
	lists instead of vectors. Fixes #297.

2019-06-22  Jay Berkenbilt  <ejb@ql.org>

	* Handle encrypted files with missing or invalid /Length entries
	in the encryption dictionary.

	* QPDFWriter: allow calling set*EncryptionParameters before
	calling setFilename. Fixes #336.

	* It now works to run --completion-bash and --completion-zsh when
	qpdf is started from an AppImage.

	* Provided a more useful error message when Windows can't get
	security context. Thanks to user zdenop for supplying some code.
	Fixes #286.

	* Favor PointerHolder over manual memory allocation in shippable
	code where possible. Fixes #235.

	* If pkg-config is available, use it to local libjpeg and zlib. If
	not, fall back to old behavior. Fixes #324.

	* The "make install" target explicitly sets a mode rather than
	relying the user's umask. Fixes #326.

	* When a file has linearization warnings but no errors, qpdf
	--check and --check-linearization now exit with code 3 instead
	of 2. Fixes #50.

	* Add new function QUtil::read_file_into_memory.

2019-06-21  Jay Berkenbilt  <ejb@ql.org>

	* When supported, qpdf builds with -fvisibility=hidden, which
	removes non-exported symbols from the shared library in a manner
	similar to how Windows DLLs work. This is better for performance
	and also better for safety and protection of private interfaces.
	See https://gcc.gnu.org/wiki/Visibility. *NOTE*: If you are
	getting linker errors trying to catch exceptions or derive things
	from a base class in the qpdf library, it's possible that a
	QPDF_DLL_CLASS declaration is missing somewhere. Please report
	this as a bug at https://github.com/qpdf/qpdf/issues.

	* Source-level incompatibility: remove the version
	QPDF::copyForeignObject with an unused boolean parameter. If you
	were, for some reason, calling this, just take the parameter away.

	* Source-level incompatibility: remove the version
	QPDFTokenizer::expectInlineImage with no arguments. It didn't
	produce correct inline images. This is a very low-level routine.
	There is little reason to call it outside of qpdf's lexical
	engine.

	* Source-level incompatibility: rename QUtil::strcasecmp to
	QUtil::str_compare_nocase. This is a non-compatible change, but
	QUtil::strcasecmp is hardly the most important part of qpdf's API.
	The reason for this change is that strcasecmp is a macro on some
	systems, and that was causing problems when QUtil.hh was included
	in certain circumstances. Fixes #242.

2019-06-20  Jay Berkenbilt  <ejb@ql.org>

	* Enable compilation with additional warnings for integer
	conversion and sign (-Wsign-conversion, -Wconversion for gcc and
	similar; -W3 for msvc) if supported. These warnings are on by
	default can be turned off by passing --disable-int-warnings

	* Fix all integer sign and conversion warnings. This makes all
	integer type conversions that have potential data loss explicit
	with calls that do range checks and raise an exception.

	* Change out_bufsize argument to Pl_Flate's constructor for int to
	unsigned int for compatibility with underlying zlib
	implementation.

	* Change QPDFObjectHandle::pipeStreamData's encode_flags argument
	from unsigned long to int since int is the underlying type of the
	enumerated type values that are passed to it. This change should
	be invisible to virtually all code unless you are compiling with
	strict warning flags and explicitly casting to unsigned long.

	* Add methods to QPDFObjectHandle to return the value of Integer
	objects as int and unsigned int with range checking and fallback
	behavior to avoid silent underflow/overflow conditions.

	* Add functions to QUtil to convert unsigned integers to strings,
	avoiding implicit conversion between unsigned and signed integer
	types.

	* Add QIntC.hh, containing integer type converters that do range
	checking.

2019-06-18  Jay Berkenbilt  <ejb@ql.org>

	* Remove previously submitted qpdf_read_memory_fuzzer as it is a
	small subset of qpdf_fuzzer.

2019-06-15  Jay Berkenbilt  <ejb@ql.org>

	* Update CI (Azure Pipelines) to run tests with some sanitizers.

	* Do "ideal integration" with oss-fuzz. This includes adding a
	better fuzzer with a seed corpus and adding automated tests of the
	fuzzer with the test data.

	* When parsing files, while reading an object, if there are too
	many consecutive errors without enough intervening successes, give
	up on the specific object. This reduces cases in which very badly
	damaged files send qpdf into a tail spin reading one character at
	a time and reporting warnings.

2019-06-13  Jay Berkenbilt  <ejb@ql.org>

	* Perform initial integration of Google's oss-fuzz project by
	copying the fuzzer someone from Google already did into the qpdf
	repository and adding build support. This shift in control is in
	preparation for an ideal integration with oss-fuzz.

2019-06-09  Jay Berkenbilt  <ejb@ql.org>

	* When /DecodeParms is an empty list, ignore it on read and delete
	it on write. Fixes #331.

2019-05-18  Jay Berkenbilt  <ejb@ql.org>

	* 8.4.2: release

2019-05-16  Jay Berkenbilt  <ejb@ql.org>

	* Fix memory error in Windows-only code from typo. Fixes #330.

2019-04-27  Jay Berkenbilt  <ejb@ql.org>

	* 8.4.1: release

2019-04-20  Jay Berkenbilt  <ejb@ql.org>

	* When qpdf --version is run, it will detect if the qpdf CLI was
	built with a different version of qpdf than the library. This
	usually indicates that multiple versions of qpdf are installed and
	that the library path is not set up properly. This situation
	sometimes causes confusing behavior for users who are not actually
	running the version of qpdf they think they are running.

	* Add parameter --remove-page-labels to remove page labels from
	output. In qpdf 8.3.0, the behavior changed so that page labels
	were preserved when merging and splitting files. Some users were
	relying on the fact that if you ran qpdf --empty --pages ... all
	page labels were dropped. This option makes it possible to get
	that behavior if it is explicitly desired. Fixes #317.

	* Add parameter --keep-files-open-threshold to override the
	maximum number of files that qpdf will allow to be kept open at
	once. Fixes #288.

	* Handle Unicode characters in filenames properly on Windows. The
	changes to support Unicode on the CLI in Windows broke Unicode
	filenames on that platform. Fixes #298.

	* Slightly tighten logic that determines whether an object is a
	page. The previous logic was sometimes failing to preserve
	annotations because they were passing the overly loose test for
	whether something was a page. This fix has a slight risk of
	causing some extraneous objects to be copied during page splitting
	and merging for erroneous PDF files whose page objects contain
	invalid types or are missing the /Type key entirely, both of which
	would be invalid according to the PDF specification.

	* Revert change that included preservation of outlines (bookmarks)
	in --split-pages. The way it was implemented caused a very
	significant performance penalty when splitting pages with
	outlines. We need a better solution that only copies the relevant
	items, not the whole tree.

2019-03-11  Jay Berkenbilt  <ejb@ql.org>

	* JSON serialization: add missing leading 0 to decimal values
	between -1 and 1. Fixes #308.

2019-02-01  Jay Berkenbilt  <ejb@ql.org>

	* 8.4.0: release

2019-01-31  Jay Berkenbilt  <ejb@ql.org>

	* Bug fix: do better pre-checks on images before optimizing;
	refuse to optimize images that can't be converted to JPEG because
	of colorspace or depth.

	* Add new options --externalize-inline-images, which converts
	inline images larger than a specified size to regular images, and
	--ii-min-bytes, which tweaks that size.

	* When optimizing images, inline images are now included in the
	optimization, first being converted to regular images. Use
	--keep-inline-images to exclude them from optimization. Fixes #278.

	* Add method QPDFPageObjectHelper::externalizeInlineImages, which
	converts inline images whose size is at least a specified amount
	to regular images.

	* Remove traces of acroread, which hasn't been available in Linux
	for a long time.

2019-01-30  Jay Berkenbilt  <ejb@ql.org>

	* Do not include space after ID operator in inline image data. The
	token now correctly contains the image data, the EI operator,
	and the delimiter that precedes the EI operator.

	* Improve locating of an inline image's EI operator to correctly
	handle the case of EI appearing inside the image data.

	* Very low-level QPDFTokenizer API now includes an
	expectInlineImage method that takes an input stream, enabling it
	to locate an inline image's EI operator better. When this method
	is called, the inline image token returned will not contain the EI
	operator and will contain correct image data. This is called
	automatically everywhere within the qpdf library. Most user code
	will never have to use the low-level tokenizer API. If you use
	Pl_QPDFTokenizer, this will be done automatically for you. If you
	use the low-level API and call expectInlineImage, you should call
	the new version.

2019-01-29  Jay Berkenbilt  <ejb@ql.org>

	* Bug fix: when returning an inline image token, the tokenizer no
	longer includes the delimiter that follows EI. The
	QPDFObjectHandle created from the token was correct.

	* Handle files with direct page objects, which is not allowed by
	the PDF spec but has been seen in the wild. Fixes #164.

2019-01-28  Jay Berkenbilt  <ejb@ql.org>

	* Bug fix: when using --stream-data=compress, object streams and
	xref streams were not compressed. They were compressed if no
	--stream-data option was specified. Fixes #271.

	* When linearizing or getting the list of all pages in a file,
	replace duplicated page objects with a shallow copy of the page
	object. Linearization and all page manipulation APIs require page
	objects to be unique. Pages that were originally duplicated will
	still share contents and any other indirect resources. Fixes #268.

2019-01-26  Jay Berkenbilt  <ejb@ql.org>

	* Add --overlay and --underlay options. Fixes #207.

	* Create examples/pdf-overlay-page.cc to demonstrate use of
	page/form XObject interaction

	* Add new methods QPDFPageObjectHelper::getFormXObjectForPage,
	which creates a form XObject equivalent to a page, and
	QPDFObjectHandle::placeFormXObject, which generates content stream
	code to placing a form XObject on a page.

2019-01-25  Jay Berkenbilt  <ejb@ql.org>

	* Add new method QPDFObjectHandle::getUniqueResourceName() to
	return an unused key available to be used in a resource
	dictionary.

	* Add new method QPDFPageObjectHelper::getAttribute() that
	properly handles inherited attributes and allows for creation of a
	copy of shared attributes. This is very useful if you are getting
	an attribute of a page dictionary with the intent to modify it
	privately for that page.

	* Fix QPDFPageObjectHelper::getPageImages (and the legacy
	QPDFObjectHandle::getPageImages()) to properly handle images in
	inherited resources dictionaries.

2019-01-20  Jay Berkenbilt  <ejb@ql.org>

	* Tweak the content code generated for variable text fields to
	better handle font sizes and multi-line text.

