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.

	* When generating appearance streams for variable text
	annotations, properly handle the cases of there being no
	appearance dictionary, no appearance stream, or an appearance
	stream with no BMC..EMC marker.

	* When flattening annotations, remove annotations from the file
	that don't have appearance streams. These were previously being
	preserved, but since they are invisible, there is no reason to
	preserve them when flattening annotations.

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

	* NOTE: qpdf CLI: some non-compatible changes were made to how
	qpdf interprets password arguments that contain Unicode characters
	that fall outside of ASCII. On Windows, the non-compatibility was
	unavoidable, as explained in the release notes. On all platforms,
	it is possible to get the old behavior if desired, though the old
	behavior would almost always result in files that other
	applications were unable to open. As it stands, qpdf should now be
	able to open passwords encrypted with a wide range of passwords
	that some other viewers might not handle, though even now, qpdf's
	Unicode password handling is not 100% complete.

	* Add --password-mode option, which allows fine-grained control of
	how password arguments are treated. This is discussed fully in the
	manual. Fixes #215.

	* Add option --suppress-password-recovery to disable the behavior
	of searching for a correct password by re-encoding the provided
	password. This option can be useful if you want to ensure you know
	exactly what password is being used.

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

	* When attempting to open an encrypted file with a password, if
	the password doesn't work, try alternative passwords created by
	re-interpreting the supplied password with different string
	encodings. This makes qpdf able to recover passwords with
	non-ASCII characters when either the decryption or encryption
	operation was performed with an incorrectly encoded password.

	* Fix data loss bug: qpdf was discarding referenced resources in
	the case in which a page's resource dictionary contained an
	indirect reference for either /Font or /XObject that contained
	fonts or XObjects not referenced on all pages that shared the
	resource. This was a "typo" in the code. The comment explained the
	correct behavior, and the code was clearly intended to handle this
	issue, but the implementation had an error in it. This is fixed by
	a single-line change, which can be found in git commit
	4bc434000c42a7191e705c8a38216ca6743ad9ff. That commit can be used
	as a patch that applies cleanly against qpdf 8.1.0 and forward.
	The bug was introduced in version 8.1.0. For the record, this is
	the first bug in qpdf's history that could result in silent loss
	of data when processing a correct input file. Fixes #276.

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

	* Add QUtil::possible_repaired_encodings which, given a string,
	generates other strings that represent re-interpretation of the
	bytes in a different coding system. This is used to help recover
	passwords if the password string was improperly encoded on a
	different system due to user error or a software bug.

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

	* Add new CLI flags to 128-bit and 256-bit encryption: --assemble,
	--annotate, --form, and --modify-other to control encryption
	permissions with more granularity than was allowed with the
	--modify flag. Fixes #214.

	* Add new versions of
	QPDFWriter::setR{3,4,5,6}EncryptionParameters that allow
	individual setting of the various permission bits. The old
	interfaces are retained for backward compatibility. In the "C"
	API, add qpdf_set_r{3,4,5,6}_encryption_parameters2. The new
	interfaces use separate booleans for various permissions instead
	of the qpdf_r3_modify_e enumerated type, which set permission bits
	in predefined groups.

	* Add versions of utf8 to single-byte character transcoders that
	return a success code.

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

	* Add several more string transcoding and analysis methods to
	QUtil for bidirectional conversion between PDF Doc, Win Ansi, Mac
	Roman, UTF-6, and UTF-16 along with detection of valid UTF-8 and
	UTF-16.

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

	* In the --pages option, allow the same page to be specified more
	than once. You can now do "--pages A.pdf 1,1 --" or
	"--pages A.pdf 1 A.pdf 1" instead of having to use two different
	paths to specify A.pdf. Fixes #272.

	* Add QPDFPageObjectHelper::shallowCopyPage(). This method creates
	a new page object that is a "shallow copy" of the given page as
	described in the comments in QPDFPageObjectHelper. The resulting
	object has not been added anywhere but is ready to be passed to
	QPDFPageDocumentHelper::addPage of its own QPDF or another QPDF
	object.

	* Add QPDF::getUniqueId() method to return an identifier that is
	intended to be unique within the scope of all QPDF objects created
	by the calling application in a single run.

	* In --pages, allow "." as a replacement for the current input
	file, making it possible to say "qpdf A.pdf --pages . 1-3 --"
	instead of having to repeat the input filename.

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

	* Add new configure option --enable-avoid-windows-handle, which
	causes the symbol AVOID_WINDOWS_HANDLE to be defined. If set, we
	avoid using Windows I/O HANDLE, which is disallowed in some
	versions of the Windows SDK, such as for Windows phones.
	QUtil::same_file will always return false in this case. Only
	applies to Windows builds.

	* Add new method QPDF::setImmediateCopyFrom. When called on a
	source QPDF object, streams can be copied FROM that object to
	other ones without having to keep the source QPDF or its input
	source around. The cost is copying the streams into RAM. See
	comments in QPDF.hh for setImmediateCopyFrom for a detailed
	explanation.

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

	* 8.3.0: release

	* Add sample completion files in completions. These can be used by
	packagers to install on the system wherever bash and zsh keep
	their vendor-supplied completions.

	* Add configure flag --enable-check-autofiles, which is on by
	default. Packagers whose packaging systems automatically refresh
	autoconf or libtool files should pass --disable-check-autofiles to
	./configure to suppress warnings about automatically generated
	files being outdated.

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

	* Remove the restriction in most cases that the source QPDF used
	in a copyForeignObject call has to stick around until the
	destination QPDF is written. The exceptional case is when the
	source stream gets is data using a
	QPDFObjectHandle::StreamDataProvider. For a more in-depth
	discussion, see comments around copyForeignObject in QPDF.hh.
	Fixes #219.

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

	* When generating appearances, if the font uses one of the
	standard, built-in encodings, restrict the character set to that
	rather than just to ASCII. This will allow most appearances to
	contain characters from the ISO-Latin-1 range plus a few
	additional characters.

	* Add methods QUtil::utf8_to_win_ansi and
	QUtil::utf8_to_mac_roman.

	* Add method QUtil::utf8_to_utf16.

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

	* Add new option --optimize-images, which recompresses every image
	using DCT (JPEG) compression as long as the image is not already
	compressed with lossy compression and recompressing the image
	reduces its size. The additional options --oi-min-width,
	--oi-min-height, and --oi-min-area prevent recompression of images
	whose width, height, or pixel area (width * height) are below a
	specified threshold.

	* Add new option --collate. When specified, the semantics of
	--pages change from concatenation to collation. See the manual for
	a more detailed discussion. Fixes #259.

	* Add new method QPDFWriter::getFinalVersion, which returns the
	PDF version that will ultimately be written to the final file. See
	comments in QPDFWriter.hh for some restrictions on its use. Fixes
	#266.

	* When unexpected errors are found while checking linearization
	data, print an error message instead of calling assert, which
	cause the program to crash. Fixes #209, #231.

	* Detect and recover 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 object ID of the dangling reference,
	thereby causing the dangling reference to point to the new object.
	This case is now prevented. Fixes #240.

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

        * Add --generate-appearances flag to the qpdf command-line tool to
	trigger generation of appearance streams.

	* Fix behavior of form field value setting to handle the following
	cases:
	  - Strings are always written as UTF-16
	  - Check boxes and radio buttons are handled properly with
	    synchronization of values and appearance states

	* Define constants in qpdf/Constants.h for interpretation of
	annotation and form field flags

	* Add QPDFAnnotationObjectHelper::getFlags

	* Add many new methods to QPDFFormFieldObjectHelper for querying
	flags and field types

	* Add new methods for appearance stream generation. See comments
	in QPDFFormFieldObjectHelper.hh for generateAppearance() for a
	description of limitations.
	  - QPDFAcroFormDocumentHelper::generateAppearancesIfNeeded
	  - QPDFFormFieldObjectHelper::generateAppearance

	* Bug fix: when writing form field values, always write string
	values encoded as UTF-16.

	* Add method QUtil::utf8_to_ascii, which returns an ASCII string
	for a UTF-8 string, replacing out-of-range characters with a
	specified substitute.

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

	* Add method QPDFObjectHandle::getResourceNames that returns a set
	of strings representing all second-level keys in a dictionary
	(i.e. all keys of all direct dictionary members).

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

	* Add --flatten-annotations flag to the qpdf command-line tool for
	annotation flattening.

	* Add methods for flattening form fields and annotations:
	  - QPDFPageDocumentHelper::flattenAnnotations - integrate
	    annotation appearance streams into page contents with special
	    handling for form fields: if appearance streams are up to date
	    (/NeedAppearances is false in /AcroForm), the /AcroForm key of
	    the document catalog is removed. Otherwise, a warning is
	    issued, and form fields are ignored. Non-form-field
	    annotations are always flattened if an appearance stream can
	    be found.
	  - QPDFAnnotationObjectHelper::getPageContentForAppearance -
	    generate the content stream fragment to render an appearance
	    stream in a page's content stream as a form xobject. Called by
	    flattenAnnotations.

	* Add method QPDFObjectHandle::mergeResources(), which merges
	resource dictionaries. See detailed description in
	QPDFObjectHandle.hh.

	* Add QPDFObjectHandle::Matrix, similar to
	QPDFObjectHandle::Rectangle, as a convenience class for
	six-element arrays that are used as matrices.

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

	* When specifying @arg on the command line, if the file "arg" does
	not exist, just treat this is a normal argument. This makes it
	easier to deal with files whose names start with the @ character.
	Fixes #265.

	* Tweak completion so it works with zsh as well using
	bashcompinit.

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

	* Add new options --json, --json-key, and --json-object to
	generate a json representation of the PDF file. This is described
	in more depth in the manual. You can also run qpdf --json-help to
	get a description of the json format.

