Repository: qpdf/qpdf
Pull request #267 (2018-12-18 12:00:00)

Build
trigger azure build


Patch:
diff --git a/ChangeLog b/ChangeLog
index 40ecd446..1426a50f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+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.
diff --git a/examples/pdf-bookmarks.cc b/examples/pdf-bookmarks.cc
index 7610f949..807fc02f 100644
--- a/examples/pdf-bookmarks.cc
+++ b/examples/pdf-bookmarks.cc
@@ -7,6 +7,10 @@
 #include <qpdf/QUtil.hh>
 #include <qpdf/QTC.hh>
 
+// This program demonstrates extraction of bookmarks using the qpdf
+// outlines API. Note that all the information shown by this program
+// can also be obtained from a PDF file using qpdf's --json option.
+
 static char const* whoami = 0;
 static enum { st_none, st_numbers, st_lines } style = st_none;
 static bool show_open = false;
diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml
index e327eb95..2ccaafd3 100644
--- a/manual/qpdf-manual.xml
+++ b/manual/qpdf-manual.xml
@@ -300,12 +300,67 @@ make
     inspection commands do not.  These are specifically noted.
    </para>
   </sect1>
+  <sect1 id="ref.shell-completion">
+   <title>Shell Completion</title>
+   <para>
+    Starting in qpdf version 8.3.0, qpdf provides its own completion
+    support for zsh and bash. You can enable bash completion with
+    <command>eval $(qpdf --completion-bash)</command> and zsh
+    completion with <command>eval $(qpdf --completion-zsh)</command>.
+    If <command>qpdf</command> is not in your path, you should invoke
+    it above with an absolute path. If you invoke it with a relative
+    path, it will warn you, and the completion won't work if you're in
+    a different directory.
+   </para>
+  </sect1>
   <sect1 id="ref.basic-options">
    <title>Basic Options</title>
    <para>
     The following options are the most common ones and perform
     commonly needed transformations.
     <variablelist>
+     <varlistentry>
+      <term><option>--help</option></term>
+      <listitem>
+       <para>
+        Display command-line invocation help.
+       </para>
+      </listitem>
+     </varlistentry>
+     <varlistentry>
+      <term><option>--version</option></term>
+      <listitem>
+       <para>
+        Display the current version of qpdf.
+       </para>
+      </listitem>
+     </varlistentry>
+     <varlistentry>
+      <term><option>--copyright</option></term>
+      <listitem>
+       <para>
+        Show detailed copyright information.
+       </para>
+      </listitem>
+     </varlistentry>
+     <varlistentry>
+      <term><option>--completion-bash</option></term>
+      <listitem>
+       <para>
+        Output a completion command you can eval to enable shell
+        completion from bash.
+       </para>
+      </listitem>
+     </varlistentry>
+     <varlistentry>
+      <term><option>--completion-zsh</option></term>
+      <listitem>
+       <para>
+        Output a completion command you can eval to enable shell
+        completion from zsh.
+       </para>
+      </listitem>
+     </varlistentry>
      <varlistentry>
       <term><option>--password=password</option></term>
       <listitem>
@@ -1515,7 +1570,7 @@ outfile.pdf</option>
       </listitem>
      </varlistentry>
      <varlistentry>
-      <term><option>--show-object=obj[,gen]</option></term>
+      <term><option>--show-object=trailer|obj[,gen]</option></term>
       <listitem>
        <para>
         Show the contents of the given object.  This is especially
@@ -1580,6 +1635,44 @@ outfile.pdf</option>
        </para>
       </listitem>
      </varlistentry>
+     <varlistentry>
+      <term><option>--json</option></term>
+      <listitem>
+       <para>
+        Generate a json representation of the file. This is described
+        in depth in <xref linkend="ref.json"/>
+       </para>
+      </listitem>
+     </varlistentry>
+     <varlistentry>
+      <term><option>--json-help</option></term>
+      <listitem>
+       <para>
+        Describe the format of the json output.
+       </para>
+      </listitem>
+     </varlistentry>
+     <varlistentry>
+      <term><option>--json-key=key</option></term>
+      <listitem>
+       <para>
+        This option is repeatable. If specified, only top-level keys
+        specified will be included in the json output. If not
+        specified, all keys wil be shown.
+       </para>
+      </listitem>
+      </varlistentry>
+     <varlistentry>
+      <term><option>--json-object=trailer|obj[,gen]</option></term>
+      <listitem>
+       <para>
+        This option is repeatable. If specified, only specified
+        objects will be shown in the
+        &ldquo;<literal>objects</literal>&rdquo; key of the json
+        output. If absent, all objects will be shown.
+       </para>
+      </listitem>
+     </varlistentry>
      <varlistentry>
       <term><option>--check</option></term>
       <listitem>
@@ -1777,6 +1870,8 @@ outfile.pdf</option>
  </chapter>
  <chapter id="ref.using-library">
   <title>Using the QPDF Library</title>
+  <sect1 id="ref.using.from-cxx">
+   <title>Using QPDF from C++</title>
    <para>
     The source tree for the qpdf package has an
     <filename>examples</filename> directory that contains a few
@@ -1808,6 +1903,291 @@ outfile.pdf</option>
     time.  Multiple threads may simultaneously work with different
     instances of these and all other QPDF objects.
    </para>
+  </sect1>
+  <sect1 id="ref.using.other-languages">
+   <title>Using QPDF from other languages</title>
+   <para>
+    The qpdf library is implemented in C++, which makes it hard to use
+    directly in other languages. There are a few things that can help.
+   </para>
+   <variablelist>
+    <varlistentry>
+     <term>&ldquo;C&rdquo;</term>
+     <listitem>
+      <para>
+       The qpdf library includes a &ldquo;C&rdquo; language interface
+       that provides a subset of the overall capabilities. The header
+       file <filename>qpdf/qpdf-c.h</filename> includes information
+       about its use. As long as you use a C++ linker, you can link C
+       programs with qpdf and use the C API. For languages that can
+       directly load methods from a shared library, the C API can also
+       be useful. People have reported success using the C API from
+       other languages on Windows by directly calling functions in the
+       DLL.
+      </para>
+     </listitem>
+    </varlistentry>
+    <varlistentry>
+     <term>Python</term>
+     <listitem>
+      <para>
+       A Python module called <ulink
+       url="https://pypi.org/project/pikepdf/">pikepdf</ulink>
+       provides a clean and highly functional set of Python bindings
+       to the qpdf library. Using pikepdf, you can work with PDF files
+       in a natural way and combine qpdf's capabilities with other
+       functionality provided by Python's rich standard library and
+       available modules.
+      </para>
+     </listitem>
+    </varlistentry>
+    <varlistentry>
+     <term>Other Languages</term>
+     <listitem>
+      <para>
+       Starting with version 8.3.0, the <command>qpdf</command>
+       command-line tool can produce a json representation of the PDF
+       file's non-content data. This can facilitate interacting
+       programmatically with PDF files through qpdf's command line
+       interface. For more information, please see <xref
+       linkend="ref.json"/>.
+      </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+  </sect1>
+ </chapter>
+ <chapter id="ref.json">
+  <title>QPDF JSON</title>
+  <sect1 id="ref.json-overview">
+   <title>Overview</title>
+   <para>
+    Beginning with qpdf version 8.3.0, the <command>qpdf</command>
+    command-line program can produce a json representation of the
+    non-content data in a PDF file. It includes a dump in json format
+    of all objects in the PDF file excluding the content of streams.
+    This json representation makes it very easy to look in detail at
+    the structure of a given PDF file, and it also provides a great way
+    to work with PDF files programmatically from the command-line in
+    languages that can't call or link with the qpdf library directly.
+    Note that stream data can be extracted from PDF files using other
+    qpdf command-line options.
+   </para>
+  </sect1>
+  <sect1 id="ref.json-guarantees">
+   <title>JSON Guarantees</title>
+   <para>
+    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 format. These guarantees are designed to simplify the
+    experience of a developer working with the JSON format.
+    <variablelist>
+     <varlistentry>
+      <term>Compatibility</term>
+      <listitem>
+       <para>
+        The top-level json object output is a dictionary. The json
+        output contains various nested dictionaries and arrays. With
+        the exception of dictionaries that are populated by the fields
+        of objects from the file, all instances of a dictionary are
+        guaranteed to have exactly the same keys. Future versions of
+        qpdf are free to add additional keys but not to remove keys or
+        change the type of object that a key points to. The qpdf
+        program validates this guarantee, and in the unlikely event
+        that a bug in qpdf should cause it to generate data that
+        doesn't conform to this rule, it will ask you to file a bug
+        report.
+       </para>
+       <para>
+        The top-level json structure contains a
+        &ldquo;<literal>version</literal>&rdquo; key whose value is
+        simple integer. The value of the <literal>version</literal> key
+        will be incremented if a non-compatible change is made. A
+        non-compatible change would be any change that involves removal
+        of a key, a change to the format of data pointed to by a key,
+        or a semantic change that requires a different interpretation
+        of a previously existing key. A strong effort will be made to
+        avoid breaking compatibility.
+       </para>
+      </listitem>
+     </varlistentry>
+     <varlistentry>
+      <term>Documentation</term>
+      <listitem>
+       <para>
+        The <command>qpdf</command> command can be invoked with the
+        <option>--json-help</option> option. This will output a json
+        structure that has the same structure as the json output that
+        qpdf generates, except that each field in the help output is a
+        description of the corresponding field in the json output. The
+        specific guarantees are as follows:
+        <itemizedlist>
+         <listitem>
+          <para>
+           A dictionary in the help output means that the corresponding
+           location in the actual json output is also a dictionary with
+           exactly the same keys; that is, no keys present in help are
+           absent in the real output, and no keys will be present in
+           the real output that are not in help.
+          </para>
+         </listitem>
+         <listitem>
+          <para>
+           A string in the help output is a description of the item
+           that appears in the corresponding location of the actual
+           output. The corresponding output can have any format.
+          </para>
+         </listitem>
+         <listitem>
+          <para>
+           An array in the help output always contains a single
+           element. It indicates that the corresponding location in the
+           actual output is also an array, and that each element of the
+           array has whatever format is implied by the single element
+           of the help output's array.
+          </para>
+         </listitem>
+        </itemizedlist>
+        For example, the help output indicates includes a
+        &ldquo;<literal>pagelabels</literal>&rdquo; key whose value is
+        an array of one element. That element is a dictionary with keys
+        &ldquo;<literal>index</literal>&rdquo; and
+        &ldquo;<literal>label</literal>&rdquo;. In addition to
+        describing the meaning of those keys, this tells you that the
+        actual json output will contain a <literal>pagelabels</literal>
+        array, each of whose elements is a dictionary that contains an
+        <literal>index</literal> key, a <literal>label</literal> key,
+        and no other keys.
+       </para>
+      </listitem>
+     </varlistentry>
+     <varlistentry>
+      <term>Directness and Simplicity</term>
+      <listitem>
+       <para>
+        The json output contains the value of every object in the file,
+        but it also contains some processed data. This is analogous to
+        how qpdf's library interface works. The processed data is
+        similar to the helper functions in that it allows you to look
+        at certain aspects of the PDF file without having to understand
+        all the nuances of the PDF specification, while the raw objects
+        allow you to mine the PDF for anything that the higher-level
+        interfaces are lacking.
+       </para>
+      </listitem>
+     </varlistentry>
+    </variablelist>
+   </para>
+  </sect1>
+  <sect1 id="json.limitations">
+   <title>Limitations of JSON Representation</title>
+   <para>
+    There are a few limitations to be aware of with the json structure:
+    <itemizedlist>
+     <listitem>
+      <para>
+       Strings, names, and indirect object references in the original
+       PDF file are all converted to strings in the json
+       representation. In the case of a &ldquo;normal&rdquo; PDF file,
+       you can tell the difference because a name starts with a slash
+       (<literal>/</literal>), and an indirect object reference looks
+       like <literal>n n R</literal>, but if there were to be a string
+       that looked like a name or indirect object reference, there
+       would be no way to tell this from the json output. Note that
+       there are certain cases where you know for sure what something
+       is, such as knowing that dictionary keys in objects are always
+       names and that certain things in the higher-level computed data
+       are known to contain indirect object references.
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+       The json format doesn't support binary data very well. Mostly
+       the details are not important, but they are presented here for
+       information. When qpdf outputs a string in the json
+       representation, it converts the string to UTF-8, assuming usual
+       PDF string semantics. Specifically, if the original string is
+       UTF-16, it is converted to UTF-8. Otherwise, it is assumed to
+       have PDF doc encoding, and is converted to UTF-8 with that
+       assumption. This causes strange things to happen to binary
+       strings. For example, if you had the binary string
+       <literal>&lt;038051&gt;</literal>, this would be output to the
+       json as <literal>\u0003•Q</literal> because
+       <literal>03</literal> is not a printable character and
+       <literal>80</literal> is the bullet character in PDF doc
+       encoding and is mapped to the Unicode value
+       <literal>2022</literal>. Since <literal>51</literal> is
+       <literal>Q</literal>, it is output as is. If you wanted to
+       convert back from here to a binary string, would have to
+       recognize Unicode values whose code points are higher than
+       <literal>0xFF</literal> and map those back to their
+       corresponding PDF doc encoding characters. There is no way to
+       tell the difference between a Unicode string that was originally
+       encoded as UTF-16 or one that was converted from PDF doc
+       encoding. In other words, it's best if you don't try to use the
+       json format to extract binary strings from the PDF file, but if
+       you really had to, it could be done. Note that qpdf's
+       <option>--show-object</option> option does not have this
+       limitation and will reveal the string as encoded in the original
+       file.
+      </para>
+     </listitem>
+    </itemizedlist>
+   </para>
+  </sect1>
+  <sect1 id="json.considerations">
+   <title>JSON: Special Considerations</title>
+   <para>
+    For the most part, the built-in JSON help tells you everything you
+    need to know about the JSON format, but there are a few
+    non-obvious things to be aware of:
+    <itemizedlist>
+     <listitem>
+      <para>
+       While qpdf guarantees that keys present in the help will be
+       present in the output, those fields may be null or empty if the
+       information is not known or absent in the file. Also, if you
+       specify <option>--json-keys</option>, the keys that are not
+       listed will be excluded entirely except for those that
+       <option>--json-help</option> says are always present.
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+       In a few places, there are keys with names containing
+       <literal>pageposfrom1</literal>. The values of these keys are
+       null or an integer. If an integer, they point to a page index
+       within the file numbering from 1. Note that json indexes from
+       0, and you would also use 0-based indexing using the API.
+       However, 1-based indexing is easier in this case because the
+       command-line syntax for specifying page ranges is 1-based. If
+       you were going to write a program that looked through the json
+       for information about specific pages and then use the
+       command-line to extract those pages, 1-based indexing is
+       easier. Besides, it's more convenient to subtract 1 from a
+       program in a real programming language than it is to add 1 from
+       shell code.
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+       The image information included in the <literal>page</literal>
+       section of the json output includes the key
+       &ldquo;<literal>filterable</literal>&rdquo;. Note that the
+       value of this field may depend on the
+       <option>--decode-level</option> that you invoke qpdf with. The
+       json output includes a top-level key
+       &ldquo;<literal>parameters</literal>&rdquo; that indicates the
+       decode level used for computing whether a stream was
+       filterable. For example, jpeg images will be shown as not
+       filterable by default, but they will be shown as filterable if
+       you run <command>qpdf --json --decode-level=all</command>.
+      </para>
+     </listitem>
+    </itemizedlist>
+   </para>
+  </sect1>
  </chapter>
  <chapter id="ref.design">
   <title>Design and Library Notes</title>
diff --git a/qpdf/qpdf.cc b/qpdf/qpdf.cc
index c86cb2a4..1a45180c 100644
--- a/qpdf/qpdf.cc
+++ b/qpdf/qpdf.cc
@@ -119,7 +119,7 @@ struct Options
         show_filtered_stream_data(false),
         show_pages(false),
         show_page_images(false),
-        show_json(false),
+        json(false),
         check(false),
         require_outfile(true),
         infilename(0),
@@ -193,7 +193,9 @@ struct Options
     bool show_filtered_stream_data;
     bool show_pages;
     bool show_page_images;
-    bool show_json;
+    bool json;
+    std::set<std::string> json_keys;
+    std::set<std::string> json_objects;
     bool check;
     std::vector<PageSpec> page_specs;
     std::map<std::string, RotationSpec> rotations;
@@ -243,6 +245,163 @@ ProgressReporter::reportProgress(int percentage)
               << percentage << "%" << std::endl;
 }
 
+static JSON json_schema(std::set<std::string>* keys = 0)
+{
+    // Style: use all lower-case keys with no dashes or underscores.
+    // Choose array or dictionary based on indexing. For example, we
+    // use a dictionary for objects because we want to index by object
+    // ID and an array for pages because we want to index by position.
+    // The pages in the pages array contain references back to the
+    // original object, which can be resolved in the objects
+    // dictionary. When a PDF constract that maps back to an original
+    // object is represented separately, use "object" as the key that
+    // references the original object.
+
+    // This JSON object doubles as a schema and as documentation for
+    // our JSON output. Any schema mismatch is a bug in qpdf. This
+    // helps to enforce our policy of consistently providing a known
+    // structure where every documented key will always be present,
+    // which makes it easier to consume our JSON. This is discussed in
+    // more depth in the manual.
+    JSON schema = JSON::makeDictionary();
+    schema.addDictionaryMember(
+        "version", JSON::makeString(
+            "JSON format serial number; increased for non-compatible changes"));
+    JSON j_params = schema.addDictionaryMember(
+        "parameters", JSON::makeDictionary());
+    j_params.addDictionaryMember(
+        "decodelevel", JSON::makeString(
+            "decode level used to determine stream filterability"));
+
+    bool all_keys = ((keys == 0) || keys->empty());
+
+    // The list of selectable top-level keys id duplicated in three
+    // places: json_schema, do_json, and initOptionTable.
+    if (all_keys || keys->count("objects"))
+    {
+        schema.addDictionaryMember(
+            "objects", JSON::makeString(
+                "dictionary of original objects;"
+                " keys are 'trailer' or 'n n R'"));
+    }
+    if (all_keys || keys->count("pages"))
+    {
+        JSON page = schema.addDictionaryMember("pages", JSON::makeArray()).
+            addArrayElement(JSON::makeDictionary());
+        page.addDictionaryMember(
+            "object",
+            JSON::makeString("reference to original page object"));
+        JSON image = page.addDictionaryMember("images", JSON::makeArray()).
+            addArrayElement(JSON::makeDictionary());
+        image.addDictionaryMember(
+            "name",
+            JSON::makeString("name of image in XObject table"));
+        image.addDictionaryMember(
+            "object",
+            JSON::makeString("reference to image stream"));
+        image.addDictionaryMember(
+            "width",
+            JSON::makeString("image width"));
+        image.addDictionaryMember(
+            "height",
+            JSON::makeString("image height"));
+        image.addDictionaryMember(
+            "colorspace",
+            JSON::makeString("color space"));
+        image.addDictionaryMember(
+            "bitspercomponent",
+            JSON::makeString("bits per component"));
+        image.addDictionaryMember("filter", JSON::makeArray()).
+            addArrayElement(
+                JSON::makeString("filters applied to image data"));
+        image.addDictionaryMember("decodeparms", JSON::makeArray()).
+            addArrayElement(
+                JSON::makeString("decode parameters for image data"));
+        image.addDictionaryMember(
+            "filterable",
+            JSON::makeString("whether image data can be decoded"
+                             " using the decode level qpdf was invoked with"));
+        page.addDictionaryMember("contents", JSON::makeArray()).
+            addArrayElement(
+                JSON::makeString("reference to each content stream"));
+        page.addDictionaryMember(
+            "label",
+            JSON::makeString("page label dictionary, or null if none"));
+        JSON outline = page.addDictionaryMember("outlines", JSON::makeArray()).
+            addArrayElement(JSON::makeDictionary());
+        outline.addDictionaryMember(
+            "object",
+            JSON::makeString("reference to outline that targets this page"));
+        outline.addDictionaryMember(
+            "title",
+            JSON::makeString("outline title"));
+        outline.addDictionaryMember(
+            "dest",
+            JSON::makeString("outline destination dictionary"));
+        page.addDictionaryMember(
+            "pageposfrom1",
+            JSON::makeString("position of page in document numbering from 1"));
+    }
+    if (all_keys || keys->count("pagelabels"))
+    {
+        JSON labels = schema.addDictionaryMember(
+            "pagelabels", JSON::makeArray()).
+            addArrayElement(JSON::makeDictionary());
+        labels.addDictionaryMember(
+            "index",
+            JSON::makeString("starting page position starting from zero"));
+        labels.addDictionaryMember(
+            "label",
+            JSON::makeString("page label dictionary"));
+    }
+    if (all_keys || keys->count("outlines"))
+    {
+        JSON outlines = schema.addDictionaryMember(
+            "outlines", JSON::makeArray()).
+            addArrayElement(JSON::makeDictionary());
+        outlines.addDictionaryMember(
+            "object",
+            JSON::makeString("reference to this outline"));
+        outlines.addDictionaryMember(
+            "title",
+            JSON::makeString("outline title"));
+        outlines.addDictionaryMember(
+            "dest",
+            JSON::makeString("outline destination dictionary"));
+        outlines.addDictionaryMember(
+            "kids",
+            JSON::makeString("array of descendent outlines"));
+        outlines.addDictionaryMember(
+            "open",
+            JSON::makeString("whether the outline is displayed expanded"));
+        outlines.addDictionaryMember(
+            "destpageposfrom1",
+            JSON::makeString("position of destination page in document"
+                             " numbered from 1; null if not known"));
+    }
+    return schema;
+}
+
+static void parse_object_id(std::string const& objspec,
+                            bool& trailer, int& obj, int& gen)
+{
+    if (objspec == "trailer")
+    {
+        trailer = true;
+    }
+    else
+    {
+        trailer = false;
+        obj = QUtil::string_to_int(objspec.c_str());
+        size_t comma = objspec.find(',');
+        if ((comma != std::string::npos) && (comma + 1 < objspec.length()))
+        {
+            gen = QUtil::string_to_int(
+                objspec.substr(1 + comma, std::string::npos).c_str());
+        }
+    }
+}
+
 // This is not a general-purpose argument parser. It is tightly
 // crafted to work with qpdf. qpdf's command-line syntax is very
 // complex because of its long history, and it doesn't really follow
@@ -283,6 +442,12 @@ class ArgParser
     OptionEntry oe_optionalParameter(param_arg_handler_t);
     OptionEntry oe_requiredChoices(param_arg_handler_t, char const** choices);
 
+    void argHelp();
+    void argVersion();
+    void argCopyright();
+    void argCompletionBash();
+    void argCompletionZsh();
+    void argJsonHelp();
     void argPositional(char* arg);
     void argPassword(char* parameter);
     void argEmpty();
@@ -329,7 +494,9 @@ class ArgParser
     void argShowNpages();
     void argShowPages();
     void argWithImages();
-    void argShowJson();
+    void argJson();
+    void argJsonKey(char* parameter);
+    void argJsonObject(char* parameter);
     void argCheck();
     void arg40Print(char* parameter);
     void arg40Modify(char* parameter);
@@ -354,7 +521,7 @@ class ArgParser
     void readArgsFromFile(char const* filename);
     void doFinalChecks();
     void addOptionsToCompletions();
-    void addChoicesToCompletions(std::string const&);
+    void addChoicesToCompletions(std::string const&, std::string const&);
     void handleCompletion();
     std::vector<PageSpec> parsePagesOptions();
     void parseRotationParameter(std::string const&);
@@ -368,13 +535,14 @@ class ArgParser
     Options& o;
     int cur_arg;
     bool bash_completion;
+    bool zsh_completion;
     std::string bash_prev;
     std::string bash_cur;
     std::string bash_line;
-    size_t bash_point;
     std::set<std::string> completions;
 
     std::map<std::string, OptionEntry>* option_table;
+    std::map<std::string, OptionEntry> help_option_table;
     std::map<std::string, OptionEntry> main_option_table;
     std::map<std::string, OptionEntry> encrypt40_option_table;
     std::map<std::string, OptionEntry> encrypt128_option_table;
@@ -391,7 +559,7 @@ ArgParser::ArgParser(int argc, char* argv[], Options& o) :
     o(o),
     cur_arg(0),
     bash_completion(false),
