summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/qpdf/Buffer.hh8
-rw-r--r--include/qpdf/BufferInputSource.hh8
-rw-r--r--include/qpdf/ClosedFileInputSource.hh16
-rw-r--r--include/qpdf/Constants.h72
-rw-r--r--include/qpdf/DLL.h8
-rw-r--r--include/qpdf/FileInputSource.hh8
-rw-r--r--include/qpdf/InputSource.hh8
-rw-r--r--include/qpdf/JSON.hh170
-rw-r--r--include/qpdf/Pipeline.hh8
-rw-r--r--include/qpdf/Pl_Buffer.hh8
-rw-r--r--include/qpdf/Pl_Concatenate.hh8
-rw-r--r--include/qpdf/Pl_Count.hh8
-rw-r--r--include/qpdf/Pl_DCT.hh8
-rw-r--r--include/qpdf/Pl_Discard.hh8
-rw-r--r--include/qpdf/Pl_Flate.hh8
-rw-r--r--include/qpdf/Pl_QPDFTokenizer.hh21
-rw-r--r--include/qpdf/Pl_RunLength.hh8
-rw-r--r--include/qpdf/Pl_StdioFile.hh8
-rw-r--r--include/qpdf/PointerHolder.hh8
-rw-r--r--include/qpdf/QPDF.hh254
-rw-r--r--include/qpdf/QPDFAcroFormDocumentHelper.hh22
-rw-r--r--include/qpdf/QPDFAnnotationObjectHelper.hh39
-rw-r--r--include/qpdf/QPDFDocumentHelper.hh8
-rw-r--r--include/qpdf/QPDFExc.hh12
-rw-r--r--include/qpdf/QPDFFormFieldObjectHelper.hh75
-rw-r--r--include/qpdf/QPDFNameTreeObjectHelper.hh83
-rw-r--r--include/qpdf/QPDFNumberTreeObjectHelper.hh114
-rw-r--r--include/qpdf/QPDFObjGen.hh8
-rw-r--r--include/qpdf/QPDFObject.hh11
-rw-r--r--include/qpdf/QPDFObjectHandle.hh131
-rw-r--r--include/qpdf/QPDFObjectHelper.hh8
-rw-r--r--include/qpdf/QPDFOutlineDocumentHelper.hh108
-rw-r--r--include/qpdf/QPDFOutlineObjectHelper.hh122
-rw-r--r--include/qpdf/QPDFPageDocumentHelper.hh45
-rw-r--r--include/qpdf/QPDFPageLabelDocumentHelper.hh104
-rw-r--r--include/qpdf/QPDFPageObjectHelper.hh114
-rw-r--r--include/qpdf/QPDFSystemError.hh58
-rw-r--r--include/qpdf/QPDFTokenizer.hh35
-rw-r--r--include/qpdf/QPDFWriter.hh71
-rw-r--r--include/qpdf/QPDFXRefEntry.hh8
-rw-r--r--include/qpdf/QTC.hh8
-rw-r--r--include/qpdf/QUtil.hh118
-rw-r--r--include/qpdf/RandomDataProvider.hh8
-rw-r--r--include/qpdf/Types.h8
-rw-r--r--include/qpdf/qpdf-c.h42
45 files changed, 1772 insertions, 241 deletions
diff --git a/include/qpdf/Buffer.hh b/include/qpdf/Buffer.hh
index c8b101fa..bb9a3eb9 100644
--- a/include/qpdf/Buffer.hh
+++ b/include/qpdf/Buffer.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __BUFFER_HH__
-#define __BUFFER_HH__
+#ifndef BUFFER_HH
+#define BUFFER_HH
#include <qpdf/DLL.h>
#include <cstring> // for size_t
@@ -64,4 +64,4 @@ class Buffer
unsigned char* buf;
};
-#endif // __BUFFER_HH__
+#endif // BUFFER_HH
diff --git a/include/qpdf/BufferInputSource.hh b/include/qpdf/BufferInputSource.hh
index 954ffe36..3fb0625b 100644
--- a/include/qpdf/BufferInputSource.hh
+++ b/include/qpdf/BufferInputSource.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDF_BUFFERINPUTSOURCE_HH__
-#define __QPDF_BUFFERINPUTSOURCE_HH__
+#ifndef QPDF_BUFFERINPUTSOURCE_HH
+#define QPDF_BUFFERINPUTSOURCE_HH
#include <qpdf/InputSource.hh>
#include <qpdf/Buffer.hh>
@@ -60,4 +60,4 @@ class BufferInputSource: public InputSource
qpdf_offset_t cur_offset;
};
-#endif // __QPDF_BUFFERINPUTSOURCE_HH__
+#endif // QPDF_BUFFERINPUTSOURCE_HH
diff --git a/include/qpdf/ClosedFileInputSource.hh b/include/qpdf/ClosedFileInputSource.hh
index 1e3ff82f..ee8557fc 100644
--- a/include/qpdf/ClosedFileInputSource.hh
+++ b/include/qpdf/ClosedFileInputSource.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDF_CLOSEDFILEINPUTSOURCE_HH__
-#define __QPDF_CLOSEDFILEINPUTSOURCE_HH__
+#ifndef QPDF_CLOSEDFILEINPUTSOURCE_HH
+#define QPDF_CLOSEDFILEINPUTSOURCE_HH
// This is an input source that reads from files, like
// FileInputSource, except that it opens and close the file
@@ -55,6 +55,13 @@ class ClosedFileInputSource: public InputSource
QPDF_DLL
virtual void unreadCh(char ch);
+ // The file stays open between calls to stayOpen(true) and
+ // stayOpen(false). You can use this to surround multiple
+ // operations on a single ClosedFileInputSource to reduce the
+ // overhead of a separate open/close on each call.
+ QPDF_DLL
+ void stayOpen(bool);
+
private:
ClosedFileInputSource(ClosedFileInputSource const&);
ClosedFileInputSource& operator=(ClosedFileInputSource const&);
@@ -76,8 +83,9 @@ class ClosedFileInputSource: public InputSource
std::string filename;
qpdf_offset_t offset;
FileInputSource* fis;
+ bool stay_open;
};
PointerHolder<Members> m;
};
-#endif // __QPDF_CLOSEDFILEINPUTSOURCE_HH__
+#endif // QPDF_CLOSEDFILEINPUTSOURCE_HH
diff --git a/include/qpdf/Constants.h b/include/qpdf/Constants.h
index 0191a411..1428216c 100644
--- a/include/qpdf/Constants.h
+++ b/include/qpdf/Constants.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005-2018 Jay Berkenbilt
+/* Copyright (c) 2005-2019 Jay Berkenbilt
*
* This file is part of qpdf.
*
@@ -20,8 +20,8 @@
* see the manual for additional information.
*/
-#ifndef __QPDFCONSTANTS_H__
-#define __QPDFCONSTANTS_H__
+#ifndef QPDFCONSTANTS_H
+#define QPDFCONSTANTS_H
/* Keep this file 'C' compatible so it can be used from the C and C++
* interfaces.
@@ -80,13 +80,67 @@ enum qpdf_r3_print_e
qpdf_r3p_low, /* allow only low-resolution printing */
qpdf_r3p_none /* allow no printing */
};
+
+/* qpdf_r3_modify_e doesn't allow the full flexibility of the spec. It
+ * corresponds to options in Acrobat 5's menus. The new interface in
+ * QPDFWriter offers more granularity and no longer uses this type.
+ */
enum qpdf_r3_modify_e /* Allowed changes: */
{
- qpdf_r3m_all = 0, /* General editing, comments, forms */
- qpdf_r3m_annotate, /* Comments, form field fill-in, and signing */
- qpdf_r3m_form, /* form field fill-in and signing */
- qpdf_r3m_assembly, /* only document assembly */
- qpdf_r3m_none /* no modifications */
+ qpdf_r3m_all = 0, /* All editing */
+ qpdf_r3m_annotate, /* Comments, fill forms, signing, assembly */
+ qpdf_r3m_form, /* Fill forms, signing, assembly */
+ qpdf_r3m_assembly, /* Only document assembly */
+ qpdf_r3m_none /* No modifications */
+};
+
+/* Form field flags from the PDF spec */
+
+enum pdf_form_field_flag_e
+{
+ /* flags that apply to all form fields */
+ ff_all_read_only = 1 << 0,
+ ff_all_required = 1 << 1,
+ ff_all_no_export = 1 << 2,
+
+ /* flags that apply to fields of type /Btn (button) */
+ ff_btn_no_toggle_off = 1 << 14,
+ ff_btn_radio = 1 << 15,
+ ff_btn_pushbutton = 1 << 16,
+ ff_btn_radios_in_unison = 1 << 17,
+
+ /* flags that apply to fields of type /Tx (text) */
+ ff_tx_multiline = 1 << 12,
+ ff_tx_password = 1 << 13,
+ ff_tx_file_select = 1 << 20,
+ ff_tx_do_not_spell_check = 1 << 22,
+ ff_tx_do_not_scroll = 1 << 23,
+ ff_tx_comb = 1 << 24,
+ ff_tx_rich_text = 1 << 25,
+
+ /* flags that apply to fields of type /Ch (choice) */
+ ff_ch_combo = 1 << 17,
+ ff_ch_edit = 1 << 18,
+ ff_ch_sort = 1 << 19,
+ ff_ch_multi_select = 1 << 21,
+ ff_ch_do_not_spell_check = 1 << 22,
+ ff_ch_commit_on_sel_change = 1 << 26
+};
+
+/* Annotation flags from the PDF spec */
+
+enum pdf_annotation_flag_e
+{
+ an_invisible = 1 << 0,
+ an_hidden = 1 << 1,
+ an_print = 1 << 2,
+ an_no_zoom = 1 << 3,
+ an_no_rotate = 1 << 4,
+ an_no_view = 1 << 5,
+ an_read_only = 1 << 6,
+ an_locked = 1 << 7,
+ an_toggle_no_view = 1 << 8,
+ an_locked_contents = 1 << 9
};
-#endif /* __QPDFCONSTANTS_H__ */
+#endif /* QPDFCONSTANTS_H */
diff --git a/include/qpdf/DLL.h b/include/qpdf/DLL.h
index a5f72f6a..ccd05fce 100644
--- a/include/qpdf/DLL.h
+++ b/include/qpdf/DLL.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005-2018 Jay Berkenbilt
+/* Copyright (c) 2005-2019 Jay Berkenbilt
*
* This file is part of qpdf.
*
@@ -20,8 +20,8 @@
* see the manual for additional information.
*/
-#ifndef __QPDF_DLL_HH__
-#define __QPDF_DLL_HH__
+#ifndef QPDF_DLL_HH
+#define QPDF_DLL_HH
#if defined(_WIN32) && defined(DLL_EXPORT)
# define QPDF_DLL __declspec(dllexport)
@@ -29,4 +29,4 @@
# define QPDF_DLL
#endif
-#endif /* __QPDF_DLL_HH__ */
+#endif /* QPDF_DLL_HH */
diff --git a/include/qpdf/FileInputSource.hh b/include/qpdf/FileInputSource.hh
index 4bc51262..0845f241 100644
--- a/include/qpdf/FileInputSource.hh
+++ b/include/qpdf/FileInputSource.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDF_FILEINPUTSOURCE_HH__
-#define __QPDF_FILEINPUTSOURCE_HH__
+#ifndef QPDF_FILEINPUTSOURCE_HH
+#define QPDF_FILEINPUTSOURCE_HH
#include <qpdf/InputSource.hh>
@@ -61,4 +61,4 @@ class FileInputSource: public InputSource
FILE* file;
};
-#endif // __QPDF_FILEINPUTSOURCE_HH__
+#endif // QPDF_FILEINPUTSOURCE_HH
diff --git a/include/qpdf/InputSource.hh b/include/qpdf/InputSource.hh
index 2fd95977..8465ad55 100644
--- a/include/qpdf/InputSource.hh
+++ b/include/qpdf/InputSource.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDF_INPUTSOURCE_HH__
-#define __QPDF_INPUTSOURCE_HH__
+#ifndef QPDF_INPUTSOURCE_HH
+#define QPDF_INPUTSOURCE_HH
#include <qpdf/DLL.h>
#include <qpdf/Types.h>
@@ -88,4 +88,4 @@ class InputSource
qpdf_offset_t last_offset;
};
-#endif // __QPDF_INPUTSOURCE_HH__
+#endif // QPDF_INPUTSOURCE_HH
diff --git a/include/qpdf/JSON.hh b/include/qpdf/JSON.hh
new file mode 100644
index 00000000..50bc78b6
--- /dev/null
+++ b/include/qpdf/JSON.hh
@@ -0,0 +1,170 @@
+// Copyright (c) 2005-2019 Jay Berkenbilt
+//
+// This file is part of qpdf.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Versions of qpdf prior to version 7 were released under the terms
+// of version 2.0 of the Artistic License. At your option, you may
+// continue to consider qpdf to be licensed under those terms. Please
+// see the manual for additional information.
+
+#ifndef JSON_HH
+#define JSON_HH
+
+// This is a simple JSON serializer, primarily designed for
+// serializing QPDF Objects as JSON. JSON objects contain their data
+// as smart pointers. One JSON object is added to another, this
+// pointer is copied. This means you can create temporary JSON objects
+// on the stack, add them to other objects, and let them go out of
+// scope safely. It also means that if the json JSON object is added
+// in more than one place, all copies share underlying data.
+
+#include <qpdf/DLL.h>
+#include <qpdf/PointerHolder.hh>
+#include <string>
+#include <map>
+#include <vector>
+#include <list>
+
+class JSON
+{
+ public:
+ QPDF_DLL
+ std::string unparse() const;
+
+ // The JSON spec calls dictionaries "objects", but that creates
+ // too much confusion when referring to instances of the JSON
+ // class.
+ QPDF_DLL
+ static JSON makeDictionary();
+ // addDictionaryMember returns the newly added item.
+ QPDF_DLL
+ JSON addDictionaryMember(std::string const& key, JSON const&);
+ QPDF_DLL
+ static JSON makeArray();
+ // addArrayElement returns the newly added item.
+ QPDF_DLL
+ JSON addArrayElement(JSON const&);
+ QPDF_DLL
+ static JSON makeString(std::string const& utf8);
+ QPDF_DLL
+ static JSON makeInt(long long int value);
+ QPDF_DLL
+ static JSON makeReal(double value);
+ QPDF_DLL
+ static JSON makeNumber(std::string const& encoded);
+ QPDF_DLL
+ static JSON makeBool(bool value);
+ QPDF_DLL
+ static JSON makeNull();
+
+ // Check this JSON object against a "schema". This is not a schema
+ // according to any standard. It's just a template of what the
+ // JSON is supposed to contain. The checking does the following:
+ //
+ // * The schema is a nested structure containing dictionaries,
+ // single-element arrays, and strings only.
+ // * Recursively walk the schema
+ // * If the current value is a dictionary, this object must have
+ // a dictionary in the same place with the same keys
+ // * If the current value is an array, this object must have an
+ // array in the same place. The schema's array must contain a
+ // single element, which is used as a schema to validate each
+ // element of this object's corresponding array.
+ // * Otherwise, the value is ignored.
+ //
+ // QPDF's JSON output conforms to certain strict compatibility
+ // rules as discussed in the manual. The idea is that a JSON
+ // structure created manually in qpdf.cc doubles as both JSON help
+ // information and a schema for validating the JSON that qpdf
+ // generates. Any discrepancies are a bug in qpdf.
+ QPDF_DLL
+ bool checkSchema(JSON schema, std::list<std::string>& errors);
+
+ private:
+ static std::string encode_string(std::string const& utf8);
+
+ struct JSON_value
+ {
+ virtual ~JSON_value();
+ virtual std::string unparse(size_t depth) const = 0;
+ };
+ struct JSON_dictionary: public JSON_value
+ {
+ virtual ~JSON_dictionary();
+ virtual std::string unparse(size_t depth) const;
+ std::map<std::string, PointerHolder<JSON_value> > members;
+ };
+ struct JSON_array: public JSON_value
+ {
+ virtual ~JSON_array();
+ virtual std::string unparse(size_t depth) const;
+ std::vector<PointerHolder<JSON_value> > elements;
+ };
+ struct JSON_string: public JSON_value
+ {
+ JSON_string(std::string const& utf8);
+ virtual ~JSON_string();
+ virtual std::string unparse(size_t depth) const;
+ std::string encoded;
+ };
+ struct JSON_number: public JSON_value
+ {
+ JSON_number(long long val);
+ JSON_number(double val);
+ JSON_number(std::string const& val);
+ virtual ~JSON_number();
+ virtual std::string unparse(size_t depth) const;
+ std::string encoded;
+ };
+ struct JSON_bool: public JSON_value
+ {
+ JSON_bool(bool val);
+ virtual ~JSON_bool();
+ virtual std::string unparse(size_t depth) const;
+ bool value;
+ };
+ struct JSON_null: public JSON_value
+ {
+ virtual ~JSON_null();
+ virtual std::string unparse(size_t depth) const;
+ };
+
+ JSON(PointerHolder<JSON_value>);
+
+ static bool
+ checkSchemaInternal(JSON_value* this_v, JSON_value* sch_v,
+ std::list<std::string>& errors,
+ std::string prefix);
+
+ class Members
+ {
+ friend class JSON;
+
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members(PointerHolder<JSON_value>);
+ Members(Members const&);
+
+ PointerHolder<JSON_value> value;
+ };
+
+ PointerHolder<Members> m;
+};
+
+
+#endif // JSON_HH
diff --git a/include/qpdf/Pipeline.hh b/include/qpdf/Pipeline.hh
index 105dd7cb..b7bc5a7e 100644
--- a/include/qpdf/Pipeline.hh
+++ b/include/qpdf/Pipeline.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -41,8 +41,8 @@
// are not. It is up to the caller to use a pipeline according to its
// own restrictions.
-#ifndef __PIPELINE_HH__
-#define __PIPELINE_HH__
+#ifndef PIPELINE_HH
+#define PIPELINE_HH
#include <qpdf/DLL.h>
#include <string>
@@ -82,4 +82,4 @@ class Pipeline
Pipeline* next;
};
-#endif // __PIPELINE_HH__
+#endif // PIPELINE_HH
diff --git a/include/qpdf/Pl_Buffer.hh b/include/qpdf/Pl_Buffer.hh
index 7b49a73a..5eb143b2 100644
--- a/include/qpdf/Pl_Buffer.hh
+++ b/include/qpdf/Pl_Buffer.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __PL_BUFFER_HH__
-#define __PL_BUFFER_HH__
+#ifndef PL_BUFFER_HH
+#define PL_BUFFER_HH
// This pipeline accumulates the data passed to it into a memory
// buffer. Each subsequent use of this buffer appends to the data
@@ -62,4 +62,4 @@ class Pl_Buffer: public Pipeline
size_t total_size;
};
-#endif // __PL_BUFFER_HH__
+#endif // PL_BUFFER_HH
diff --git a/include/qpdf/Pl_Concatenate.hh b/include/qpdf/Pl_Concatenate.hh
index 32f87a4a..26e5849e 100644
--- a/include/qpdf/Pl_Concatenate.hh
+++ b/include/qpdf/Pl_Concatenate.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __PL_CONCATENATE_HH__
-#define __PL_CONCATENATE_HH__
+#ifndef PL_CONCATENATE_HH
+#define PL_CONCATENATE_HH
// This pipeline will drop all regular finished calls rather than
// passing them onto next. To finish downstream streams, call
@@ -50,4 +50,4 @@ class Pl_Concatenate: public Pipeline
void manualFinish();
};
-#endif // __PL_CONCATENATE_HH__
+#endif // PL_CONCATENATE_HH
diff --git a/include/qpdf/Pl_Count.hh b/include/qpdf/Pl_Count.hh
index 7b78b326..c3f7b3e1 100644
--- a/include/qpdf/Pl_Count.hh
+++ b/include/qpdf/Pl_Count.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __PL_COUNT_HH__
-#define __PL_COUNT_HH__
+#ifndef PL_COUNT_HH
+#define PL_COUNT_HH
// This pipeline is reusable; i.e., it is safe to call write() after
// calling finish().
@@ -52,4 +52,4 @@ class Pl_Count: public Pipeline
unsigned char last_char;
};
-#endif // __PL_COUNT_HH__
+#endif // PL_COUNT_HH
diff --git a/include/qpdf/Pl_DCT.hh b/include/qpdf/Pl_DCT.hh
index 984aad96..665a2b01 100644
--- a/include/qpdf/Pl_DCT.hh
+++ b/include/qpdf/Pl_DCT.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __PL_DCT_HH__
-#define __PL_DCT_HH__
+#ifndef PL_DCT_HH
+#define PL_DCT_HH
#include <qpdf/Pipeline.hh>
#include <qpdf/Pl_Buffer.hh>
@@ -81,4 +81,4 @@ class Pl_DCT: public Pipeline
};
-#endif // __PL_DCT_HH__
+#endif // PL_DCT_HH
diff --git a/include/qpdf/Pl_Discard.hh b/include/qpdf/Pl_Discard.hh
index 3c15650c..129431b2 100644
--- a/include/qpdf/Pl_Discard.hh
+++ b/include/qpdf/Pl_Discard.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __PL_DISCARD_HH__
-#define __PL_DISCARD_HH__
+#ifndef PL_DISCARD_HH
+#define PL_DISCARD_HH
// This pipeline discards its output. It is an end-of-line pipeline
// (with no next).
@@ -43,4 +43,4 @@ class Pl_Discard: public Pipeline
virtual void finish();
};
-#endif // __PL_DISCARD_HH__
+#endif // PL_DISCARD_HH
diff --git a/include/qpdf/Pl_Flate.hh b/include/qpdf/Pl_Flate.hh
index cbc44bcf..fdd66996 100644
--- a/include/qpdf/Pl_Flate.hh
+++ b/include/qpdf/Pl_Flate.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __PL_FLATE_HH__
-#define __PL_FLATE_HH__
+#ifndef PL_FLATE_HH
+#define PL_FLATE_HH
#include <qpdf/Pipeline.hh>
@@ -53,4 +53,4 @@ class Pl_Flate: public Pipeline
void* zdata;
};
-#endif // __PL_FLATE_HH__
+#endif // PL_FLATE_HH
diff --git a/include/qpdf/Pl_QPDFTokenizer.hh b/include/qpdf/Pl_QPDFTokenizer.hh
index 65dc7919..a571b079 100644
--- a/include/qpdf/Pl_QPDFTokenizer.hh
+++ b/include/qpdf/Pl_QPDFTokenizer.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,14 +19,15 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __PL_QPDFTOKENIZER_HH__
-#define __PL_QPDFTOKENIZER_HH__
+#ifndef PL_QPDFTOKENIZER_HH
+#define PL_QPDFTOKENIZER_HH
#include <qpdf/Pipeline.hh>
#include <qpdf/QPDFTokenizer.hh>
#include <qpdf/PointerHolder.hh>
#include <qpdf/QPDFObjectHandle.hh>
+#include <qpdf/Pl_Buffer.hh>
// Tokenize the incoming text using QPDFTokenizer and pass the tokens
// in turn to a QPDFObjectHandle::TokenFilter object. All bytes of
@@ -44,22 +45,24 @@ class Pl_QPDFTokenizer: public Pipeline
// Whatever pipeline is provided as "next" will be set as the
// pipeline that the token filter writes to. If next is not
// provided, any output written by the filter will be discarded.
+ QPDF_DLL
Pl_QPDFTokenizer(char const* identifier,
QPDFObjectHandle::TokenFilter* filter,
Pipeline* next = 0);
+ QPDF_DLL
virtual ~Pl_QPDFTokenizer();
+ QPDF_DLL
virtual void write(unsigned char* buf, size_t len);
+ QPDF_DLL
virtual void finish();
private:
- void processChar(char ch);
- void checkUnread();
-
class Members
{
friend class Pl_QPDFTokenizer;
public:
+ QPDF_DLL
~Members();
private:
@@ -68,11 +71,9 @@ class Pl_QPDFTokenizer: public Pipeline
QPDFObjectHandle::TokenFilter* filter;
QPDFTokenizer tokenizer;
- bool last_char_was_cr;
- bool unread_char;
- char char_to_unread;
+ Pl_Buffer buf;
};
PointerHolder<Members> m;
};
-#endif // __PL_QPDFTOKENIZER_HH__
+#endif // PL_QPDFTOKENIZER_HH
diff --git a/include/qpdf/Pl_RunLength.hh b/include/qpdf/Pl_RunLength.hh
index be30ed22..b8e696b6 100644
--- a/include/qpdf/Pl_RunLength.hh
+++ b/include/qpdf/Pl_RunLength.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __PL_RUNLENGTH_HH__
-#define __PL_RUNLENGTH_HH__
+#ifndef PL_RUNLENGTH_HH
+#define PL_RUNLENGTH_HH
#include <qpdf/Pipeline.hh>
@@ -53,4 +53,4 @@ class Pl_RunLength: public Pipeline
unsigned int length;
};
-#endif // __PL_RUNLENGTH_HH__
+#endif // PL_RUNLENGTH_HH
diff --git a/include/qpdf/Pl_StdioFile.hh b/include/qpdf/Pl_StdioFile.hh
index b89ead43..fd228333 100644
--- a/include/qpdf/Pl_StdioFile.hh
+++ b/include/qpdf/Pl_StdioFile.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -21,8 +21,8 @@
// End-of-line pipeline that simply writes its data to a stdio FILE* object.
-#ifndef __PL_STDIOFILE_HH__
-#define __PL_STDIOFILE_HH__
+#ifndef PL_STDIOFILE_HH
+#define PL_STDIOFILE_HH
#include <qpdf/Pipeline.hh>
@@ -51,4 +51,4 @@ class Pl_StdioFile: public Pipeline
FILE* file;
};
-#endif // __PL_STDIOFILE_HH__
+#endif // PL_STDIOFILE_HH
diff --git a/include/qpdf/PointerHolder.hh b/include/qpdf/PointerHolder.hh
index 99c12878..18833773 100644
--- a/include/qpdf/PointerHolder.hh
+++ b/include/qpdf/PointerHolder.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __POINTERHOLDER_HH__
-#define __POINTERHOLDER_HH__
+#ifndef POINTERHOLDER_HH
+#define POINTERHOLDER_HH
// This class is basically boost::shared_pointer but predates that by
// several years.
@@ -182,4 +182,4 @@ class PointerHolder
Data* data;
};
-#endif // __POINTERHOLDER_HH__
+#endif // POINTERHOLDER_HH
diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh
index 681d233c..634c9bd1 100644
--- a/include/qpdf/QPDF.hh
+++ b/include/qpdf/QPDF.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDF_HH__
-#define __QPDF_HH__
+#ifndef QPDF_HH
+#define QPDF_HH
#include <qpdf/DLL.h>
#include <qpdf/Types.h>
@@ -160,6 +160,39 @@ class QPDF
QPDF_DLL
void setAttemptRecovery(bool);
+ // Tell other QPDF objects that streams copied from this QPDF need
+ // to be fully copied when copyForeignObject is called on them.
+ // Calling setIgnoreXRefStreams(true) on a QPDF object makes it
+ // possible for the object and its input source to disappear
+ // before streams copied from it are written with the destination
+ // QPDF object. Confused? Ordinarily, if you are going to copy
+ // objects from a source QPDF object to a destination QPDF object
+ // using copyForeignObject or addPage, the source object's input
+ // source must stick around until after the destination PDF is
+ // written. If you call this method on the source QPDF object, it
+ // sends a signal to the destination object that it must fully
+ // copy the stream data when copyForeignObject. It will do this by
+ // making a copy in RAM. Ordinarily the stream data is copied
+ // lazily to avoid unnecessary duplication of the stream data.
+ // Note that the stream data is copied into RAM only once
+ // regardless of how many objects the stream is copied into. The
+ // result is that, if you called setImmediateCopyFrom(true) on a
+ // given QPDF object prior to copying any of its streams, you do
+ // not need to keep it or its input source around after copying
+ // its objects to another QPDF. This is true even if the source
+ // streams use StreamDataProvider. Note that this method is called
+ // on the QPDF object you are copying FROM, not the one you are
+ // copying to. The reasoning for this is that there's no reason a
+ // given QPDF may not get objects copied to it from a variety of
+ // other objects, some transient and some not. Since what's
+ // relevant is whether the source QPDF is transient, the method
+ // must be called on the source QPDF, not the destination one.
+ // Since this method will make a copy of the stream in RAM, so be
+ // sure you have enough memory to simultaneously hold all the
+ // streams you're copying.
+ QPDF_DLL
+ void setImmediateCopyFrom(bool);
+
// Other public methods
// Return the list of warnings that have been issued so far and
@@ -170,6 +203,16 @@ class QPDF
QPDF_DLL
std::vector<QPDFExc> getWarnings();
+ // Return an application-scoped unique ID for this QPDF object.
+ // This is not a globally unique ID. It is constructing using a
+ // timestamp and a random number and is intended to be unique
+ // among QPDF objects that are created by a single run of an
+ // application. While it's very likely that these are actually
+ // globally unique, it is not recommended to use them for
+ // long-term purposes.
+ QPDF_DLL
+ unsigned long long getUniqueId() const;
+
QPDF_DLL
std::string getFilename() const;
QPDF_DLL
@@ -237,19 +280,39 @@ class QPDF
replaceReserved(QPDFObjectHandle reserved,
QPDFObjectHandle replacement);
- // Copy an object from another QPDF to this one. Please note that
- // the QPDF object containing the object being copied must stick
- // around because it is still used to retrieve any stream data
- // referenced by the copied objects.
+ // Copy an object from another QPDF to this one. Starting with
+ // qpdf version 8.3.0, it is no longer necessary to keep the
+ // original QPDF around after the call to copyForeignObject as
+ // long as the source of any copied stream data is still
+ // available. Usually this means you just have to keep the input
+ // file around, not the QPDF object. The exception to this is if
+ // you copy a stream that gets its data from a
+ // QPDFObjectHandle::StreamDataProvider. In this case only, the
+ // original stream's QPDF object must stick around because the
+ // QPDF object is itself the source of the original stream data.
+ // For a more in-depth discussion, please see the TODO file.
+ // Starting in 8.4.0, you can call setImmediateCopyFrom(true) on
+ // the SOURCE QPDF object (the one you're copying FROM). If you do
+ // this prior to copying any of its objects, then neither the
+ // source QPDF object nor its input source needs to stick around
+ // at all regardless of the source. The cost is that the stream
+ // data is copied into RAM at the time copyForeignObject is
+ // called. See setImmediateCopyFrom for more information.
//
- // The return value is an indirect reference to the copied object
- // in this file. This method is intended to be used to copy
- // non-page objects and will not copy page objects. To copy page
- // objects, pass the foreign page object directly to addPage (or
- // addPageAt). If you copy objects that contain references to
- // pages, you should copy the pages first using addPage(At).
- // Otherwise references to the pages that have not been copied
- // will be replaced with nulls.
+ // The return value of this method is an indirect reference to the
+ // copied object in this file. This method is intended to be used
+ // to copy non-page objects. To copy page objects, pass the
+ // foreign page object directly to addPage (or addPageAt). If you
+ // copy objects that contain references to pages, you should copy
+ // the pages first using addPage(At). Otherwise references to the
+ // pages that have not been copied will be replaced with nulls. It
+ // is possible to use copyForeignObject on page objects if you are
+ // not going to use them as pages. Doing so copies the object
+ // normally but does not update the page structure. For example,
+ // it is a valid use case to use copyForeignObject for a page that
+ // you are going to turn into a form XObject, though you can also
+ // use QPDFPageObjectHelper::getFormXObjectForPage for that
+ // purpose.
// When copying objects with this method, object structure will be
// preserved, so all indirectly referenced indirect objects will
@@ -431,9 +494,21 @@ class QPDF
QPDF_DLL
void showXRefTable();
+ // Detect all indirect references to objects that don't exist and
+ // resolve them by replacing them with null, which is how the PDF
+ // spec says to interpret such dangling references. This method is
+ // called automatically if you try to add any new objects, if you
+ // call getAllObjects, and before a file is written. The qpdf
+ // object caches whether it has run this to avoid running it
+ // multiple times. You can pass true to force it to run again if
+ // you have explicitly added new objects that may have additional
+ // dangling references.
+ QPDF_DLL
+ void fixDanglingReferences(bool force = false);
+
// Return the approximate number of indirect objects. It is
// approximate because not all objects in the file are preserved
- // in all cases.
+ // in all cases, and gaps in object numbering are not preserved.
QPDF_DLL
size_t getObjectCount();
@@ -458,15 +533,16 @@ class QPDF
void optimize(std::map<int, int> const& object_stream_data,
bool allow_changes = true);
- // Traverse page tree return all /Page objects. For efficiency,
- // this method returns a const reference to an internal vector of
- // pages. Calls to addPage, addPageAt, and removePage safely
- // update this, but directly manipulation of the pages three or
- // pushing inheritable objects to the page level may invalidate
- // it. See comments for updateAllPagesCache() for additional
- // notes. Newer code should use
- // QPDFPageDocumentHelper::getAllPages instead. The decision to
- // expose this internal cache was arguably incorrect, but it is
+ // Traverse page tree return all /Page objects. It also detects
+ // and resolves cases in which the same /Page object is
+ // duplicated. For efficiency, this method returns a const
+ // reference to an internal vector of pages. Calls to addPage,
+ // addPageAt, and removePage safely update this, but directly
+ // manipulation of the pages three or pushing inheritable objects
+ // to the page level may invalidate it. See comments for
+ // updateAllPagesCache() for additional notes. Newer code should
+ // use QPDFPageDocumentHelper::getAllPages instead. The decision
+ // to expose this internal cache was arguably incorrect, but it is
// being left here for compatibility. It is, however, completely
// safe to use this for files that you are not modifying.
QPDF_DLL
@@ -629,9 +705,59 @@ class QPDF
std::set<QPDFObjGen> visiting;
};
+ class EncryptionParameters
+ {
+ friend class QPDF;
+ public:
+ EncryptionParameters();
+
+ private:
+ bool encrypted;
+ bool encryption_initialized;
+ int encryption_V;
+ int encryption_R;
+ bool encrypt_metadata;
+ std::map<std::string, encryption_method_e> crypt_filters;
+ encryption_method_e cf_stream;
+ encryption_method_e cf_string;
+ encryption_method_e cf_file;
+ std::string provided_password;
+ std::string user_password;
+ std::string encryption_key;
+ std::string cached_object_encryption_key;
+ int cached_key_objid;
+ int cached_key_generation;
+ };
+
+ class ForeignStreamData
+ {
+ friend class QPDF;
+ public:
+ ForeignStreamData(
+ PointerHolder<EncryptionParameters> encp,
+ PointerHolder<InputSource> file,
+ int foreign_objid,
+ int foreign_generation,
+ qpdf_offset_t offset,
+ size_t length,
+ bool is_attachment_stream,
+ QPDFObjectHandle local_dict);
+
+ private:
+ PointerHolder<EncryptionParameters> encp;
+ PointerHolder<InputSource> file;
+ int foreign_objid;
+ int foreign_generation;
+ qpdf_offset_t offset;
+ size_t length;
+ bool is_attachment_stream;
+ QPDFObjectHandle local_dict;
+ };
+
class CopiedStreamDataProvider: public QPDFObjectHandle::StreamDataProvider
{
public:
+ CopiedStreamDataProvider(QPDF& destination_qpdf);
virtual ~CopiedStreamDataProvider()
{
}
@@ -639,9 +765,14 @@ class QPDF
Pipeline* pipeline);
void registerForeignStream(QPDFObjGen const& local_og,
QPDFObjectHandle foreign_stream);
+ void registerForeignStream(QPDFObjGen const& local_og,
+ PointerHolder<ForeignStreamData>);
private:
+ QPDF& destination_qpdf;
std::map<QPDFObjGen, QPDFObjectHandle> foreign_streams;
+ std::map<QPDFObjGen,
+ PointerHolder<ForeignStreamData> > foreign_stream_data;
};
class StringDecrypter: public QPDFObjectHandle::StringDecrypter
@@ -714,6 +845,7 @@ class QPDF
PointerHolder<QPDFObject> resolve(int objid, int generation);
void resolveObjectsInStream(int obj_stream_number);
void findAttachmentStreams();
+ void stopOnError(std::string const& message);
// Calls finish() on the pipeline when done but does not delete it
bool pipeStreamData(int objid, int generation,
@@ -722,6 +854,21 @@ class QPDF
Pipeline* pipeline,
bool suppress_warnings,
bool will_retry);
+ bool pipeForeignStreamData(
+ PointerHolder<ForeignStreamData>,
+ Pipeline*,
+ unsigned long encode_flags,
+ qpdf_stream_decode_level_e decode_level);
+ static bool pipeStreamData(PointerHolder<QPDF::EncryptionParameters> encp,
+ PointerHolder<InputSource> file,
+ QPDF& qpdf_for_warning,
+ int objid, int generation,
+ qpdf_offset_t offset, size_t length,
+ QPDFObjectHandle dict,
+ bool is_attachment_stream,
+ Pipeline* pipeline,
+ bool suppress_warnings,
+ bool will_retry);
// For QPDFWriter:
@@ -751,10 +898,9 @@ class QPDF
// methods to support page handling
void getAllPagesInternal(QPDFObjectHandle cur_pages,
- std::vector<QPDFObjectHandle>& result);
- void getAllPagesInternal2(QPDFObjectHandle cur_pages,
- std::vector<QPDFObjectHandle>& result,
- std::set<QPDFObjGen>& visited);
+ std::vector<QPDFObjectHandle>& result,
+ std::set<QPDFObjGen>& visited,
+ std::set<QPDFObjGen>& seen);
void insertPage(QPDFObjectHandle newpage, int pos);
int findPage(QPDFObjGen const& og);
int findPage(QPDFObjectHandle& page);
@@ -763,9 +909,12 @@ class QPDF
bool check_duplicate);
// methods to support encryption -- implemented in QPDF_encryption.cc
- encryption_method_e interpretCF(QPDFObjectHandle);
+ static encryption_method_e interpretCF(
+ PointerHolder<EncryptionParameters> encp, QPDFObjectHandle);
void initializeEncryption();
- std::string getKeyForObject(int objid, int generation, bool use_aes);
+ static std::string getKeyForObject(
+ PointerHolder<EncryptionParameters> encp,
+ int objid, int generation, bool use_aes);
void decryptString(std::string&, int objid, int generation);
static std::string compute_encryption_key_from_password(
std::string const& password, EncryptionData const& data);
@@ -774,14 +923,18 @@ class QPDF
static std::string recover_encryption_key_with_password(
std::string const& password, EncryptionData const& data,
bool& perms_valid);
- void decryptStream(
- Pipeline*& pipeline, int objid, int generation,
- QPDFObjectHandle& stream_dict,
+ static void decryptStream(
+ PointerHolder<EncryptionParameters> encp,
+ PointerHolder<InputSource> file,
+ QPDF& qpdf_for_warning, Pipeline*& pipeline,
+ int objid, int generation,
+ QPDFObjectHandle& stream_dict, bool is_attachment_stream,
std::vector<PointerHolder<Pipeline> >& heap);
- // Methods to support object copying
+ // Unused copyForeignObject -- remove at next ABI change
QPDFObjectHandle copyForeignObject(
- QPDFObjectHandle foreign, bool allow_page);
+ QPDFObjectHandle foreign, bool unused);
+ // Methods to support object copying
void reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier,
bool top);
QPDFObjectHandle replaceForeignIndirectObjects(
@@ -1135,11 +1288,6 @@ class QPDF
QPDFObjectHandle,
std::map<std::string, std::vector<QPDFObjectHandle> >&,
std::vector<QPDFObjectHandle>& all_pages,
- bool allow_changes, bool warn_skipped_keys);
- void pushInheritedAttributesToPageInternal2(
- QPDFObjectHandle,
- std::map<std::string, std::vector<QPDFObjectHandle> >&,
- std::vector<QPDFObjectHandle>& all_pages,
bool allow_changes, bool warn_skipped_keys,
std::set<QPDFObjGen>& visited);
void updateObjectMaps(ObjUser const& ou, QPDFObjectHandle oh);
@@ -1152,36 +1300,24 @@ class QPDF
friend class QPDF;
public:
+ QPDF_DLL
~Members();
private:
Members();
Members(Members const&);
+ unsigned long long unique_id;
QPDFTokenizer tokenizer;
PointerHolder<InputSource> file;
std::string last_object_description;
bool provided_password_is_hex_key;
- bool encrypted;
- bool encryption_initialized;
bool ignore_xref_streams;
bool suppress_warnings;
std::ostream* out_stream;
std::ostream* err_stream;
bool attempt_recovery;
- int encryption_V;
- int encryption_R;
- bool encrypt_metadata;
- std::map<std::string, encryption_method_e> crypt_filters;
- encryption_method_e cf_stream;
- encryption_method_e cf_string;
- encryption_method_e cf_file;
- std::string provided_password;
- std::string user_password;
- std::string encryption_key;
- std::string cached_object_encryption_key;
- int cached_key_objid;
- int cached_key_generation;
+ PointerHolder<EncryptionParameters> encp;
std::string pdf_version;
std::map<QPDFObjGen, QPDFXRefEntry> xref_table;
std::set<int> deleted_objects;
@@ -1192,12 +1328,14 @@ class QPDF
std::map<QPDFObjGen, int> pageobj_to_pages_pos;
bool pushed_inherited_attributes_to_pages;
std::vector<QPDFExc> warnings;
- std::map<QPDF*, ObjCopier> object_copiers;
+ std::map<unsigned long long, ObjCopier> object_copiers;
PointerHolder<QPDFObjectHandle::StreamDataProvider> copied_streams;
// copied_stream_data_provider is owned by copied_streams
CopiedStreamDataProvider* copied_stream_data_provider;
std::set<QPDFObjGen> attachment_streams;
bool reconstructed_xref;
+ bool fixed_dangling_refs;
+ bool immediate_copy_from;
// Linearization data
qpdf_offset_t first_xref_item_offset; // actual value from file
@@ -1239,4 +1377,4 @@ class QPDF
PointerHolder<Members> m;
};
-#endif // __QPDF_HH__
+#endif // QPDF_HH
diff --git a/include/qpdf/QPDFAcroFormDocumentHelper.hh b/include/qpdf/QPDFAcroFormDocumentHelper.hh
index 519f626b..b0e05f50 100644
--- a/include/qpdf/QPDFAcroFormDocumentHelper.hh
+++ b/include/qpdf/QPDFAcroFormDocumentHelper.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDFACROFORMDOCUMENTHELPER_HH__
-#define __QPDFACROFORMDOCUMENTHELPER_HH__
+#ifndef QPDFACROFORMDOCUMENTHELPER_HH
+#define QPDFACROFORMDOCUMENTHELPER_HH
// This document helper is intended to help with operations on
// interactive forms. Here are the key things to know:
@@ -85,6 +85,10 @@ class QPDFAcroFormDocumentHelper: public QPDFDocumentHelper
public:
QPDF_DLL
QPDFAcroFormDocumentHelper(QPDF&);
+ QPDF_DLL
+ virtual ~QPDFAcroFormDocumentHelper()
+ {
+ }
// This class lazily creates an internal cache of the mapping
// among form fields, annotations, and pages. Methods within this
@@ -153,6 +157,16 @@ class QPDFAcroFormDocumentHelper: public QPDFDocumentHelper
QPDF_DLL
void setNeedAppearances(bool);
+ // If /NeedAppearances is false, do nothing. Otherwise generate
+ // appearance streams for all widget annotations that need them.
+ // See comments in QPDFFormFieldObjectHelper.hh for
+ // generateAppearance for limitations. For checkbox and radio
+ // button fields, this code ensures that appearance state is
+ // consistent with the field's value and uses any pre-existing
+ // appearance streams.
+ QPDF_DLL
+ void generateAppearancesIfNeeded();
+
private:
void analyze();
void traverseField(QPDFObjectHandle field,
@@ -181,4 +195,4 @@ class QPDFAcroFormDocumentHelper: public QPDFDocumentHelper
PointerHolder<Members> m;
};
-#endif // __QPDFACROFORMDOCUMENTHELPER_HH__
+#endif // QPDFACROFORMDOCUMENTHELPER_HH
diff --git a/include/qpdf/QPDFAnnotationObjectHelper.hh b/include/qpdf/QPDFAnnotationObjectHelper.hh
index a5bb5a0d..e2493bba 100644
--- a/include/qpdf/QPDFAnnotationObjectHelper.hh
+++ b/include/qpdf/QPDFAnnotationObjectHelper.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,10 +19,11 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDFANNOTATIONOBJECTHELPER_HH__
-#define __QPDFANNOTATIONOBJECTHELPER_HH__
+#ifndef QPDFANNOTATIONOBJECTHELPER_HH
+#define QPDFANNOTATIONOBJECTHELPER_HH
#include <qpdf/QPDFObjectHelper.hh>
+#include <qpdf/Constants.h>
#include <qpdf/DLL.h>
@@ -31,6 +32,10 @@ class QPDFAnnotationObjectHelper: public QPDFObjectHelper
public:
QPDF_DLL
QPDFAnnotationObjectHelper(QPDFObjectHandle);
+ QPDF_DLL
+ virtual ~QPDFAnnotationObjectHelper()
+ {
+ }
// This class provides helper methods for certain types of
// annotations. At its introduction, it only supports Widget
@@ -56,6 +61,11 @@ class QPDFAnnotationObjectHelper: public QPDFObjectHelper
QPDF_DLL
std::string getAppearanceState();
+ // Return flags from "/F". The value is a logical or of
+ // pdf_annotation_flag_e as defined in qpdf/Constants.h.
+ QPDF_DLL
+ int getFlags();
+
// Return a specific stream. "which" may be one of "/N", "/R", or
// "/D" to indicate the normal, rollover, or down appearance
// stream. (Any value may be passed to "which"; if an appearance
@@ -68,10 +78,29 @@ class QPDFAnnotationObjectHelper: public QPDFObjectHelper
QPDFObjectHandle getAppearanceStream(std::string const& which,
std::string const& state = "");
+ // Generate text suitable for addition to the containing page's
+ // content stream that draws this annotation's appearance stream
+ // as a form XObject. The value "name" is the resource name that
+ // will be used to refer to the form xobject. The value "rotate"
+ // should be set to the page's /Rotate value or 0 if none. The
+ // values of required_flags and forbidden_flags are constructed by
+ // logically "or"ing annotation flags of type
+ // pdf_annotation_flag_e defined in qpdf/Constants.h. Content will
+ // be returned only if all required_flags are set and no
+ // forbidden_flags are set. For example, including an_no_view in
+ // forbidden_flags could be useful for creating an on-screen view,
+ // and including an_print to required_flags could be useful if
+ // preparing to print.
+ QPDF_DLL
+ std::string getPageContentForAppearance(
+ std::string const& name, int rotate,
+ int required_flags = 0,
+ int forbidden_flags = an_invisible | an_hidden);
+
private:
class Members
{
- friend class QPDFPageObjectHelper;
+ friend class QPDFAnnotationObjectHelper;
public:
QPDF_DLL
@@ -85,4 +114,4 @@ class QPDFAnnotationObjectHelper: public QPDFObjectHelper
PointerHolder<Members> m;
};
-#endif // __QPDFANNOTATIONOBJECTHELPER_HH__
+#endif // QPDFANNOTATIONOBJECTHELPER_HH
diff --git a/include/qpdf/QPDFDocumentHelper.hh b/include/qpdf/QPDFDocumentHelper.hh
index 3b180743..60da87dd 100644
--- a/include/qpdf/QPDFDocumentHelper.hh
+++ b/include/qpdf/QPDFDocumentHelper.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDFDOCUMENTHELPER_HH__
-#define __QPDFDOCUMENTHELPER_HH__
+#ifndef QPDFDOCUMENTHELPER_HH
+#define QPDFDOCUMENTHELPER_HH
#include <qpdf/DLL.h>
#include <qpdf/QPDF.hh>
@@ -63,4 +63,4 @@ class QPDFDocumentHelper
QPDF& qpdf;
};
-#endif // __QPDFDOCUMENTHELPER_HH__
+#endif // QPDFDOCUMENTHELPER_HH
diff --git a/include/qpdf/QPDFExc.hh b/include/qpdf/QPDFExc.hh
index 5ef7c803..fe0aa1d5 100644
--- a/include/qpdf/QPDFExc.hh
+++ b/include/qpdf/QPDFExc.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDFEXC_HH__
-#define __QPDFEXC_HH__
+#ifndef QPDFEXC_HH
+#define QPDFEXC_HH
#include <qpdf/DLL.h>
#include <qpdf/Types.h>
@@ -39,7 +39,9 @@ class QPDFExc: public std::runtime_error
qpdf_offset_t offset,
std::string const& message);
QPDF_DLL
- virtual ~QPDFExc() throw ();
+ virtual ~QPDFExc() throw ()
+ {
+ }
// To get a complete error string, call what(), provided by
// std::exception. The accessors below return the original values
@@ -75,4 +77,4 @@ class QPDFExc: public std::runtime_error
std::string message;
};
-#endif // __QPDFEXC_HH__
+#endif // QPDFEXC_HH
diff --git a/include/qpdf/QPDFFormFieldObjectHelper.hh b/include/qpdf/QPDFFormFieldObjectHelper.hh
index 4654d956..58c5d098 100644
--- a/include/qpdf/QPDFFormFieldObjectHelper.hh
+++ b/include/qpdf/QPDFFormFieldObjectHelper.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDFFORMFIELDOBJECTHELPER_HH__
-#define __QPDFFORMFIELDOBJECTHELPER_HH__
+#ifndef QPDFFORMFIELDOBJECTHELPER_HH
+#define QPDFFORMFIELDOBJECTHELPER_HH
// This object helper helps with form fields for interactive forms.
// Please see comments in QPDFAcroFormDocumentHelper.hh for additional
@@ -29,6 +29,9 @@
#include <qpdf/QPDFObjectHelper.hh>
#include <qpdf/DLL.h>
+#include <vector>
+
+class QPDFAnnotationObjectHelper;
class QPDFFormFieldObjectHelper: public QPDFObjectHelper
{
@@ -37,6 +40,10 @@ class QPDFFormFieldObjectHelper: public QPDFObjectHelper
QPDFFormFieldObjectHelper();
QPDF_DLL
QPDFFormFieldObjectHelper(QPDFObjectHandle);
+ QPDF_DLL
+ virtual ~QPDFFormFieldObjectHelper()
+ {
+ }
QPDF_DLL
bool isNull();
@@ -116,6 +123,38 @@ class QPDFFormFieldObjectHelper: public QPDFObjectHelper
QPDF_DLL
int getQuadding();
+ // Return field flags from /Ff. The value is a logical or of
+ // pdf_form_field_flag_e as defined in qpdf/Constants.h
+ QPDF_DLL
+ int getFlags();
+
+ // Methods for testing for particular types of form fields
+
+ // Returns true if field is of type /Tx
+ QPDF_DLL
+ bool isText();
+ // Returns true if field is of type /Btn and flags do not indicate
+ // some other type of button.
+ QPDF_DLL
+ bool isCheckbox();
+ // Returns true if field is a checkbox and is checked.
+ QPDF_DLL
+ bool isChecked();
+ // Returns true if field is of type /Btn and flags indicate that
+ // it is a radio button
+ QPDF_DLL
+ bool isRadioButton();
+ // Returns true if field is of type /Btn and flags indicate that
+ // it is a pushbutton
+ QPDF_DLL
+ bool isPushbutton();
+ // Returns true if fields if of type /Ch
+ QPDF_DLL
+ bool isChoice();
+ // Returns choices as UTF-8 strings
+ QPDF_DLL
+ std::vector<std::string> getChoices();
+
// Set an attribute to the given value
QPDF_DLL
void setFieldAttribute(std::string const& key, QPDFObjectHandle value);
@@ -126,10 +165,13 @@ class QPDFFormFieldObjectHelper: public QPDFObjectHelper
void setFieldAttribute(std::string const& key,
std::string const& utf8_value);
- // Set /V (field value) to the given value. Optionally set
- // /NeedAppearances to true. You can explicitly tell this method
- // not to set /NeedAppearances if you are going to explicitly
- // generate an appearance stream yourself.
+ // Set /V (field value) to the given value. If need_appearances is
+ // true and the field type is either /Tx (text) or /Ch (choice),
+ // set /NeedAppearances to true. You can explicitly tell this
+ // method not to set /NeedAppearances if you are going to generate
+ // an appearance stream yourself. Starting with qpdf 8.3.0, this
+ // method handles fields of type /Btn (checkboxes, radio buttons,
+ // pushbuttons) specially.
QPDF_DLL
void setV(QPDFObjectHandle value, bool need_appearances = true);
@@ -139,7 +181,24 @@ class QPDFFormFieldObjectHelper: public QPDFObjectHelper
QPDF_DLL
void setV(std::string const& utf8_value, bool need_appearances = true);
+ // Update the appearance stream for this field. Note that qpdf's
+ // ability to generate appearance streams is limited. We only
+ // generate appearance streams for streams of type text or choice.
+ // The appearance uses the default parameters provided in the
+ // file, and it only supports ASCII characters. Quadding is
+ // currently ignored. While this functionality is limited, it
+ // should do a decent job on properly constructed PDF files when
+ // field values are restricted to ASCII characters.
+ QPDF_DLL
+ void generateAppearance(QPDFAnnotationObjectHelper&);
+
private:
+ void setRadioButtonValue(QPDFObjectHandle name);
+ void setCheckBoxValue(bool value);
+ void generateTextAppearance(QPDFAnnotationObjectHelper&);
+ QPDFObjectHandle getFontFromResource(
+ QPDFObjectHandle resources, std::string const& font_name);
+
class Members
{
friend class QPDFFormFieldObjectHelper;
@@ -156,4 +215,4 @@ class QPDFFormFieldObjectHelper: public QPDFObjectHelper
PointerHolder<Members> m;
};
-#endif // __QPDFFORMFIELDOBJECTHELPER_HH__
+#endif // QPDFFORMFIELDOBJECTHELPER_HH
diff --git a/include/qpdf/QPDFNameTreeObjectHelper.hh b/include/qpdf/QPDFNameTreeObjectHelper.hh
new file mode 100644
index 00000000..04a15ca8
--- /dev/null
+++ b/include/qpdf/QPDFNameTreeObjectHelper.hh
@@ -0,0 +1,83 @@
+// Copyright (c) 2005-2019 Jay Berkenbilt
+//
+// This file is part of qpdf.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Versions of qpdf prior to version 7 were released under the terms
+// of version 2.0 of the Artistic License. At your option, you may
+// continue to consider qpdf to be licensed under those terms. Please
+// see the manual for additional information.
+
+#ifndef QPDFNAMETREEOBJECTHELPER_HH
+#define QPDFNAMETREEOBJECTHELPER_HH
+
+#include <qpdf/QPDFObjectHelper.hh>
+#include <qpdf/QPDFObjGen.hh>
+#include <map>
+
+#include <qpdf/DLL.h>
+
+// This is an object helper for name trees. See section 7.9.6 in the
+// PDF spec (ISO 32000) for a description of name trees. This
+// implementation disregards stated limits and sequencing and simply
+// builds a map from string object. If the array of values does not
+// contain a string where expected, this implementation silently skips
+// forward until it finds a string. When looking up items in the name
+// tree, use UTF-8 strings. All names are normalized for lookup
+// purposes.
+
+class QPDFNameTreeObjectHelper: public QPDFObjectHelper
+{
+ public:
+ QPDF_DLL
+ QPDFNameTreeObjectHelper(QPDFObjectHandle);
+ QPDF_DLL
+ virtual ~QPDFNameTreeObjectHelper();
+
+ // Return whether the number tree has an explicit entry for this
+ // number.
+ QPDF_DLL
+ bool hasName(std::string const& utf8);
+
+ // Find an object by name. If found, returns true and initializes
+ // oh.
+ QPDF_DLL
+ bool findObject(std::string const& utf8, QPDFObjectHandle& oh);
+
+ QPDF_DLL
+ std::map<std::string, QPDFObjectHandle> getAsMap() const;
+
+ private:
+ class Members
+ {
+ friend class QPDFNameTreeObjectHelper;
+
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members();
+ Members(Members const&);
+
+ std::map<std::string, QPDFObjectHandle> entries;
+ std::set<QPDFObjGen> seen;
+ };
+
+ void updateMap(QPDFObjectHandle oh);
+
+ PointerHolder<Members> m;
+};
+
+#endif // QPDFNAMETREEOBJECTHELPER_HH
diff --git a/include/qpdf/QPDFNumberTreeObjectHelper.hh b/include/qpdf/QPDFNumberTreeObjectHelper.hh
new file mode 100644
index 00000000..60e5bd9a
--- /dev/null
+++ b/include/qpdf/QPDFNumberTreeObjectHelper.hh
@@ -0,0 +1,114 @@
+// Copyright (c) 2005-2019 Jay Berkenbilt
+//
+// This file is part of qpdf.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Versions of qpdf prior to version 7 were released under the terms
+// of version 2.0 of the Artistic License. At your option, you may
+// continue to consider qpdf to be licensed under those terms. Please
+// see the manual for additional information.
+
+#ifndef QPDFNUMBERTREEOBJECTHELPER_HH
+#define QPDFNUMBERTREEOBJECTHELPER_HH
+
+#include <qpdf/QPDFObjectHelper.hh>
+#include <qpdf/QPDFObjGen.hh>
+#include <functional>
+#include <map>
+
+#include <qpdf/DLL.h>
+
+// This is an object helper for number trees. See section 7.9.7 in the
+// PDF spec (ISO 32000) for a description of number trees. This
+// implementation disregards stated limits and sequencing and simply
+// builds a map from numerical index to object. If the array of
+// numbers does not contain a numerical value where expected, this
+// implementation silently skips forward until it finds a number.
+
+class QPDFNumberTreeObjectHelper: public QPDFObjectHelper
+{
+ public:
+ QPDF_DLL
+ QPDFNumberTreeObjectHelper(QPDFObjectHandle);
+ QPDF_DLL
+ virtual ~QPDFNumberTreeObjectHelper()
+ {
+ }
+
+ typedef long long int numtree_number;
+
+ // Return overall minimum and maximum indices
+ QPDF_DLL
+ numtree_number getMin();
+ QPDF_DLL
+ numtree_number getMax();
+
+ // Return whether the number tree has an explicit entry for this
+ // number.
+ QPDF_DLL
+ bool hasIndex(numtree_number idx);
+
+ // Find an object with a specific index. If found, returns true
+ // and initializes oh.
+ QPDF_DLL
+ bool findObject(numtree_number idx, QPDFObjectHandle& oh);
+ // Find the object at the index or, if not found, the object whose
+ // index is the highest index less than the requested index. If
+ // the requested index is less than the minimum, return false.
+ // Otherwise, return true, initialize oh to the object, and set
+ // offset to the difference between the requested index and the
+ // actual index. For example, if a number tree has values for 3
+ // and 6 and idx is 5, this method would return true, initialize
+ // oh to the value with index 3, and set offset to 2 (5 - 3).
+ QPDF_DLL
+ bool findObjectAtOrBelow(numtree_number idx, QPDFObjectHandle& oh,
+ numtree_number& offset);
+
+ typedef std::map<numtree_number, QPDFObjectHandle> idx_map;
+ QPDF_DLL
+ idx_map getAsMap() const;
+
+ private:
+ class Members
+ {
+ friend class QPDFNumberTreeObjectHelper;
+ typedef QPDFNumberTreeObjectHelper::numtree_number numtree_number;
+
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members();
+ Members(Members const&);
+
+ // Use a reverse sorted map so we can use the lower_bound
+ // method for searching. lower_bound returns smallest entry
+ // not before the searched entry, meaning that the searched
+ // entry is the lower bound. There's also an upper_bound
+ // method, but it does not do what you'd think it should.
+ // lower_bound implements >=, and upper_bound implements >.
+ typedef std::map<numtree_number,
+ QPDFObjectHandle,
+ std::greater<numtree_number> > idx_map;
+ idx_map entries;
+ std::set<QPDFObjGen> seen;
+ };
+
+ void updateMap(QPDFObjectHandle oh);
+
+ PointerHolder<Members> m;
+};
+
+#endif // QPDFNUMBERTREEOBJECTHELPER_HH
diff --git a/include/qpdf/QPDFObjGen.hh b/include/qpdf/QPDFObjGen.hh
index b7b14af1..81c45d9f 100644
--- a/include/qpdf/QPDFObjGen.hh
+++ b/include/qpdf/QPDFObjGen.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDFOBJGEN_HH__
-#define __QPDFOBJGEN_HH__
+#ifndef QPDFOBJGEN_HH
+#define QPDFOBJGEN_HH
#include <qpdf/DLL.h>
@@ -48,4 +48,4 @@ class QPDFObjGen
int gen;
};
-#endif // __QPDFOBJGEN_HH__
+#endif // QPDFOBJGEN_HH
diff --git a/include/qpdf/QPDFObject.hh b/include/qpdf/QPDFObject.hh
index da54c027..9878804b 100644
--- a/include/qpdf/QPDFObject.hh
+++ b/include/qpdf/QPDFObject.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,11 +19,12 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDFOBJECT_HH__
-#define __QPDFOBJECT_HH__
+#ifndef QPDFOBJECT_HH
+#define QPDFOBJECT_HH
#include <qpdf/DLL.h>
#include <qpdf/PointerHolder.hh>
+#include <qpdf/JSON.hh>
#include <string>
@@ -62,6 +63,7 @@ class QPDFObject
virtual ~QPDFObject() {}
virtual std::string unparse() = 0;
+ virtual JSON getJSON() = 0;
// Return a unique type code for the object
virtual object_type_e getTypeCode() const = 0;
@@ -100,6 +102,7 @@ class QPDFObject
{
friend class QPDFObject;
public:
+ QPDF_DLL
~Members();
private:
Members();
@@ -109,4 +112,4 @@ class QPDFObject
PointerHolder<Members> m;
};
-#endif // __QPDFOBJECT_HH__
+#endif // QPDFOBJECT_HH
diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh
index 6e45b5fd..b181bd79 100644
--- a/include/qpdf/QPDFObjectHandle.hh
+++ b/include/qpdf/QPDFObjectHandle.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDFOBJECTHANDLE_HH__
-#define __QPDFOBJECTHANDLE_HH__
+#ifndef QPDFOBJECTHANDLE_HH
+#define QPDFOBJECTHANDLE_HH
#include <qpdf/DLL.h>
#include <qpdf/Types.h>
@@ -198,6 +198,38 @@ class QPDFObjectHandle
double ury;
};
+ // Convenience object for transformation matrices
+ class Matrix
+ {
+ public:
+ Matrix() :
+ a(0.0),
+ b(0.0),
+ c(0.0),
+ d(0.0),
+ e(0.0),
+ f(0.0)
+ {
+ }
+ Matrix(double a, double b, double c,
+ double d, double e, double f) :
+ a(a),
+ b(b),
+ c(c),
+ d(d),
+ e(e),
+ f(f)
+ {
+ }
+
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ };
+
QPDF_DLL
QPDFObjectHandle();
QPDF_DLL
@@ -255,6 +287,12 @@ class QPDFObjectHandle
// Public factory methods
+ // Wrap an object in an array if it is not already an array. This
+ // is a helper for cases in which something in a PDF may either be
+ // a single item or an array of items, which is a common idiom.
+ QPDF_DLL
+ QPDFObjectHandle wrapInArray();
+
// Construct an object of any type from a string representation of
// the object. Throws QPDFExc with an empty filename and an
// offset into the string if there is an error. Any indirect
@@ -362,6 +400,8 @@ class QPDFObjectHandle
QPDF_DLL
static QPDFObjectHandle newArray(Rectangle const&);
QPDF_DLL
+ static QPDFObjectHandle newArray(Matrix const&);
+ QPDF_DLL
static QPDFObjectHandle newDictionary();
QPDF_DLL
static QPDFObjectHandle newDictionary(
@@ -371,6 +411,10 @@ class QPDFObjectHandle
// form of newArray.
QPDF_DLL
static QPDFObjectHandle newFromRectangle(Rectangle const&);
+ // Create an array from a matrix. Equivalent to the matrix
+ // form of newArray.
+ QPDF_DLL
+ static QPDFObjectHandle newFromMatrix(Matrix const&);
// Create a new stream and associate it with the given qpdf
// object. A subsequent call must be made to replaceStreamData()
@@ -494,6 +538,12 @@ class QPDFObjectHandle
// rectangle. Otherwise, return the rectangle [0, 0, 0, 0]
QPDF_DLL
Rectangle getArrayAsRectangle();
+ QPDF_DLL
+ bool isMatrix();
+ // If the array an array of six numeric values, return as a
+ // matrix. Otherwise, return the matrix [1, 0, 0, 1, 0, 0]
+ QPDF_DLL
+ Matrix getArrayAsMatrix();
// Methods for dictionary objects
QPDF_DLL
@@ -509,6 +559,59 @@ class QPDFObjectHandle
QPDF_DLL
bool isOrHasName(std::string const&);
+ // Merge resource dictionaries. Assumes resource dictionaries have
+ // the property that the collection of keys of all first-level
+ // dictionary members contains no duplicates. This method does
+ // nothing if both this object and the other object are not
+ // dictionaries. Otherwise, it has following behavior, where
+ // "object" refers to the object whose method is invoked, and
+ // "other" refers to the argument:
+ //
+ // * For each key in "other" whose value is an array:
+ // * If "object" does not have that entry, shallow copy it.
+ // * Otherwise, if "object" has an array in the same place,
+ // append to that array any objects in "other"'s array that
+ // are not already present.
+ // * For each key in "other" whose value is a dictionary:
+ // * If "object" does not have that entry, shallow copy it.
+ // * Otherwise, for each key in the subdictionary:
+ // * If key is not present in "object"'s entry, shallow copy it.
+ // * Otherwise, ignore. Conflicts are not detected.
+ //
+ // The primary purpose of this method is to facilitate merging of
+ // resource dictionaries that are supposed to have the same scope
+ // as each other. For example, this can be used to merge a form
+ // XObject's /Resources dictionary with a form field's /DR.
+ // Conflicts are not detected. If, in the future, there should be
+ // a need to detect conflicts, this method could detect them and
+ // return a mapping from old to new names. This mapping could be
+ // used for filtering the stream. This would be necessary, for
+ // example, to merge a form XObject's resources with a page's
+ // resources with the intention of concatenating the content
+ // streams.
+ QPDF_DLL
+ void mergeResources(QPDFObjectHandle other);
+
+ // Get all resource names from a resource dictionary. If this
+ // object is a dictionary, this method returns a set of all the
+ // keys in all top-level subdictionaries. For resources
+ // dictionaries, this is the collection of names that may be
+ // referenced in the content stream.
+ QPDF_DLL
+ std::set<std::string> getResourceNames();
+
+ // Find a unique name within a resource dictionary starting with a
+ // given prefix. This method works by appending a number to the
+ // given prefix. It searches starting with min_suffix and sets
+ // min_suffix to selected value upon return. This can be used to
+ // increase efficiency if adding multiple items with the same
+ // prefix. (Why doesn't it set min_suffix to the next number?
+ // Well, maybe you aren't going to actually use the name it
+ // returns.)
+ QPDF_DLL
+ std::string getUniqueResourceName(std::string const& prefix,
+ int& min_suffix);
+
// Return the QPDF object that owns an indirect object. Returns
// null for a direct object.
QPDF_DLL
@@ -727,6 +830,25 @@ class QPDFObjectHandle
QPDF_DLL
std::string unparseBinary();
+ // Return encoded as JSON. For most object types, there is an
+ // obvious mapping. The JSON is generated as follows:
+ // * Names are encoded as strings representing the normalized value of
+ // getName()
+ // * Indirect references are encoded as strings containing "obj gen R"
+ // * Strings are encoded as UTF-8 strings with unrepresentable binary
+ // characters encoded as \uHHHH
+ // * Encoding streams just encodes the stream's dictionary; the stream
+ // data is not represented
+ // * Object types that are only valid in content streams (inline
+ // image, operator) as well as "reserved" objects are not
+ // representable and will be serialized as "null".
+ // If dereference_indirect is true and this is an indirect object,
+ // show the actual contents of the object. The effect of
+ // dereference_indirect applies only to this object. It is not
+ // recursive.
+ QPDF_DLL
+ JSON getJSON(bool dereference_indirect = false);
+
// Legacy helper methods for commonly performed operations on
// pages. Newer code should use QPDFPageObjectHelper instead. The
// specification and behavior of these methods are the same as the
@@ -750,6 +872,7 @@ class QPDFObjectHandle
// do nothing. Objects read normally from the file have
// descriptions. See comments on setObjectDescription for
// additional details.
+ QPDF_DLL
void warnIfPossible(std::string const& warning,
bool throw_if_no_description = false);
@@ -927,4 +1050,4 @@ class QPDFObjectHandle
PointerHolder<Members> m;
};
-#endif // __QPDFOBJECTHANDLE_HH__
+#endif // QPDFOBJECTHANDLE_HH
diff --git a/include/qpdf/QPDFObjectHelper.hh b/include/qpdf/QPDFObjectHelper.hh
index 8aec8955..c61f4c38 100644
--- a/include/qpdf/QPDFObjectHelper.hh
+++ b/include/qpdf/QPDFObjectHelper.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDFOBJECTHELPER_HH__
-#define __QPDFOBJECTHELPER_HH__
+#ifndef QPDFOBJECTHELPER_HH
+#define QPDFOBJECTHELPER_HH
#include <qpdf/DLL.h>
@@ -64,4 +64,4 @@ class QPDFObjectHelper
QPDFObjectHandle oh;
};
-#endif // __QPDFOBJECTHELPER_HH__
+#endif // QPDFOBJECTHELPER_HH
diff --git a/include/qpdf/QPDFOutlineDocumentHelper.hh b/include/qpdf/QPDFOutlineDocumentHelper.hh
new file mode 100644
index 00000000..f1920574
--- /dev/null
+++ b/include/qpdf/QPDFOutlineDocumentHelper.hh
@@ -0,0 +1,108 @@
+// Copyright (c) 2005-2019 Jay Berkenbilt
+//
+// This file is part of qpdf.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Versions of qpdf prior to version 7 were released under the terms
+// of version 2.0 of the Artistic License. At your option, you may
+// continue to consider qpdf to be licensed under those terms. Please
+// see the manual for additional information.
+
+#ifndef QPDFOUTLINEDOCUMENTHELPER_HH
+#define QPDFOUTLINEDOCUMENTHELPER_HH
+
+#include <qpdf/QPDFDocumentHelper.hh>
+#include <qpdf/QPDFOutlineObjectHelper.hh>
+#include <qpdf/QPDFNameTreeObjectHelper.hh>
+
+#include <qpdf/QPDF.hh>
+#include <map>
+#include <list>
+#include <set>
+
+#include <qpdf/DLL.h>
+
+// This is a document helper for outlines, also known as bookmarks.
+// Outlines are discussed in section 12.3.3 of the PDF spec
+// (ISO-32000). With the help of QPDFOutlineObjectHelper, the outlines
+// tree is traversed, and a bidirectional map is made between pages
+// and outlines. See also QPDFOutlineObjectHelper.
+
+class QPDFOutlineDocumentHelper: public QPDFDocumentHelper
+{
+ public:
+ QPDF_DLL
+ QPDFOutlineDocumentHelper(QPDF&);
+ QPDF_DLL
+ virtual ~QPDFOutlineDocumentHelper();
+
+ QPDF_DLL
+ bool hasOutlines();
+
+ QPDF_DLL
+ std::list<QPDFOutlineObjectHelper> getTopLevelOutlines();
+
+ // If the name is a name object, look it up in the /Dests key of
+ // the document catalog. If the name is a string, look it up in
+ // the name tree pointed to by the /Dests key of the names
+ // dictionary.
+ QPDF_DLL
+ QPDFObjectHandle
+ resolveNamedDest(QPDFObjectHandle name);
+
+ // Return a list outlines that are known to target the specified
+ // page
+ QPDF_DLL
+ std::list<QPDFOutlineObjectHelper> getOutlinesForPage(QPDFObjGen const&);
+
+ class Accessor
+ {
+ friend class QPDFOutlineObjectHelper;
+
+ QPDF_DLL
+ static bool
+ checkSeen(QPDFOutlineDocumentHelper& dh, QPDFObjGen const& og)
+ {
+ return dh.checkSeen(og);
+ }
+ };
+ friend class Accessor;
+
+ private:
+ bool checkSeen(QPDFObjGen const& og);
+ void initializeByPage();
+
+ class Members
+ {
+ friend class QPDFOutlineDocumentHelper;
+
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members();
+ Members(Members const&);
+
+ std::list<QPDFOutlineObjectHelper> outlines;
+ std::set<QPDFObjGen> seen;
+ QPDFObjectHandle dest_dict;
+ PointerHolder<QPDFNameTreeObjectHelper> names_dest;
+ std::map<QPDFObjGen, std::list<QPDFOutlineObjectHelper> > by_page;
+ };
+
+ PointerHolder<Members> m;
+};
+
+#endif // QPDFOUTLINEDOCUMENTHELPER_HH
diff --git a/include/qpdf/QPDFOutlineObjectHelper.hh b/include/qpdf/QPDFOutlineObjectHelper.hh
new file mode 100644
index 00000000..9063b86f
--- /dev/null
+++ b/include/qpdf/QPDFOutlineObjectHelper.hh
@@ -0,0 +1,122 @@
+// Copyright (c) 2005-2019 Jay Berkenbilt
+//
+// This file is part of qpdf.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Versions of qpdf prior to version 7 were released under the terms
+// of version 2.0 of the Artistic License. At your option, you may
+// continue to consider qpdf to be licensed under those terms. Please
+// see the manual for additional information.
+
+#ifndef QPDFOUTLINEOBJECTHELPER_HH
+#define QPDFOUTLINEOBJECTHELPER_HH
+
+#include <qpdf/QPDFObjectHelper.hh>
+#include <qpdf/QPDFObjGen.hh>
+#include <list>
+
+class QPDFOutlineDocumentHelper;
+
+#include <qpdf/DLL.h>
+
+// This is an object helper for outline items. Outlines, also known as
+// bookmarks, are described in section 12.3.3 of the PDF spec
+// (ISO-32000). See comments below for details.
+
+class QPDFOutlineObjectHelper: public QPDFObjectHelper
+{
+ public:
+ QPDF_DLL
+ virtual ~QPDFOutlineObjectHelper()
+ {
+ // This must be cleared explicitly to avoid circular references
+ // that prevent cleanup of pointer holders.
+ this->m->parent = 0;
+ }
+
+ // All constructors are private. You can only create one of these
+ // using QPDFOutlineDocumentHelper.
+
+ // Return parent pointer. Returns a null pointer if this is a
+ // top-level outline.
+ QPDF_DLL
+ PointerHolder<QPDFOutlineObjectHelper> getParent();
+
+ // Return children as a list.
+ QPDF_DLL
+ std::list<QPDFOutlineObjectHelper> getKids();
+
+ // Return the destination, regardless of whether it is named or
+ // explicit and whether it is directly provided or in a GoTo
+ // action. Returns a null object if the destination can't be
+ // determined. Named destinations can be resolved using the older
+ // root /Dest dictionary or the current names tree.
+ QPDF_DLL
+ QPDFObjectHandle getDest();
+
+ // Return the page that the outline points to. Returns a null
+ // object if the destination page can't be determined.
+ QPDF_DLL
+ QPDFObjectHandle getDestPage();
+
+ // Returns the value of /Count as present in the object, or 0 if
+ // not present. If count is positive, the outline is open. If
+ // negative, it is closed. Either way, the absolute value is the
+ // number descendant items that would be visible if this were
+ // open.
+ QPDF_DLL
+ int getCount();
+
+ // Returns the title as a UTF-8 string. Returns the empty string
+ // if there is no title.
+ QPDF_DLL
+ std::string getTitle();
+
+ class Accessor
+ {
+ friend class QPDFOutlineDocumentHelper;
+
+ static QPDFOutlineObjectHelper
+ create(QPDFObjectHandle oh, QPDFOutlineDocumentHelper& dh, int depth)
+ {
+ return QPDFOutlineObjectHelper(oh, dh, depth);
+ }
+ };
+ friend class Accessor;
+
+ private:
+ QPDF_DLL
+ QPDFOutlineObjectHelper(QPDFObjectHandle, QPDFOutlineDocumentHelper&, int);
+
+ class Members
+ {
+ friend class QPDFOutlineObjectHelper;
+
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members(QPDFOutlineDocumentHelper& dh);
+ Members(Members const&);
+
+ QPDFOutlineDocumentHelper& dh;
+ PointerHolder<QPDFOutlineObjectHelper> parent;
+ std::list<QPDFOutlineObjectHelper> kids;
+ };
+
+ PointerHolder<Members> m;
+};
+
+#endif // QPDFOUTLINEOBJECTHELPER_HH
diff --git a/include/qpdf/QPDFPageDocumentHelper.hh b/include/qpdf/QPDFPageDocumentHelper.hh
index 514f7277..096a401c 100644
--- a/include/qpdf/QPDFPageDocumentHelper.hh
+++ b/include/qpdf/QPDFPageDocumentHelper.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,11 +19,12 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDFPAGEDOCUMENTHELPER_HH__
-#define __QPDFPAGEDOCUMENTHELPER_HH__
+#ifndef QPDFPAGEDOCUMENTHELPER_HH
+#define QPDFPAGEDOCUMENTHELPER_HH
#include <qpdf/QPDFDocumentHelper.hh>
#include <qpdf/QPDFPageObjectHelper.hh>
+#include <qpdf/Constants.h>
#include <qpdf/DLL.h>
@@ -31,11 +32,17 @@
#include <qpdf/QPDF.hh>
+class QPDFAcroFormDocumentHelper;
+
class QPDFPageDocumentHelper: public QPDFDocumentHelper
{
public:
QPDF_DLL
QPDFPageDocumentHelper(QPDF&);
+ QPDF_DLL
+ virtual ~QPDFPageDocumentHelper()
+ {
+ }
// Traverse page tree, and return all /Page objects wrapped in
// QPDFPageObjectHelper objects. Unlike with
@@ -66,7 +73,12 @@ class QPDFPageDocumentHelper: public QPDFDocumentHelper
// indirect. If it is an indirect object from another QPDF, this
// method will call pushInheritedAttributesToPage on the other
// file and then copy the page to this QPDF using the same
- // underlying code as copyForeignObject.
+ // underlying code as copyForeignObject. Note that you can call
+ // copyForeignObject directly to copy a page from a different
+ // file, but the resulting object will not be a page in the new
+ // file. You could do this, for example, to convert a page into a
+ // form XObject, though for that, you're better off using
+ // QPDFPageObjectHelper::getFormXObjectForPage.
QPDF_DLL
void addPage(QPDFPageObjectHelper newpage, bool first);
@@ -80,7 +92,30 @@ class QPDFPageDocumentHelper: public QPDFDocumentHelper
QPDF_DLL
void removePage(QPDFPageObjectHelper page);
+ // For every annotation, integrate the annotation's appearance
+ // stream into the containing page's content streams, merge the
+ // annotation's resources with the page's resources, and remove
+ // the annotation from the page. Handles widget annotations
+ // associated with interactive form fields as a special case,
+ // including removing the /AcroForm key from the document catalog.
+ // The values passed to required_flags and forbidden_flags are
+ // passed along to
+ // QPDFAnnotationObjectHelper::getPageContentForAppearance. See
+ // comments there in QPDFAnnotationObjectHelper.hh for meanings of
+ // those flags.
+ QPDF_DLL
+ void flattenAnnotations(
+ int required_flags = 0,
+ int forbidden_flags = an_invisible | an_hidden);
+
private:
+ void flattenAnnotationsForPage(
+ QPDFPageObjectHelper& page,
+ QPDFObjectHandle& resources,
+ QPDFAcroFormDocumentHelper& afdh,
+ int required_flags,
+ int forbidden_flags);
+
class Members
{
friend class QPDFPageDocumentHelper;
@@ -97,4 +132,4 @@ class QPDFPageDocumentHelper: public QPDFDocumentHelper
PointerHolder<Members> m;
};
-#endif // __QPDFPAGEDOCUMENTHELPER_HH__
+#endif // QPDFPAGEDOCUMENTHELPER_HH
diff --git a/include/qpdf/QPDFPageLabelDocumentHelper.hh b/include/qpdf/QPDFPageLabelDocumentHelper.hh
new file mode 100644
index 00000000..2ad05934
--- /dev/null
+++ b/include/qpdf/QPDFPageLabelDocumentHelper.hh
@@ -0,0 +1,104 @@
+// Copyright (c) 2005-2019 Jay Berkenbilt
+//
+// This file is part of qpdf.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Versions of qpdf prior to version 7 were released under the terms
+// of version 2.0 of the Artistic License. At your option, you may
+// continue to consider qpdf to be licensed under those terms. Please
+// see the manual for additional information.
+
+#ifndef QPDFPAGELABELDOCUMENTHELPER_HH
+#define QPDFPAGELABELDOCUMENTHELPER_HH
+
+#include <qpdf/QPDFDocumentHelper.hh>
+
+#include <qpdf/QPDF.hh>
+#include <qpdf/QPDFNumberTreeObjectHelper.hh>
+#include <vector>
+
+#include <qpdf/DLL.h>
+
+// Page labels are discussed in the PDF spec (ISO-32000) in section
+// 12.4.2.
+//
+// Page labels are implemented as a number tree. Each key is a page
+// index, numbered from 0. The values are dictionaries with the
+// following keys, all optional:
+//
+// * /Type: if present, must be /PageLabel
+// * /S: one of /D, /R, /r, /A, or /a for decimal, upper-case and
+// lower-case Roman numeral, or upper-case and lower-case alphabetic
+// * /P: if present, a fixed prefix string that is prepended to each
+// page number
+// * /St: the starting number, or 1 if not specified
+
+class QPDFPageLabelDocumentHelper: public QPDFDocumentHelper
+{
+ public:
+ QPDF_DLL
+ QPDFPageLabelDocumentHelper(QPDF&);
+ QPDF_DLL
+ virtual ~QPDFPageLabelDocumentHelper()
+ {
+ }
+
+ QPDF_DLL
+ bool hasPageLabels();
+
+ // Return a page label dictionary representing the page label for
+ // the given page. The page does not need to appear explicitly in
+ // the page label dictionary. This method will adjust /St as
+ // needed to produce a label that is suitable for the page.
+ QPDF_DLL
+ QPDFObjectHandle getLabelForPage(long long page_idx);
+
+ // Append to the incoming vector a list of objects suitable for
+ // inclusion in a /PageLabels dictionary's /Nums field. start_idx
+ // and end_idx are the indexes to the starting and ending pages
+ // (inclusive) in the original file, and new_start_idx is the
+ // index to the first page in the new file. For example, if pages
+ // 10 through 12 of one file are being copied to a new file as
+ // pages 6 through 8, you would call getLabelsForPageRange(10, 12,
+ // 6), which would return as many entries as are required to add
+ // to the new file's PageLabels. This method fabricates a suitable
+ // entry even if the original document has no page labels. This
+ // behavior facilitates using this function to incrementally build
+ // up a page labels tree when merging files.
+ QPDF_DLL
+ void
+ getLabelsForPageRange(long long start_idx, long long end_idx,
+ long long new_start_idx,
+ std::vector<QPDFObjectHandle>& new_labels);
+
+ private:
+ class Members
+ {
+ friend class QPDFPageLabelDocumentHelper;
+
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members();
+ Members(Members const&);
+
+ PointerHolder<QPDFNumberTreeObjectHelper> labels;
+ };
+
+ PointerHolder<Members> m;
+};
+
+#endif // QPDFPAGELABELDOCUMENTHELPER_HH
diff --git a/include/qpdf/QPDFPageObjectHelper.hh b/include/qpdf/QPDFPageObjectHelper.hh
index 08a7d8ab..d7291723 100644
--- a/include/qpdf/QPDFPageObjectHelper.hh
+++ b/include/qpdf/QPDFPageObjectHelper.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDFPAGEOBJECTHELPER_HH__
-#define __QPDFPAGEOBJECTHELPER_HH__
+#ifndef QPDFPAGEOBJECTHELPER_HH
+#define QPDFPAGEOBJECTHELPER_HH
#include <qpdf/QPDFObjectHelper.hh>
#include <qpdf/QPDFAnnotationObjectHelper.hh>
@@ -34,17 +34,50 @@ class QPDFPageObjectHelper: public QPDFObjectHelper
public:
QPDF_DLL
QPDFPageObjectHelper(QPDFObjectHandle);
+ QPDF_DLL
+ virtual ~QPDFPageObjectHelper()
+ {
+ }
+
+ // Return the effective value of this attribute for the page. If
+ // the requested attribute is not present on the page but is
+ // inheritable, look up through the page's ancestors in the page
+ // tree. If copy_if_shared is true, then this method will replace
+ // the attribute with a shallow copy if it is in indirect or
+ // inherited and return the copy. You should do this if you are
+ // going to modify the returned object and want the modifications
+ // to apply to the current page only.
+ QPDF_DLL
+ QPDFObjectHandle
+ getAttribute(std::string const& name, bool copy_if_shared);
+
+ // Return the TrimBox. If not defined, fall back to CropBox
+ QPDF_DLL
+ QPDFObjectHandle
+ getTrimBox(bool copy_if_shared = false);
+
+ // Return the CropBox. If not defined, fall back to MediaBox
+ QPDF_DLL
+ QPDFObjectHandle
+ getCropBox(bool copy_if_shared = false);
+
+ // Return the MediaBox
+ QPDF_DLL
+ QPDFObjectHandle
+ getMediaBox(bool copy_if_shared = false);
// Returns an empty map if there are no images or no resources.
- // This function does not presently support inherited resources.
- // If this is a significant concern, call
- // pushInheritedAttributesToPage() on the QPDF object that owns
- // this page. See comment in the source for details. Return value
- // is a map from XObject name to the image object, which is always
- // a stream.
+ // Prior to qpdf 8.4.0, this function did not support inherited
+ // resources, but it does now. Return value is a map from XObject
+ // name to the image object, which is always a stream.
QPDF_DLL
std::map<std::string, QPDFObjectHandle> getPageImages();
+ // Convert each inline image to an external (normal) image if the
+ // size is at least the specified number of bytes.
+ QPDF_DLL
+ void externalizeInlineImages(size_t min_size = 0);
+
// Return the annotations in the page's "/Annots" list, if any. If
// only_subtype is non-empty, only include annotations of the
// given subtype.
@@ -136,6 +169,67 @@ class QPDFPageObjectHelper: public QPDFObjectHelper
QPDF_DLL
void removeUnreferencedResources();
+ // Return a new QPDFPageDocumentHelper that is a duplicate of the
+ // page. The returned object is an indirect object that is ready
+ // to be inserted into the same or a different QPDF object using
+ // any of the addPage methods in QPDFPageDocumentHelper or QPDF.
+ // Without calling one of those methods, the page will not be
+ // added anywhere. The new page object shares all content streams
+ // and indirect object resources with the original page, so if you
+ // are going to modify the contents or other aspects of the page,
+ // you will need to handling copying of the component parts
+ // separately.
+ QPDF_DLL
+ QPDFPageObjectHelper shallowCopyPage();
+
+ // Return a transformation matrix whose effect is the same as the
+ // page's /Rotate and /UserUnit parameters. If invert is true,
+ // return a matrix whose effect is the opposite. The regular
+ // matrix is suitable for taking something from this page to put
+ // elsewhere, and the second one is suitable for putting something
+ // else onto this page. The page's TrimBox is used as the bounding
+ // box for purposes of computing the matrix.
+ QPDF_DLL
+ QPDFObjectHandle::Matrix getMatrixForTransformations(bool invert = false);
+
+ // Return a form XObject that draws this page. This is useful for
+ // n-up operations, underlay, overlay, thumbnail generation, or
+ // any other case in which it is useful to replicate the contents
+ // of a page in some other context. The dictionaries are shallow
+ // copies of the original page dictionary, and the contents are
+ // coalesced from the page's contents. The resulting object handle
+ // is not referenced anywhere. If handle_transformations is true,
+ // the resulting form XObject's /Matrix will be set to replicate
+ // rotation (/Rotate) and scaling (/UserUnit) in the page's
+ // dictionary. In this way, the page's transformations will be
+ // preserved when placing this object on another page.
+ QPDF_DLL
+ QPDFObjectHandle getFormXObjectForPage(bool handle_transformations = true);
+
+ // Return content stream text that will place the given form
+ // XObject (fo) using the resource name "name" on this page
+ // centered within the given rectangle and shrunk to fit if
+ // necessary. If invert_transformations is true, the effect of any
+ // rotation (/Rotate) and scaling (/UserUnit) applied to the
+ // current page will be inverted in the form XObject placement.
+ // This will cause the form XObject's absolute orientation to be
+ // preserved. You could overlay one page on another by calling
+ // getFormXObjectForPage on the original page,
+ // QPDFObjectHandle::getUniqueResourceName on the destination
+ // page's Resources dictionary to generate a name for the
+ // resulting object, and calling placeFormXObject on the
+ // destination page. Then insert the new fo (or, if it comes from
+ // a different file, the result of calling copyForeignObject on
+ // it) into the resources dictionary using name, and append or
+ // prepend the content to the page's content streams. See the
+ // overlay/underlay code in qpdf.cc or
+ // examples/pdf-overlay-page.cc for an example.
+ QPDF_DLL
+ std::string placeFormXObject(
+ QPDFObjectHandle fo, std::string name,
+ QPDFObjectHandle::Rectangle rect,
+ bool invert_transformations = true);
+
private:
class Members
{
@@ -153,4 +247,4 @@ class QPDFPageObjectHelper: public QPDFObjectHelper
PointerHolder<Members> m;
};
-#endif // __QPDFPAGEOBJECTHELPER_HH__
+#endif // QPDFPAGEOBJECTHELPER_HH
diff --git a/include/qpdf/QPDFSystemError.hh b/include/qpdf/QPDFSystemError.hh
new file mode 100644
index 00000000..c4e48713
--- /dev/null
+++ b/include/qpdf/QPDFSystemError.hh
@@ -0,0 +1,58 @@
+// Copyright (c) 2005-2019 Jay Berkenbilt
+//
+// This file is part of qpdf.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Versions of qpdf prior to version 7 were released under the terms
+// of version 2.0 of the Artistic License. At your option, you may
+// continue to consider qpdf to be licensed under those terms. Please
+// see the manual for additional information.
+
+#ifndef QPDFSYSTEMERROR_HH
+#define QPDFSYSTEMERROR_HH
+
+#include <qpdf/DLL.h>
+#include <qpdf/Types.h>
+
+#include <qpdf/Constants.h>
+#include <string>
+#include <stdexcept>
+
+class QPDFSystemError: public std::runtime_error
+{
+ public:
+ QPDF_DLL
+ QPDFSystemError(std::string const& description,
+ int system_errno);
+ QPDF_DLL
+ virtual ~QPDFSystemError() throw ();
+
+ // To get a complete error string, call what(), provided by
+ // std::exception. The accessors below return the original values
+ // used to create the exception.
+
+ QPDF_DLL
+ std::string const& getDescription() const;
+ QPDF_DLL
+ int getErrno() const;
+
+ private:
+ static std::string createWhat(std::string const& description,
+ int system_errno);
+
+ std::string description;
+ int system_errno;
+};
+
+#endif // QPDFSYSTEMERROR_HH
diff --git a/include/qpdf/QPDFTokenizer.hh b/include/qpdf/QPDFTokenizer.hh
index eb9215aa..ed33e13c 100644
--- a/include/qpdf/QPDFTokenizer.hh
+++ b/include/qpdf/QPDFTokenizer.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDFTOKENIZER_HH__
-#define __QPDFTOKENIZER_HH__
+#ifndef QPDFTOKENIZER_HH
+#define QPDFTOKENIZER_HH
#include <qpdf/DLL.h>
@@ -174,11 +174,25 @@ class QPDFTokenizer
size_t max_len = 0);
// Calling this method puts the tokenizer in a state for reading
- // inline images. In that state, it will return all data up to and
- // including the next EI token. After you call this method, the
- // next call to readToken (or the token created next time getToken
- // returns true) will either be tt_inline_image or tt_bad. This is
- // the only way readToken returns a tt_inline_image token.
+ // inline images. You should call this method after reading the
+ // character following the ID operator. In that state, it will
+ // return all data up to BUT NOT INCLUDING the next EI token. This
+ // is a difference in behavior from the legacy version. After you
+ // call this method, the next call to readToken (or the token
+ // created next time getToken returns true) will either be
+ // tt_inline_image or tt_bad. This is the only way readToken
+ // returns a tt_inline_image token. The older version of this
+ // method that takes does not take a PointerHolder<InputSource>
+ // will always end the inline image the first time it sees
+ // something that looks like an EI operator and will include the
+ // EI operator in the token. It is being maintained for backward
+ // compatibility only and will likely be removed in the future.
+ QPDF_DLL
+ void expectInlineImage(PointerHolder<InputSource> input);
+
+ // Legacy version. New code should not call this. The token
+ // returned will include the EI keyword. The recipient of the
+ // token will have to remove it.
QPDF_DLL
void expectInlineImage();
@@ -190,6 +204,7 @@ class QPDFTokenizer
void resolveLiteral();
bool isSpace(char);
bool isDelimiter(char);
+ void findEI(PointerHolder<InputSource> input);
enum state_e {
st_top, st_in_space, st_in_comment, st_in_string, st_lt, st_gt,
@@ -223,14 +238,16 @@ class QPDFTokenizer
std::string error_message;
bool unread_char;
char char_to_unread;
+ size_t inline_image_bytes;
// State for strings
int string_depth;
bool string_ignoring_newline;
char bs_num_register[4];
bool last_char_was_bs;
+ bool last_char_was_cr;
};
PointerHolder<Members> m;
};
-#endif // __QPDFTOKENIZER_HH__
+#endif // QPDFTOKENIZER_HH
diff --git a/include/qpdf/QPDFWriter.hh b/include/qpdf/QPDFWriter.hh
index 1802078a..1aa4e8a8 100644
--- a/include/qpdf/QPDFWriter.hh
+++ b/include/qpdf/QPDFWriter.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -23,8 +23,8 @@
// new PDF files. See comments through the header file for additional
// details.
-#ifndef __QPDFWRITER_HH__
-#define __QPDFWRITER_HH__
+#ifndef QPDFWRITER_HH
+#define QPDFWRITER_HH
#include <qpdf/DLL.h>
#include <qpdf/Types.h>
@@ -343,6 +343,49 @@ class QPDFWriter
// setting R4 parameters pushes the version to at least 1.5, or if
// AES is used, 1.6, and setting R5 or R6 parameters pushes the
// version to at least 1.7 with extension level 3.
+ //
+ // Note about Unicode passwords: the PDF specification requires
+ // passwords to be encoded with PDF Doc encoding for R <= 4 and
+ // UTF-8 for R >= 5. In all cases, these methods take strings of
+ // bytes as passwords. It is up to the caller to ensure that
+ // passwords are properly encoded. The qpdf command-line tool
+ // tries to do this, as discussed in the manual. If you are doing
+ // this from your own application, QUtil contains many transcoding
+ // functions that could be useful to you, most notably
+ // utf8_to_pdf_doc.
+ QPDF_DLL
+ void setR3EncryptionParameters(
+ char const* user_password, char const* owner_password,
+ bool allow_accessibility, bool allow_extract,
+ bool allow_assemble, bool allow_annotate_and_form,
+ bool allow_form_filling, bool allow_modify_other,
+ qpdf_r3_print_e print);
+ QPDF_DLL
+ void setR4EncryptionParameters(
+ char const* user_password, char const* owner_password,
+ bool allow_accessibility, bool allow_extract,
+ bool allow_assemble, bool allow_annotate_and_form,
+ bool allow_form_filling, bool allow_modify_other,
+ qpdf_r3_print_e print, bool encrypt_metadata, bool use_aes);
+ // R5 is deprecated. Do not use it for production use. Writing
+ // R5 is supported by qpdf primarily to generate test files for
+ // applications that may need to test R5 support.
+ QPDF_DLL
+ void setR5EncryptionParameters(
+ char const* user_password, char const* owner_password,
+ bool allow_accessibility, bool allow_extract,
+ bool allow_assemble, bool allow_annotate_and_form,
+ bool allow_form_filling, bool allow_modify_other,
+ qpdf_r3_print_e print, bool encrypt_metadata);
+ QPDF_DLL
+ void setR6EncryptionParameters(
+ char const* user_password, char const* owner_password,
+ bool allow_accessibility, bool allow_extract,
+ bool allow_assemble, bool allow_annotate_and_form,
+ bool allow_form_filling, bool allow_modify_other,
+ qpdf_r3_print_e print, bool encrypt_metadata_aes);
+
+ // Pre qpdf 8.4.0 API
QPDF_DLL
void setR2EncryptionParameters(
char const* user_password, char const* owner_password,
@@ -359,9 +402,6 @@ class QPDFWriter
bool allow_accessibility, bool allow_extract,
qpdf_r3_print_e print, qpdf_r3_modify_e modify,
bool encrypt_metadata, bool use_aes);
- // R5 is deprecated. Do not use it for production use. Writing
- // R5 is supported by qpdf primarily to generate test files for
- // applications that may need to test R5 support.
QPDF_DLL
void setR5EncryptionParameters(
char const* user_password, char const* owner_password,
@@ -404,6 +444,18 @@ class QPDFWriter
QPDF_DLL
void registerProgressReporter(PointerHolder<ProgressReporter>);
+ // Return the PDF version that will be written into the header.
+ // Calling this method does all the preparation for writing, so it
+ // is an error to call any methods that may cause a change to the
+ // version. Adding new objects to the original file after calling
+ // this may also cause problems. It is safe to update existing
+ // objects or stream contents after calling this method, e.g., to
+ // include the final version number in metadata.
+ QPDF_DLL
+ std::string getFinalVersion();
+
+ // Write the final file. There is no expectation of being able to
+ // call write() more than once.
QPDF_DLL
void write();
@@ -447,6 +499,8 @@ class QPDFWriter
std::set<int>& bits_to_clear,
char const* user_password, char const* owner_password,
bool allow_accessibility, bool allow_extract,
+ bool allow_assemble, bool allow_annotate_and_form,
+ bool allow_form_filling, bool allow_modify_other,
qpdf_r3_print_e print, qpdf_r3_modify_e modify);
void disableIncompatibleEncryption(int major, int minor,
int extension_level);
@@ -473,6 +527,7 @@ class QPDFWriter
void writeLinearized();
void enqueuePart(std::vector<QPDFObjectHandle>& part);
void writeEncryptionDictionary();
+ void doWriteSetup();
void writeHeader();
void writeHintStream(int hint_id);
qpdf_offset_t writeXRefTable(
@@ -530,6 +585,7 @@ class QPDFWriter
friend class QPDFWriter;
public:
+ QPDF_DLL
~Members();
private:
@@ -597,6 +653,7 @@ class QPDFWriter
bool deterministic_id;
Pl_MD5* md5_pipeline;
std::string deterministic_id_data;
+ bool did_write_setup;
// For linearization only
std::string lin_pass1_filename;
@@ -616,4 +673,4 @@ class QPDFWriter
PointerHolder<Members> m;
};
-#endif // __QPDFWRITER_HH__
+#endif // QPDFWRITER_HH
diff --git a/include/qpdf/QPDFXRefEntry.hh b/include/qpdf/QPDFXRefEntry.hh
index d85e54da..ee3cf746 100644
--- a/include/qpdf/QPDFXRefEntry.hh
+++ b/include/qpdf/QPDFXRefEntry.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QPDFXREFENTRY_HH__
-#define __QPDFXREFENTRY_HH__
+#ifndef QPDFXREFENTRY_HH
+#define QPDFXREFENTRY_HH
#include <qpdf/DLL.h>
#include <qpdf/Types.h>
@@ -54,4 +54,4 @@ class QPDFXRefEntry
int field2;
};
-#endif // __QPDFXREFENTRY_HH__
+#endif // QPDFXREFENTRY_HH
diff --git a/include/qpdf/QTC.hh b/include/qpdf/QTC.hh
index 1de779db..048f1794 100644
--- a/include/qpdf/QTC.hh
+++ b/include/qpdf/QTC.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QTC_HH__
-#define __QTC_HH__
+#ifndef QTC_HH
+#define QTC_HH
#include <qpdf/DLL.h>
@@ -30,4 +30,4 @@ namespace QTC
void TC(char const* const scope, char const* const ccase, int n = 0);
};
-#endif // __QTC_HH__
+#endif // QTC_HH
diff --git a/include/qpdf/QUtil.hh b/include/qpdf/QUtil.hh
index a81b0a9e..02dec5ad 100644
--- a/include/qpdf/QUtil.hh
+++ b/include/qpdf/QUtil.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,13 +19,14 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __QUTIL_HH__
-#define __QUTIL_HH__
+#ifndef QUTIL_HH
+#define QUTIL_HH
#include <qpdf/DLL.h>
#include <qpdf/Types.h>
#include <string>
#include <list>
+#include <vector>
#include <stdexcept>
#include <stdio.h>
#include <time.h>
@@ -61,9 +62,14 @@ namespace QUtil
QPDF_DLL
unsigned char* unsigned_char_pointer(char const* str);
- // Throw std::runtime_error with a string formed by appending to
+ // Throw QPDFSystemError, which is derived from
+ // std::runtime_error, with a string formed by appending to
// "description: " the standard string corresponding to the
- // current value of errno.
+ // current value of errno. You can retrieve the value of errno by
+ // calling getErrno() on the QPDFSystemError. Prior to qpdf 8.2.0,
+ // this method threw system::runtime_error directly, but since
+ // QPDFSystemError is derived from system::runtime_error, old code
+ // that specifically catches std::runtime_error will still work.
QPDF_DLL
void throw_system_error(std::string const& description);
@@ -141,11 +147,104 @@ namespace QUtil
std::string toUTF8(unsigned long uval);
// Return a string containing the byte representation of the
- // UTF-16 BE encoding for the unicode value passed in.
+ // UTF-16 big-endian encoding for the unicode value passed in.
// Unrepresentable code points are converted to U+FFFD.
QPDF_DLL
std::string toUTF16(unsigned long uval);
+ // Test whether this is a UTF-16 big-endian string. This is
+ // indicated by first two bytes being 0xFE 0xFF.
+ QPDF_DLL
+ bool is_utf16(std::string const&);
+
+ // Convert a UTF-8 encoded string to UTF-16 big-endian.
+ // Unrepresentable code points are converted to U+FFFD.
+ QPDF_DLL
+ std::string utf8_to_utf16(std::string const& utf8);
+
+ // Convert a UTF-8 encoded string to the specified single-byte
+ // encoding system by replacing all unsupported characters with
+ // the given unknown_char.
+ QPDF_DLL
+ std::string utf8_to_ascii(
+ std::string const& utf8, char unknown_char = '?');
+ QPDF_DLL
+ std::string utf8_to_win_ansi(
+ std::string const& utf8, char unknown_char = '?');
+ QPDF_DLL
+ std::string utf8_to_mac_roman(
+ std::string const& utf8, char unknown_char = '?');
+ QPDF_DLL
+ std::string utf8_to_pdf_doc(
+ std::string const& utf8, char unknown_char = '?');
+
+ // These versions return true if the conversion was successful and
+ // false if any unrepresentable characters were found and had to
+ // be substituted with the unknown character.
+ QPDF_DLL
+ bool utf8_to_ascii(
+ std::string const& utf8, std::string& ascii, char unknown_char = '?');
+ QPDF_DLL
+ bool utf8_to_win_ansi(
+ std::string const& utf8, std::string& win, char unknown_char = '?');
+ QPDF_DLL
+ bool utf8_to_mac_roman(
+ std::string const& utf8, std::string& mac, char unknown_char = '?');
+ QPDF_DLL
+ bool utf8_to_pdf_doc(
+ std::string const& utf8, std::string& pdfdoc, char unknown_char = '?');
+
+ // Convert a UTF-16 big-endian encoded string to UTF-8.
+ // Unrepresentable code points are converted to U+FFFD.
+ QPDF_DLL
+ std::string utf16_to_utf8(std::string const& utf16);
+
+ // Convert from the specified single-byte encoding system to
+ // UTF-8. There is no ascii_to_utf8 because all ASCII strings are
+ // already valid UTF-8.
+ QPDF_DLL
+ std::string win_ansi_to_utf8(std::string const& win);
+ QPDF_DLL
+ std::string mac_roman_to_utf8(std::string const& mac);
+ QPDF_DLL
+ std::string pdf_doc_to_utf8(std::string const& pdfdoc);
+
+ // Analyze a string for encoding. We can't tell the difference
+ // between any single-byte encodings, and we can't tell for sure
+ // whether a string that happens to be valid UTF-8 isn't a
+ // different encoding, but we can at least tell a few things to
+ // help us guess. If there are no characters with the high bit
+ // set, has_8bit_chars is false, and the other values are also
+ // false, even though ASCII strings are valid UTF-8. is_valid_utf8
+ // means that the string is non-trivially valid UTF-8.
+ QPDF_DLL
+ void analyze_encoding(std::string const& str,
+ bool& has_8bit_chars,
+ bool& is_valid_utf8,
+ bool& is_utf16);
+
+ // Try to compensate for previously incorrectly encoded strings.
+ // We want to compensate for the following errors:
+ //
+ // * The string was supposed to be UTF-8 but was one of the
+ // single-byte encodings
+ // * The string was supposed to be PDF Doc but was either UTF-8 or
+ // one of the other single-byte encodings
+ //
+ // The returned vector always contains the original string first,
+ // and then it contains what the correct string would be in the
+ // event that the original string was the result of any of the
+ // above errors.
+ //
+ // This method is useful for attempting to recover a password that
+ // may have been previously incorrectly encoded. For example, the
+ // password was supposed to be UTF-8 but the previous application
+ // used a password encoded in WinAnsi, or if the previous password
+ // was supposed to be PDFDoc but was actually given as UTF-8 or
+ // WinAnsi, this method would find the correct password.
+ QPDF_DLL
+ std::vector<std::string> possible_repaired_encodings(std::string);
+
// If secure random number generation is supported on your
// platform and qpdf was not compiled with insecure random number
// generation, this returns a cryptographically secure random
@@ -215,6 +314,11 @@ namespace QUtil
QPDF_DLL
bool is_number(char const*);
+
+ // This method parses the numeric range syntax used by the qpdf
+ // command-line tool. May throw std::runtime_error.
+ QPDF_DLL
+ std::vector<int> parse_numrange(char const* range, int max);
};
-#endif // __QUTIL_HH__
+#endif // QUTIL_HH
diff --git a/include/qpdf/RandomDataProvider.hh b/include/qpdf/RandomDataProvider.hh
index 59849289..c3a519aa 100644
--- a/include/qpdf/RandomDataProvider.hh
+++ b/include/qpdf/RandomDataProvider.hh
@@ -1,4 +1,4 @@
-// Copyright (c) 2005-2018 Jay Berkenbilt
+// Copyright (c) 2005-2019 Jay Berkenbilt
//
// This file is part of qpdf.
//
@@ -19,8 +19,8 @@
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
-#ifndef __RANDOMDATAPROVIDER_HH__
-#define __RANDOMDATAPROVIDER_HH__
+#ifndef RANDOMDATAPROVIDER_HH
+#define RANDOMDATAPROVIDER_HH
#include <string.h> // for size_t
@@ -42,4 +42,4 @@ class RandomDataProvider
RandomDataProvider& operator=(RandomDataProvider const&);
};
-#endif // __RANDOMDATAPROVIDER_HH__
+#endif // RANDOMDATAPROVIDER_HH
diff --git a/include/qpdf/Types.h b/include/qpdf/Types.h
index ae959fed..aa0695f1 100644
--- a/include/qpdf/Types.h
+++ b/include/qpdf/Types.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005-2018 Jay Berkenbilt
+/* Copyright (c) 2005-2019 Jay Berkenbilt
*
* This file is part of qpdf.
*
@@ -20,8 +20,8 @@
* see the manual for additional information.
*/
-#ifndef __QPDFTYPES_H__
-#define __QPDFTYPES_H__
+#ifndef QPDFTYPES_H
+#define QPDFTYPES_H
/* Provide an offset type that should be as big as off_t on just about
* any system. If your compiler doesn't support C99 (or at least the
@@ -30,4 +30,4 @@
typedef long long int qpdf_offset_t;
-#endif /* __QPDFTYPES_H__ */
+#endif /* QPDFTYPES_H */
diff --git a/include/qpdf/qpdf-c.h b/include/qpdf/qpdf-c.h
index a6002a92..c0983a53 100644
--- a/include/qpdf/qpdf-c.h
+++ b/include/qpdf/qpdf-c.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005-2018 Jay Berkenbilt
+/* Copyright (c) 2005-2019 Jay Berkenbilt
*
* This file is part of qpdf.
*
@@ -20,8 +20,8 @@
* see the manual for additional information.
*/
-#ifndef __QPDF_C_H__
-#define __QPDF_C_H__
+#ifndef QPDF_C_H
+#define QPDF_C_H
/*
* This file defines a basic "C" API for qpdf. It provides access to
@@ -390,6 +390,40 @@ extern "C" {
QPDF_BOOL allow_extract, QPDF_BOOL allow_annotate);
QPDF_DLL
+ void qpdf_set_r3_encryption_parameters2(
+ qpdf_data qpdf, char const* user_password, char const* owner_password,
+ QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
+ QPDF_BOOL allow_assemble, QPDF_BOOL allow_annotate_and_form,
+ QPDF_BOOL allow_form_filling, QPDF_BOOL allow_modify_other,
+ enum qpdf_r3_print_e print);
+
+ QPDF_DLL
+ void qpdf_set_r4_encryption_parameters2(
+ qpdf_data qpdf, char const* user_password, char const* owner_password,
+ QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
+ QPDF_BOOL allow_assemble, QPDF_BOOL allow_annotate_and_form,
+ QPDF_BOOL allow_form_filling, QPDF_BOOL allow_modify_other,
+ enum qpdf_r3_print_e print,
+ QPDF_BOOL encrypt_metadata, QPDF_BOOL use_aes);
+
+ QPDF_DLL
+ void qpdf_set_r5_encryption_parameters2(
+ qpdf_data qpdf, char const* user_password, char const* owner_password,
+ QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
+ QPDF_BOOL allow_assemble, QPDF_BOOL allow_annotate_and_form,
+ QPDF_BOOL allow_form_filling, QPDF_BOOL allow_modify_other,
+ enum qpdf_r3_print_e print, QPDF_BOOL encrypt_metadata);
+
+ QPDF_DLL
+ void qpdf_set_r6_encryption_parameters2(
+ qpdf_data qpdf, char const* user_password, char const* owner_password,
+ QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
+ QPDF_BOOL allow_assemble, QPDF_BOOL allow_annotate_and_form,
+ QPDF_BOOL allow_form_filling, QPDF_BOOL allow_modify_other,
+ enum qpdf_r3_print_e print, QPDF_BOOL encrypt_metadata);
+
+ /* Pre 8.4.0 encryption API */
+ QPDF_DLL
void qpdf_set_r3_encryption_parameters(
qpdf_data qpdf, char const* user_password, char const* owner_password,
QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
@@ -442,4 +476,4 @@ extern "C" {
#endif
-#endif /* __QPDF_C_H__ */
+#endif /* QPDF_C_H */