2018-12-21  Jay Berkenbilt  <ejb@ql.org>

	* Allow --show-object=trailer for showing the document trailer.

	* You can now use eval $(qpdf --completion-bash) to enable bash
	completion for qpdf. It's not perfect, but it works pretty well.

2018-12-19  Jay Berkenbilt  <ejb@ql.org>

	* When splitting pages using --split-pages, the outlines
	dictionary and some supporting metadata are copied into the split
	files. The result is that all bookmarks from the original file
	appear, and those that point to pages that are preserved work
	while those that point to pages that are not preserved don't do
	anything. This is an interim step toward proper support for
	bookmark preservation in split files.

	* Add QPDFOutlineDocumentHelper and QPDFOutlineObjectHelper for
	handling outlines (bookmarks) including bidirectionally mapping
	between bookmarks and pages. Initially there is no support for
	modifying the outlines hierarchy.

2018-12-18  Jay Berkenbilt  <ejb@ql.org>

	* New method QPDFObjectHandle::getJSON() returns a JSON object
	with a partial representation of the object. See
	QPDFObjectHandle.hh for a detailed description.

	* Add a simple JSON serializer. This is not a complete or
	general-purpose JSON library. It allows assembly and serialization
	of JSON structures with some restrictions, which are described in
	the header file.

	* Add QPDFNameTreeObjectHelper class. This class provides useful
	methods for dealing with name trees, which are discussed in
	section 7.9.6 of the PDF spec (ISO-32000).

	* Preserve page labels when merging and splitting files. Prior
	versions of qpdf simply preserved the page label information from
	the first file, which usually wouldn't make any sense in the
	merged file. Now any page that had a page number in any original
	file will have the same page number after merging or splitting.

	* Add QPDFPageLabelDocumentHelper class. This is a document helper
	class that provides useful methods for dealing with page labels.
	It abstracts the fact that they are stored as number trees and
	deals with interpolating intermediate values that are not in the
	tree. It also has helper functions used by the qpdf command line
	tool to preserve page labels when merging and splitting files.

	* Add QPDFNumberTreeObjectHelper class. This class provides useful
	methods for dealing with number trees, which are discussed in
	section 7.9.7 of the PDF spec (ISO-32000). Page label dictionaries
	are represented as number trees.

	* New method QPDFObjectHandle::wrapInArray returns the object
	itself if it is an array. Otherwise, it returns an array
	containing the object. This is useful for dealing with PDF data
	that is sometimes expressed as a single element and sometimes
	expressed as an array, which is a somewhat common PDF idiom.