-    bash_point(0)
+    zsh_completion(false)
 {
     option_table = &main_option_table;
     initOptionTable();
@@ -449,7 +617,15 @@ ArgParser::oe_requiredChoices(param_arg_handler_t h, char const** choices)
 void
 ArgParser::initOptionTable()
 {
-    std::map<std::string, OptionEntry>* t = &this->main_option_table;
+    std::map<std::string, OptionEntry>* t = &this->help_option_table;
+    (*t)["help"] = oe_bare(&ArgParser::argHelp);
+    (*t)["version"] = oe_bare(&ArgParser::argVersion);
+    (*t)["copyright"] = oe_bare(&ArgParser::argCopyright);
+    (*t)["completion-bash"] = oe_bare(&ArgParser::argCompletionBash);
+    (*t)["completion-zsh"] = oe_bare(&ArgParser::argCompletionZsh);
+    (*t)["json-help"] = oe_bare(&ArgParser::argJsonHelp);
+
+    t = &this->main_option_table;
     char const* yn[] = {"y", "n", 0};
     (*t)[""] = oe_positional(&ArgParser::argPositional);
     (*t)["password"] = oe_requiredParameter(&ArgParser::argPassword, "pass");
@@ -519,7 +695,15 @@ ArgParser::initOptionTable()
     (*t)["show-npages"] = oe_bare(&ArgParser::argShowNpages);
     (*t)["show-pages"] = oe_bare(&ArgParser::argShowPages);
     (*t)["with-images"] = oe_bare(&ArgParser::argWithImages);
-    (*t)["show-json"] = oe_bare(&ArgParser::argShowJson);
+    (*t)["json"] = oe_bare(&ArgParser::argJson);
+    // The list of selectable top-level keys id duplicated in three
+    // places: json_schema, do_json, and initOptionTable.
+    char const* jsonKeyChoices[] = {
+        "objects", "pages", "pagelabels", "outlines", 0};
+    (*t)["json-key"] = oe_requiredChoices(
+        &ArgParser::argJsonKey, jsonKeyChoices);
+    (*t)["json-object"] = oe_requiredParameter(
+        &ArgParser::argJsonObject, "trailer|obj[,gen]");
     (*t)["check"] = oe_bare(&ArgParser::argCheck);
 
     t = &this->encrypt40_option_table;
@@ -569,6 +753,108 @@ ArgParser::argPositional(char* arg)
     }
 }
 
+void
+ArgParser::argVersion()
+{
+    std::cout
+        << whoami << " version " << QPDF::QPDFVersion() << std::endl
+        << "Run " << whoami << " --copyright to see copyright and license information."
+        << std::endl;
+}
+
+void
+ArgParser::argCopyright()
+{
+    // Make sure the output looks right on an 80-column display.
+    //               1         2         3         4         5         6         7         8
+    //      12345678901234567890123456789012345678901234567890123456789012345678901234567890
+    std::cout
+        << whoami << " version " << QPDF::QPDFVersion() << std::endl
+        << std::endl
+        << "Copyright (c) 2005-2018 Jay Berkenbilt"
+        << std::endl
+        << "QPDF is licensed under the Apache License, Version 2.0 (the \"License\");"
+        << std::endl
+        << "not use this file except in compliance with the License."
+        << std::endl
+        << "You may obtain a copy of the License at"
+        << std::endl
+        << std::endl
+        << "  http://www.apache.org/licenses/LICENSE-2.0"
+        << std::endl
+        << std::endl
+        << "Unless required by applicable law or agreed to in writing, software"
+        << std::endl
+        << "distributed under the License is distributed on an \"AS IS\" BASIS,"
+        << std::endl
+        << "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied."
+        << std::endl
+        << "See the License for the specific language governing permissions and"
+        << std::endl
+        << "limitations under the License."
+        << std::endl
+        << std::endl
+        << "Versions of qpdf prior to version 7 were released under the terms"
+        << std::endl
+        << "of version 2.0 of the Artistic License. At your option, you may"
+        << std::endl
+        << "continue to consider qpdf to be licensed under those terms. Please"
+        << std::endl
+        << "see the manual for additional information."
+        << std::endl;
+}
+
+void
+ArgParser::argHelp()
+{
+    std::cout << help;
+}
+
+void
+ArgParser::argCompletionBash()
+{
+    std::cout << "complete -o bashdefault -o default -o nospace"
+              << " -C " << argv[0] << " " << whoami << std::endl;
+    // Put output before error so calling from zsh works properly
+    std::string path = argv[0];
+    size_t slash = path.find('/');
+    if ((slash != 0) && (slash != std::string::npos))
+    {
+        std::cerr << "WARNING: qpdf completion enabled"
+                  << " using relative path to qpdf" << std::endl;
+    }
+}
+
+void
+ArgParser::argCompletionZsh()
+{
+    std::cout << "autoload -U +X bashcompinit && bashcompinit && ";
+    argCompletionBash();
+}
+void
+ArgParser::argJsonHelp()
+{
+    // Make sure the output looks right on an 80-column display.
+    //               1         2         3         4         5         6         7         8
+    //      12345678901234567890123456789012345678901234567890123456789012345678901234567890
+    std::cout
+        << "The json block below contains the same structure with the same keys as the"
+        << std::endl
+        << "json generated by qpdf. In the block below, the values are descriptions of"
+        << std::endl
+        << "the meanings of those entries. The specific contract guaranteed by qpdf in"
+        << std::endl
+        << "its json representation is explained in more detail in the manual. You can"
+        << std::endl
+        << "specify a subset of top-level keys when you invoke qpdf, but the \"version\""
+        << std::endl
+        << "and \"parameters\" keys will always be present."
+        << std::endl
+        << std::endl
+        << json_schema().serialize()
+        << std::endl;
+}
+
 void
 ArgParser::argPassword(char* parameter)
 {
@@ -931,21 +1217,7 @@ ArgParser::argShowXref()
 void
 ArgParser::argShowObject(char* parameter)
 {
-    if (strcmp(parameter, "trailer") == 0)
-    {
-        o.show_trailer = true;
-    }
-    else
-    {
-        char* obj = parameter;
-        char* gen = obj;
-        if ((gen = strchr(obj, ',')) != 0)
-        {
-            *gen++ = 0;
-            o.show_gen = QUtil::string_to_int(gen);
-        }
-        o.show_obj = QUtil::string_to_int(obj);
-    }
+    parse_object_id(parameter, o.show_trailer, o.show_obj, o.show_gen);
     o.require_outfile = false;
 }
 
@@ -982,12 +1254,24 @@ ArgParser::argWithImages()
 }
 
 void
-ArgParser::argShowJson()
+ArgParser::argJson()
 {
-    o.show_json = true;
+    o.json = true;
     o.require_outfile = false;
 }
 
+void
+ArgParser::argJsonKey(char* parameter)
+{
+    o.json_keys.insert(parameter);
+}
+
+void
+ArgParser::argJsonObject(char* parameter)
+{
+    o.json_objects.insert(parameter);
+}
+
 void
 ArgParser::argCheck()
 {
@@ -1124,7 +1408,24 @@ ArgParser::handleArgFileArguments()
     new_argv.push_back(PointerHolder<char>(true, QUtil::copy_string(argv[0])));
     for (int i = 1; i < argc; ++i)
     {
+        char* argfile = 0;
         if ((strlen(argv[i]) > 1) && (argv[i][0] == '@'))
+        {
+            try
+            {
+                argfile = 1 + argv[i];
+                if (strcmp(argfile, "-") != 0)
+                {
+                    fclose(QUtil::safe_fopen(argfile, "rb"));
+                }
+            }
+            catch (std::runtime_error&)
+            {
+                // The file's not there; treating as regular option
+                argfile = 0;
+            }
+        }
+        if (argfile)
         {
             readArgsFromFile(1+argv[i]);
         }
@@ -1148,30 +1449,85 @@ void
 ArgParser::handleBashArguments()
 {
     // Do a minimal job of parsing bash_line into arguments. This
-    // doesn't do everything the shell does, but it should be good
-    // enough for purposes of handling completion. We can't use
-    // new_argv because this has to interoperate with @file arguments.
-
-    enum { st_top, st_quote } state = st_top;
+    // doesn't do everything the shell does (e.g. $(...), variable
+    // expansion, arithmetic, globs, etc.), but it should be good
+    // enough for purposes of handling completion. As we build up the
+    // new argv, we can't use this->new_argv because this code has to
+    // interoperate with @file arguments, so memory for both ways of
+    // fabricating argv has to be protected.
+
+    bool last_was_backslash = false;
+    enum { st_top, st_squote, st_dquote } state = st_top;
     std::string arg;
     for (std::string::iterator iter = bash_line.begin();
          iter != bash_line.end(); ++iter)
     {
         char ch = (*iter);
-        if ((state == st_top) && QUtil::is_space(ch) && (! arg.empty()))
+        if (last_was_backslash)
+        {
+            arg.append(1, ch);
+            last_was_backslash = false;
+        }
+        else if (ch == '\\')
         {
-            bash_argv.push_back(
-                PointerHolder<char>(
-                    true, QUtil::copy_string(arg.c_str())));
-            arg.clear();
+            last_was_backslash = true;
         }
         else
         {
-            if (ch == '"')
+            bool append = false;
+            switch (state)
             {
-                state = (state == st_top ? st_quote : st_top);
+              case st_top:
+                if (QUtil::is_space(ch))
+                {
+                    if (! arg.empty())
+                    {
+                        bash_argv.push_back(
+                            PointerHolder<char>(
+                                true, QUtil::copy_string(arg.c_str())));
+                        arg.clear();
+                    }
+                }
+                else if (ch == '"')
+                {
+                    state = st_dquote;
+                }
+                else if (ch == '\'')
+                {
+                    state = st_squote;
+                }
+                else
+                {
+                    append = true;
+                }
+                break;
+
+              case st_squote:
+                if (ch == '\'')
+                {
+                    state = st_top;
+                }
+                else
+                {
+                    append = true;
+                }
+                break;
+
+              case st_dquote:
+                if (ch == '"')
+                {
+                    state = st_top;
+                }
+                else
+                {
+                    append = true;
+                }
+                break;
+            }
+            if (append)
+            {
+                arg.append(1, ch);
             }
-            arg.append(1, ch);
         }
     }
     if (bash_argv.empty())
@@ -1215,6 +1571,7 @@ Basic Options\n\
 --copyright             show qpdf's copyright and license information\n\
 --help                  show command-line argument help\n\
 --completion-bash       output a bash complete command you can eval\n\
+--completion-zsh        output a zsh complete command you can eval\n\
 --password=password     specify a password for accessing encrypted files\n\
 --verbose               provide additional informational output\n\
 --progress              give progress indicators while writing output\n\
@@ -1470,6 +1827,20 @@ automated test suites for software that uses the qpdf library.\n\
 --show-pages              shows the object/generation number for each page\n\
   --with-images           also shows the object IDs for images on each page\n\
 --check                   check file structure + encryption, linearization\n\
+--json                    generate a json representation of the file\n\
+--json-help               describe the format of the json representation\n\
+--json-key=key            repeatable; prune json structure to include only\n\
+                          specified keys. If absent, all keys are shown\n\
+--json-object=trailer|[obj,gen]\n\
+                          repeatable; include only specified objects in the\n\
+                          \"objects\" section of the json. If absent, all\n\
+                          objects are shown\n\
+\n\
+The json representation generated by qpdf is designed to facilitate\n\
+processing of qpdf from other programming languages that have a hard\n\
+time calling C++ APIs. Run qpdf --json-help for details on the format.\n\
+The manual has more in-depth information about the json representation\n\
+and certain compatibility guarantees that qpdf provides.\n\
 \n\
 The --raw-stream-data and --filtered-stream-data options are ignored\n\
 unless --show-object is given.  Either of these options will cause the\n\
@@ -1512,75 +1883,6 @@ ArgParser::usage(std::string const& message)
     }
 }
 
-static JSON json_schema()
-{
-    // This JSON object doubles as a schema and as documentation for
-    // our JSON output. Any schema mismatch is a bug in qpdf. This
-    // helps to enforce our policy of consistently providing a known
-    // structure where every documented key will always be present,
-    // which makes it easier to consume our JSON. This is discussed in
-    // more depth in the manual.
-    JSON schema = JSON::makeDictionary();
-    schema.addDictionaryMember(
-        "version", JSON::makeString(
-            "JSON format serial number; increased for non-compatible changes"));
-    schema.addDictionaryMember(
-        "objects", JSON::makeString(
-            "Original objects; keys are 'trailer' or 'n n R'"));
-    JSON page = schema.addDictionaryMember("pages", JSON::makeArray()).
-        addArrayElement(JSON::makeDictionary());
-    page.addDictionaryMember(
-        "object",
-        JSON::makeString("reference to original page object"));
-    JSON image = page.addDictionaryMember("images", JSON::makeArray()).
-        addArrayElement(JSON::makeDictionary());
-    image.addDictionaryMember(
-        "object",
-        JSON::makeString("reference to image stream"));
-    image.addDictionaryMember(
-        "width",
-        JSON::makeString("image width"));
-    image.addDictionaryMember(
-        "height",
-        JSON::makeString("image height"));
-    image.addDictionaryMember("filter", JSON::makeArray()).
-        addArrayElement(
-            JSON::makeString("filters applied to image data"));
-    image.addDictionaryMember("decodeparms", JSON::makeArray()).
-        addArrayElement(
-            JSON::makeString("decode parameters for image data"));
-    image.addDictionaryMember(
-        "filterable",
-        JSON::makeString("whether image data can be decoded"
-                         " using the decode level qpdf was invoked with"));
-    page.addDictionaryMember("contents", JSON::makeArray()).
-        addArrayElement(
-            JSON::makeString("reference to each content stream"));
-    page.addDictionaryMember(
-        "label",
-        JSON::makeString("page label dictionary, or null if none"));
-    JSON labels = schema.addDictionaryMember("pagelabels", JSON::makeArray()).
-        addArrayElement(JSON::makeDictionary());
-    labels.addDictionaryMember(
-        "index",
-        JSON::makeString("starting page position starting from zero"));
-    labels.addDictionaryMember(
-        "label",
-        JSON::makeString("page label dictionary"));
-    JSON outline = page.addDictionaryMember("outlines", JSON::makeArray()).
-        addArrayElement(JSON::makeDictionary());
-    outline.addDictionaryMember(
-        "object",
-        JSON::makeString("reference to outline that targets this page"));
-    outline.addDictionaryMember(
-        "title",
-        JSON::makeString("outline title"));
-    outline.addDictionaryMember(
-        "destination",
-        JSON::makeString("outline destination dictionary"));
-    return schema;
-}
-
 static std::string show_bool(bool v)
 {
     return v ? "allowed" : "not allowed";
@@ -1820,9 +2122,6 @@ ArgParser::handleHelpArgs()
     // Handle special-case informational options that are only
     // available as the sole option.
 
-    // The options processed here are also handled as a special case
-    // in handleCompletion.
-
     if (argc != 2)
     {
         return;
@@ -1841,74 +2140,9 @@ ArgParser::handleHelpArgs()
     {
         return;
     }
-    if (strcmp(arg, "version") == 0)
+    if (this->help_option_table.count(arg))
     {
-        std::cout
-            << whoami << " version " << QPDF::QPDFVersion() << std::endl
-            << "Run " << whoami << " --copyright to see copyright and license information."
-            << std::endl;
-        exit(0);
-    }
-
-    if (strcmp(arg, "copyright") == 0)
-    {
-        // Make sure the output looks right on an 80-column display.
-        //               1         2         3         4         5         6         7         8
-        //      12345678901234567890123456789012345678901234567890123456789012345678901234567890
-        std::cout
-            << whoami << " version " << QPDF::QPDFVersion() << std::endl
-            << std::endl
-            << "Copyright (c) 2005-2018 Jay Berkenbilt"
-            << std::endl
-            << "QPDF is licensed under the Apache License, Version 2.0 (the \"License\");"
-            << std::endl
-            << "not use this file except in compliance with the License."
-            << std::endl
-            << "You may obtain a copy of the License at"
-            << std::endl
-            << std::endl
-            << "  http://www.apache.org/licenses/LICENSE-2.0"
-            << std::endl
-            << std::endl
-            << "Unless required by applicable law or agreed to in writing, software"
-            << std::endl
-            << "distributed under the License is distributed on an \"AS IS\" BASIS,"
-            << std::endl
-            << "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied."
-            << std::endl
-            << "See the License for the specific language governing permissions and"
-            << std::endl
-            << "limitations under the License."
-            << std::endl
-            << std::endl
-            << "Versions of qpdf prior to version 7 were released under the terms"
-            << std::endl
-            << "of version 2.0 of the Artistic License. At your option, you may"
-            << std::endl
-            << "continue to consider qpdf to be licensed under those terms. Please"
-            << std::endl
-            << "see the manual for additional information."
-            << std::endl;
-        exit(0);
-    }
-
-    if (strcmp(arg, "help") == 0)
-    {
-        std::cout << help;
-        exit(0);
-    }
-
-    if (strcmp(arg, "completion-bash") == 0)
-    {
-        std::string path = argv[0];
-        size_t slash = path.find('/');
-        if ((slash != 0) && (slash != std::string::npos))
-        {
-            std::cerr << "WARNING: qpdf completion enabled"
-                      << " using relative path to qpdf" << std::endl;
-        }
-        std::cout << "complete -o bashdefault -o default -o nospace"
-                  << " -C " << argv[0] << " " << whoami << std::endl;
+        (this->*(this->help_option_table[arg].bare_arg_handler))();
         exit(0);
     }
 }
@@ -1989,16 +2223,65 @@ ArgParser::checkCompletion()
         int p = QUtil::string_to_int(bash_point_env.c_str());
         if ((p > 0) && (p <= static_cast<int>(bash_line.length())))
         {
-            // Point to the last character
-            bash_point = static_cast<size_t>(p) - 1;
+            // Truncate the line. We ignore everything at or after the
+            // cursor for completion purposes.
+            bash_line = bash_line.substr(0, p);
         }
-        if (argc >= 4)
+        // Set bash_cur and bash_prev based on bash_line rather than
+        // relying on argv. This enables us to use bashcompinit to get
+        // completion in zsh too since bashcompinit sets COMP_LINE and
+        // COMP_POINT but doesn't invoke the command with options like
+        // bash does.
+
+        // p is equal to length of the string. Walk backwards looking
+        // for the first separator. bash_cur is everything after the
+        // last separator, possibly empty.
+        char sep(0);
+        while (--p > 0)
         {
-            bash_cur = argv[2];
-            bash_prev = argv[3];
-            handleBashArguments();
-            bash_completion = true;
+            char ch = bash_line.at(p);
+            if ((ch == ' ') || (ch == '=') || (ch == ':'))
+            {
+                sep = ch;
+                break;
+            }
         }
+        bash_cur = bash_line.substr(1+p, std::string::npos);
+        if ((sep == ':') || (sep == '='))
+        {
+            // Bash sets prev to the non-space separator if any.
+            // Actually, if there are multiple separators in a row,
+            // they are all included in prev, but that detail is not
+            // important to us and not worth coding.
+            bash_prev = bash_line.substr(p, 1);
+        }
+        else
+        {
+            // Go back to the last separator and set prev based on
+            // that.
+            int p1 = p;
+            while (--p1 > 0)
+            {
+                char ch = bash_line.at(p1);
+                if ((ch == ' ') || (ch == ':') || (ch == '='))
+                {
+                    bash_prev = bash_line.substr(p1 + 1, p - p1 - 1);
+                    break;
+                }
+            }
+        }
+        if (bash_prev.empty())
+        {
+            bash_prev = bash_line.substr(0, p);
+        }
+        if (argc == 1)
+        {
+            // This is probably zsh using bashcompinit. There are a
+            // few differences in the expected output.
+            zsh_completion = true;
+        }
+        handleBashArguments();
+        bash_completion = true;
     }
 }
 
@@ -2171,7 +2454,8 @@ ArgParser::doFinalChecks()
 }
 
 void
-ArgParser::addChoicesToCompletions(std::string const& option)
+ArgParser::addChoicesToCompletions(std::string const& option,
+                                   std::string const& extra_prefix)
 {
     if (this->option_table->count(option) != 0)
     {
@@ -2179,7 +2463,7 @@ ArgParser::addChoicesToCompletions(std::string const& option)
         for (std::set<std::string>::iterator iter = oe.choices.begin();
              iter != oe.choices.end(); ++iter)
         {
-            completions.insert(*iter);
+            completions.insert(extra_prefix + *iter);
         }
     }
 }
@@ -2208,6 +2492,7 @@ ArgParser::addOptionsToCompletions()
 void
 ArgParser::handleCompletion()
 {
+    std::string extra_prefix;
     if (this->completions.empty())
     {
         // Detect --option=... Bash treats the = as a word separator.
@@ -2215,7 +2500,7 @@ ArgParser::handleCompletion()
         if (bash_cur.empty() && (bash_prev.length() > 2) &&
             (bash_prev.at(0) == '-') &&
             (bash_prev.at(1) == '-') &&
-            (bash_line.at(bash_point) == '='))
+            (bash_line.at(bash_line.length() - 1) == '='))
         {
             choice_option = bash_prev.substr(2, std::string::npos);
         }
@@ -2244,26 +2529,34 @@ ArgParser::handleCompletion()
         }
         if (! choice_option.empty())
         {
-            addChoicesToCompletions(choice_option);
+            if (zsh_completion)
+            {
+                // zsh wants --option=choice rather than just choice
+                extra_prefix = "--" + choice_option + "=";
+            }
+            addChoicesToCompletions(choice_option, extra_prefix);
         }
         else if ((! bash_cur.empty()) && (bash_cur.at(0) == '-'))
         {
             addOptionsToCompletions();
             if (this->argc == 1)
             {
-                // Handle options usually handled by handleHelpArgs.
-                this->completions.insert("--help");
-                this->completions.insert("--version");
-                this->completions.insert("--copyright");
-                this->completions.insert("--completion-bash");
+                // Help options are valid only by themselves.
+                for (std::map<std::string, OptionEntry>::iterator iter =
+                         this->help_option_table.begin();
+                     iter != this->help_option_table.end(); ++iter)
+                {
+                    this->completions.insert("--" + (*iter).first);
+                }
             }
         }
     }
+    std::string prefix = extra_prefix + bash_cur;
     for (std::set<std::string>::iterator iter = completions.begin();
          iter != completions.end(); ++iter)
     {
-        if (this->bash_cur.empty() ||
-            ((*iter).substr(0, bash_cur.length()) == bash_cur))
+        if (prefix.empty() ||
+            ((*iter).substr(0, prefix.length()) == prefix))
         {
             std::cout << *iter << std::endl;
         }
@@ -2487,38 +2780,51 @@ static void do_show_pages(QPDF& pdf, Options& o)
     }
 }
 
-static void do_show_json(QPDF& pdf, Options& o)
+static void do_json_objects(QPDF& pdf, Options& o, JSON& j)
 {
-    JSON j = JSON::makeDictionary();
-    // This version is updated every time a non-backward-compatible
-    // change is made to the JSON format. Clients of the JSON are to
-    // ignore unrecognized keys, so we only update the version of a
-    // key disappears or if its value changes meaning.
-    j.addDictionaryMember("version", JSON::makeInt(1));
-
-    // Objects
-
     // Add all objects. Do this first before other code below modifies
     // things by doing stuff like calling
     // pushInheritedAttributesToPage.
+    bool all_objects = o.json_objects.empty();
+    std::set<QPDFObjGen> wanted_og;
+    for (std::set<std::string>::iterator iter = o.json_objects.begin();
+         iter != o.json_objects.end(); ++iter)
+    {
+        bool trailer;
+        int obj = 0;
+        int gen = 0;
+        parse_object_id(*iter, trailer, obj, gen);
+        if (obj)
+        {
+            wanted_og.insert(QPDFObjGen(obj, gen));
+        }
+    }
     JSON j_objects = j.addDictionaryMember("objects", JSON::makeDictionary());
-    j_objects.addDictionaryMember("trailer", pdf.getTrailer().getJSON(true));
+    if (all_objects || o.json_objects.count("trailer"))
+    {
+        j_objects.addDictionaryMember(
+            "trailer", pdf.getTrailer().getJSON(true));
+    }
     std::vector<QPDFObjectHandle> objects = pdf.getAllObjects();
     for (std::vector<QPDFObjectHandle>::iterator iter = objects.begin();
          iter != objects.end(); ++iter)
     {
-        j_objects.addDictionaryMember(
-            (*iter).unparse(), (*iter).getJSON(true));
+        if (all_objects || wanted_og.count((*iter).getObjGen()))
+        {
+            j_objects.addDictionaryMember(
+                (*iter).unparse(), (*iter).getJSON(true));
+        }
     }
+}
 