2018-10-11  Jay Berkenbilt  <ejb@ql.org>

	* Files generated by autogen.sh are now committed so that it is
	possible to build on platforms without autoconf directly from a
	clean checkout of the repository. The configure script detects if
	the files are out of date when it also determines that the tools
	are present to regenerate them.

	* Add build in Azure Pipelines, now that it is free for open
	source projects.

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

	* 8.2.1: release

	* Add new option --keep-files-open=[yn] to control whether qpdf
	keeps files open when merging. Prior to version 8.1.0, qpdf always
	kept all files open, but this meant that the number of files that
	could be merged was limited by the operating system's open file
	limit. Version 8.1.0 opened files as they were referenced, but
	this caused a major performance impact. Version 8.2.0 optimized
	the performance but did so in a way that, for local file systems,
	there was a small but unavoidable performance hit, but for
	networked file systems, the performance impact could be very high.
	Starting with version 8.2.1, the default behavior is that files
	are kept open if no more than 200 files are specified, but that
	the behavior can be explicitly overridden with the
	--keep-files-open flag. If you are merging more than 200 files but
	less than the operating system's max open files limit, you may
	want to use --keep-files-open=y. If you are using a local file
	system where the overhead is low and you might sometimes merge
	more than the OS limit's number of files, you may want to specify
	--keep-files-open=n. Fixes #237.

2018-08-16  Jay Berkenbilt  <ejb@ql.org>

	* 8.2.0: release

2018-08-14  Jay Berkenbilt  <ejb@ql.org>

	* For the mingw builds, change the name of the DLL import library
	from libqpdf.a to libqpdf.dll.a to avoid confusing it with a
	static library. This potentially clears the way for supporting a
	static library in the future, though presently, the qpdf Windows
	build only builds the DLL and executables. Fixes #225.

2018-08-13  Jay Berkenbilt  <ejb@ql.org>

	* Add new class QPDFSystemError, derived from std::runtime_error,
	which is now thrown by QUtil::throw_system_error. This enables the
	triggering errno value to be retrieved. Fixes #221.

2018-08-12  Jay Berkenbilt  <ejb@ql.org>

	* qpdf command line: add --no-warn option to suppress issuing
	warning messages. If there are any conditions that would have
	caused warnings to be issued, the exit status is still 3.

	* Rewrite the internals of Pl_Buffer to be much more efficient in
	use of memory at a very slight performance cost. The old
	implementation could cause memory usage to go out of control for
	files with large images compressed using the TIFF predictor.
	Fixes #228.

2018-08-05  Jay Berkenbilt  <ejb@ql.org>

	* Bug fix: end of line characters were not properly handled inside
	strings in some cases. Fixes #226.

	* Bug fix: infinite loop on progress reporting for very small
	files. Fixes #230.

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

	* Performance fix: optimize page merging operation to avoid
	unnecessary open/close calls on files being merged. Fixes #217.

	* Add ClosedFileInputSource::stayOpen method, enabling a
	ClosedFileInputSource to stay open during manually indicated
	periods of high activity, thus reducing the overhead of frequent
	open/close operations.