-    // Pages
-
+static void do_json_pages(QPDF& pdf, Options& o, JSON& j)
+{
     JSON j_pages = j.addDictionaryMember("pages", JSON::makeArray());
-    QPDFPageDocumentHelper dh(pdf);
+    QPDFPageDocumentHelper pdh(pdf);
     QPDFPageLabelDocumentHelper pldh(pdf);
     QPDFOutlineDocumentHelper odh(pdf);
-    dh.pushInheritedAttributesToPage();
-    std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
+    pdh.pushInheritedAttributesToPage();
+    std::vector<QPDFPageObjectHelper> pages = pdh.getAllPages();
     size_t pageno = 0;
     for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
          iter != pages.end(); ++iter, ++pageno)
@@ -2545,6 +2851,10 @@ static void do_show_json(QPDF& pdf, Options& o)
                 "width", dict.getKey("/Width").getJSON());
             j_image.addDictionaryMember(
                 "height", dict.getKey("/Height").getJSON());
+            j_image.addDictionaryMember(
+                "colorspace", dict.getKey("/ColorSpace").getJSON());
+            j_image.addDictionaryMember(
+                "bitspercomponent", dict.getKey("/BitsPerComponent").getJSON());
             QPDFObjectHandle filters = dict.getKey("/Filter").wrapInArray();
             j_image.addDictionaryMember(
                 "filter", filters.getJSON());
@@ -2593,13 +2903,18 @@ static void do_show_json(QPDF& pdf, Options& o)
             j_outline.addDictionaryMember(
                 "title", JSON::makeString((*oiter).getTitle()));
             j_outline.addDictionaryMember(
-                "destination", (*oiter).getDest().getJSON(true));
+                "dest", (*oiter).getDest().getJSON(true));
         }
+        j_page.addDictionaryMember("pageposfrom1", JSON::makeInt(1 + pageno));
     }
+}
 
-    // Page labels
-
+static void do_json_page_labels(QPDF& pdf, Options& o, JSON& j)
+{
     JSON j_labels = j.addDictionaryMember("pagelabels", JSON::makeArray());
+    QPDFPageLabelDocumentHelper pldh(pdf);
+    QPDFPageDocumentHelper pdh(pdf);
+    std::vector<QPDFPageObjectHelper> pages = pdh.getAllPages();
     if (pldh.hasPageLabels())
     {
         std::vector<QPDFObjectHandle> labels;
@@ -2622,10 +2937,108 @@ static void do_show_json(QPDF& pdf, Options& o)
             j_label.addDictionaryMember("label", (*iter).getJSON());
         }
     }