2018-06-23  Jay Berkenbilt  <ejb@ql.org>

	* 8.1.0: release

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

	* Bug fix: properly decrypt files with 40-bit keys that use
	revision 3 of the security handler. Prior to this, qpdf was
	reporting "invalid password" in this case. Fixes #212.

	* With --verbose, print information about each input file when
	merging files.

	* Add progress reporting to QPDFWriter. Programmatically, you can
	register a progress reporter with registerProgressReporter(). From
	the command line, passing --progress will give progress indicators
	in increments of no less than 1% as output files are written.
	Fixes #200.

	* Add new method QPDF::getObjectCount(). This gives an approximate
	(upper bound) account of objects in the QPDF object.

	* Don't leave files open when merging. This makes it possible
	merge more files at once than the operating system's open file
	limit. Fixes #154.

	* Add ClosedFileInputSource class, and input source that keeps its
	input file closed when not reading it. At the expense of some
	performance, this allows you to operate on many files without
	opening too many files at the operating system level.

	* Add new option --preserve-unreferenced-resources, which
	suppresses removal of unreferenced objects from page resource
	dictionaries during page splitting operations.

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

	* Add method QPDFPageObjectHelper::removeUnreferencedResources and
	also QPDFPageDocumentHelper::removeUnreferencedResources that
	calls the former on every page. This method removes any XObject or
	Font references from the page's resource dictionary if they are
	not referenced anywhere in any of the content streams. This
	significantly reduces the size of split files whose pages
	internally share resource dictionaries. Fixes #203.

	* The --rotate option to qpdf no longer requires an explicit page
	range. You can now rotate all pages of a document with
	qpdf --rotate=angle in.pdf out.pdf. Fixes #211.

	* Create examples/pdf-set-form-values.cc to illustrate use of
	interactive form helpers.

	* Added methods QPDFAcroFormDocumentHelper::setNeedAppearances and
	added methods to QPDFFormFieldObjectHelper to set a field's value,
	optionally updating the document to indicate that appearance
	streams need to be regenerated.

	* Added QPDFObject::newUnicodeString and QPDFObject::unparseBinary
	to allow for more convenient creation of strings that are
	explicitly encoded in UTF-16 BE. This is useful for creating
	Unicode strings that appear outside of content streams, such as in
	page labels, outlines, form field values, etc.

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

	* Added new classes QPDFAcroFormDocumentHelper,
	QPDFFormFieldObjectHelper, and QPDFAnnotationObjectHelper to
	assist with working with interactive forms in PDF files. At
	present, API methods for reading forms, form fields, and widget
	annotations have been added. It is likely that some additional
	methods for modifying forms will be added in the future. Note that
	qpdf remains a library whose function is primarily focused around
	document structure and metadata rather than content. As such, it
	is not expected that qpdf will have higher level APIs for
	generating form contents, but qpdf will hopefully gain the
	capability to deal with the bookkeeping aspects of wiring up all
	the objects, which could make it a useful library for other
	software that works with PDF interactive forms. PDF forms are
	complex, and the terminology around them is confusing. Please see
	comments at the top of QPDFAcroFormDocumentHelper.hh for
	additional discussion.

	* Added new classes QPDFPageDocumentHelper and QPDFPageObjectHelper
	for page-level API functions. These classes introduce a new API
	pattern of document helpers and object helpers in qpdf. The helper
	classes provide a higher level API for working with certain types
	of structural features of PDF while still staying true to qpdf's
	philosophy of not isolating the user from the underlying
	structure. Please see the chapter in the documentation entitled
	"Design and Library Notes" for additional discussion. The examples
	have also been updated to use QPDFPageDocumentHelper and
	QPDFPageObjectHelper when performing page-level operations.

2018-06-19  Jay Berkenbilt  <ejb@ql.org>

	* New QPDFObject::Rectangle class will convert to and from arrays
	of four numerical values. Rectangles are used in various places
	within the PDF file format and are called out as a specific data
	type in the PDF specification.

2018-05-12  Jay Berkenbilt  <ejb@ql.org>

	* In newline before endstream mode, an extra newline was not
	inserted prior to the endstream that ends object streams.
	Fixes #205.

2018-04-15  Jay Berkenbilt  <ejb@ql.org>

	* Arbitrarily limit the depth of data structures represented by
	direct object. This is CVE-2018-9918. Fixes #202.

2018-03-06  Jay Berkenbilt  <ejb@ql.org>

	* 8.0.2: release

	* Properly handle pages with no contents. Fixes #194.

2018-03-05  Jay Berkenbilt  <ejb@ql.org>

	* Improve handling of loops while following cross reference
	tables. Fixes #192.

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

	* 8.0.1: release

	* On the command line when specifying page ranges, support
	preceding a page number by "r" to indicate that it should be
	counted from the end. For example, the range r3-r1 would indicate
	the last three pages of a document.

2018-03-03  Jay Berkenbilt  <ejb@ql.org>

	* Ignore zlib data check errors while uncompressing streams. This
	is consistent with behaviors of other readers and enables handling
	of some incorrectly written zlib streams. Fixes #191.

2018-02-25  Jay Berkenbilt  <ejb@ql.org>

	* 8.0.0: release

2018-02-17  Jay Berkenbilt  <ejb@ql.org>

	* Fix QPDFObjectHandle::getUTF8Val() to properly handle strings
	that are encoded with PDF Doc Encoding. Fixes #179.

	* Add qpdf_check_pdf to the "C" API. This method just attempts to
	read the entire file and produce no output, making possible to
	assess whether the file has any errors that qpdf can detect.

	* Major enhancements to handling of type errors within the qpdf
	library. This fix is intended to eliminate those annoying cases
	where qpdf would exit with a message like "operation for
	dictionary object attempted on object of wrong type" without
	providing any context. Now qpdf keeps enough context to be able to
	issue a proper warning and to handle such conditions in a sensible
	way. This should greatly increase the number of bad files that
	qpdf can recover, and it should make it much easier to figure out
	what's broken when a file contains errors.

	* Error message fix: replace "file position" with "offset" in
	error messages that report lexical or parsing errors. Sometimes
	it's an offset in an object stream or a content stream rather than
	a file position, so this makes the error message less confusing in
	those cases. It still requires some knowledge to find the exact
	position of the error, since when it's not a file offset, it's
	probably an offset into a stream after uncompressing it.

	* Error message fix: correct some cases in which the object that
	contained a lexical error was omitted from the error message.

	* Error message fix: improve file name in the error message when
	there is a parser error inside an object stream.