+}
+
+static void add_outlines_to_json(
+    std::list<QPDFOutlineObjectHelper> outlines, JSON& j,
+    std::map<QPDFObjGen, int>& page_numbers)
+{
+    for (std::list<QPDFOutlineObjectHelper>::iterator iter = outlines.begin();
+         iter != outlines.end(); ++iter)
+    {
+        QPDFOutlineObjectHelper& ol = *iter;
+        JSON jo = j.addArrayElement(JSON::makeDictionary());
+        jo.addDictionaryMember("object", ol.getObjectHandle().getJSON());
+        jo.addDictionaryMember("title", JSON::makeString(ol.getTitle()));
+        jo.addDictionaryMember("dest", ol.getDest().getJSON(true));
+        jo.addDictionaryMember("open", JSON::makeBool(ol.getCount() >= 0));
+        QPDFObjectHandle page = ol.getDestPage();
+        JSON j_destpage = JSON::makeNull();
+        if (page.isIndirect())
+        {
+            QPDFObjGen og = page.getObjGen();
+            if (page_numbers.count(og))
+            {
+                j_destpage = JSON::makeInt(page_numbers[og]);
+            }
+        }
+        jo.addDictionaryMember("destpageposfrom1", j_destpage);
+        JSON j_kids = jo.addDictionaryMember("kids", JSON::makeArray());
+        add_outlines_to_json(ol.getKids(), j_kids, page_numbers);
+    }
+}
+
+static void do_json_outlines(QPDF& pdf, Options& o, JSON& j)
+{
+    std::map<QPDFObjGen, int> page_numbers;
+    QPDFPageDocumentHelper dh(pdf);
+    std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
+    int n = 0;
+    for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
+	 iter != pages.end(); ++iter)
+    {
+	QPDFObjectHandle oh = (*iter).getObjectHandle();
+	page_numbers[oh.getObjGen()] = ++n;
+    }
+
+    JSON j_outlines = j.addDictionaryMember(
+        "outlines", JSON::makeArray());
+    QPDFOutlineDocumentHelper odh(pdf);
+    add_outlines_to_json(odh.getTopLevelOutlines(), j_outlines, page_numbers);
+}
+
+static void do_json(QPDF& pdf, Options& o)
+{
+    JSON j = JSON::makeDictionary();
+    // This version is updated every time a non-backward-compatible
+    // change is made to the JSON format. Clients of the JSON are to
+    // ignore unrecognized keys, so we only update the version of a
+    // key disappears or if its value changes meaning.
+    j.addDictionaryMember("version", JSON::makeInt(1));
+    JSON j_params = j.addDictionaryMember(
+        "parameters", JSON::makeDictionary());
+    std::string decode_level_str;
+    switch (o.decode_level)
+    {
+        case qpdf_dl_none:
+          decode_level_str = "none";
+          break;
+        case qpdf_dl_generalized:
+          decode_level_str = "generalized";
+          break;
+        case qpdf_dl_specialized:
+          decode_level_str = "specialized";
+          break;
+        case qpdf_dl_all:
+          decode_level_str = "all";
+          break;
+    }
+    j_params.addDictionaryMember(
+        "decodelevel", JSON::makeString(decode_level_str));
+
+    bool all_keys = o.json_keys.empty();
+    // The list of selectable top-level keys id duplicated in three
+    // places: json_schema, do_json, and initOptionTable.
+    if (all_keys || o.json_keys.count("objects"))
+    {
+        do_json_objects(pdf, o, j);
+    }
+    if (all_keys || o.json_keys.count("pages"))
+    {
+        do_json_pages(pdf, o, j);
+    }
+    if (all_keys || o.json_keys.count("pagelabels"))
+    {
+        do_json_page_labels(pdf, o, j);
+    }
+    if (all_keys || o.json_keys.count("outlines"))
+    {
+        do_json_outlines(pdf, o, j);
+    }
 
     // Check against schema
 
-    JSON schema = json_schema();
+    JSON schema = json_schema(&o.json_keys);
     std::list<std::string> errors;
     if (! j.checkSchema(schema, errors))
     {
@@ -2652,9 +3065,9 @@ static void do_inspection(QPDF& pdf, Options& o)
     {
         do_check(pdf, o, exit_code);
     }
-    if (o.show_json)
+    if (o.json)
     {
-        do_show_json(pdf, o);
+        do_json(pdf, o);
     }
     if (o.show_npages)
     {


Test patch:
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index 8c81efc8..8c976f6d 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -116,24 +116,41 @@ my @completion_tests = (
     ['qpdf --decode-l', undef, 'decode-l'],
     ['qpdf --decode-lzzz', 15, 'decode-l'],
     ['qpdf --decode-level=', undef, 'decode-level'],
+    ['qpdf --decode-level=g', undef, 'decode-level-g'],
     ['qpdf --check -', undef, 'later-arg'],
+    ['qpdf infile outfile oops --ch', undef, 'usage-empty'],
+    ['qpdf --encrypt \'user " password\' ', undef, 'quoting'],
+    ['qpdf --encrypt \'user password\' ', undef, 'quoting'],
+    ['qpdf --encrypt "user password" ', undef, 'quoting'],
+    ['qpdf --encrypt "user pass\'word" ', undef, 'quoting'],
+    ['qpdf --encrypt user\ password ', undef, 'quoting'],
     );
-$n_tests += scalar(@completion_tests);
+$n_tests += 2 * scalar(@completion_tests);
 foreach my $c (@completion_tests)
 {
     my ($cmd, $point, $description) = @$c;
     my $out = "completion-$description.out";
+    my $zout = "completion-$description-zsh.out";
+    if (! -f $zout)
+    {
+        $zout = $out;
+    }
     $td->runtest("bash completion: $description",
                  {$td->COMMAND => [@{bash_completion($cmd, $point)}],
                       $td->FILTER => "perl filter-completion.pl $out"},
                  {$td->FILE => "$out", $td->EXIT_STATUS => 0},
                  $td->NORMALIZE_NEWLINES);
+    $td->runtest("zsh completion: $description",
+                 {$td->COMMAND => [@{zsh_completion($cmd, $point)}],
+                      $td->FILTER => "perl filter-completion.pl $zout"},
+                 {$td->FILE => "$zout", $td->EXIT_STATUS => 0},
+                 $td->NORMALIZE_NEWLINES);
 }
 
 show_ntests();
 # ----------
 $td->notify("--- Argument Parsing ---");
-$n_tests += 3;
+$n_tests += 4;
 
 $td->runtest("required argument",
              {$td->COMMAND => "qpdf --password minimal.pdf"},
@@ -150,6 +167,11 @@ $td->runtest("required argument with choices",
 	     {$td->REGEXP => "must be given as --decode-level=\\{.*all.*\\}",
                   $td->EXIT_STATUS => 2},
              $td->NORMALIZE_NEWLINES);
+copy("minimal.pdf", '@file.pdf');
+$td->runtest("\@file exists and file doesn't",
+             {$td->COMMAND => "qpdf --check \@file.pdf"},
+             {$td->FILE => "check-at-file.out", $td->EXIT_STATUS => 0},
+             $td->NORMALIZE_NEWLINES);
 
 show_ntests();
 # ----------
@@ -325,6 +347,47 @@ foreach my $f (@outline_files)
                  $td->NORMALIZE_NEWLINES);
 }
 
+show_ntests();
+# ----------
+$td->notify("--- JSON Tests ---");
+my @json_files = (
+    ['outlines-with-actions', []],
+    ['outlines-with-old-root-dests', []],
+    ['page-labels-and-outlines', []],
+    ['page-labels-num-tree', []],
+    ['image-streams', []],
+    ['image-streams', ['--decode-level=all']],
+    ['image-streams', ['--decode-level=specialized']],
+    ['page-labels-and-outlines', ['--json-key=objects']],
+    ['page-labels-and-outlines', ['--json-key=pages']],
+    ['page-labels-and-outlines', ['--json-key=pagelabels']],
+    ['page-labels-and-outlines', ['--json-key=outlines']],
+    ['page-labels-and-outlines',
+     ['--json-key=outlines', '--json-key=pages']],
+    ['page-labels-and-outlines',
+     ['--json-key=objects', '--json-object=trailer']],
+    ['page-labels-and-outlines',
+     ['--json-key=objects', '--json-object=trailer', '--json-object=2 0 R']],
+);
+$n_tests += scalar(@json_files);
+foreach my $d (@json_files)
+{
+    my ($file, $xargs) = @$d;
+    my $out = "json-$file";
+    foreach my $x (@$xargs)
+    {
+        my $y = $x;
+        $y =~ s/^.*=//;
+        $y =~ s/\s.*//;
+        $out .= "-$y";
+    }
+    my $in = "$file.pdf";
+    $td->runtest("json $out",
+                 {$td->COMMAND => ['qpdf', '--json', @$xargs, $in]},
+                 {$td->FILE => "$out.out", $td->EXIT_STATUS => 0},
+                 $td->NORMALIZE_NEWLINES);
+}
+
 show_ntests();
 # ----------
 $td->notify("--- Page API Tests ---");
@@ -1041,6 +1104,8 @@ show_ntests();
 $td->notify("--- Overwrite self ---");
 $n_tests += 1;
 
+copy("minimal.pdf", "a.pdf");
+# Also tests @- for reading args from stdin
 $td->runtest("don't overwrite self",
              {$td->COMMAND => "(echo a.pdf; echo a.pdf) | qpdf \@-"},
              {$td->REGEXP => "input file and output file are the same.*",
@@ -3178,6 +3243,9 @@ sub show_ntests
     {
 	$td->emphasize("tests so far: ". calc_ntests());
     }
+    # Calling cleanup here helps to ensure that sections of the test
+    # suite are isolated.
+    cleanup();
 }
 
 sub bash_completion
@@ -3198,6 +3266,16 @@ sub bash_completion
      "qpdf", $this, $cur, $prev];
 }
 
+sub zsh_completion
+{
+    my ($line, $point) = @_;
+    if (! defined $point)
+    {
+        $point = length($line);
+    }
+    ['env', "COMP_LINE=$line", "COMP_POINT=$point", "qpdf"];
+}
+
 sub check_pdf
 {
     my ($description, $command, $output, $status) = @_;
@@ -3312,5 +3390,5 @@ sub get_md5_checksum
 sub cleanup
 {
     system("rm -rf *.ps *.pnm ?.pdf ?.qdf *.enc* tif1 tif2 tiff-cache");
-    system("rm -rf *split-out* ???-kfo.pdf *.tmpout");
+    system("rm -rf *split-out* ???-kfo.pdf *.tmpout \@file.pdf");
 }
diff --git a/qpdf/qtest/qpdf/check-at-file.out b/qpdf/qtest/qpdf/check-at-file.out
new file mode 100644
index 00000000..9d4f1618
--- /dev/null
+++ b/qpdf/qtest/qpdf/check-at-file.out
@@ -0,0 +1,6 @@
+checking @file.pdf
+PDF Version: 1.3
+File is not encrypted
+File is not linearized
+No syntax or stream encoding errors found; the file may still contain
+errors that qpdf cannot detect
diff --git a/qpdf/qtest/qpdf/completion-decode-level-g-zsh.out b/qpdf/qtest/qpdf/completion-decode-level-g-zsh.out
new file mode 100644
index 00000000..47a40bba
--- /dev/null
+++ b/qpdf/qtest/qpdf/completion-decode-level-g-zsh.out
@@ -0,0 +1,6 @@
+--decode-level=generalized
+!--decode-level=all
+!--decode-level=none
+!all
+!generalized
+!none
diff --git a/qpdf/qtest/qpdf/completion-decode-level-g.out b/qpdf/qtest/qpdf/completion-decode-level-g.out
new file mode 100644
index 00000000..ab5d711d
--- /dev/null
+++ b/qpdf/qtest/qpdf/completion-decode-level-g.out
@@ -0,0 +1,6 @@
+generalized
+!--decode-level=all
+!--decode-level=generalized
+!--decode-level=none
+!all
+!none
diff --git a/qpdf/qtest/qpdf/completion-decode-level-zsh.out b/qpdf/qtest/qpdf/completion-decode-level-zsh.out
new file mode 100644
index 00000000..0d5d2e33
--- /dev/null
+++ b/qpdf/qtest/qpdf/completion-decode-level-zsh.out
@@ -0,0 +1,7 @@
+--decode-level=all
+--decode-level=generalized
+--decode-level=none
+!--help
+!all
+!generalized
+!none
diff --git a/qpdf/qtest/qpdf/completion-decode-level.out b/qpdf/qtest/qpdf/completion-decode-level.out
index 776f1e1f..3e48c118 100644
--- a/qpdf/qtest/qpdf/completion-decode-level.out
+++ b/qpdf/qtest/qpdf/completion-decode-level.out
@@ -1,4 +1,7 @@
 all
 generalized
 none
+!--decode-level=all
+!--decode-level=generalized
+!--decode-level=none
 !--help
diff --git a/qpdf/qtest/qpdf/completion-quoting.out b/qpdf/qtest/qpdf/completion-quoting.out
new file mode 100644
index 00000000..0d8a0622
--- /dev/null
+++ b/qpdf/qtest/qpdf/completion-quoting.out
@@ -0,0 +1,1 @@
+owner-password
diff --git a/qpdf/qtest/qpdf/completion-usage-empty.out b/qpdf/qtest/qpdf/completion-usage-empty.out
new file mode 100644
index 00000000..442e725d
--- /dev/null
+++ b/qpdf/qtest/qpdf/completion-usage-empty.out
@@ -0,0 +1,1 @@
+!--check
diff --git a/qpdf/qtest/qpdf/json-image-streams-all.out b/qpdf/qtest/qpdf/json-image-streams-all.out
new file mode 100644
index 00000000..487a11f2
--- /dev/null
+++ b/qpdf/qtest/qpdf/json-image-streams-all.out
@@ -0,0 +1,622 @@
+{
+  "objects": {
+    "1 0 R": {
+      "/Pages": "2 0 R",
+      "/Type": "/Catalog"
+    },
+    "10 0 R": {
+      "/Contents": "27 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "28 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "11 0 R": {
+      "/Contents": "29 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "30 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "12 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 97
+    },
+    "13 0 R": {
+      "/BaseFont": "/Helvetica",
+      "/Encoding": "/WinAnsiEncoding",
+      "/Name": "/F1",
+      "/Subtype": "/Type1",
+      "/Type": "/Font"
+    },
+    "14 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceCMYK",
+      "/Filter": "/FlateDecode",
+      "/Height": 480,
+      "/Length": 847,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "15 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 102
+    },
+    "16 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceCMYK",
+      "/Filter": "/DCTDecode",
+      "/Height": 480,
+      "/Length": 9364,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "17 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 108
+    },
+    "18 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceCMYK",
+      "/Filter": "/RunLengthDecode",
+      "/Height": 480,
+      "/Length": 768998,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "19 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 96
+    },
+    "2 0 R": {
+      "/Count": 9,
+      "/Kids": [
+        "3 0 R",
+        "4 0 R",
+        "5 0 R",
+        "6 0 R",
+        "7 0 R",
+        "8 0 R",
+        "9 0 R",
+        "10 0 R",
+        "11 0 R"
+      ],
+      "/Type": "/Pages"
+    },
+    "20 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceRGB",
+      "/Filter": "/FlateDecode",
+      "/Height": 480,
+      "/Length": 645,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "21 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 99
+    },
+    "22 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceRGB",
+      "/Filter": "/DCTDecode",
+      "/Height": 480,
+      "/Length": 3650,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "23 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 106
+    },
+    "24 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceRGB",
+      "/Filter": "/RunLengthDecode",
+      "/Height": 480,
+      "/Length": 641497,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "25 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 97
+    },
+    "26 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceGray",
+      "/Filter": "/FlateDecode",
+      "/Height": 480,
+      "/Length": 221,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "27 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 101
+    },
+    "28 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceGray",
+      "/Filter": "/DCTDecode",
+      "/Height": 480,
+      "/Length": 2587,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "29 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 108
+    },
+    "3 0 R": {
+      "/Contents": "12 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "14 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "30 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceGray",
+      "/Filter": "/RunLengthDecode",
+      "/Height": 480,
+      "/Length": 3001,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "4 0 R": {
+      "/Contents": "15 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "16 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "5 0 R": {
+      "/Contents": "17 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "18 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "6 0 R": {
+      "/Contents": "19 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "20 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "7 0 R": {
+      "/Contents": "21 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "22 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "8 0 R": {
+      "/Contents": "23 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "24 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "9 0 R": {
+      "/Contents": "25 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "26 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "trailer": {
+      "/ID": [
+        "S¶Ł”łîð\u000e¢¬\u0007}_)\u0012¶",
+        "S¶Ł”łîð\u000e¢¬\u0007}_)\u0012¶"
+      ],
+      "/Root": "1 0 R",
+      "/Size": 31
+    }
+  },
+  "outlines": [],
+  "pagelabels": [],
+  "pages": [
+    {
+      "contents": [
+        "12 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceCMYK",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/FlateDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "14 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "3 0 R",
+      "outlines": [],
+      "pageposfrom1": 1
+    },
+    {
+      "contents": [
+        "15 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceCMYK",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/DCTDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "16 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "4 0 R",
+      "outlines": [],
+      "pageposfrom1": 2
+    },
+    {
+      "contents": [
+        "17 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceCMYK",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/RunLengthDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "18 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "5 0 R",
+      "outlines": [],
+      "pageposfrom1": 3
+    },
+    {
+      "contents": [
+        "19 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceRGB",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/FlateDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "20 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "6 0 R",
+      "outlines": [],
+      "pageposfrom1": 4
+    },
+    {
+      "contents": [
+        "21 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceRGB",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/DCTDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "22 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "7 0 R",
+      "outlines": [],
+      "pageposfrom1": 5
+    },
+    {
+      "contents": [
+        "23 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceRGB",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/RunLengthDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "24 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "8 0 R",
+      "outlines": [],
+      "pageposfrom1": 6
+    },
+    {
+      "contents": [
+        "25 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceGray",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/FlateDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "26 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "9 0 R",
+      "outlines": [],
+      "pageposfrom1": 7
+    },
+    {
+      "contents": [
+        "27 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceGray",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/DCTDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "28 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "10 0 R",
+      "outlines": [],
+      "pageposfrom1": 8
+    },
+    {
+      "contents": [
+        "29 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceGray",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/RunLengthDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "30 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "11 0 R",
+      "outlines": [],
+      "pageposfrom1": 9
+    }
+  ],
+  "parameters": {
+    "decodelevel": "all"
+  },
+  "version": 1
+}
diff --git a/qpdf/qtest/qpdf/json-image-streams-specialized.out b/qpdf/qtest/qpdf/json-image-streams-specialized.out
new file mode 100644
index 00000000..65f1b0fc
--- /dev/null
+++ b/qpdf/qtest/qpdf/json-image-streams-specialized.out
@@ -0,0 +1,622 @@
+{
+  "objects": {
+    "1 0 R": {
+      "/Pages": "2 0 R",
+      "/Type": "/Catalog"
+    },
+    "10 0 R": {
+      "/Contents": "27 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "28 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "11 0 R": {
+      "/Contents": "29 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "30 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "12 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 97
+    },
+    "13 0 R": {
+      "/BaseFont": "/Helvetica",
+      "/Encoding": "/WinAnsiEncoding",
+      "/Name": "/F1",
+      "/Subtype": "/Type1",
+      "/Type": "/Font"
+    },
+    "14 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceCMYK",
+      "/Filter": "/FlateDecode",
+      "/Height": 480,
+      "/Length": 847,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "15 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 102
+    },
+    "16 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceCMYK",
+      "/Filter": "/DCTDecode",
+      "/Height": 480,
+      "/Length": 9364,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "17 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 108
+    },
+    "18 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceCMYK",
+      "/Filter": "/RunLengthDecode",
+      "/Height": 480,
+      "/Length": 768998,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "19 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 96
+    },
+    "2 0 R": {
+      "/Count": 9,
+      "/Kids": [
+        "3 0 R",
+        "4 0 R",
+        "5 0 R",
+        "6 0 R",
+        "7 0 R",
+        "8 0 R",
+        "9 0 R",
+        "10 0 R",
+        "11 0 R"
+      ],
+      "/Type": "/Pages"
+    },
+    "20 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceRGB",
+      "/Filter": "/FlateDecode",
+      "/Height": 480,
+      "/Length": 645,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "21 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 99
+    },
+    "22 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceRGB",
+      "/Filter": "/DCTDecode",
+      "/Height": 480,
+      "/Length": 3650,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "23 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 106
+    },
+    "24 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceRGB",
+      "/Filter": "/RunLengthDecode",
+      "/Height": 480,
+      "/Length": 641497,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "25 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 97
+    },
+    "26 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceGray",
+      "/Filter": "/FlateDecode",
+      "/Height": 480,
+      "/Length": 221,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "27 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 101
+    },
+    "28 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceGray",
+      "/Filter": "/DCTDecode",
+      "/Height": 480,
+      "/Length": 2587,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "29 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 108
+    },
+    "3 0 R": {
+      "/Contents": "12 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "14 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "30 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceGray",
+      "/Filter": "/RunLengthDecode",
+      "/Height": 480,
+      "/Length": 3001,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "4 0 R": {
+      "/Contents": "15 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "16 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "5 0 R": {
+      "/Contents": "17 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "18 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "6 0 R": {
+      "/Contents": "19 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "20 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "7 0 R": {
+      "/Contents": "21 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "22 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "8 0 R": {
+      "/Contents": "23 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "24 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "9 0 R": {
+      "/Contents": "25 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "26 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "trailer": {
+      "/ID": [
+        "S¶Ł”łîð\u000e¢¬\u0007}_)\u0012¶",
+        "S¶Ł”łîð\u000e¢¬\u0007}_)\u0012¶"
+      ],
+      "/Root": "1 0 R",
+      "/Size": 31
+    }
+  },
+  "outlines": [],
+  "pagelabels": [],
+  "pages": [
+    {
+      "contents": [
+        "12 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceCMYK",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/FlateDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "14 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "3 0 R",
+      "outlines": [],
+      "pageposfrom1": 1
+    },
+    {
+      "contents": [
+        "15 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceCMYK",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/DCTDecode"
+          ],
+          "filterable": false,
+          "height": 480,
+          "name": "/Im1",
+          "object": "16 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "4 0 R",
+      "outlines": [],
+      "pageposfrom1": 2
+    },
+    {
+      "contents": [
+        "17 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceCMYK",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/RunLengthDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "18 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "5 0 R",
+      "outlines": [],
+      "pageposfrom1": 3
+    },
+    {
+      "contents": [
+        "19 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceRGB",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/FlateDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "20 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "6 0 R",
+      "outlines": [],
+      "pageposfrom1": 4
+    },
+    {
+      "contents": [
+        "21 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceRGB",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/DCTDecode"
+          ],
+          "filterable": false,
+          "height": 480,
+          "name": "/Im1",
+          "object": "22 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "7 0 R",
+      "outlines": [],
+      "pageposfrom1": 5
+    },
+    {
+      "contents": [
+        "23 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceRGB",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/RunLengthDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "24 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "8 0 R",
+      "outlines": [],
+      "pageposfrom1": 6
+    },
+    {
+      "contents": [
+        "25 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceGray",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/FlateDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "26 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "9 0 R",
+      "outlines": [],
+      "pageposfrom1": 7
+    },
+    {
+      "contents": [
+        "27 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceGray",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/DCTDecode"
+          ],
+          "filterable": false,
+          "height": 480,
+          "name": "/Im1",
+          "object": "28 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "10 0 R",
+      "outlines": [],
+      "pageposfrom1": 8
+    },
+    {
+      "contents": [
+        "29 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceGray",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/RunLengthDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "30 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "11 0 R",
+      "outlines": [],
+      "pageposfrom1": 9
+    }
+  ],
+  "parameters": {
+    "decodelevel": "specialized"
+  },
+  "version": 1
+}
diff --git a/qpdf/qtest/qpdf/json-image-streams.out b/qpdf/qtest/qpdf/json-image-streams.out
new file mode 100644
index 00000000..20fba7f2
--- /dev/null
+++ b/qpdf/qtest/qpdf/json-image-streams.out
@@ -0,0 +1,622 @@
+{
+  "objects": {
+    "1 0 R": {
+      "/Pages": "2 0 R",
+      "/Type": "/Catalog"
+    },
+    "10 0 R": {
+      "/Contents": "27 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "28 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "11 0 R": {
+      "/Contents": "29 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "30 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "12 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 97
+    },
+    "13 0 R": {
+      "/BaseFont": "/Helvetica",
+      "/Encoding": "/WinAnsiEncoding",
+      "/Name": "/F1",
+      "/Subtype": "/Type1",
+      "/Type": "/Font"
+    },
+    "14 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceCMYK",
+      "/Filter": "/FlateDecode",
+      "/Height": 480,
+      "/Length": 847,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "15 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 102
+    },
+    "16 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceCMYK",
+      "/Filter": "/DCTDecode",
+      "/Height": 480,
+      "/Length": 9364,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "17 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 108
+    },
+    "18 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceCMYK",
+      "/Filter": "/RunLengthDecode",
+      "/Height": 480,
+      "/Length": 768998,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "19 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 96
+    },
+    "2 0 R": {
+      "/Count": 9,
+      "/Kids": [
+        "3 0 R",
+        "4 0 R",
+        "5 0 R",
+        "6 0 R",
+        "7 0 R",
+        "8 0 R",
+        "9 0 R",
+        "10 0 R",
+        "11 0 R"
+      ],
+      "/Type": "/Pages"
+    },
+    "20 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceRGB",
+      "/Filter": "/FlateDecode",
+      "/Height": 480,
+      "/Length": 645,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "21 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 99
+    },
+    "22 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceRGB",
+      "/Filter": "/DCTDecode",
+      "/Height": 480,
+      "/Length": 3650,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "23 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 106
+    },
+    "24 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceRGB",
+      "/Filter": "/RunLengthDecode",
+      "/Height": 480,
+      "/Length": 641497,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "25 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 97
+    },
+    "26 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceGray",
+      "/Filter": "/FlateDecode",
+      "/Height": 480,
+      "/Length": 221,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "27 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 101
+    },
+    "28 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceGray",
+      "/Filter": "/DCTDecode",
+      "/Height": 480,
+      "/Length": 2587,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "29 0 R": {
+      "/Filter": "/FlateDecode",
+      "/Length": 108
+    },
+    "3 0 R": {
+      "/Contents": "12 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "14 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "30 0 R": {
+      "/BitsPerComponent": 8,
+      "/ColorSpace": "/DeviceGray",
+      "/Filter": "/RunLengthDecode",
+      "/Height": 480,
+      "/Length": 3001,
+      "/Subtype": "/Image",
+      "/Type": "/XObject",
+      "/Width": 400
+    },
+    "4 0 R": {
+      "/Contents": "15 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "16 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "5 0 R": {
+      "/Contents": "17 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "18 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "6 0 R": {
+      "/Contents": "19 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "20 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "7 0 R": {
+      "/Contents": "21 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "22 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "8 0 R": {
+      "/Contents": "23 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "24 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "9 0 R": {
+      "/Contents": "25 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        392
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "13 0 R"
+        },
+        "/ProcSet": [
+          "/PDF",
+          "/Text",
+          "/ImageC"
+        ],
+        "/XObject": {
+          "/Im1": "26 0 R"
+        }
+      },
+      "/Type": "/Page"
+    },
+    "trailer": {
+      "/ID": [
+        "S¶Ł”łîð\u000e¢¬\u0007}_)\u0012¶",
+        "S¶Ł”łîð\u000e¢¬\u0007}_)\u0012¶"
+      ],
+      "/Root": "1 0 R",
+      "/Size": 31
+    }
+  },
+  "outlines": [],
+  "pagelabels": [],
+  "pages": [
+    {
+      "contents": [
+        "12 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceCMYK",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/FlateDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "14 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "3 0 R",
+      "outlines": [],
+      "pageposfrom1": 1
+    },
+    {
+      "contents": [
+        "15 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceCMYK",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/DCTDecode"
+          ],
+          "filterable": false,
+          "height": 480,
+          "name": "/Im1",
+          "object": "16 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "4 0 R",
+      "outlines": [],
+      "pageposfrom1": 2
+    },
+    {
+      "contents": [
+        "17 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceCMYK",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/RunLengthDecode"
+          ],
+          "filterable": false,
+          "height": 480,
+          "name": "/Im1",
+          "object": "18 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "5 0 R",
+      "outlines": [],
+      "pageposfrom1": 3
+    },
+    {
+      "contents": [
+        "19 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceRGB",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/FlateDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "20 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "6 0 R",
+      "outlines": [],
+      "pageposfrom1": 4
+    },
+    {
+      "contents": [
+        "21 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceRGB",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/DCTDecode"
+          ],
+          "filterable": false,
+          "height": 480,
+          "name": "/Im1",
+          "object": "22 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "7 0 R",
+      "outlines": [],
+      "pageposfrom1": 5
+    },
+    {
+      "contents": [
+        "23 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceRGB",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/RunLengthDecode"
+          ],
+          "filterable": false,
+          "height": 480,
+          "name": "/Im1",
+          "object": "24 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "8 0 R",
+      "outlines": [],
+      "pageposfrom1": 6
+    },
+    {
+      "contents": [
+        "25 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceGray",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/FlateDecode"
+          ],
+          "filterable": true,
+          "height": 480,
+          "name": "/Im1",
+          "object": "26 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "9 0 R",
+      "outlines": [],
+      "pageposfrom1": 7
+    },
+    {
+      "contents": [
+        "27 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceGray",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/DCTDecode"
+          ],
+          "filterable": false,
+          "height": 480,
+          "name": "/Im1",
+          "object": "28 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "10 0 R",
+      "outlines": [],
+      "pageposfrom1": 8
+    },
+    {
+      "contents": [
+        "29 0 R"
+      ],
+      "images": [
+        {
+          "bitspercomponent": 8,
+          "colorspace": "/DeviceGray",
+          "decodeparms": [
+            null
+          ],
+          "filter": [
+            "/RunLengthDecode"
+          ],
+          "filterable": false,
+          "height": 480,
+          "name": "/Im1",
+          "object": "30 0 R",
+          "width": 400
+        }
+      ],
+      "label": null,
+      "object": "11 0 R",
+      "outlines": [],
+      "pageposfrom1": 9
+    }
+  ],
+  "parameters": {
+    "decodelevel": "generalized"
+  },
+  "version": 1
+}
diff --git a/qpdf/qtest/qpdf/json-outlines-with-actions.out b/qpdf/qtest/qpdf/json-outlines-with-actions.out
new file mode 100644
index 00000000..bf6f117d
--- /dev/null
+++ b/qpdf/qtest/qpdf/json-outlines-with-actions.out
@@ -0,0 +1,1459 @@
+{
+  "objects": {
+    "1 0 R": {
+      "/Names": {
+        "/Dests": "107 0 R"
+      },
+      "/Outlines": "2 0 R",
+      "/PageMode": "/UseOutlines",
+      "/Pages": "3 0 R",
+      "/Type": "/Catalog"
+    },
+    "10 0 R": {
+      "/Contents": "48 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "100 0 R": {
+      "/Count": -2,
+      "/Dest": [
+        "18 0 R",
+        "/FitV",
+        100
+      ],
+      "/First": "104 0 R",
+      "/Last": "105 0 R",
+      "/Next": "101 0 R",
+      "/Parent": "36 0 R",
+      "/Title": "Biherbadem 1.1.1 -> 12: /FitV 100",
+      "/Type": "/Outline"
+    },
+    "101 0 R": {
+      "/Count": 1,
+      "/Dest": [
+        "18 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/First": "106 0 R",
+      "/Last": "106 0 R",
+      "/Parent": "36 0 R",
+      "/Prev": "100 0 R",
+      "/Title": "Gawehwehweh 1.1.2 -> 12: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "102 0 R": {
+      "/Dest": "gabeebee",
+      "/Next": "103 0 R",
+      "/Parent": "37 0 R",
+      "/Title": "Gabeebeebee (name) 1.2.1 -> 1: /FitR 66 714 180 770",
+      "/Type": "/Outline"
+    },
+    "103 0 R": {
+      "/A": {
+        "/D": [
+          "6 0 R",
+          "/XYZ",
+          null,
+          null,
+          null
+        ],
+        "/S": "/GoTo",
+        "/Type": "/Action"
+      },
+      "/Parent": "37 0 R",
+      "/Prev": "102 0 R",
+      "/Title": "Merschqaberschq (A) 1.2.2 -> 0: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "104 0 R": {
+      "/A": {
+        "/D": "glarp",
+        "/S": "/GoTo",
+        "/Type": "/Action"
+      },
+      "/Next": "105 0 R",
+      "/Parent": "100 0 R",
+      "/Title": "Glarpenspliel (A, name) 1.1.1.1 -> 18: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "105 0 R": {
+      "/Dest": [
+        "25 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/Parent": "100 0 R",
+      "/Prev": "104 0 R",
+      "/Title": "Hagoogamagoogle 1.1.1.2 -> 19: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "106 0 R": {
+      "/Dest": "108 0 R",
+      "/Parent": "101 0 R",
+      "/Title": "Jawarnianbvarwash 1.1.2.1 -> 22: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "107 0 R": {
+      "/Names": [
+        "gabeebee",
+        [
+          "7 0 R",
+          "/FitR",
+          66,
+          714,
+          180,
+          770
+        ],
+        "glarp",
+        [
+          "24 0 R",
+          "/XYZ",
+          null,
+          null,
+          null
+        ]
+      ]
+    },
+    "108 0 R": [
+      "28 0 R",
+      "/XYZ",
+      null,
+      null,
+      null
+    ],
+    "11 0 R": {
+      "/Contents": "50 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "12 0 R": {
+      "/Contents": "52 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "13 0 R": {
+      "/Contents": "54 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "14 0 R": {
+      "/Contents": "56 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "15 0 R": {
+      "/Contents": "58 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "16 0 R": {
+      "/Contents": "60 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "17 0 R": {
+      "/Contents": "62 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "18 0 R": {
+      "/Contents": "64 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "19 0 R": {
+      "/Contents": "66 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "2 0 R": {
+      "/Count": 6,
+      "/First": "4 0 R",
+      "/Last": "5 0 R",
+      "/Type": "/Outlines"
+    },
+    "20 0 R": {
+      "/Contents": "68 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "21 0 R": {
+      "/Contents": "70 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "22 0 R": {
+      "/Contents": "72 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "23 0 R": {
+      "/Contents": "74 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "24 0 R": {
+      "/Contents": "76 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "25 0 R": {
+      "/Contents": "78 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "26 0 R": {
+      "/Contents": "80 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "27 0 R": {
+      "/Contents": "82 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "28 0 R": {
+      "/Contents": "84 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "29 0 R": {
+      "/Contents": "86 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "3 0 R": {
+      "/Count": 30,
+      "/Kids": [
+        "6 0 R",
+        "7 0 R",
+        "8 0 R",
+        "9 0 R",
+        "10 0 R",
+        "11 0 R",
+        "12 0 R",
+        "13 0 R",
+        "14 0 R",
+        "15 0 R",
+        "16 0 R",
+        "17 0 R",
+        "18 0 R",
+        "19 0 R",
+        "20 0 R",
+        "21 0 R",
+        "22 0 R",
+        "23 0 R",
+        "24 0 R",
+        "25 0 R",
+        "26 0 R",
+        "27 0 R",
+        "28 0 R",
+        "29 0 R",
+        "30 0 R",
+        "31 0 R",
+        "32 0 R",
+        "33 0 R",
+        "34 0 R",
+        "35 0 R"
+      ],
+      "/Type": "/Pages"
+    },
+    "30 0 R": {
+      "/Contents": "88 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "31 0 R": {
+      "/Contents": "90 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "32 0 R": {
+      "/Contents": "92 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "33 0 R": {
+      "/Contents": "94 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "34 0 R": {
+      "/Contents": "96 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "35 0 R": {
+      "/Contents": "98 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "36 0 R": {
+      "/Count": -3,
+      "/Dest": [
+        "17 0 R",
+        "/Fit"
+      ],
+      "/First": "100 0 R",
+      "/Last": "101 0 R",
+      "/Next": "37 0 R",
+      "/Parent": "4 0 R",
+      "/Title": "Mern 1.1 -> 11: /Fit",
+      "/Type": "/Outline"
+    },
+    "37 0 R": {
+      "/Count": 2,
+      "/Dest": [
+        "19 0 R",
+        "/FitH",
+        792
+      ],
+      "/First": "102 0 R",
+      "/Last": "103 0 R",
+      "/Parent": "4 0 R",
+      "/Prev": "36 0 R",
+      "/Title": "Squash ÷πʬ÷ 1.2 -> 13: /FitH 792",
+      "/Type": "/Outline"
+    },
+    "38 0 R": {
+      "/Length": "39 0 R"
+    },
+    "39 0 R": 45,
+    "4 0 R": {
+      "/Count": 4,
+      "/Dest": [
+        "11 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/First": "36 0 R",
+      "/Last": "37 0 R",
+      "/Next": "5 0 R",
+      "/Parent": "2 0 R",
+      "/Title": "Potato 1 -> 5: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "40 0 R": {
+      "/BaseFont": "/Helvetica",
+      "/Encoding": "/WinAnsiEncoding",
+      "/Name": "/F1",
+      "/Subtype": "/Type1",
+      "/Type": "/Font"
+    },
+    "41 0 R": [
+      "/PDF",
+      "/Text"
+    ],
+    "42 0 R": {
+      "/Length": "43 0 R"
+    },
+    "43 0 R": 45,
+    "44 0 R": {
+      "/Length": "45 0 R"
+    },
+    "45 0 R": 45,
+    "46 0 R": {
+      "/Length": "47 0 R"
+    },
+    "47 0 R": 45,
+    "48 0 R": {
+      "/Length": "49 0 R"
+    },
+    "49 0 R": 45,
+    "5 0 R": {
+      "/Dest": [
+        "21 0 R",
+        "/XYZ",
+        66,
+        756,
+        3
+      ],
+      "/Parent": "2 0 R",
+      "/Prev": "4 0 R",
+      "/Title": "Salad 2 -> 15: /XYZ 66 756 3",
+      "/Type": "/Outline"
+    },
+    "50 0 R": {
+      "/Length": "51 0 R"
+    },
+    "51 0 R": 45,
+    "52 0 R": {
+      "/Length": "53 0 R"
+    },
+    "53 0 R": 45,
+    "54 0 R": {
+      "/Length": "55 0 R"
+    },
+    "55 0 R": 45,
+    "56 0 R": {
+      "/Length": "57 0 R"
+    },
+    "57 0 R": 45,
+    "58 0 R": {
+      "/Length": "59 0 R"
+    },
+    "59 0 R": 45,
+    "6 0 R": {
+      "/Contents": "38 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "60 0 R": {
+      "/Length": "61 0 R"
+    },
+    "61 0 R": 46,
+    "62 0 R": {
+      "/Length": "63 0 R"
+    },
+    "63 0 R": 46,
+    "64 0 R": {
+      "/Length": "65 0 R"
+    },
+    "65 0 R": 46,
+    "66 0 R": {
+      "/Length": "67 0 R"
+    },
+    "67 0 R": 46,
+    "68 0 R": {
+      "/Length": "69 0 R"
+    },
+    "69 0 R": 46,
+    "7 0 R": {
+      "/Contents": "42 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "70 0 R": {
+      "/Length": "71 0 R"
+    },
+    "71 0 R": 46,
+    "72 0 R": {
+      "/Length": "73 0 R"
+    },
+    "73 0 R": 46,
+    "74 0 R": {
+      "/Length": "75 0 R"
+    },
+    "75 0 R": 46,
+    "76 0 R": {
+      "/Length": "77 0 R"
+    },
+    "77 0 R": 46,
+    "78 0 R": {
+      "/Length": "79 0 R"
+    },
+    "79 0 R": 46,
+    "8 0 R": {
+      "/Contents": "44 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "80 0 R": {
+      "/Length": "81 0 R"
+    },
+    "81 0 R": 46,
+    "82 0 R": {
+      "/Length": "83 0 R"
+    },
+    "83 0 R": 46,
+    "84 0 R": {
+      "/Length": "85 0 R"
+    },
+    "85 0 R": 46,
+    "86 0 R": {
+      "/Length": "87 0 R"
+    },
+    "87 0 R": 46,
+    "88 0 R": {
+      "/Length": "89 0 R"
+    },
+    "89 0 R": 46,
+    "9 0 R": {
+      "/Contents": "46 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "90 0 R": {
+      "/Length": "91 0 R"
+    },
+    "91 0 R": 46,
+    "92 0 R": {
+      "/Length": "93 0 R"
+    },
+    "93 0 R": 46,
+    "94 0 R": {
+      "/Length": "95 0 R"
+    },
+    "95 0 R": 46,
+    "96 0 R": {
+      "/Length": "97 0 R"
+    },
+    "97 0 R": 46,
+    "98 0 R": {
+      "/Length": "99 0 R"
+    },
+    "99 0 R": 46,
+    "trailer": {
+      "/ID": [
+        "Õ+\u000c\u0017Â\u0016Pib®gC¯ì&\u000f",
+        "Õ+\u000c\u0017Â\u0016Pib®gC¯ì&\u000f"
+      ],
+      "/Root": "1 0 R",
+      "/Size": 109
+    }
+  },
+  "outlines": [
+    {
+      "dest": [
+        "11 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "destpageposfrom1": 6,
+      "kids": [
+        {
+          "dest": [
+            "17 0 R",
+            "/Fit"
+          ],
+          "destpageposfrom1": 12,
+          "kids": [
+            {
+              "dest": [
+                "18 0 R",
+                "/FitV",
+                100
+              ],
+              "destpageposfrom1": 13,
+              "kids": [
+                {
+                  "dest": [
+                    "24 0 R",
+                    "/XYZ",
+                    null,
+                    null,
+                    null
+                  ],
+                  "destpageposfrom1": 19,
+                  "kids": [],
+                  "object": "104 0 R",
+                  "open": true,
+                  "title": "Glarpenspliel (A, name) 1.1.1.1 -> 18: /XYZ null null null"
+                },
+                {
+                  "dest": [
+                    "25 0 R",
+                    "/XYZ",
+                    null,
+                    null,
+                    null
+                  ],
+                  "destpageposfrom1": 20,
+                  "kids": [],
+                  "object": "105 0 R",
+                  "open": true,
+                  "title": "Hagoogamagoogle 1.1.1.2 -> 19: /XYZ null null null"
+                }
+              ],
+              "object": "100 0 R",
+              "open": false,
+              "title": "Biherbadem 1.1.1 -> 12: /FitV 100"
+            },
+            {
+              "dest": [
+                "18 0 R",
+                "/XYZ",
+                null,
+                null,
+                null
+              ],
+              "destpageposfrom1": 13,
+              "kids": [
+                {
+                  "dest": [
+                    "28 0 R",
+                    "/XYZ",
+                    null,
+                    null,
+                    null
+                  ],
+                  "destpageposfrom1": 23,
+                  "kids": [],
+                  "object": "106 0 R",
+                  "open": true,
+                  "title": "Jawarnianbvarwash 1.1.2.1 -> 22: /XYZ null null null"
+                }
+              ],
+              "object": "101 0 R",
+              "open": true,
+              "title": "Gawehwehweh 1.1.2 -> 12: /XYZ null null null"
+            }
+          ],
+          "object": "36 0 R",
+          "open": false,
+          "title": "Mern 1.1 -> 11: /Fit"
+        },
+        {
+          "dest": [
+            "19 0 R",
+            "/FitH",
+            792
+          ],
+          "destpageposfrom1": 14,
+          "kids": [
+            {
+              "dest": [
+                "7 0 R",
+                "/FitR",
+                66,
+                714,
+                180,
+                770
+              ],
+              "destpageposfrom1": 2,
+              "kids": [],
+              "object": "102 0 R",
+              "open": true,
+              "title": "Gabeebeebee (name) 1.2.1 -> 1: /FitR 66 714 180 770"
+            },
+            {
+              "dest": [
+                "6 0 R",
+                "/XYZ",
+                null,
+                null,
+                null
+              ],
+              "destpageposfrom1": 1,
+              "kids": [],
+              "object": "103 0 R",
+              "open": true,
+              "title": "Merschqaberschq (A) 1.2.2 -> 0: /XYZ null null null"
+            }
+          ],
+          "object": "37 0 R",
+          "open": true,
+          "title": "Squash ÷πʬ÷ 1.2 -> 13: /FitH 792"
+        }
+      ],
+      "object": "4 0 R",
+      "open": true,
+      "title": "Potato 1 -> 5: /XYZ null null null"
+    },
+    {
+      "dest": [
+        "21 0 R",
+        "/XYZ",
+        66,
+        756,
+        3
+      ],
+      "destpageposfrom1": 16,
+      "kids": [],
+      "object": "5 0 R",
+      "open": true,
+      "title": "Salad 2 -> 15: /XYZ 66 756 3"
+    }
+  ],
+  "pagelabels": [],
+  "pages": [
+    {
+      "contents": [
+        "38 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "6 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "6 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "103 0 R",
+          "title": "Merschqaberschq (A) 1.2.2 -> 0: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 1
+    },
+    {
+      "contents": [
+        "42 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "7 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "7 0 R",
+            "/FitR",
+            66,
+            714,
+            180,
+            770
+          ],
+          "object": "102 0 R",
+          "title": "Gabeebeebee (name) 1.2.1 -> 1: /FitR 66 714 180 770"
+        }
+      ],
+      "pageposfrom1": 2
+    },
+    {
+      "contents": [
+        "44 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "8 0 R",
+      "outlines": [],
+      "pageposfrom1": 3
+    },
+    {
+      "contents": [
+        "46 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "9 0 R",
+      "outlines": [],
+      "pageposfrom1": 4
+    },
+    {
+      "contents": [
+        "48 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "10 0 R",
+      "outlines": [],
+      "pageposfrom1": 5
+    },
+    {
+      "contents": [
+        "50 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "11 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "11 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "4 0 R",
+          "title": "Potato 1 -> 5: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 6
+    },
+    {
+      "contents": [
+        "52 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "12 0 R",
+      "outlines": [],
+      "pageposfrom1": 7
+    },
+    {
+      "contents": [
+        "54 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "13 0 R",
+      "outlines": [],
+      "pageposfrom1": 8
+    },
+    {
+      "contents": [
+        "56 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "14 0 R",
+      "outlines": [],
+      "pageposfrom1": 9
+    },
+    {
+      "contents": [
+        "58 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "15 0 R",
+      "outlines": [],
+      "pageposfrom1": 10
+    },
+    {
+      "contents": [
+        "60 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "16 0 R",
+      "outlines": [],
+      "pageposfrom1": 11
+    },
+    {
+      "contents": [
+        "62 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "17 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "17 0 R",
+            "/Fit"
+          ],
+          "object": "36 0 R",
+          "title": "Mern 1.1 -> 11: /Fit"
+        }
+      ],
+      "pageposfrom1": 12
+    },
+    {
+      "contents": [
+        "64 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "18 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "18 0 R",
+            "/FitV",
+            100
+          ],
+          "object": "100 0 R",
+          "title": "Biherbadem 1.1.1 -> 12: /FitV 100"
+        },
+        {
+          "dest": [
+            "18 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "101 0 R",
+          "title": "Gawehwehweh 1.1.2 -> 12: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 13
+    },
+    {
+      "contents": [
+        "66 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "19 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "19 0 R",
+            "/FitH",
+            792
+          ],
+          "object": "37 0 R",
+          "title": "Squash ÷πʬ÷ 1.2 -> 13: /FitH 792"
+        }
+      ],
+      "pageposfrom1": 14
+    },
+    {
+      "contents": [
+        "68 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "20 0 R",
+      "outlines": [],
+      "pageposfrom1": 15
+    },
+    {
+      "contents": [
+        "70 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "21 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "21 0 R",
+            "/XYZ",
+            66,
+            756,
+            3
+          ],
+          "object": "5 0 R",
+          "title": "Salad 2 -> 15: /XYZ 66 756 3"
+        }
+      ],
+      "pageposfrom1": 16
+    },
+    {
+      "contents": [
+        "72 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "22 0 R",
+      "outlines": [],
+      "pageposfrom1": 17
+    },
+    {
+      "contents": [
+        "74 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "23 0 R",
+      "outlines": [],
+      "pageposfrom1": 18
+    },
+    {
+      "contents": [
+        "76 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "24 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "24 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "104 0 R",
+          "title": "Glarpenspliel (A, name) 1.1.1.1 -> 18: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 19
+    },
+    {
+      "contents": [
+        "78 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "25 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "25 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "105 0 R",
+          "title": "Hagoogamagoogle 1.1.1.2 -> 19: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 20
+    },
+    {
+      "contents": [
+        "80 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "26 0 R",
+      "outlines": [],
+      "pageposfrom1": 21
+    },
+    {
+      "contents": [
+        "82 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "27 0 R",
+      "outlines": [],
+      "pageposfrom1": 22
+    },
+    {
+      "contents": [
+        "84 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "28 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "28 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "106 0 R",
+          "title": "Jawarnianbvarwash 1.1.2.1 -> 22: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 23
+    },
+    {
+      "contents": [
+        "86 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "29 0 R",
+      "outlines": [],
+      "pageposfrom1": 24
+    },
+    {
+      "contents": [
+        "88 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "30 0 R",
+      "outlines": [],
+      "pageposfrom1": 25
+    },
+    {
+      "contents": [
+        "90 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "31 0 R",
+      "outlines": [],
+      "pageposfrom1": 26
+    },
+    {
+      "contents": [
+        "92 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "32 0 R",
+      "outlines": [],
+      "pageposfrom1": 27
+    },
+    {
+      "contents": [
+        "94 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "33 0 R",
+      "outlines": [],
+      "pageposfrom1": 28
+    },
+    {
+      "contents": [
+        "96 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "34 0 R",
+      "outlines": [],
+      "pageposfrom1": 29
+    },
+    {
+      "contents": [
+        "98 0 R"
+      ],
+      "images": [],
+      "label": null,
+      "object": "35 0 R",
+      "outlines": [],
+      "pageposfrom1": 30
+    }
+  ],
+  "parameters": {
+    "decodelevel": "generalized"
+  },
+  "version": 1
+}
diff --git a/qpdf/qtest/qpdf/json-outlines-with-old-root-dests.out b/qpdf/qtest/qpdf/json-outlines-with-old-root-dests.out
new file mode 100644
index 00000000..b74cc1a0
--- /dev/null
+++ b/qpdf/qtest/qpdf/json-outlines-with-old-root-dests.out
@@ -0,0 +1,1569 @@
+{
+  "objects": {
+    "1 0 R": {
+      "/Dests": "107 0 R",
+      "/Outlines": "2 0 R",
+      "/PageLabels": {
+        "/Nums": [
+          0,
+          {
+            "/P": "0"
+          },
+          1,
+          {
+            "/S": "/R"
+          }
+        ]
+      },
+      "/PageMode": "/UseOutlines",
+      "/Pages": "3 0 R",
+      "/Type": "/Catalog"
+    },
+    "10 0 R": {
+      "/Contents": "48 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "100 0 R": {
+      "/Count": -2,
+      "/Dest": [
+        "18 0 R",
+        "/FitV",
+        100
+      ],
+      "/First": "104 0 R",
+      "/Last": "105 0 R",
+      "/Next": "101 0 R",
+      "/Parent": "36 0 R",
+      "/Title": "•Biherbadem 1.1.1 -> 12: /FitV 100",
+      "/Type": "/Outline"
+    },
+    "101 0 R": {
+      "/Count": 1,
+      "/Dest": [
+        "18 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/First": "106 0 R",
+      "/Last": "106 0 R",
+      "/Parent": "36 0 R",
+      "/Prev": "100 0 R",
+      "/Title": "•Gawehwehweh 1.1.2 -> 12: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "102 0 R": {
+      "/Dest": "/gabeebee",
+      "/Next": "103 0 R",
+      "/Parent": "37 0 R",
+      "/Title": "•Gabeebeebee (name) 1.2.1 -> 1: /FitR 66 714 180 770",
+      "/Type": "/Outline"
+    },
+    "103 0 R": {
+      "/A": {
+        "/D": [
+          "6 0 R",
+          "/XYZ",
+          null,
+          null,
+          null
+        ],
+        "/S": "/GoTo",
+        "/Type": "/Action"
+      },
+      "/Parent": "37 0 R",
+      "/Prev": "102 0 R",
+      "/Title": "•Merschqaberschq (A) 1.2.2 -> 0: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "104 0 R": {
+      "/A": {
+        "/D": "/glarp",
+        "/S": "/GoTo",
+        "/Type": "/Action"
+      },
+      "/Next": "105 0 R",
+      "/Parent": "100 0 R",
+      "/Title": "•Glarpenspliel (A, name) 1.1.1.1 -> 18: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "105 0 R": {
+      "/Dest": [
+        "25 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/Parent": "100 0 R",
+      "/Prev": "104 0 R",
+      "/Title": "•Hagoogamagoogle 1.1.1.2 -> 19: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "106 0 R": {
+      "/Dest": [
+        "28 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/Parent": "101 0 R",
+      "/Title": "•Jawarnianbvarwash 1.1.2.1 -> 22: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "107 0 R": {
+      "/gabeebee": [
+        "7 0 R",
+        "/FitR",
+        66,
+        714,
+        180,
+        770
+      ],
+      "/glarp": [
+        "24 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ]
+    },
+    "11 0 R": {
+      "/Contents": "50 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "12 0 R": {
+      "/Contents": "52 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "13 0 R": {
+      "/Contents": "54 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "14 0 R": {
+      "/Contents": "56 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "15 0 R": {
+      "/Contents": "58 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "16 0 R": {
+      "/Contents": "60 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "17 0 R": {
+      "/Contents": "62 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "18 0 R": {
+      "/Contents": "64 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "19 0 R": {
+      "/Contents": "66 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "2 0 R": {
+      "/Count": 6,
+      "/First": "4 0 R",
+      "/Last": "5 0 R",
+      "/Type": "/Outlines"
+    },
+    "20 0 R": {
+      "/Contents": "68 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "21 0 R": {
+      "/Contents": "70 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "22 0 R": {
+      "/Contents": "72 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "23 0 R": {
+      "/Contents": "74 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "24 0 R": {
+      "/Contents": "76 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "25 0 R": {
+      "/Contents": "78 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "26 0 R": {
+      "/Contents": "80 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "27 0 R": {
+      "/Contents": "82 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "28 0 R": {
+      "/Contents": "84 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "29 0 R": {
+      "/Contents": "86 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "3 0 R": {
+      "/Count": 30,
+      "/Kids": [
+        "6 0 R",
+        "7 0 R",
+        "8 0 R",
+        "9 0 R",
+        "10 0 R",
+        "11 0 R",
+        "12 0 R",
+        "13 0 R",
+        "14 0 R",
+        "15 0 R",
+        "16 0 R",
+        "17 0 R",
+        "18 0 R",
+        "19 0 R",
+        "20 0 R",
+        "21 0 R",
+        "22 0 R",
+        "23 0 R",
+        "24 0 R",
+        "25 0 R",
+        "26 0 R",
+        "27 0 R",
+        "28 0 R",
+        "29 0 R",
+        "30 0 R",
+        "31 0 R",
+        "32 0 R",
+        "33 0 R",
+        "34 0 R",
+        "35 0 R"
+      ],
+      "/Type": "/Pages"
+    },
+    "30 0 R": {
+      "/Contents": "88 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "31 0 R": {
+      "/Contents": "90 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "32 0 R": {
+      "/Contents": "92 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "33 0 R": {
+      "/Contents": "94 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "34 0 R": {
+      "/Contents": "96 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "35 0 R": {
+      "/Contents": "98 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "36 0 R": {
+      "/Count": 3,
+      "/Dest": [
+        "17 0 R",
+        "/Fit"
+      ],
+      "/First": "100 0 R",
+      "/Last": "101 0 R",
+      "/Next": "37 0 R",
+      "/Parent": "4 0 R",
+      "/Title": "•Mern 1.1 -> 11: /Fit",
+      "/Type": "/Outline"
+    },
+    "37 0 R": {
+      "/Count": 2,
+      "/Dest": [
+        "19 0 R",
+        "/FitH",
+        792
+      ],
+      "/First": "102 0 R",
+      "/Last": "103 0 R",
+      "/Parent": "4 0 R",
+      "/Prev": "36 0 R",
+      "/Title": "•Squash ÷πʬ÷ 1.2 -> 13: /FitH 792",
+      "/Type": "/Outline"
+    },
+    "38 0 R": {
+      "/Length": "39 0 R"
+    },
+    "39 0 R": 44,
+    "4 0 R": {
+      "/Count": 4,
+      "/Dest": [
+        "11 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/First": "36 0 R",
+      "/Last": "37 0 R",
+      "/Next": "5 0 R",
+      "/Parent": "2 0 R",
+      "/Title": "•Potato 1 -> 5: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "40 0 R": {
+      "/BaseFont": "/Helvetica",
+      "/Encoding": "/WinAnsiEncoding",
+      "/Name": "/F1",
+      "/Subtype": "/Type1",
+      "/Type": "/Font"
+    },
+    "41 0 R": [
+      "/PDF",
+      "/Text"
+    ],
+    "42 0 R": {
+      "/Length": "43 0 R"
+    },
+    "43 0 R": 44,
+    "44 0 R": {
+      "/Length": "45 0 R"
+    },
+    "45 0 R": 44,
+    "46 0 R": {
+      "/Length": "47 0 R"
+    },
+    "47 0 R": 44,
+    "48 0 R": {
+      "/Length": "49 0 R"
+    },
+    "49 0 R": 44,
+    "5 0 R": {
+      "/Dest": [
+        "21 0 R",
+        "/XYZ",
+        66,
+        756,
+        3
+      ],
+      "/Parent": "2 0 R",
+      "/Prev": "4 0 R",
+      "/Title": "•Salad 2 -> 15: /XYZ 66 756 3",
+      "/Type": "/Outline"
+    },
+    "50 0 R": {
+      "/Length": "51 0 R"
+    },
+    "51 0 R": 44,
+    "52 0 R": {
+      "/Length": "53 0 R"
+    },
+    "53 0 R": 44,
+    "54 0 R": {
+      "/Length": "55 0 R"
+    },
+    "55 0 R": 44,
+    "56 0 R": {
+      "/Length": "57 0 R"
+    },
+    "57 0 R": 44,
+    "58 0 R": {
+      "/Length": "59 0 R"
+    },
+    "59 0 R": 44,
+    "6 0 R": {
+      "/Contents": "38 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "60 0 R": {
+      "/Length": "61 0 R"
+    },
+    "61 0 R": 45,
+    "62 0 R": {
+      "/Length": "63 0 R"
+    },
+    "63 0 R": 45,
+    "64 0 R": {
+      "/Length": "65 0 R"
+    },
+    "65 0 R": 45,
+    "66 0 R": {
+      "/Length": "67 0 R"
+    },
+    "67 0 R": 45,
+    "68 0 R": {
+      "/Length": "69 0 R"
+    },
+    "69 0 R": 45,
+    "7 0 R": {
+      "/Contents": "42 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "70 0 R": {
+      "/Length": "71 0 R"
+    },
+    "71 0 R": 45,
+    "72 0 R": {
+      "/Length": "73 0 R"
+    },
+    "73 0 R": 45,
+    "74 0 R": {
+      "/Length": "75 0 R"
+    },
+    "75 0 R": 45,
+    "76 0 R": {
+      "/Length": "77 0 R"
+    },
+    "77 0 R": 45,
+    "78 0 R": {
+      "/Length": "79 0 R"
+    },
+    "79 0 R": 45,
+    "8 0 R": {
+      "/Contents": "44 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "80 0 R": {
+      "/Length": "81 0 R"
+    },
+    "81 0 R": 45,
+    "82 0 R": {
+      "/Length": "83 0 R"
+    },
+    "83 0 R": 45,
+    "84 0 R": {
+      "/Length": "85 0 R"
+    },
+    "85 0 R": 45,
+    "86 0 R": {
+      "/Length": "87 0 R"
+    },
+    "87 0 R": 45,
+    "88 0 R": {
+      "/Length": "89 0 R"
+    },
+    "89 0 R": 45,
+    "9 0 R": {
+      "/Contents": "46 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "90 0 R": {
+      "/Length": "91 0 R"
+    },
+    "91 0 R": 45,
+    "92 0 R": {
+      "/Length": "93 0 R"
+    },
+    "93 0 R": 45,
+    "94 0 R": {
+      "/Length": "95 0 R"
+    },
+    "95 0 R": 45,
+    "96 0 R": {
+      "/Length": "97 0 R"
+    },
+    "97 0 R": 45,
+    "98 0 R": {
+      "/Length": "99 0 R"
+    },
+    "99 0 R": 45,
+    "trailer": {
+      "/ID": [
+        "Õ+\u000c\u0017Â\u0016Pib®gC¯ì&\u000f",
+        "Õ+\u000c\u0017Â\u0016Pib®gC¯ì&\u000f"
+      ],
+      "/Root": "1 0 R",
+      "/Size": 108
+    }
+  },
+  "outlines": [
+    {
+      "dest": [
+        "11 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "destpageposfrom1": 6,
+      "kids": [
+        {
+          "dest": [
+            "17 0 R",
+            "/Fit"
+          ],
+          "destpageposfrom1": 12,
+          "kids": [
+            {
+              "dest": [
+                "18 0 R",
+                "/FitV",
+                100
+              ],
+              "destpageposfrom1": 13,
+              "kids": [
+                {
+                  "dest": [
+                    "24 0 R",
+                    "/XYZ",
+                    null,
+                    null,
+                    null
+                  ],
+                  "destpageposfrom1": 19,
+                  "kids": [],
+                  "object": "104 0 R",
+                  "open": true,
+                  "title": "•Glarpenspliel (A, name) 1.1.1.1 -> 18: /XYZ null null null"
+                },
+                {
+                  "dest": [
+                    "25 0 R",
+                    "/XYZ",
+                    null,
+                    null,
+                    null
+                  ],
+                  "destpageposfrom1": 20,
+                  "kids": [],
+                  "object": "105 0 R",
+                  "open": true,
+                  "title": "•Hagoogamagoogle 1.1.1.2 -> 19: /XYZ null null null"
+                }
+              ],
+              "object": "100 0 R",
+              "open": false,
+              "title": "•Biherbadem 1.1.1 -> 12: /FitV 100"
+            },
+            {
+              "dest": [
+                "18 0 R",
+                "/XYZ",
+                null,
+                null,
+                null
+              ],
+              "destpageposfrom1": 13,
+              "kids": [
+                {
+                  "dest": [
+                    "28 0 R",
+                    "/XYZ",
+                    null,
+                    null,
+                    null
+                  ],
+                  "destpageposfrom1": 23,
+                  "kids": [],
+                  "object": "106 0 R",
+                  "open": true,
+                  "title": "•Jawarnianbvarwash 1.1.2.1 -> 22: /XYZ null null null"
+                }
+              ],
+              "object": "101 0 R",
+              "open": true,
+              "title": "•Gawehwehweh 1.1.2 -> 12: /XYZ null null null"
+            }
+          ],
+          "object": "36 0 R",
+          "open": true,
+          "title": "•Mern 1.1 -> 11: /Fit"
+        },
+        {
+          "dest": [
+            "19 0 R",
+            "/FitH",
+            792
+          ],
+          "destpageposfrom1": 14,
+          "kids": [
+            {
+              "dest": [
+                "7 0 R",
+                "/FitR",
+                66,
+                714,
+                180,
+                770
+              ],
+              "destpageposfrom1": 2,
+              "kids": [],
+              "object": "102 0 R",
+              "open": true,
+              "title": "•Gabeebeebee (name) 1.2.1 -> 1: /FitR 66 714 180 770"
+            },
+            {
+              "dest": [
+                "6 0 R",
+                "/XYZ",
+                null,
+                null,
+                null
+              ],
+              "destpageposfrom1": 1,
+              "kids": [],
+              "object": "103 0 R",
+              "open": true,
+              "title": "•Merschqaberschq (A) 1.2.2 -> 0: /XYZ null null null"
+            }
+          ],
+          "object": "37 0 R",
+          "open": true,
+          "title": "•Squash ÷πʬ÷ 1.2 -> 13: /FitH 792"
+        }
+      ],
+      "object": "4 0 R",
+      "open": true,
+      "title": "•Potato 1 -> 5: /XYZ null null null"
+    },
+    {
+      "dest": [
+        "21 0 R",
+        "/XYZ",
+        66,
+        756,
+        3
+      ],
+      "destpageposfrom1": 16,
+      "kids": [],
+      "object": "5 0 R",
+      "open": true,
+      "title": "•Salad 2 -> 15: /XYZ 66 756 3"
+    }
+  ],
+  "pagelabels": [
+    {
+      "index": 0,
+      "label": {
+        "/P": "0",
+        "/St": 1
+      }
+    },
+    {
+      "index": 1,
+      "label": {
+        "/S": "/R",
+        "/St": 1
+      }
+    }
+  ],
+  "pages": [
+    {
+      "contents": [
+        "38 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "0",
+        "/St": 1
+      },
+      "object": "6 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "6 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "103 0 R",
+          "title": "•Merschqaberschq (A) 1.2.2 -> 0: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 1
+    },
+    {
+      "contents": [
+        "42 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 1
+      },
+      "object": "7 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "7 0 R",
+            "/FitR",
+            66,
+            714,
+            180,
+            770
+          ],
+          "object": "102 0 R",
+          "title": "•Gabeebeebee (name) 1.2.1 -> 1: /FitR 66 714 180 770"
+        }
+      ],
+      "pageposfrom1": 2
+    },
+    {
+      "contents": [
+        "44 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 2
+      },
+      "object": "8 0 R",
+      "outlines": [],
+      "pageposfrom1": 3
+    },
+    {
+      "contents": [
+        "46 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 3
+      },
+      "object": "9 0 R",
+      "outlines": [],
+      "pageposfrom1": 4
+    },
+    {
+      "contents": [
+        "48 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 4
+      },
+      "object": "10 0 R",
+      "outlines": [],
+      "pageposfrom1": 5
+    },
+    {
+      "contents": [
+        "50 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 5
+      },
+      "object": "11 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "11 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "4 0 R",
+          "title": "•Potato 1 -> 5: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 6
+    },
+    {
+      "contents": [
+        "52 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 6
+      },
+      "object": "12 0 R",
+      "outlines": [],
+      "pageposfrom1": 7
+    },
+    {
+      "contents": [
+        "54 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 7
+      },
+      "object": "13 0 R",
+      "outlines": [],
+      "pageposfrom1": 8
+    },
+    {
+      "contents": [
+        "56 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 8
+      },
+      "object": "14 0 R",
+      "outlines": [],
+      "pageposfrom1": 9
+    },
+    {
+      "contents": [
+        "58 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 9
+      },
+      "object": "15 0 R",
+      "outlines": [],
+      "pageposfrom1": 10
+    },
+    {
+      "contents": [
+        "60 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 10
+      },
+      "object": "16 0 R",
+      "outlines": [],
+      "pageposfrom1": 11
+    },
+    {
+      "contents": [
+        "62 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 11
+      },
+      "object": "17 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "17 0 R",
+            "/Fit"
+          ],
+          "object": "36 0 R",
+          "title": "•Mern 1.1 -> 11: /Fit"
+        }
+      ],
+      "pageposfrom1": 12
+    },
+    {
+      "contents": [
+        "64 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 12
+      },
+      "object": "18 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "18 0 R",
+            "/FitV",
+            100
+          ],
+          "object": "100 0 R",
+          "title": "•Biherbadem 1.1.1 -> 12: /FitV 100"
+        },
+        {
+          "dest": [
+            "18 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "101 0 R",
+          "title": "•Gawehwehweh 1.1.2 -> 12: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 13
+    },
+    {
+      "contents": [
+        "66 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 13
+      },
+      "object": "19 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "19 0 R",
+            "/FitH",
+            792
+          ],
+          "object": "37 0 R",
+          "title": "•Squash ÷πʬ÷ 1.2 -> 13: /FitH 792"
+        }
+      ],
+      "pageposfrom1": 14
+    },
+    {
+      "contents": [
+        "68 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 14
+      },
+      "object": "20 0 R",
+      "outlines": [],
+      "pageposfrom1": 15
+    },
+    {
+      "contents": [
+        "70 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 15
+      },
+      "object": "21 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "21 0 R",
+            "/XYZ",
+            66,
+            756,
+            3
+          ],
+          "object": "5 0 R",
+          "title": "•Salad 2 -> 15: /XYZ 66 756 3"
+        }
+      ],
+      "pageposfrom1": 16
+    },
+    {
+      "contents": [
+        "72 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 16
+      },
+      "object": "22 0 R",
+      "outlines": [],
+      "pageposfrom1": 17
+    },
+    {
+      "contents": [
+        "74 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 17
+      },
+      "object": "23 0 R",
+      "outlines": [],
+      "pageposfrom1": 18
+    },
+    {
+      "contents": [
+        "76 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 18
+      },
+      "object": "24 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "24 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "104 0 R",
+          "title": "•Glarpenspliel (A, name) 1.1.1.1 -> 18: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 19
+    },
+    {
+      "contents": [
+        "78 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 19
+      },
+      "object": "25 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "25 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "105 0 R",
+          "title": "•Hagoogamagoogle 1.1.1.2 -> 19: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 20
+    },
+    {
+      "contents": [
+        "80 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 20
+      },
+      "object": "26 0 R",
+      "outlines": [],
+      "pageposfrom1": 21
+    },
+    {
+      "contents": [
+        "82 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 21
+      },
+      "object": "27 0 R",
+      "outlines": [],
+      "pageposfrom1": 22
+    },
+    {
+      "contents": [
+        "84 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 22
+      },
+      "object": "28 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "28 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "106 0 R",
+          "title": "•Jawarnianbvarwash 1.1.2.1 -> 22: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 23
+    },
+    {
+      "contents": [
+        "86 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 23
+      },
+      "object": "29 0 R",
+      "outlines": [],
+      "pageposfrom1": 24
+    },
+    {
+      "contents": [
+        "88 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 24
+      },
+      "object": "30 0 R",
+      "outlines": [],
+      "pageposfrom1": 25
+    },
+    {
+      "contents": [
+        "90 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 25
+      },
+      "object": "31 0 R",
+      "outlines": [],
+      "pageposfrom1": 26
+    },
+    {
+      "contents": [
+        "92 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 26
+      },
+      "object": "32 0 R",
+      "outlines": [],
+      "pageposfrom1": 27
+    },
+    {
+      "contents": [
+        "94 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 27
+      },
+      "object": "33 0 R",
+      "outlines": [],
+      "pageposfrom1": 28
+    },
+    {
+      "contents": [
+        "96 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 28
+      },
+      "object": "34 0 R",
+      "outlines": [],
+      "pageposfrom1": 29
+    },
+    {
+      "contents": [
+        "98 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 29
+      },
+      "object": "35 0 R",
+      "outlines": [],
+      "pageposfrom1": 30
+    }
+  ],
+  "parameters": {
+    "decodelevel": "generalized"
+  },
+  "version": 1
+}
diff --git a/qpdf/qtest/qpdf/json-page-labels-and-outlines-objects-trailer-2.out b/qpdf/qtest/qpdf/json-page-labels-and-outlines-objects-trailer-2.out
new file mode 100644
index 00000000..30a6f9db
--- /dev/null
+++ b/qpdf/qtest/qpdf/json-page-labels-and-outlines-objects-trailer-2.out
@@ -0,0 +1,48 @@
+{
+  "objects": {
+    "2 0 R": {
+      "/Count": 30,
+      "/Kids": [
+        "3 0 R",
+        "4 0 R",
+        "5 0 R",
+        "6 0 R",
+        "7 0 R",
+        "8 0 R",
+        "9 0 R",
+        "10 0 R",
+        "11 0 R",
+        "12 0 R",
+        "13 0 R",
+        "14 0 R",
+        "15 0 R",
+        "16 0 R",
+        "17 0 R",
+        "18 0 R",
+        "19 0 R",
+        "20 0 R",
+        "21 0 R",
+        "22 0 R",
+        "23 0 R",
+        "24 0 R",
+        "25 0 R",
+        "26 0 R",
+        "27 0 R",
+        "28 0 R",
+        "29 0 R",
+        "30 0 R",
+        "31 0 R",
+        "32 0 R"
+      ],
+      "/Type": "/Pages"
+    },
+    "trailer": {
+      "/Root": "1 0 R",
+      "/Size": 107
+    }
+  },
+  "parameters": {
+    "decodelevel": "generalized"
+  },
+  "version": 1
+}
diff --git a/qpdf/qtest/qpdf/json-page-labels-and-outlines-objects-trailer.out b/qpdf/qtest/qpdf/json-page-labels-and-outlines-objects-trailer.out
new file mode 100644
index 00000000..f590c095
--- /dev/null
+++ b/qpdf/qtest/qpdf/json-page-labels-and-outlines-objects-trailer.out
@@ -0,0 +1,12 @@
+{
+  "objects": {
+    "trailer": {
+      "/Root": "1 0 R",
+      "/Size": 107
+    }
+  },
+  "parameters": {
+    "decodelevel": "generalized"
+  },
+  "version": 1
+}
diff --git a/qpdf/qtest/qpdf/json-page-labels-and-outlines-objects.out b/qpdf/qtest/qpdf/json-page-labels-and-outlines-objects.out
new file mode 100644
index 00000000..d44793df
--- /dev/null
+++ b/qpdf/qtest/qpdf/json-page-labels-and-outlines-objects.out
@@ -0,0 +1,912 @@
+{
+  "objects": {
+    "1 0 R": {
+      "/Outlines": "95 0 R",
+      "/PageLabels": {
+        "/Nums": [
+          0,
+          {
+            "/P": ""
+          },
+          2,
+          {
+            "/S": "/r",
+            "/St": 1
+          },
+          7,
+          {
+            "/P": ""
+          },
+          9,
+          {
+            "/S": "/r",
+            "/St": 6
+          },
+          11,
+          {
+            "/P": ""
+          },
+          12,
+          {
+            "/S": "/D",
+            "/St": 2
+          },
+          15,
+          {
+            "/S": "/D",
+            "/St": 6
+          },
+          19,
+          {
+            "/P": ""
+          },
+          20,
+          {
+            "/S": "/D",
+            "/St": 12
+          },
+          22,
+          {
+            "/S": "/D",
+            "/St": 16059
+          },
+          23,
+          {
+            "/S": "/r",
+            "/St": 50
+          },
+          29,
+          {
+            "/S": "/r",
+            "/St": 54
+          }
+        ]
+      },
+      "/PageMode": "/UseOutlines",
+      "/Pages": "2 0 R",
+      "/Type": "/Catalog"
+    },
+    "10 0 R": {
+      "/Contents": "49 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "100 0 R": {
+      "/Count": -2,
+      "/Dest": [
+        "15 0 R",
+        "/FitV",
+        100
+      ],
+      "/First": "102 0 R",
+      "/Last": "103 0 R",
+      "/Next": "101 0 R",
+      "/Parent": "98 0 R",
+      "/Title": "Isosicle 1.1.1 -> 12: /FitV 100",
+      "/Type": "/Outline"
+    },
+    "101 0 R": {
+      "/Count": 1,
+      "/Dest": [
+        "15 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/First": "104 0 R",
+      "/Last": "104 0 R",
+      "/Parent": "98 0 R",
+      "/Prev": "100 0 R",
+      "/Title": "Isosicle 1.1.2 -> 12: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "102 0 R": {
+      "/Dest": [
+        "21 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/Next": "103 0 R",
+      "/Parent": "100 0 R",
+      "/Title": "Isosicle 1.1.1.1 -> 18: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "103 0 R": {
+      "/Dest": [
+        "22 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/Parent": "100 0 R",
+      "/Prev": "102 0 R",
+      "/Title": "Isosicle 1.1.1.2 -> 19: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "104 0 R": {
+      "/Dest": [
+        "25 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/Parent": "101 0 R",
+      "/Title": "Isosicle 1.1.2.1 -> 22: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "105 0 R": {
+      "/Dest": [
+        "4 0 R",
+        "/FitR",
+        66,
+        714,
+        180,
+        770
+      ],
+      "/Next": "106 0 R",
+      "/Parent": "99 0 R",
+      "/Title": "Trepsichord 1.2.1 -> 1: /FitR 66 714 180 770",
+      "/Type": "/Outline"
+    },
+    "106 0 R": {
+      "/Dest": [
+        "3 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/Parent": "99 0 R",
+      "/Prev": "105 0 R",
+      "/Title": "Trepsicle 1.2.2 -> 0: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "11 0 R": {
+      "/Contents": "51 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "12 0 R": {
+      "/Contents": "53 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "13 0 R": {
+      "/Contents": "55 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "14 0 R": {
+      "/Contents": "57 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "15 0 R": {
+      "/Contents": "59 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "16 0 R": {
+      "/Contents": "61 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "17 0 R": {
+      "/Contents": "63 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "18 0 R": {
+      "/Contents": "65 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "19 0 R": {
+      "/Contents": "67 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "2 0 R": {
+      "/Count": 30,
+      "/Kids": [
+        "3 0 R",
+        "4 0 R",
+        "5 0 R",
+        "6 0 R",
+        "7 0 R",
+        "8 0 R",
+        "9 0 R",
+        "10 0 R",
+        "11 0 R",
+        "12 0 R",
+        "13 0 R",
+        "14 0 R",
+        "15 0 R",
+        "16 0 R",
+        "17 0 R",
+        "18 0 R",
+        "19 0 R",
+        "20 0 R",
+        "21 0 R",
+        "22 0 R",
+        "23 0 R",
+        "24 0 R",
+        "25 0 R",
+        "26 0 R",
+        "27 0 R",
+        "28 0 R",
+        "29 0 R",
+        "30 0 R",
+        "31 0 R",
+        "32 0 R"
+      ],
+      "/Type": "/Pages"
+    },
+    "20 0 R": {
+      "/Contents": "69 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "21 0 R": {
+      "/Contents": "71 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "22 0 R": {
+      "/Contents": "73 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "23 0 R": {
+      "/Contents": "75 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "24 0 R": {
+      "/Contents": "77 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "25 0 R": {
+      "/Contents": "79 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "26 0 R": {
+      "/Contents": "81 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "27 0 R": {
+      "/Contents": "83 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "28 0 R": {
+      "/Contents": "85 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "29 0 R": {
+      "/Contents": "87 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "3 0 R": {
+      "/Contents": "33 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "30 0 R": {
+      "/Contents": "89 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "31 0 R": {
+      "/Contents": "91 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "32 0 R": {
+      "/Contents": "93 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "33 0 R": {
+      "/Length": "34 0 R"
+    },
+    "34 0 R": 46,
+    "35 0 R": {
+      "/BaseFont": "/Helvetica",
+      "/Encoding": "/WinAnsiEncoding",
+      "/Name": "/F1",
+      "/Subtype": "/Type1",
+      "/Type": "/Font"
+    },
+    "36 0 R": [
+      "/PDF",
+      "/Text"
+    ],
+    "37 0 R": {
+      "/Length": "38 0 R"
+    },
+    "38 0 R": 46,
+    "39 0 R": {
+      "/Length": "40 0 R"
+    },
+    "4 0 R": {
+      "/Contents": "37 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "40 0 R": 46,
+    "41 0 R": {
+      "/Length": "42 0 R"
+    },
+    "42 0 R": 46,
+    "43 0 R": {
+      "/Length": "44 0 R"
+    },
+    "44 0 R": 46,
+    "45 0 R": {
+      "/Length": "46 0 R"
+    },
+    "46 0 R": 46,
+    "47 0 R": {
+      "/Length": "48 0 R"
+    },
+    "48 0 R": 46,
+    "49 0 R": {
+      "/Length": "50 0 R"
+    },
+    "5 0 R": {
+      "/Contents": "39 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "50 0 R": 46,
+    "51 0 R": {
+      "/Length": "52 0 R"
+    },
+    "52 0 R": 46,
+    "53 0 R": {
+      "/Length": "54 0 R"
+    },
+    "54 0 R": 46,
+    "55 0 R": {
+      "/Length": "56 0 R"
+    },
+    "56 0 R": 47,
+    "57 0 R": {
+      "/Length": "58 0 R"
+    },
+    "58 0 R": 47,
+    "59 0 R": {
+      "/Length": "60 0 R"
+    },
+    "6 0 R": {
+      "/Contents": "41 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "60 0 R": 47,
+    "61 0 R": {
+      "/Length": "62 0 R"
+    },
+    "62 0 R": 47,
+    "63 0 R": {
+      "/Length": "64 0 R"
+    },
+    "64 0 R": 47,
+    "65 0 R": {
+      "/Length": "66 0 R"
+    },
+    "66 0 R": 47,
+    "67 0 R": {
+      "/Length": "68 0 R"
+    },
+    "68 0 R": 47,
+    "69 0 R": {
+      "/Length": "70 0 R"
+    },
+    "7 0 R": {
+      "/Contents": "43 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "70 0 R": 47,
+    "71 0 R": {
+      "/Length": "72 0 R"
+    },
+    "72 0 R": 47,
+    "73 0 R": {
+      "/Length": "74 0 R"
+    },
+    "74 0 R": 47,
+    "75 0 R": {
+      "/Length": "76 0 R"
+    },
+    "76 0 R": 47,
+    "77 0 R": {
+      "/Length": "78 0 R"
+    },
+    "78 0 R": 47,
+    "79 0 R": {
+      "/Length": "80 0 R"
+    },
+    "8 0 R": {
+      "/Contents": "45 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "80 0 R": 47,
+    "81 0 R": {
+      "/Length": "82 0 R"
+    },
+    "82 0 R": 47,
+    "83 0 R": {
+      "/Length": "84 0 R"
+    },
+    "84 0 R": 47,
+    "85 0 R": {
+      "/Length": "86 0 R"
+    },
+    "86 0 R": 47,
+    "87 0 R": {
+      "/Length": "88 0 R"
+    },
+    "88 0 R": 47,
+    "89 0 R": {
+      "/Length": "90 0 R"
+    },
+    "9 0 R": {
+      "/Contents": "47 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "90 0 R": 47,
+    "91 0 R": {
+      "/Length": "92 0 R"
+    },
+    "92 0 R": 47,
+    "93 0 R": {
+      "/Length": "94 0 R"
+    },
+    "94 0 R": 47,
+    "95 0 R": {
+      "/Count": 6,
+      "/First": "96 0 R",
+      "/Last": "97 0 R",
+      "/Type": "/Outlines"
+    },
+    "96 0 R": {
+      "/Count": 4,
+      "/Dest": [
+        "8 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/First": "98 0 R",
+      "/Last": "99 0 R",
+      "/Next": "97 0 R",
+      "/Parent": "95 0 R",
+      "/Title": "Isís 1 -> 5: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "97 0 R": {
+      "/Dest": [
+        "18 0 R",
+        "/XYZ",
+        66,
+        756,
+        3
+      ],
+      "/Parent": "95 0 R",
+      "/Prev": "96 0 R",
+      "/Title": "Trepak 2 -> 15: /XYZ 66 756 3",
+      "/Type": "/Outline"
+    },
+    "98 0 R": {
+      "/Count": -3,
+      "/Dest": [
+        "14 0 R",
+        "/Fit"
+      ],
+      "/First": "100 0 R",
+      "/Last": "101 0 R",
+      "/Next": "99 0 R",
+      "/Parent": "96 0 R",
+      "/Title": "Amanda 1.1 -> 11: /Fit",
+      "/Type": "/Outline"
+    },
+    "99 0 R": {
+      "/Count": 2,
+      "/Dest": [
+        "16 0 R",
+        "/FitH",
+        792
+      ],
+      "/First": "105 0 R",
+      "/Last": "106 0 R",
+      "/Parent": "96 0 R",
+      "/Prev": "98 0 R",
+      "/Title": "Sandy ÷Σανδι÷ 1.2 -> 13: /FitH 792",
+      "/Type": "/Outline"
+    },
+    "trailer": {
+      "/Root": "1 0 R",
+      "/Size": 107
+    }
+  },
+  "parameters": {
+    "decodelevel": "generalized"
+  },
+  "version": 1
+}
diff --git a/qpdf/qtest/qpdf/json-page-labels-and-outlines-outlines-pages.out b/qpdf/qtest/qpdf/json-page-labels-and-outlines-outlines-pages.out
new file mode 100644
index 00000000..f57dca17
--- /dev/null
+++ b/qpdf/qtest/qpdf/json-page-labels-and-outlines-outlines-pages.out
@@ -0,0 +1,678 @@
+{
+  "outlines": [
+    {
+      "dest": [
+        "8 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "destpageposfrom1": 6,
+      "kids": [
+        {
+          "dest": [
+            "14 0 R",
+            "/Fit"
+          ],
+          "destpageposfrom1": 12,
+          "kids": [
+            {
+              "dest": [
+                "15 0 R",
+                "/FitV",
+                100
+              ],
+              "destpageposfrom1": 13,
+              "kids": [
+                {
+                  "dest": [
+                    "21 0 R",
+                    "/XYZ",
+                    null,
+                    null,
+                    null
+                  ],
+                  "destpageposfrom1": 19,
+                  "kids": [],
+                  "object": "102 0 R",
+                  "open": true,
+                  "title": "Isosicle 1.1.1.1 -> 18: /XYZ null null null"
+                },
+                {
+                  "dest": [
+                    "22 0 R",
+                    "/XYZ",
+                    null,
+                    null,
+                    null
+                  ],
+                  "destpageposfrom1": 20,
+                  "kids": [],
+                  "object": "103 0 R",
+                  "open": true,
+                  "title": "Isosicle 1.1.1.2 -> 19: /XYZ null null null"
+                }
+              ],
+              "object": "100 0 R",
+              "open": false,
+              "title": "Isosicle 1.1.1 -> 12: /FitV 100"
+            },
+            {
+              "dest": [
+                "15 0 R",
+                "/XYZ",
+                null,
+                null,
+                null
+              ],
+              "destpageposfrom1": 13,
+              "kids": [
+                {
+                  "dest": [
+                    "25 0 R",
+                    "/XYZ",
+                    null,
+                    null,
+                    null
+                  ],
+                  "destpageposfrom1": 23,
+                  "kids": [],
+                  "object": "104 0 R",
+                  "open": true,
+                  "title": "Isosicle 1.1.2.1 -> 22: /XYZ null null null"
+                }
+              ],
+              "object": "101 0 R",
+              "open": true,
+              "title": "Isosicle 1.1.2 -> 12: /XYZ null null null"
+            }
+          ],
+          "object": "98 0 R",
+          "open": false,
+          "title": "Amanda 1.1 -> 11: /Fit"
+        },
+        {
+          "dest": [
+            "16 0 R",
+            "/FitH",
+            792
+          ],
+          "destpageposfrom1": 14,
+          "kids": [
+            {
+              "dest": [
+                "4 0 R",
+                "/FitR",
+                66,
+                714,
+                180,
+                770
+              ],
+              "destpageposfrom1": 2,
+              "kids": [],
+              "object": "105 0 R",
+              "open": true,
+              "title": "Trepsichord 1.2.1 -> 1: /FitR 66 714 180 770"
+            },
+            {
+              "dest": [
+                "3 0 R",
+                "/XYZ",
+                null,
+                null,
+                null
+              ],
+              "destpageposfrom1": 1,
+              "kids": [],
+              "object": "106 0 R",
+              "open": true,
+              "title": "Trepsicle 1.2.2 -> 0: /XYZ null null null"
+            }
+          ],
+          "object": "99 0 R",
+          "open": true,
+          "title": "Sandy ÷Σανδι÷ 1.2 -> 13: /FitH 792"
+        }
+      ],
+      "object": "96 0 R",
+      "open": true,
+      "title": "Isís 1 -> 5: /XYZ null null null"
+    },
+    {
+      "dest": [
+        "18 0 R",
+        "/XYZ",
+        66,
+        756,
+        3
+      ],
+      "destpageposfrom1": 16,
+      "kids": [],
+      "object": "97 0 R",
+      "open": true,
+      "title": "Trepak 2 -> 15: /XYZ 66 756 3"
+    }
+  ],
+  "pages": [
+    {
+      "contents": [
+        "33 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 1
+      },
+      "object": "3 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "3 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "106 0 R",
+          "title": "Trepsicle 1.2.2 -> 0: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 1
+    },
+    {
+      "contents": [
+        "37 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 2
+      },
+      "object": "4 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "4 0 R",
+            "/FitR",
+            66,
+            714,
+            180,
+            770
+          ],
+          "object": "105 0 R",
+          "title": "Trepsichord 1.2.1 -> 1: /FitR 66 714 180 770"
+        }
+      ],
+      "pageposfrom1": 2
+    },
+    {
+      "contents": [
+        "39 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 1
+      },
+      "object": "5 0 R",
+      "outlines": [],
+      "pageposfrom1": 3
+    },
+    {
+      "contents": [
+        "41 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 2
+      },
+      "object": "6 0 R",
+      "outlines": [],
+      "pageposfrom1": 4
+    },
+    {
+      "contents": [
+        "43 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 3
+      },
+      "object": "7 0 R",
+      "outlines": [],
+      "pageposfrom1": 5
+    },
+    {
+      "contents": [
+        "45 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 4
+      },
+      "object": "8 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "8 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "96 0 R",
+          "title": "Isís 1 -> 5: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 6
+    },
+    {
+      "contents": [
+        "47 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 5
+      },
+      "object": "9 0 R",
+      "outlines": [],
+      "pageposfrom1": 7
+    },
+    {
+      "contents": [
+        "49 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 1
+      },
+      "object": "10 0 R",
+      "outlines": [],
+      "pageposfrom1": 8
+    },
+    {
+      "contents": [
+        "51 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 2
+      },
+      "object": "11 0 R",
+      "outlines": [],
+      "pageposfrom1": 9
+    },
+    {
+      "contents": [
+        "53 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 6
+      },
+      "object": "12 0 R",
+      "outlines": [],
+      "pageposfrom1": 10
+    },
+    {
+      "contents": [
+        "55 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 7
+      },
+      "object": "13 0 R",
+      "outlines": [],
+      "pageposfrom1": 11
+    },
+    {
+      "contents": [
+        "57 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 1
+      },
+      "object": "14 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "14 0 R",
+            "/Fit"
+          ],
+          "object": "98 0 R",
+          "title": "Amanda 1.1 -> 11: /Fit"
+        }
+      ],
+      "pageposfrom1": 12
+    },
+    {
+      "contents": [
+        "59 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 2
+      },
+      "object": "15 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "15 0 R",
+            "/FitV",
+            100
+          ],
+          "object": "100 0 R",
+          "title": "Isosicle 1.1.1 -> 12: /FitV 100"
+        },
+        {
+          "dest": [
+            "15 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "101 0 R",
+          "title": "Isosicle 1.1.2 -> 12: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 13
+    },
+    {
+      "contents": [
+        "61 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 3
+      },
+      "object": "16 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "16 0 R",
+            "/FitH",
+            792
+          ],
+          "object": "99 0 R",
+          "title": "Sandy ÷Σανδι÷ 1.2 -> 13: /FitH 792"
+        }
+      ],
+      "pageposfrom1": 14
+    },
+    {
+      "contents": [
+        "63 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 4
+      },
+      "object": "17 0 R",
+      "outlines": [],
+      "pageposfrom1": 15
+    },
+    {
+      "contents": [
+        "65 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 6
+      },
+      "object": "18 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "18 0 R",
+            "/XYZ",
+            66,
+            756,
+            3
+          ],
+          "object": "97 0 R",
+          "title": "Trepak 2 -> 15: /XYZ 66 756 3"
+        }
+      ],
+      "pageposfrom1": 16
+    },
+    {
+      "contents": [
+        "67 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 7
+      },
+      "object": "19 0 R",
+      "outlines": [],
+      "pageposfrom1": 17
+    },
+    {
+      "contents": [
+        "69 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 8
+      },
+      "object": "20 0 R",
+      "outlines": [],
+      "pageposfrom1": 18
+    },
+    {
+      "contents": [
+        "71 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 9
+      },
+      "object": "21 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "21 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "102 0 R",
+          "title": "Isosicle 1.1.1.1 -> 18: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 19
+    },
+    {
+      "contents": [
+        "73 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 1
+      },
+      "object": "22 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "22 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "103 0 R",
+          "title": "Isosicle 1.1.1.2 -> 19: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 20
+    },
+    {
+      "contents": [
+        "75 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 12
+      },
+      "object": "23 0 R",
+      "outlines": [],
+      "pageposfrom1": 21
+    },
+    {
+      "contents": [
+        "77 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 13
+      },
+      "object": "24 0 R",
+      "outlines": [],
+      "pageposfrom1": 22
+    },
+    {
+      "contents": [
+        "79 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 16059
+      },
+      "object": "25 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "25 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "104 0 R",
+          "title": "Isosicle 1.1.2.1 -> 22: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 23
+    },
+    {
+      "contents": [
+        "81 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 50
+      },
+      "object": "26 0 R",
+      "outlines": [],
+      "pageposfrom1": 24
+    },
+    {
+      "contents": [
+        "83 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 51
+      },
+      "object": "27 0 R",
+      "outlines": [],
+      "pageposfrom1": 25
+    },
+    {
+      "contents": [
+        "85 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 52
+      },
+      "object": "28 0 R",
+      "outlines": [],
+      "pageposfrom1": 26
+    },
+    {
+      "contents": [
+        "87 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 53
+      },
+      "object": "29 0 R",
+      "outlines": [],
+      "pageposfrom1": 27
+    },
+    {
+      "contents": [
+        "89 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 54
+      },
+      "object": "30 0 R",
+      "outlines": [],
+      "pageposfrom1": 28
+    },
+    {
+      "contents": [
+        "91 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 55
+      },
+      "object": "31 0 R",
+      "outlines": [],
+      "pageposfrom1": 29
+    },
+    {
+      "contents": [
+        "93 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 54
+      },
+      "object": "32 0 R",
+      "outlines": [],
+      "pageposfrom1": 30
+    }
+  ],
+  "parameters": {
+    "decodelevel": "generalized"
+  },
+  "version": 1
+}
diff --git a/qpdf/qtest/qpdf/json-page-labels-and-outlines-outlines.out b/qpdf/qtest/qpdf/json-page-labels-and-outlines-outlines.out
new file mode 100644
index 00000000..7b1394ad
--- /dev/null
+++ b/qpdf/qtest/qpdf/json-page-labels-and-outlines-outlines.out
@@ -0,0 +1,161 @@
+{
+  "outlines": [
+    {
+      "dest": [
+        "8 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "destpageposfrom1": 6,
+      "kids": [
+        {
+          "dest": [
+            "14 0 R",
+            "/Fit"
+          ],
+          "destpageposfrom1": 12,
+          "kids": [
+            {
+              "dest": [
+                "15 0 R",
+                "/FitV",
+                100
+              ],
+              "destpageposfrom1": 13,
+              "kids": [
+                {
+                  "dest": [
+                    "21 0 R",
+                    "/XYZ",
+                    null,
+                    null,
+                    null
+                  ],
+                  "destpageposfrom1": 19,
+                  "kids": [],
+                  "object": "102 0 R",
+                  "open": true,
+                  "title": "Isosicle 1.1.1.1 -> 18: /XYZ null null null"
+                },
+                {
+                  "dest": [
+                    "22 0 R",
+                    "/XYZ",
+                    null,
+                    null,
+                    null
+                  ],
+                  "destpageposfrom1": 20,
+                  "kids": [],
+                  "object": "103 0 R",
+                  "open": true,
+                  "title": "Isosicle 1.1.1.2 -> 19: /XYZ null null null"
+                }
+              ],
+              "object": "100 0 R",
+              "open": false,
+              "title": "Isosicle 1.1.1 -> 12: /FitV 100"
+            },
+            {
+              "dest": [
+                "15 0 R",
+                "/XYZ",
+                null,
+                null,
+                null
+              ],
+              "destpageposfrom1": 13,
+              "kids": [
+                {
+                  "dest": [
+                    "25 0 R",
+                    "/XYZ",
+                    null,
+                    null,
+                    null
+                  ],
+                  "destpageposfrom1": 23,
+                  "kids": [],
+                  "object": "104 0 R",
+                  "open": true,
+                  "title": "Isosicle 1.1.2.1 -> 22: /XYZ null null null"
+                }
+              ],
+              "object": "101 0 R",
+              "open": true,
+              "title": "Isosicle 1.1.2 -> 12: /XYZ null null null"
+            }
+          ],
+          "object": "98 0 R",
+          "open": false,
+          "title": "Amanda 1.1 -> 11: /Fit"
+        },
+        {
+          "dest": [
+            "16 0 R",
+            "/FitH",
+            792
+          ],
+          "destpageposfrom1": 14,
+          "kids": [
+            {
+              "dest": [
+                "4 0 R",
+                "/FitR",
+                66,
+                714,
+                180,
+                770
+              ],
+              "destpageposfrom1": 2,
+              "kids": [],
+              "object": "105 0 R",
+              "open": true,
+              "title": "Trepsichord 1.2.1 -> 1: /FitR 66 714 180 770"
+            },
+            {
+              "dest": [
+                "3 0 R",
+                "/XYZ",
+                null,
+                null,
+                null
+              ],
+              "destpageposfrom1": 1,
+              "kids": [],
+              "object": "106 0 R",
+              "open": true,
+              "title": "Trepsicle 1.2.2 -> 0: /XYZ null null null"
+            }
+          ],
+          "object": "99 0 R",
+          "open": true,
+          "title": "Sandy ÷Σανδι÷ 1.2 -> 13: /FitH 792"
+        }
+      ],
+      "object": "96 0 R",
+      "open": true,
+      "title": "Isís 1 -> 5: /XYZ null null null"
+    },
+    {
+      "dest": [
+        "18 0 R",
+        "/XYZ",
+        66,
+        756,
+        3
+      ],
+      "destpageposfrom1": 16,
+      "kids": [],
+      "object": "97 0 R",
+      "open": true,
+      "title": "Trepak 2 -> 15: /XYZ 66 756 3"
+    }
+  ],
+  "parameters": {
+    "decodelevel": "generalized"
+  },
+  "version": 1
+}
diff --git a/qpdf/qtest/qpdf/json-page-labels-and-outlines-pagelabels.out b/qpdf/qtest/qpdf/json-page-labels-and-outlines-pagelabels.out
new file mode 100644
index 00000000..54f3db92
--- /dev/null
+++ b/qpdf/qtest/qpdf/json-page-labels-and-outlines-pagelabels.out
@@ -0,0 +1,92 @@
+{
+  "pagelabels": [
+    {
+      "index": 0,
+      "label": {
+        "/P": "",
+        "/St": 1
+      }
+    },
+    {
+      "index": 2,
+      "label": {
+        "/S": "/r",
+        "/St": 1
+      }
+    },
+    {
+      "index": 7,
+      "label": {
+        "/P": "",
+        "/St": 1
+      }
+    },
+    {
+      "index": 9,
+      "label": {
+        "/S": "/r",
+        "/St": 6
+      }
+    },
+    {
+      "index": 11,
+      "label": {
+        "/P": "",
+        "/St": 1
+      }
+    },
+    {
+      "index": 12,
+      "label": {
+        "/S": "/D",
+        "/St": 2
+      }
+    },
+    {
+      "index": 15,
+      "label": {
+        "/S": "/D",
+        "/St": 6
+      }
+    },
+    {
+      "index": 19,
+      "label": {
+        "/P": "",
+        "/St": 1
+      }
+    },
+    {
+      "index": 20,
+      "label": {
+        "/S": "/D",
+        "/St": 12
+      }
+    },
+    {
+      "index": 22,
+      "label": {
+        "/S": "/D",
+        "/St": 16059
+      }
+    },
+    {
+      "index": 23,
+      "label": {
+        "/S": "/r",
+        "/St": 50
+      }
+    },
+    {
+      "index": 29,
+      "label": {
+        "/S": "/r",
+        "/St": 54
+      }
+    }
+  ],
+  "parameters": {
+    "decodelevel": "generalized"
+  },
+  "version": 1
+}
diff --git a/qpdf/qtest/qpdf/json-page-labels-and-outlines-pages.out b/qpdf/qtest/qpdf/json-page-labels-and-outlines-pages.out
new file mode 100644
index 00000000..b3f9dc4c
--- /dev/null
+++ b/qpdf/qtest/qpdf/json-page-labels-and-outlines-pages.out
@@ -0,0 +1,523 @@
+{
+  "pages": [
+    {
+      "contents": [
+        "33 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 1
+      },
+      "object": "3 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "3 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "106 0 R",
+          "title": "Trepsicle 1.2.2 -> 0: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 1
+    },
+    {
+      "contents": [
+        "37 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 2
+      },
+      "object": "4 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "4 0 R",
+            "/FitR",
+            66,
+            714,
+            180,
+            770
+          ],
+          "object": "105 0 R",
+          "title": "Trepsichord 1.2.1 -> 1: /FitR 66 714 180 770"
+        }
+      ],
+      "pageposfrom1": 2
+    },
+    {
+      "contents": [
+        "39 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 1
+      },
+      "object": "5 0 R",
+      "outlines": [],
+      "pageposfrom1": 3
+    },
+    {
+      "contents": [
+        "41 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 2
+      },
+      "object": "6 0 R",
+      "outlines": [],
+      "pageposfrom1": 4
+    },
+    {
+      "contents": [
+        "43 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 3
+      },
+      "object": "7 0 R",
+      "outlines": [],
+      "pageposfrom1": 5
+    },
+    {
+      "contents": [
+        "45 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 4
+      },
+      "object": "8 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "8 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "96 0 R",
+          "title": "Isís 1 -> 5: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 6
+    },
+    {
+      "contents": [
+        "47 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 5
+      },
+      "object": "9 0 R",
+      "outlines": [],
+      "pageposfrom1": 7
+    },
+    {
+      "contents": [
+        "49 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 1
+      },
+      "object": "10 0 R",
+      "outlines": [],
+      "pageposfrom1": 8
+    },
+    {
+      "contents": [
+        "51 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 2
+      },
+      "object": "11 0 R",
+      "outlines": [],
+      "pageposfrom1": 9
+    },
+    {
+      "contents": [
+        "53 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 6
+      },
+      "object": "12 0 R",
+      "outlines": [],
+      "pageposfrom1": 10
+    },
+    {
+      "contents": [
+        "55 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 7
+      },
+      "object": "13 0 R",
+      "outlines": [],
+      "pageposfrom1": 11
+    },
+    {
+      "contents": [
+        "57 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 1
+      },
+      "object": "14 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "14 0 R",
+            "/Fit"
+          ],
+          "object": "98 0 R",
+          "title": "Amanda 1.1 -> 11: /Fit"
+        }
+      ],
+      "pageposfrom1": 12
+    },
+    {
+      "contents": [
+        "59 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 2
+      },
+      "object": "15 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "15 0 R",
+            "/FitV",
+            100
+          ],
+          "object": "100 0 R",
+          "title": "Isosicle 1.1.1 -> 12: /FitV 100"
+        },
+        {
+          "dest": [
+            "15 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "101 0 R",
+          "title": "Isosicle 1.1.2 -> 12: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 13
+    },
+    {
+      "contents": [
+        "61 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 3
+      },
+      "object": "16 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "16 0 R",
+            "/FitH",
+            792
+          ],
+          "object": "99 0 R",
+          "title": "Sandy ÷Σανδι÷ 1.2 -> 13: /FitH 792"
+        }
+      ],
+      "pageposfrom1": 14
+    },
+    {
+      "contents": [
+        "63 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 4
+      },
+      "object": "17 0 R",
+      "outlines": [],
+      "pageposfrom1": 15
+    },
+    {
+      "contents": [
+        "65 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 6
+      },
+      "object": "18 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "18 0 R",
+            "/XYZ",
+            66,
+            756,
+            3
+          ],
+          "object": "97 0 R",
+          "title": "Trepak 2 -> 15: /XYZ 66 756 3"
+        }
+      ],
+      "pageposfrom1": 16
+    },
+    {
+      "contents": [
+        "67 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 7
+      },
+      "object": "19 0 R",
+      "outlines": [],
+      "pageposfrom1": 17
+    },
+    {
+      "contents": [
+        "69 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 8
+      },
+      "object": "20 0 R",
+      "outlines": [],
+      "pageposfrom1": 18
+    },
+    {
+      "contents": [
+        "71 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 9
+      },
+      "object": "21 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "21 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "102 0 R",
+          "title": "Isosicle 1.1.1.1 -> 18: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 19
+    },
+    {
+      "contents": [
+        "73 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 1
+      },
+      "object": "22 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "22 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "103 0 R",
+          "title": "Isosicle 1.1.1.2 -> 19: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 20
+    },
+    {
+      "contents": [
+        "75 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 12
+      },
+      "object": "23 0 R",
+      "outlines": [],
+      "pageposfrom1": 21
+    },
+    {
+      "contents": [
+        "77 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 13
+      },
+      "object": "24 0 R",
+      "outlines": [],
+      "pageposfrom1": 22
+    },
+    {
+      "contents": [
+        "79 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 16059
+      },
+      "object": "25 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "25 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "104 0 R",
+          "title": "Isosicle 1.1.2.1 -> 22: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 23
+    },
+    {
+      "contents": [
+        "81 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 50
+      },
+      "object": "26 0 R",
+      "outlines": [],
+      "pageposfrom1": 24
+    },
+    {
+      "contents": [
+        "83 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 51
+      },
+      "object": "27 0 R",
+      "outlines": [],
+      "pageposfrom1": 25
+    },
+    {
+      "contents": [
+        "85 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 52
+      },
+      "object": "28 0 R",
+      "outlines": [],
+      "pageposfrom1": 26
+    },
+    {
+      "contents": [
+        "87 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 53
+      },
+      "object": "29 0 R",
+      "outlines": [],
+      "pageposfrom1": 27
+    },
+    {
+      "contents": [
+        "89 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 54
+      },
+      "object": "30 0 R",
+      "outlines": [],
+      "pageposfrom1": 28
+    },
+    {
+      "contents": [
+        "91 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 55
+      },
+      "object": "31 0 R",
+      "outlines": [],
+      "pageposfrom1": 29
+    },
+    {
+      "contents": [
+        "93 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 54
+      },
+      "object": "32 0 R",
+      "outlines": [],
+      "pageposfrom1": 30
+    }
+  ],
+  "parameters": {
+    "decodelevel": "generalized"
+  },
+  "version": 1
+}
diff --git a/qpdf/qtest/qpdf/json-page-labels-and-outlines.out b/qpdf/qtest/qpdf/json-page-labels-and-outlines.out
new file mode 100644
index 00000000..a954373b
--- /dev/null
+++ b/qpdf/qtest/qpdf/json-page-labels-and-outlines.out
@@ -0,0 +1,1670 @@
+{
+  "objects": {
+    "1 0 R": {
+      "/Outlines": "95 0 R",
+      "/PageLabels": {
+        "/Nums": [
+          0,
+          {
+            "/P": ""
+          },
+          2,
+          {
+            "/S": "/r",
+            "/St": 1
+          },
+          7,
+          {
+            "/P": ""
+          },
+          9,
+          {
+            "/S": "/r",
+            "/St": 6
+          },
+          11,
+          {
+            "/P": ""
+          },
+          12,
+          {
+            "/S": "/D",
+            "/St": 2
+          },
+          15,
+          {
+            "/S": "/D",
+            "/St": 6
+          },
+          19,
+          {
+            "/P": ""
+          },
+          20,
+          {
+            "/S": "/D",
+            "/St": 12
+          },
+          22,
+          {
+            "/S": "/D",
+            "/St": 16059
+          },
+          23,
+          {
+            "/S": "/r",
+            "/St": 50
+          },
+          29,
+          {
+            "/S": "/r",
+            "/St": 54
+          }
+        ]
+      },
+      "/PageMode": "/UseOutlines",
+      "/Pages": "2 0 R",
+      "/Type": "/Catalog"
+    },
+    "10 0 R": {
+      "/Contents": "49 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "100 0 R": {
+      "/Count": -2,
+      "/Dest": [
+        "15 0 R",
+        "/FitV",
+        100
+      ],
+      "/First": "102 0 R",
+      "/Last": "103 0 R",
+      "/Next": "101 0 R",
+      "/Parent": "98 0 R",
+      "/Title": "Isosicle 1.1.1 -> 12: /FitV 100",
+      "/Type": "/Outline"
+    },
+    "101 0 R": {
+      "/Count": 1,
+      "/Dest": [
+        "15 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/First": "104 0 R",
+      "/Last": "104 0 R",
+      "/Parent": "98 0 R",
+      "/Prev": "100 0 R",
+      "/Title": "Isosicle 1.1.2 -> 12: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "102 0 R": {
+      "/Dest": [
+        "21 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/Next": "103 0 R",
+      "/Parent": "100 0 R",
+      "/Title": "Isosicle 1.1.1.1 -> 18: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "103 0 R": {
+      "/Dest": [
+        "22 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/Parent": "100 0 R",
+      "/Prev": "102 0 R",
+      "/Title": "Isosicle 1.1.1.2 -> 19: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "104 0 R": {
+      "/Dest": [
+        "25 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/Parent": "101 0 R",
+      "/Title": "Isosicle 1.1.2.1 -> 22: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "105 0 R": {
+      "/Dest": [
+        "4 0 R",
+        "/FitR",
+        66,
+        714,
+        180,
+        770
+      ],
+      "/Next": "106 0 R",
+      "/Parent": "99 0 R",
+      "/Title": "Trepsichord 1.2.1 -> 1: /FitR 66 714 180 770",
+      "/Type": "/Outline"
+    },
+    "106 0 R": {
+      "/Dest": [
+        "3 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/Parent": "99 0 R",
+      "/Prev": "105 0 R",
+      "/Title": "Trepsicle 1.2.2 -> 0: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "11 0 R": {
+      "/Contents": "51 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "12 0 R": {
+      "/Contents": "53 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "13 0 R": {
+      "/Contents": "55 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "14 0 R": {
+      "/Contents": "57 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "15 0 R": {
+      "/Contents": "59 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "16 0 R": {
+      "/Contents": "61 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "17 0 R": {
+      "/Contents": "63 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "18 0 R": {
+      "/Contents": "65 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "19 0 R": {
+      "/Contents": "67 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "2 0 R": {
+      "/Count": 30,
+      "/Kids": [
+        "3 0 R",
+        "4 0 R",
+        "5 0 R",
+        "6 0 R",
+        "7 0 R",
+        "8 0 R",
+        "9 0 R",
+        "10 0 R",
+        "11 0 R",
+        "12 0 R",
+        "13 0 R",
+        "14 0 R",
+        "15 0 R",
+        "16 0 R",
+        "17 0 R",
+        "18 0 R",
+        "19 0 R",
+        "20 0 R",
+        "21 0 R",
+        "22 0 R",
+        "23 0 R",
+        "24 0 R",
+        "25 0 R",
+        "26 0 R",
+        "27 0 R",
+        "28 0 R",
+        "29 0 R",
+        "30 0 R",
+        "31 0 R",
+        "32 0 R"
+      ],
+      "/Type": "/Pages"
+    },
+    "20 0 R": {
+      "/Contents": "69 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "21 0 R": {
+      "/Contents": "71 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "22 0 R": {
+      "/Contents": "73 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "23 0 R": {
+      "/Contents": "75 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "24 0 R": {
+      "/Contents": "77 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "25 0 R": {
+      "/Contents": "79 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "26 0 R": {
+      "/Contents": "81 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "27 0 R": {
+      "/Contents": "83 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "28 0 R": {
+      "/Contents": "85 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "29 0 R": {
+      "/Contents": "87 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "3 0 R": {
+      "/Contents": "33 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "30 0 R": {
+      "/Contents": "89 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "31 0 R": {
+      "/Contents": "91 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "32 0 R": {
+      "/Contents": "93 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "33 0 R": {
+      "/Length": "34 0 R"
+    },
+    "34 0 R": 46,
+    "35 0 R": {
+      "/BaseFont": "/Helvetica",
+      "/Encoding": "/WinAnsiEncoding",
+      "/Name": "/F1",
+      "/Subtype": "/Type1",
+      "/Type": "/Font"
+    },
+    "36 0 R": [
+      "/PDF",
+      "/Text"
+    ],
+    "37 0 R": {
+      "/Length": "38 0 R"
+    },
+    "38 0 R": 46,
+    "39 0 R": {
+      "/Length": "40 0 R"
+    },
+    "4 0 R": {
+      "/Contents": "37 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "40 0 R": 46,
+    "41 0 R": {
+      "/Length": "42 0 R"
+    },
+    "42 0 R": 46,
+    "43 0 R": {
+      "/Length": "44 0 R"
+    },
+    "44 0 R": 46,
+    "45 0 R": {
+      "/Length": "46 0 R"
+    },
+    "46 0 R": 46,
+    "47 0 R": {
+      "/Length": "48 0 R"
+    },
+    "48 0 R": 46,
+    "49 0 R": {
+      "/Length": "50 0 R"
+    },
+    "5 0 R": {
+      "/Contents": "39 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "50 0 R": 46,
+    "51 0 R": {
+      "/Length": "52 0 R"
+    },
+    "52 0 R": 46,
+    "53 0 R": {
+      "/Length": "54 0 R"
+    },
+    "54 0 R": 46,
+    "55 0 R": {
+      "/Length": "56 0 R"
+    },
+    "56 0 R": 47,
+    "57 0 R": {
+      "/Length": "58 0 R"
+    },
+    "58 0 R": 47,
+    "59 0 R": {
+      "/Length": "60 0 R"
+    },
+    "6 0 R": {
+      "/Contents": "41 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "60 0 R": 47,
+    "61 0 R": {
+      "/Length": "62 0 R"
+    },
+    "62 0 R": 47,
+    "63 0 R": {
+      "/Length": "64 0 R"
+    },
+    "64 0 R": 47,
+    "65 0 R": {
+      "/Length": "66 0 R"
+    },
+    "66 0 R": 47,
+    "67 0 R": {
+      "/Length": "68 0 R"
+    },
+    "68 0 R": 47,
+    "69 0 R": {
+      "/Length": "70 0 R"
+    },
+    "7 0 R": {
+      "/Contents": "43 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "70 0 R": 47,
+    "71 0 R": {
+      "/Length": "72 0 R"
+    },
+    "72 0 R": 47,
+    "73 0 R": {
+      "/Length": "74 0 R"
+    },
+    "74 0 R": 47,
+    "75 0 R": {
+      "/Length": "76 0 R"
+    },
+    "76 0 R": 47,
+    "77 0 R": {
+      "/Length": "78 0 R"
+    },
+    "78 0 R": 47,
+    "79 0 R": {
+      "/Length": "80 0 R"
+    },
+    "8 0 R": {
+      "/Contents": "45 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "80 0 R": 47,
+    "81 0 R": {
+      "/Length": "82 0 R"
+    },
+    "82 0 R": 47,
+    "83 0 R": {
+      "/Length": "84 0 R"
+    },
+    "84 0 R": 47,
+    "85 0 R": {
+      "/Length": "86 0 R"
+    },
+    "86 0 R": 47,
+    "87 0 R": {
+      "/Length": "88 0 R"
+    },
+    "88 0 R": 47,
+    "89 0 R": {
+      "/Length": "90 0 R"
+    },
+    "9 0 R": {
+      "/Contents": "47 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "2 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "35 0 R"
+        },
+        "/ProcSet": "36 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "90 0 R": 47,
+    "91 0 R": {
+      "/Length": "92 0 R"
+    },
+    "92 0 R": 47,
+    "93 0 R": {
+      "/Length": "94 0 R"
+    },
+    "94 0 R": 47,
+    "95 0 R": {
+      "/Count": 6,
+      "/First": "96 0 R",
+      "/Last": "97 0 R",
+      "/Type": "/Outlines"
+    },
+    "96 0 R": {
+      "/Count": 4,
+      "/Dest": [
+        "8 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "/First": "98 0 R",
+      "/Last": "99 0 R",
+      "/Next": "97 0 R",
+      "/Parent": "95 0 R",
+      "/Title": "Isís 1 -> 5: /XYZ null null null",
+      "/Type": "/Outline"
+    },
+    "97 0 R": {
+      "/Dest": [
+        "18 0 R",
+        "/XYZ",
+        66,
+        756,
+        3
+      ],
+      "/Parent": "95 0 R",
+      "/Prev": "96 0 R",
+      "/Title": "Trepak 2 -> 15: /XYZ 66 756 3",
+      "/Type": "/Outline"
+    },
+    "98 0 R": {
+      "/Count": -3,
+      "/Dest": [
+        "14 0 R",
+        "/Fit"
+      ],
+      "/First": "100 0 R",
+      "/Last": "101 0 R",
+      "/Next": "99 0 R",
+      "/Parent": "96 0 R",
+      "/Title": "Amanda 1.1 -> 11: /Fit",
+      "/Type": "/Outline"
+    },
+    "99 0 R": {
+      "/Count": 2,
+      "/Dest": [
+        "16 0 R",
+        "/FitH",
+        792
+      ],
+      "/First": "105 0 R",
+      "/Last": "106 0 R",
+      "/Parent": "96 0 R",
+      "/Prev": "98 0 R",
+      "/Title": "Sandy ÷Σανδι÷ 1.2 -> 13: /FitH 792",
+      "/Type": "/Outline"
+    },
+    "trailer": {
+      "/Root": "1 0 R",
+      "/Size": 107
+    }
+  },
+  "outlines": [
+    {
+      "dest": [
+        "8 0 R",
+        "/XYZ",
+        null,
+        null,
+        null
+      ],
+      "destpageposfrom1": 6,
+      "kids": [
+        {
+          "dest": [
+            "14 0 R",
+            "/Fit"
+          ],
+          "destpageposfrom1": 12,
+          "kids": [
+            {
+              "dest": [
+                "15 0 R",
+                "/FitV",
+                100
+              ],
+              "destpageposfrom1": 13,
+              "kids": [
+                {
+                  "dest": [
+                    "21 0 R",
+                    "/XYZ",
+                    null,
+                    null,
+                    null
+                  ],
+                  "destpageposfrom1": 19,
+                  "kids": [],
+                  "object": "102 0 R",
+                  "open": true,
+                  "title": "Isosicle 1.1.1.1 -> 18: /XYZ null null null"
+                },
+                {
+                  "dest": [
+                    "22 0 R",
+                    "/XYZ",
+                    null,
+                    null,
+                    null
+                  ],
+                  "destpageposfrom1": 20,
+                  "kids": [],
+                  "object": "103 0 R",
+                  "open": true,
+                  "title": "Isosicle 1.1.1.2 -> 19: /XYZ null null null"
+                }
+              ],
+              "object": "100 0 R",
+              "open": false,
+              "title": "Isosicle 1.1.1 -> 12: /FitV 100"
+            },
+            {
+              "dest": [
+                "15 0 R",
+                "/XYZ",
+                null,
+                null,
+                null
+              ],
+              "destpageposfrom1": 13,
+              "kids": [
+                {
+                  "dest": [
+                    "25 0 R",
+                    "/XYZ",
+                    null,
+                    null,
+                    null
+                  ],
+                  "destpageposfrom1": 23,
+                  "kids": [],
+                  "object": "104 0 R",
+                  "open": true,
+                  "title": "Isosicle 1.1.2.1 -> 22: /XYZ null null null"
+                }
+              ],
+              "object": "101 0 R",
+              "open": true,
+              "title": "Isosicle 1.1.2 -> 12: /XYZ null null null"
+            }
+          ],
+          "object": "98 0 R",
+          "open": false,
+          "title": "Amanda 1.1 -> 11: /Fit"
+        },
+        {
+          "dest": [
+            "16 0 R",
+            "/FitH",
+            792
+          ],
+          "destpageposfrom1": 14,
+          "kids": [
+            {
+              "dest": [
+                "4 0 R",
+                "/FitR",
+                66,
+                714,
+                180,
+                770
+              ],
+              "destpageposfrom1": 2,
+              "kids": [],
+              "object": "105 0 R",
+              "open": true,
+              "title": "Trepsichord 1.2.1 -> 1: /FitR 66 714 180 770"
+            },
+            {
+              "dest": [
+                "3 0 R",
+                "/XYZ",
+                null,
+                null,
+                null
+              ],
+              "destpageposfrom1": 1,
+              "kids": [],
+              "object": "106 0 R",
+              "open": true,
+              "title": "Trepsicle 1.2.2 -> 0: /XYZ null null null"
+            }
+          ],
+          "object": "99 0 R",
+          "open": true,
+          "title": "Sandy ÷Σανδι÷ 1.2 -> 13: /FitH 792"
+        }
+      ],
+      "object": "96 0 R",
+      "open": true,
+      "title": "Isís 1 -> 5: /XYZ null null null"
+    },
+    {
+      "dest": [
+        "18 0 R",
+        "/XYZ",
+        66,
+        756,
+        3
+      ],
+      "destpageposfrom1": 16,
+      "kids": [],
+      "object": "97 0 R",
+      "open": true,
+      "title": "Trepak 2 -> 15: /XYZ 66 756 3"
+    }
+  ],
+  "pagelabels": [
+    {
+      "index": 0,
+      "label": {
+        "/P": "",
+        "/St": 1
+      }
+    },
+    {
+      "index": 2,
+      "label": {
+        "/S": "/r",
+        "/St": 1
+      }
+    },
+    {
+      "index": 7,
+      "label": {
+        "/P": "",
+        "/St": 1
+      }
+    },
+    {
+      "index": 9,
+      "label": {
+        "/S": "/r",
+        "/St": 6
+      }
+    },
+    {
+      "index": 11,
+      "label": {
+        "/P": "",
+        "/St": 1
+      }
+    },
+    {
+      "index": 12,
+      "label": {
+        "/S": "/D",
+        "/St": 2
+      }
+    },
+    {
+      "index": 15,
+      "label": {
+        "/S": "/D",
+        "/St": 6
+      }
+    },
+    {
+      "index": 19,
+      "label": {
+        "/P": "",
+        "/St": 1
+      }
+    },
+    {
+      "index": 20,
+      "label": {
+        "/S": "/D",
+        "/St": 12
+      }
+    },
+    {
+      "index": 22,
+      "label": {
+        "/S": "/D",
+        "/St": 16059
+      }
+    },
+    {
+      "index": 23,
+      "label": {
+        "/S": "/r",
+        "/St": 50
+      }
+    },
+    {
+      "index": 29,
+      "label": {
+        "/S": "/r",
+        "/St": 54
+      }
+    }
+  ],
+  "pages": [
+    {
+      "contents": [
+        "33 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 1
+      },
+      "object": "3 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "3 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "106 0 R",
+          "title": "Trepsicle 1.2.2 -> 0: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 1
+    },
+    {
+      "contents": [
+        "37 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 2
+      },
+      "object": "4 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "4 0 R",
+            "/FitR",
+            66,
+            714,
+            180,
+            770
+          ],
+          "object": "105 0 R",
+          "title": "Trepsichord 1.2.1 -> 1: /FitR 66 714 180 770"
+        }
+      ],
+      "pageposfrom1": 2
+    },
+    {
+      "contents": [
+        "39 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 1
+      },
+      "object": "5 0 R",
+      "outlines": [],
+      "pageposfrom1": 3
+    },
+    {
+      "contents": [
+        "41 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 2
+      },
+      "object": "6 0 R",
+      "outlines": [],
+      "pageposfrom1": 4
+    },
+    {
+      "contents": [
+        "43 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 3
+      },
+      "object": "7 0 R",
+      "outlines": [],
+      "pageposfrom1": 5
+    },
+    {
+      "contents": [
+        "45 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 4
+      },
+      "object": "8 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "8 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "96 0 R",
+          "title": "Isís 1 -> 5: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 6
+    },
+    {
+      "contents": [
+        "47 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 5
+      },
+      "object": "9 0 R",
+      "outlines": [],
+      "pageposfrom1": 7
+    },
+    {
+      "contents": [
+        "49 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 1
+      },
+      "object": "10 0 R",
+      "outlines": [],
+      "pageposfrom1": 8
+    },
+    {
+      "contents": [
+        "51 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 2
+      },
+      "object": "11 0 R",
+      "outlines": [],
+      "pageposfrom1": 9
+    },
+    {
+      "contents": [
+        "53 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 6
+      },
+      "object": "12 0 R",
+      "outlines": [],
+      "pageposfrom1": 10
+    },
+    {
+      "contents": [
+        "55 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 7
+      },
+      "object": "13 0 R",
+      "outlines": [],
+      "pageposfrom1": 11
+    },
+    {
+      "contents": [
+        "57 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 1
+      },
+      "object": "14 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "14 0 R",
+            "/Fit"
+          ],
+          "object": "98 0 R",
+          "title": "Amanda 1.1 -> 11: /Fit"
+        }
+      ],
+      "pageposfrom1": 12
+    },
+    {
+      "contents": [
+        "59 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 2
+      },
+      "object": "15 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "15 0 R",
+            "/FitV",
+            100
+          ],
+          "object": "100 0 R",
+          "title": "Isosicle 1.1.1 -> 12: /FitV 100"
+        },
+        {
+          "dest": [
+            "15 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "101 0 R",
+          "title": "Isosicle 1.1.2 -> 12: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 13
+    },
+    {
+      "contents": [
+        "61 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 3
+      },
+      "object": "16 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "16 0 R",
+            "/FitH",
+            792
+          ],
+          "object": "99 0 R",
+          "title": "Sandy ÷Σανδι÷ 1.2 -> 13: /FitH 792"
+        }
+      ],
+      "pageposfrom1": 14
+    },
+    {
+      "contents": [
+        "63 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 4
+      },
+      "object": "17 0 R",
+      "outlines": [],
+      "pageposfrom1": 15
+    },
+    {
+      "contents": [
+        "65 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 6
+      },
+      "object": "18 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "18 0 R",
+            "/XYZ",
+            66,
+            756,
+            3
+          ],
+          "object": "97 0 R",
+          "title": "Trepak 2 -> 15: /XYZ 66 756 3"
+        }
+      ],
+      "pageposfrom1": 16
+    },
+    {
+      "contents": [
+        "67 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 7
+      },
+      "object": "19 0 R",
+      "outlines": [],
+      "pageposfrom1": 17
+    },
+    {
+      "contents": [
+        "69 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 8
+      },
+      "object": "20 0 R",
+      "outlines": [],
+      "pageposfrom1": 18
+    },
+    {
+      "contents": [
+        "71 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 9
+      },
+      "object": "21 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "21 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "102 0 R",
+          "title": "Isosicle 1.1.1.1 -> 18: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 19
+    },
+    {
+      "contents": [
+        "73 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 1
+      },
+      "object": "22 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "22 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "103 0 R",
+          "title": "Isosicle 1.1.1.2 -> 19: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 20
+    },
+    {
+      "contents": [
+        "75 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 12
+      },
+      "object": "23 0 R",
+      "outlines": [],
+      "pageposfrom1": 21
+    },
+    {
+      "contents": [
+        "77 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 13
+      },
+      "object": "24 0 R",
+      "outlines": [],
+      "pageposfrom1": 22
+    },
+    {
+      "contents": [
+        "79 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 16059
+      },
+      "object": "25 0 R",
+      "outlines": [
+        {
+          "dest": [
+            "25 0 R",
+            "/XYZ",
+            null,
+            null,
+            null
+          ],
+          "object": "104 0 R",
+          "title": "Isosicle 1.1.2.1 -> 22: /XYZ null null null"
+        }
+      ],
+      "pageposfrom1": 23
+    },
+    {
+      "contents": [
+        "81 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 50
+      },
+      "object": "26 0 R",
+      "outlines": [],
+      "pageposfrom1": 24
+    },
+    {
+      "contents": [
+        "83 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 51
+      },
+      "object": "27 0 R",
+      "outlines": [],
+      "pageposfrom1": 25
+    },
+    {
+      "contents": [
+        "85 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 52
+      },
+      "object": "28 0 R",
+      "outlines": [],
+      "pageposfrom1": 26
+    },
+    {
+      "contents": [
+        "87 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 53
+      },
+      "object": "29 0 R",
+      "outlines": [],
+      "pageposfrom1": 27
+    },
+    {
+      "contents": [
+        "89 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 54
+      },
+      "object": "30 0 R",
+      "outlines": [],
+      "pageposfrom1": 28
+    },
+    {
+      "contents": [
+        "91 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 55
+      },
+      "object": "31 0 R",
+      "outlines": [],
+      "pageposfrom1": 29
+    },
+    {
+      "contents": [
+        "93 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 54
+      },
+      "object": "32 0 R",
+      "outlines": [],
+      "pageposfrom1": 30
+    }
+  ],
+  "parameters": {
+    "decodelevel": "generalized"
+  },
+  "version": 1
+}
diff --git a/qpdf/qtest/qpdf/json-page-labels-num-tree.out b/qpdf/qtest/qpdf/json-page-labels-num-tree.out
new file mode 100644
index 00000000..673accd3
--- /dev/null
+++ b/qpdf/qtest/qpdf/json-page-labels-num-tree.out
@@ -0,0 +1,1305 @@
+{
+  "objects": {
+    "1 0 R": {
+      "/PageLabels": "2 0 R",
+      "/Pages": "3 0 R",
+      "/Type": "/Catalog"
+    },
+    "10 0 R": {
+      "/Contents": "48 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "11 0 R": {
+      "/Contents": "50 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "12 0 R": {
+      "/Contents": "52 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "13 0 R": {
+      "/Contents": "54 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "14 0 R": {
+      "/Contents": "56 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "15 0 R": {
+      "/Contents": "58 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "16 0 R": {
+      "/Contents": "60 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "17 0 R": {
+      "/Contents": "62 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "18 0 R": {
+      "/Contents": "64 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "19 0 R": {
+      "/Contents": "66 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "2 0 R": {
+      "/Kids": [
+        "4 0 R",
+        "5 0 R"
+      ]
+    },
+    "20 0 R": {
+      "/Contents": "68 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "21 0 R": {
+      "/Contents": "70 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "22 0 R": {
+      "/Contents": "72 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "23 0 R": {
+      "/Contents": "74 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "24 0 R": {
+      "/Contents": "76 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "25 0 R": {
+      "/Contents": "78 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "26 0 R": {
+      "/Contents": "80 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "27 0 R": {
+      "/Contents": "82 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "28 0 R": {
+      "/Contents": "84 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "29 0 R": {
+      "/Contents": "86 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "3 0 R": {
+      "/Count": 30,
+      "/Kids": [
+        "6 0 R",
+        "7 0 R",
+        "8 0 R",
+        "9 0 R",
+        "10 0 R",
+        "11 0 R",
+        "12 0 R",
+        "13 0 R",
+        "14 0 R",
+        "15 0 R",
+        "16 0 R",
+        "17 0 R",
+        "18 0 R",
+        "19 0 R",
+        "20 0 R",
+        "21 0 R",
+        "22 0 R",
+        "23 0 R",
+        "24 0 R",
+        "25 0 R",
+        "26 0 R",
+        "27 0 R",
+        "28 0 R",
+        "29 0 R",
+        "30 0 R",
+        "31 0 R",
+        "32 0 R",
+        "33 0 R",
+        "34 0 R",
+        "35 0 R"
+      ],
+      "/Type": "/Pages"
+    },
+    "30 0 R": {
+      "/Contents": "88 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "31 0 R": {
+      "/Contents": "90 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "32 0 R": {
+      "/Contents": "92 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "33 0 R": {
+      "/Contents": "94 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "34 0 R": {
+      "/Contents": "96 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "35 0 R": {
+      "/Contents": "98 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "36 0 R": {
+      "/Limits": [
+        0,
+        9
+      ],
+      "/Nums": [
+        0,
+        {
+          "/S": "/r"
+        },
+        2,
+        {
+          "/P": "blank"
+        },
+        3,
+        {
+          "/P": "X-",
+          "/S": "/A",
+          "/St": 17
+        },
+        5,
+        {
+          "/P": ""
+        },
+        6,
+        {
+          "/S": "/R",
+          "/St": 3
+        },
+        9,
+        {
+          "/S": "/D"
+        }
+      ]
+    },
+    "37 0 R": {
+      "/Limits": [
+        11,
+        19
+      ],
+      "/Nums": [
+        11,
+        {
+          "/S": "/a"
+        },
+        12,
+        {
+          "/S": "/a",
+          "/St": 3
+        },
+        15,
+        {
+          "/P": "q.",
+          "/S": "/D",
+          "/St": 6
+        },
+        19,
+        {
+          "/P": "www"
+        }
+      ]
+    },
+    "38 0 R": {
+      "/Length": "39 0 R"
+    },
+    "39 0 R": 46,
+    "4 0 R": {
+      "/Kids": [
+        "36 0 R",
+        "37 0 R"
+      ],
+      "/Limits": [
+        0,
+        19
+      ]
+    },
+    "40 0 R": {
+      "/BaseFont": "/Helvetica",
+      "/Encoding": "/WinAnsiEncoding",
+      "/Name": "/F1",
+      "/Subtype": "/Type1",
+      "/Type": "/Font"
+    },
+    "41 0 R": [
+      "/PDF",
+      "/Text"
+    ],
+    "42 0 R": {
+      "/Length": "43 0 R"
+    },
+    "43 0 R": 46,
+    "44 0 R": {
+      "/Length": "45 0 R"
+    },
+    "45 0 R": 46,
+    "46 0 R": {
+      "/Length": "47 0 R"
+    },
+    "47 0 R": 46,
+    "48 0 R": {
+      "/Length": "49 0 R"
+    },
+    "49 0 R": 46,
+    "5 0 R": {
+      "/Limits": [
+        20,
+        29
+      ],
+      "/Nums": [
+        20,
+        {
+          "/S": "/D",
+          "/St": 12
+        },
+        22,
+        {
+          "/S": "/D",
+          "/St": 16059
+        },
+        23,
+        {
+          "/S": "/R",
+          "/St": 50
+        },
+        29,
+        {
+          "/S": "/r",
+          "/St": 54
+        }
+      ]
+    },
+    "50 0 R": {
+      "/Length": "51 0 R"
+    },
+    "51 0 R": 46,
+    "52 0 R": {
+      "/Length": "53 0 R"
+    },
+    "53 0 R": 46,
+    "54 0 R": {
+      "/Length": "55 0 R"
+    },
+    "55 0 R": 46,
+    "56 0 R": {
+      "/Length": "57 0 R"
+    },
+    "57 0 R": 46,
+    "58 0 R": {
+      "/Length": "59 0 R"
+    },
+    "59 0 R": 46,
+    "6 0 R": {
+      "/Contents": "38 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "60 0 R": {
+      "/Length": "61 0 R"
+    },
+    "61 0 R": 47,
+    "62 0 R": {
+      "/Length": "63 0 R"
+    },
+    "63 0 R": 47,
+    "64 0 R": {
+      "/Length": "65 0 R"
+    },
+    "65 0 R": 47,
+    "66 0 R": {
+      "/Length": "67 0 R"
+    },
+    "67 0 R": 47,
+    "68 0 R": {
+      "/Length": "69 0 R"
+    },
+    "69 0 R": 47,
+    "7 0 R": {
+      "/Contents": "42 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "70 0 R": {
+      "/Length": "71 0 R"
+    },
+    "71 0 R": 47,
+    "72 0 R": {
+      "/Length": "73 0 R"
+    },
+    "73 0 R": 47,
+    "74 0 R": {
+      "/Length": "75 0 R"
+    },
+    "75 0 R": 47,
+    "76 0 R": {
+      "/Length": "77 0 R"
+    },
+    "77 0 R": 47,
+    "78 0 R": {
+      "/Length": "79 0 R"
+    },
+    "79 0 R": 47,
+    "8 0 R": {
+      "/Contents": "44 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "80 0 R": {
+      "/Length": "81 0 R"
+    },
+    "81 0 R": 47,
+    "82 0 R": {
+      "/Length": "83 0 R"
+    },
+    "83 0 R": 47,
+    "84 0 R": {
+      "/Length": "85 0 R"
+    },
+    "85 0 R": 47,
+    "86 0 R": {
+      "/Length": "87 0 R"
+    },
+    "87 0 R": 47,
+    "88 0 R": {
+      "/Length": "89 0 R"
+    },
+    "89 0 R": 47,
+    "9 0 R": {
+      "/Contents": "46 0 R",
+      "/MediaBox": [
+        0,
+        0,
+        612,
+        792
+      ],
+      "/Parent": "3 0 R",
+      "/Resources": {
+        "/Font": {
+          "/F1": "40 0 R"
+        },
+        "/ProcSet": "41 0 R"
+      },
+      "/Type": "/Page"
+    },
+    "90 0 R": {
+      "/Length": "91 0 R"
+    },
+    "91 0 R": 47,
+    "92 0 R": {
+      "/Length": "93 0 R"
+    },
+    "93 0 R": 47,
+    "94 0 R": {
+      "/Length": "95 0 R"
+    },
+    "95 0 R": 47,
+    "96 0 R": {
+      "/Length": "97 0 R"
+    },
+    "97 0 R": 47,
+    "98 0 R": {
+      "/Length": "99 0 R"
+    },
+    "99 0 R": 47,
+    "trailer": {
+      "/ID": [
+        "’ù\u0019Þxtó¼\\·¯½\u001eŁ7»",
+        "\rþ\u0018©LÞ\u000fKýÈl\u0003¯\u0019\u0001\u000e"
+      ],
+      "/Root": "1 0 R",
+      "/Size": 100
+    }
+  },
+  "outlines": [],
+  "pagelabels": [
+    {
+      "index": 0,
+      "label": {
+        "/S": "/r",
+        "/St": 1
+      }
+    },
+    {
+      "index": 2,
+      "label": {
+        "/P": "blank",
+        "/St": 1
+      }
+    },
+    {
+      "index": 3,
+      "label": {
+        "/P": "X-",
+        "/S": "/A",
+        "/St": 17
+      }
+    },
+    {
+      "index": 5,
+      "label": {
+        "/P": "",
+        "/St": 1
+      }
+    },
+    {
+      "index": 6,
+      "label": {
+        "/S": "/R",
+        "/St": 3
+      }
+    },
+    {
+      "index": 9,
+      "label": {
+        "/S": "/D",
+        "/St": 1
+      }
+    },
+    {
+      "index": 11,
+      "label": {
+        "/S": "/a",
+        "/St": 1
+      }
+    },
+    {
+      "index": 12,
+      "label": {
+        "/S": "/a",
+        "/St": 3
+      }
+    },
+    {
+      "index": 15,
+      "label": {
+        "/P": "q.",
+        "/S": "/D",
+        "/St": 6
+      }
+    },
+    {
+      "index": 19,
+      "label": {
+        "/P": "www",
+        "/St": 1
+      }
+    },
+    {
+      "index": 20,
+      "label": {
+        "/S": "/D",
+        "/St": 12
+      }
+    },
+    {
+      "index": 22,
+      "label": {
+        "/S": "/D",
+        "/St": 16059
+      }
+    },
+    {
+      "index": 23,
+      "label": {
+        "/S": "/R",
+        "/St": 50
+      }
+    },
+    {
+      "index": 29,
+      "label": {
+        "/S": "/r",
+        "/St": 54
+      }
+    }
+  ],
+  "pages": [
+    {
+      "contents": [
+        "38 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 1
+      },
+      "object": "6 0 R",
+      "outlines": [],
+      "pageposfrom1": 1
+    },
+    {
+      "contents": [
+        "42 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 2
+      },
+      "object": "7 0 R",
+      "outlines": [],
+      "pageposfrom1": 2
+    },
+    {
+      "contents": [
+        "44 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "blank",
+        "/St": 1
+      },
+      "object": "8 0 R",
+      "outlines": [],
+      "pageposfrom1": 3
+    },
+    {
+      "contents": [
+        "46 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "X-",
+        "/S": "/A",
+        "/St": 17
+      },
+      "object": "9 0 R",
+      "outlines": [],
+      "pageposfrom1": 4
+    },
+    {
+      "contents": [
+        "48 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "X-",
+        "/S": "/A",
+        "/St": 18
+      },
+      "object": "10 0 R",
+      "outlines": [],
+      "pageposfrom1": 5
+    },
+    {
+      "contents": [
+        "50 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "",
+        "/St": 1
+      },
+      "object": "11 0 R",
+      "outlines": [],
+      "pageposfrom1": 6
+    },
+    {
+      "contents": [
+        "52 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 3
+      },
+      "object": "12 0 R",
+      "outlines": [],
+      "pageposfrom1": 7
+    },
+    {
+      "contents": [
+        "54 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 4
+      },
+      "object": "13 0 R",
+      "outlines": [],
+      "pageposfrom1": 8
+    },
+    {
+      "contents": [
+        "56 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 5
+      },
+      "object": "14 0 R",
+      "outlines": [],
+      "pageposfrom1": 9
+    },
+    {
+      "contents": [
+        "58 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 1
+      },
+      "object": "15 0 R",
+      "outlines": [],
+      "pageposfrom1": 10
+    },
+    {
+      "contents": [
+        "60 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 2
+      },
+      "object": "16 0 R",
+      "outlines": [],
+      "pageposfrom1": 11
+    },
+    {
+      "contents": [
+        "62 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/a",
+        "/St": 1
+      },
+      "object": "17 0 R",
+      "outlines": [],
+      "pageposfrom1": 12
+    },
+    {
+      "contents": [
+        "64 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/a",
+        "/St": 3
+      },
+      "object": "18 0 R",
+      "outlines": [],
+      "pageposfrom1": 13
+    },
+    {
+      "contents": [
+        "66 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/a",
+        "/St": 4
+      },
+      "object": "19 0 R",
+      "outlines": [],
+      "pageposfrom1": 14
+    },
+    {
+      "contents": [
+        "68 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/a",
+        "/St": 5
+      },
+      "object": "20 0 R",
+      "outlines": [],
+      "pageposfrom1": 15
+    },
+    {
+      "contents": [
+        "70 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "q.",
+        "/S": "/D",
+        "/St": 6
+      },
+      "object": "21 0 R",
+      "outlines": [],
+      "pageposfrom1": 16
+    },
+    {
+      "contents": [
+        "72 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "q.",
+        "/S": "/D",
+        "/St": 7
+      },
+      "object": "22 0 R",
+      "outlines": [],
+      "pageposfrom1": 17
+    },
+    {
+      "contents": [
+        "74 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "q.",
+        "/S": "/D",
+        "/St": 8
+      },
+      "object": "23 0 R",
+      "outlines": [],
+      "pageposfrom1": 18
+    },
+    {
+      "contents": [
+        "76 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "q.",
+        "/S": "/D",
+        "/St": 9
+      },
+      "object": "24 0 R",
+      "outlines": [],
+      "pageposfrom1": 19
+    },
+    {
+      "contents": [
+        "78 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/P": "www",
+        "/St": 1
+      },
+      "object": "25 0 R",
+      "outlines": [],
+      "pageposfrom1": 20
+    },
+    {
+      "contents": [
+        "80 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 12
+      },
+      "object": "26 0 R",
+      "outlines": [],
+      "pageposfrom1": 21
+    },
+    {
+      "contents": [
+        "82 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 13
+      },
+      "object": "27 0 R",
+      "outlines": [],
+      "pageposfrom1": 22
+    },
+    {
+      "contents": [
+        "84 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/D",
+        "/St": 16059
+      },
+      "object": "28 0 R",
+      "outlines": [],
+      "pageposfrom1": 23
+    },
+    {
+      "contents": [
+        "86 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 50
+      },
+      "object": "29 0 R",
+      "outlines": [],
+      "pageposfrom1": 24
+    },
+    {
+      "contents": [
+        "88 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 51
+      },
+      "object": "30 0 R",
+      "outlines": [],
+      "pageposfrom1": 25
+    },
+    {
+      "contents": [
+        "90 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 52
+      },
+      "object": "31 0 R",
+      "outlines": [],
+      "pageposfrom1": 26
+    },
+    {
+      "contents": [
+        "92 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 53
+      },
+      "object": "32 0 R",
+      "outlines": [],
+      "pageposfrom1": 27
+    },
+    {
+      "contents": [
+        "94 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 54
+      },
+      "object": "33 0 R",
+      "outlines": [],
+      "pageposfrom1": 28
+    },
+    {
+      "contents": [
+        "96 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/R",
+        "/St": 55
+      },
+      "object": "34 0 R",
+      "outlines": [],
+      "pageposfrom1": 29
+    },
+    {
+      "contents": [
+        "98 0 R"
+      ],
+      "images": [],
+      "label": {
+        "/S": "/r",
+        "/St": 54
+      },
+      "object": "35 0 R",
+      "outlines": [],
+      "pageposfrom1": 30
+    }
+  ],
+  "parameters": {
+    "decodelevel": "generalized"
+  },
+  "version": 1
+}