2018-02-11  Jay Berkenbilt  <ejb@ql.org>

	* Add QPDFObjectHandle::filterPageContents method to provide a
	different interface for applying token filters to page contents
	without modifying the ultimate output.

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

        * Changes listed on today's date are numerous and reflect
	significant enhancements to qpdf's lexical layer. While many
	nuances are discussed and a handful of small bugs were fixed, it
	should be emphasized that none of these issues have any impact on
	any output or behavior of qpdf under "normal" operation. There are
	some changes that have an effect on content stream normalization
	as with qdf mode or on code that interacts with PDF files
	lexically using QPDFTokenizer. There are no incompatible changes
	for normal operation. There are a few changes that will affect the
	exact error messages issued on certain bad files, and there is a
	small non-compatible enhancement regarding the behavior of
	manually constructed QPDFTokenizer::Token objects. Users of the
	qpdf command line tool will see no changes other than the addition
	of a new command-line flag and possibly some improved error
	messages.

	* Significant lexer (tokenizer) enhancements. These are changes to
	the QPDFTokenizer class. These changes are of concern only to
	people who are operating with PDF files at the lexical layer using
	qpdf. They have little or no impact on most high-level interfaces
	or the command-line tool.

	New token types tt_space and tt_comment to recognize whitespace
	and comments. this makes it possible to tokenize a PDF file or
	stream and preserve everything about it.

	For backward compatibility, space and comment tokens are not
	returned by the tokenizer unless QPDFTokenizer.includeIgnorable()
	is called.

	Better handling of null bytes. These are now included in space
	tokens rather than being their own "tt_word" tokens. This should
	have no impact on any correct PDF file and has no impact on
	output, but it may change offsets in some error messages when
	trying to parse contents of bad files. Under default operation,
	qpdf does not attempt to parse content streams, so this change is
	mostly invisible.

	Bug fix to handling of bad tokens at ends of streams. Now, when
	allowEOF() has been called, these are treated as bad tokens
	(tt_bad or an exception, depending on invocation), and a
	separate tt_eof token is returned. Before the bad token
	contents were returned as the value of a tt_eof token. tt_eof
	tokens are always empty now.

	Fix a bug that would, on rare occasions, report the offset in an
	error message in the wrong space because of spaces or comments
	adjacent to a bad token.

	Clarify in comments exactly where the input source is positioned
	surrounding calls to readToken and getToken.

	* Add a new token type for inline images. This token type is only
	returned by QPDFTokenizer immediately following a call to
	expectInlineImage(). This change includes internal refactoring of
	a handful of places that all separately handled inline images, The
	logic of detecting inline images in content streams is now handled
	in one place in the code. Also we are more flexible about what
	characters may surround the EI operator that marks the end of an
	inline image.

	* New method QPDFObjectHandle::parsePageContents() to improve upon
	QPDFObjectHandle::parseContentStream(). The parseContentStream
	method used to operate on a single content stream, but was fixed
	to properly handle pages with contents split across multiple
	streams in an earlier release. The new method parsePageContents()
	can be called on the page object rather than the value of the
	page dictionary's /Contents key. This removes a few lines of
	boiler-plate code from any code that uses parseContentStream, and
	it also enables creation of more helpful error messages if
	problems are encountered as the error messages can include
	information about which page the streams come from.

	* Update content stream parsing example
	(examples/pdf-parse-content.cc) to use new
	QPDFObjectHandle::parsePageContents() method in favor of the older
	QPDFObjectHandle::parseContentStream() method.

	* Bug fix: change where the trailing newline is added to a stream
	in QDF mode when content normalization is enabled (the default for
	QDF mode). Before, the content normalizer ensured that the output
	ended with a trailing newline, but this had the undesired side
	effect of including the newline in the stream data for purposes of
	length computation. QPDFWriter already appends a newline without
	counting in length for better readability. Ordinarily this makes
	no difference, but in the rare case of a page's contents being
	split in the middle of a token, the old behavior could cause the
	extra newline to be interpreted as part of the token. This bug
	could only be triggered in qdf mode, which is a mode intended for
	manual inspection of PDF files' contents, so it is very unlikely
	to have caused any actual problems for people using qpdf for
	production use. Even if it did, it would be very unusual for a PDF
	file to actually be adversely affected by this issue.

	* Add support for coalescing a page's contents into a single
	stream if they are represented as an array of streams. This can be
	performed from the command line using the --coalesce-contents
	option. Coalescing content streams can simplify things for
	software that wants to operate on a page's content streams without
	having to handle weird edge cases like content streams split in
	the middle of tokens. Note that
	QPDFObjectHandle::parsePageContents and
	QPDFObjectHandle::parseContentStream already handled split content
	streams. This is mainly to set the stage for new methods of
	operating on page contents. The new method
	QPDFObjectHandle::pipeContentStreams will pipe all of a page's
	content streams though a single pipeline. The new method
	QPDFObjectHandle.coalesceContentStreams, when called on a page
	object, will do nothing if the page's contents are a single
	stream, but if they are an array of streams, it will replace the
	page's contents with a single stream whose contents are the
	concatenation of the original streams.

	* A few library routines throw exceptions if called on non-page
	objects. These constraints have been relaxed somewhat to make qpdf
	more tolerant of files whose page dictionaries are not properly
	marked as such. Mostly exceptions about page operations being
	called on non page objects will only be thrown in cases where the
	operation had no chance of succeeding anyway. This change has no
	impact on any default mode operations, but it could allow
	applications that use page-level APIs in QPDFObjectHandle to be
	more tolerant of certain types of damaged files.

	* Add QPDFObjectHandle::TokenFilter class and methods to use it to
	perform lexical filtering on content streams. You can call
	QPDFObjectHandle::addTokenFilter on stream object, or you can call
	the higher level QPDFObjectHandle::addContentTokenFilter on a page
	object to cause the stream's contents to passed through a token
	filter while being retrieved by QPDFWriter or any other consumer.
	For details on using TokenFilter, please see comments in
	QPDFObjectHandle.hh.

	* Enhance the string, type QPDFTokenizer::Token constructor to
	initialize a raw value in addition to a value. Tokens have a
	value, which is a canonical representation, and a raw value. For
	all tokens except strings and names, the raw value and the value
	are the same. For strings, the value excludes the outer delimiters
	and has non-printing characters normalized. For names, the value
	resolves non-printing characters. In order to better facilitate
	token filters that mostly preserve contents and to enable
	developers to be mostly unconcerned about the nuances of token
	values and raw values, creating string and name tokens now
	properly handles this subtlety of values and raw values. When
	constructing string tokens, take care to avoid passing in the
	outer delimiters. This has always been the case, but it is now
	clarified in comments in QPDFObjectHandle.hh::TokenFilter. This
	has no impact on any existing code unless there's some code
	somewhere that was relying on Token::getRawValue() returning an
	empty string for a manually constructed token. The token class's
	operator== method still only looks at type and value, not raw
	value. For example, string tokens for <41> and (A) would still be
	equal because both are representations of the string "A".

	* Add QPDFObjectHandle::isDataModified method. This method just
	returns true if addTokenFilter has been called on the stream. It
	enables a caller to determine whether it is safe to optimize away
	piping of stream data in cases where the input and output are
	expected to be the same. QPDFWriter uses this internally to skip
	the optimization of not re-compressing already compressed streams
	if addTokenFilter has been called. Most developers will not have
	to worry about this as it is used internally in the library in the
	places that need it. If you are manually retrieving stream data
	with QPDFObjectHandle::getStreamData or
	QPDFObjectHandle::pipeStreamData, you don't need to worry about
	this at all.

	* Provide heavily annotated examples/pdf-filter-tokens.cc example
	that illustrates use of some simple token filters.

	* When normalizing content streams, as in qdf mode, issue warning
	about bad tokens. Content streams are only normalized when this is
	explicitly requested, so this has no impact on normal operation.
	However, in qdf mode, if qpdf detects a bad token, it means that
	either there's a bug in qpdf's lexer, that the file is damaged, or
	that the page's contents are split in a weird way. In any of those
	cases, qpdf could potentially damage the stream's contents by
	replacing carriage returns with newlines or otherwise messing with
	spaces. The mostly likely case of this would be an inline image's
	compressed data being divided across two streams and having the
	compressed data in the second stream contain a carriage return as
	part of its binary data. If you are using qdf mode just to look at
	PDF files in text editors, this usually doesn't matter. In cases
	of contents split across multiple streams, coalescing streams
	would eliminate the problem, so the warning mentions this. Prior
	to this enhancement, the chances of qdf mode writing incorrect
	data were already very low. This change should make it nearly
	impossible for qdf mode to unknowingly write invalid data.

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

	* Add QPDFWriter::setLinearizationPass1Filename method and
	--linearize-pass1 command line option to allow specification of a
	file into which QPDFWriter will write its intermediate
	linearization pass 1 file. This is useful only for debugging qpdf.
	qpdf creates linearized files by computing the output in two
	passes. Ordinarily the first pass is discarded and not written
	anywhere. This option allows it to be inspected.

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

	* 7.1.1: release

	* Bug fix: properly linearize files whose /ID has a length of
	other than 16 bytes.

	* Rename some test files to avoid files with three dots in their
	names. Fixes #173.

	* Fix various build and compilation issues on some platforms and
	compilers. Fixes #176, #172, #177

	* Fix a few typos and clarify a few comments in header files.

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

	* 7.1.0: release

	* Allow raw encryption key to be specified in library and command
	line with the QPDF::setPasswordIsHexKey method and
	--password-is-hex-key option. Allow encryption key to be displayed
	with --show-encryption-key option. Thanks to Didier Stevens
	<didier.stevens@gmail.com> for the idea and contribution of one
	implementation of this idea. See his blog post at
	https://blog.didierstevens.com/2017/12/28/cracking-encrypted-pdfs-part-3/
	for a discussion of using this for cracking encrypted PDFs. I hope
	that a future release of qpdf will include some additional
	recovery options that may also make use of this capability.

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

	* Fix lexical error: the PDF specification allows floating point
	numbers to end with ".". Fixes #165.

	* Fix link order in the build to avoid conflicts when building
	from source while an older version of qpdf is installed. Fixes #158.

	* Add support for TIFF predictor for LZW and Flate streams. Now
	all predictor functions are supported. Fixes #171.

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

	* Clarify documentation around options that control parsing but
	not output creation. Two options: --suppress-recovery and
	--ignore-xref-streams, were documented in the "Advanced
