mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 10:58:58 +00:00
Add QPDFObjectHandle manipulation to C API
This commit is contained in:
parent
78b9d6bfd4
commit
2050977099
@ -1,3 +1,11 @@
|
||||
2020-11-28 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* Add new functions to the C API for manipulating
|
||||
QPDFObjectHandles. The new functions allow creation and
|
||||
modification of objects, which brings a lot of additional power to
|
||||
the C API. See include/qpdf/qpdf-c.h for details and
|
||||
examples/pdf-c-objects.c for a simple example.
|
||||
|
||||
2020-11-21 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* 10.0.4: release
|
||||
|
@ -11,7 +11,9 @@ BINS_examples = \
|
||||
pdf-count-strings \
|
||||
pdf-set-form-values \
|
||||
pdf-overlay-page
|
||||
CBINS_examples = pdf-linearize
|
||||
CBINS_examples = \
|
||||
pdf-c-objects \
|
||||
pdf-linearize
|
||||
|
||||
TARGETS_examples = $(foreach B,$(BINS_examples) $(CBINS_examples),examples/$(OUTPUT_DIR)/$(call binname,$(B)))
|
||||
|
||||
|
114
examples/pdf-c-objects.c
Normal file
114
examples/pdf-c-objects.c
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* This is an example program to demonstrate use of object handle
|
||||
* functions in the C API.
|
||||
*/
|
||||
|
||||
#include <qpdf/qpdf-c.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static char const* whoami = 0;
|
||||
|
||||
static void usage()
|
||||
{
|
||||
fprintf(stderr, "Usage: %s infile infile-password outfile\n", whoami);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
QPDF_BOOL
|
||||
modify_file(qpdf_data qpdf)
|
||||
{
|
||||
/* This small example performs the following operation on the
|
||||
* document catalog (a.k.a. root):
|
||||
* - Remove PageLayout
|
||||
* - Remove OpenAction
|
||||
* - If there are outlines, set PageMode to UseOutlines; otherwise,
|
||||
* remove it.
|
||||
*/
|
||||
|
||||
qpdf_oh root = qpdf_get_root(qpdf);
|
||||
qpdf_oh_remove_key(qpdf, root, "/PageLayout");
|
||||
qpdf_oh_remove_key(qpdf, root, "/OpenAction");
|
||||
/* 0 is never a valid qpdf_oh */
|
||||
qpdf_oh pagemode = 0;
|
||||
if (qpdf_oh_is_dictionary(
|
||||
qpdf, qpdf_oh_get_key(qpdf, root, "/PageLabels")))
|
||||
{
|
||||
pagemode = qpdf_oh_new_name(qpdf, "/UseOutlines");
|
||||
}
|
||||
else
|
||||
{
|
||||
pagemode = qpdf_oh_new_null(qpdf);
|
||||
}
|
||||
qpdf_oh_replace_or_remove_key(qpdf, root, "/PageMode", pagemode);
|
||||
|
||||
return QPDF_TRUE;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
char* infile = NULL;
|
||||
char* password = NULL;
|
||||
char* outfile = NULL;
|
||||
qpdf_data qpdf = qpdf_init();
|
||||
int warnings = 0;
|
||||
int errors = 0;
|
||||
char* p = 0;
|
||||
|
||||
if ((p = strrchr(argv[0], '/')) != NULL)
|
||||
{
|
||||
whoami = p + 1;
|
||||
}
|
||||
else if ((p = strrchr(argv[0], '\\')) != NULL)
|
||||
{
|
||||
whoami = p + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
whoami = argv[0];
|
||||
}
|
||||
|
||||
if (argc != 4)
|
||||
{
|
||||
usage();
|
||||
}
|
||||
|
||||
infile = argv[1];
|
||||
password = argv[2];
|
||||
outfile = argv[3];
|
||||
|
||||
if (((qpdf_read(qpdf, infile, password) & QPDF_ERRORS) == 0) &&
|
||||
modify_file(qpdf) &&
|
||||
((qpdf_init_write(qpdf, outfile) & QPDF_ERRORS) == 0))
|
||||
{
|
||||
/* Use static ID for testing only. For production, a
|
||||
* non-static ID is used. See also
|
||||
* qpdf_set_deterministic_ID. */
|
||||
qpdf_set_static_ID(qpdf, QPDF_TRUE); /* for testing only */
|
||||
qpdf_write(qpdf);
|
||||
}
|
||||
while (qpdf_more_warnings(qpdf))
|
||||
{
|
||||
warnings = 1;
|
||||
printf("warning: %s\n",
|
||||
qpdf_get_error_full_text(qpdf, qpdf_next_warning(qpdf)));
|
||||
}
|
||||
if (qpdf_has_error(qpdf))
|
||||
{
|
||||
errors = 1;
|
||||
printf("error: %s\n",
|
||||
qpdf_get_error_full_text(qpdf, qpdf_get_error(qpdf)));
|
||||
}
|
||||
qpdf_cleanup(&qpdf);
|
||||
if (errors)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
else if (warnings)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
33
examples/qtest/c-objects.test
Normal file
33
examples/qtest/c-objects.test
Normal file
@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env perl
|
||||
require 5.008;
|
||||
BEGIN { $^W = 1; }
|
||||
use strict;
|
||||
|
||||
chdir("c-objects") or die "chdir testdir failed: $!\n";
|
||||
|
||||
require TestDriver;
|
||||
|
||||
cleanup();
|
||||
|
||||
my $td = new TestDriver('c-objects');
|
||||
|
||||
my $qpdf = $ENV{'QPDF_BIN'} or die;
|
||||
|
||||
foreach my $i (qw(1 2))
|
||||
{
|
||||
$td->runtest("c-objects ($i)",
|
||||
{$td->COMMAND => "pdf-c-objects $i.pdf '' a.pdf"},
|
||||
{$td->STRING => "", $td->EXIT_STATUS => 0});
|
||||
$td->runtest("check output",
|
||||
{$td->FILE => "a.pdf"},
|
||||
{$td->FILE => "$i-out.pdf"});
|
||||
}
|
||||
|
||||
cleanup();
|
||||
|
||||
$td->report(4);
|
||||
|
||||
sub cleanup
|
||||
{
|
||||
unlink "a.pdf";
|
||||
}
|
BIN
examples/qtest/c-objects/1-out.pdf
Normal file
BIN
examples/qtest/c-objects/1-out.pdf
Normal file
Binary file not shown.
1501
examples/qtest/c-objects/1.pdf
Normal file
1501
examples/qtest/c-objects/1.pdf
Normal file
File diff suppressed because it is too large
Load Diff
BIN
examples/qtest/c-objects/2-out.pdf
Normal file
BIN
examples/qtest/c-objects/2-out.pdf
Normal file
Binary file not shown.
97
examples/qtest/c-objects/2.pdf
Normal file
97
examples/qtest/c-objects/2.pdf
Normal file
@ -0,0 +1,97 @@
|
||||
%PDF-1.3
|
||||
%¿÷¢þ
|
||||
%QDF-1.0
|
||||
|
||||
1 0 obj
|
||||
<<
|
||||
/Pages 2 0 R
|
||||
/Type /Catalog
|
||||
/PageLayout /v1
|
||||
/OpenAction /v2
|
||||
>>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<<
|
||||
/Count 1
|
||||
/Kids [
|
||||
3 0 R
|
||||
]
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
%% Page 1
|
||||
3 0 obj
|
||||
<<
|
||||
/Contents 4 0 R
|
||||
/MediaBox [
|
||||
0
|
||||
0
|
||||
612
|
||||
792
|
||||
]
|
||||
/Parent 2 0 R
|
||||
/Resources <<
|
||||
/Font <<
|
||||
/F1 6 0 R
|
||||
>>
|
||||
/ProcSet 7 0 R
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
endobj
|
||||
|
||||
%% Contents for page 1
|
||||
4 0 obj
|
||||
<<
|
||||
/Length 5 0 R
|
||||
>>
|
||||
stream
|
||||
BT
|
||||
/F1 24 Tf
|
||||
72 720 Td
|
||||
(Potato) Tj
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
44
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica
|
||||
/Encoding /WinAnsiEncoding
|
||||
/Name /F1
|
||||
/Subtype /Type1
|
||||
/Type /Font
|
||||
>>
|
||||
endobj
|
||||
|
||||
7 0 obj
|
||||
[
|
||||
/PDF
|
||||
/Text
|
||||
]
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 8
|
||||
0000000000 65535 f
|
||||
0000000025 00000 n
|
||||
0000000115 00000 n
|
||||
0000000197 00000 n
|
||||
0000000412 00000 n
|
||||
0000000511 00000 n
|
||||
0000000530 00000 n
|
||||
0000000648 00000 n
|
||||
trailer <<
|
||||
/Root 1 0 R
|
||||
/Size 8
|
||||
/ID [<ed2874a4596cc552b835f7f40431a8f5><ed2874a4596cc552b835f7f40431a8f5>]
|
||||
>>
|
||||
startxref
|
||||
683
|
||||
%%EOF
|
@ -471,6 +471,230 @@ extern "C" {
|
||||
QPDF_DLL
|
||||
QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf);
|
||||
|
||||
/* Object handling.
|
||||
*
|
||||
* These methods take and return a qpdf_oh, which is just an
|
||||
* unsigned integer. The value 0 is never returned, which makes it
|
||||
* usable as an uninitialized value.
|
||||
*
|
||||
* Each function below, starting with qpdf_oh, corresponds to a
|
||||
* specific method of QPDFObjectHandler. For example,
|
||||
* qpdf_oh_is_bool corresponds to QPDFObjectHandle::isBool. If the
|
||||
* C++ method is overloaded, the C function's name will be
|
||||
* disambiguated. If the C++ method takes optional argumens, the C
|
||||
* method will have required arguments in those positions. For
|
||||
* details about the method, please see comments in
|
||||
* QPDFObjectHandle.hh. Comments here only explain things that are
|
||||
* specific to the "C" API.
|
||||
*
|
||||
* Only a fraction of the methods of QPDFObjectHandle are
|
||||
* available here. Most of the basic methods for creating,
|
||||
* accessing, and modifying most types of objects are present.
|
||||
* Most of the higher-level functions are not implemented.
|
||||
* Functions for dealing with content streams as well as objects
|
||||
* that only exist in content streams (operators and inline
|
||||
* images) are mostly not provided.
|
||||
*
|
||||
* To refer to a specific QPDFObjectHandle, you need a pair
|
||||
* consisting of a qpdf_data and a qpdf_oh, which is just an index
|
||||
* into an internal table of objects. All memory allocated by any
|
||||
* of these methods is returned when qpdf_cleanup is called.
|
||||
*
|
||||
* Regarding memory, the same rules apply as the above functions.
|
||||
* Specifically, if a method returns a char*, the memory is
|
||||
* managed by the library and, unless otherwise specified, is not
|
||||
* expected to be valid after the next qpdf call.
|
||||
*
|
||||
* The qpdf_data object keeps a cache of objects returned by these
|
||||
* methods. Once you are finished referencing an object, you can
|
||||
* optionally release it. Releasing objects is optional since they
|
||||
* will all get released by qpdf_cleanup, but it can help to
|
||||
* reduce the memory footprint of the qpdf_data object to release
|
||||
* them when you're done. Releasing an object does not destroy the
|
||||
* object. All QPDFObjectHandle objects are deleted when they are
|
||||
* no longer referenced. Releasing an object simply invalidates
|
||||
* the qpdf_oh handle to it. For example, if you create an object,
|
||||
* add it to an existing dictionary or array, and then release it,
|
||||
* the object is safely part of the dictionary or array.
|
||||
* Explicitly releasing an object is essentially the same as
|
||||
* letting a QPDFObjectHandle go out of scope in the C++ API.
|
||||
*/
|
||||
|
||||
/* For examples of using this API, see examples/pdf-c-objects.c */
|
||||
|
||||
typedef unsigned int qpdf_oh;
|
||||
|
||||
/* Releasing objects -- see comments above. These methods have no
|
||||
* equivalent in the C++ API.
|
||||
*/
|
||||
QPDF_DLL
|
||||
void qpdf_oh_release(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
void qpdf_oh_release_all(qpdf_data data);
|
||||
|
||||
/* Get trailer and root objects */
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_get_trailer(qpdf_data data);
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_get_root(qpdf_data data);
|
||||
|
||||
/* Wrappers around QPDFObjectHandle methods. Be sure to read
|
||||
* corresponding comments in QPDFObjectHandle.hh to understand
|
||||
* what each function does and what kinds of objects it applies
|
||||
* to.
|
||||
*/
|
||||
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_is_bool(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_is_null(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_is_integer(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_is_real(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_is_name(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_is_string(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_is_operator(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_is_inline_image(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_is_array(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_is_dictionary(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_is_stream(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_is_indirect(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_is_scalar(qpdf_data data, qpdf_oh oh);
|
||||
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_wrap_in_array(qpdf_data data, qpdf_oh oh);
|
||||
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_parse(qpdf_data data, char const* object_str);
|
||||
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_get_bool_value(qpdf_data data, qpdf_oh oh);
|
||||
|
||||
QPDF_DLL
|
||||
long long qpdf_oh_get_int_value(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
int qpdf_oh_get_int_value_as_int(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
unsigned long long qpdf_oh_get_uint_value(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
unsigned int qpdf_oh_get_uint_value_as_uint(qpdf_data data, qpdf_oh oh);
|
||||
|
||||
QPDF_DLL
|
||||
char const* qpdf_oh_get_real_value(qpdf_data data, qpdf_oh oh);
|
||||
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_is_number(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
double qpdf_oh_get_numeric_value(qpdf_data data, qpdf_oh oh);
|
||||
|
||||
QPDF_DLL
|
||||
char const* qpdf_oh_get_name(qpdf_data data, qpdf_oh oh);
|
||||
|
||||
QPDF_DLL
|
||||
char const* qpdf_oh_get_string_value(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
char const* qpdf_oh_get_utf8_value(qpdf_data data, qpdf_oh oh);
|
||||
|
||||
QPDF_DLL
|
||||
int qpdf_oh_get_array_n_items(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_get_array_item(qpdf_data data, qpdf_oh oh, int n);
|
||||
|
||||
/* "C"-specific dictionary key iteration */
|
||||
|
||||
/* Iteration is allowed on only one dictionary at a time. */
|
||||
QPDF_DLL
|
||||
void qpdf_oh_begin_dict_key_iter(qpdf_data data, qpdf_oh dict);
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_dict_more_keys(qpdf_data data);
|
||||
/* The memory returned by qpdf_oh_dict_next_key is owned by
|
||||
* qpdf_data. It is good until the next call to
|
||||
* qpdf_oh_dict_next_key with the same qpdf_data object. Calling
|
||||
* the method again, even with a different dict, invalidates
|
||||
* previous return values.
|
||||
*/
|
||||
QPDF_DLL
|
||||
char const* qpdf_oh_dict_next_key(qpdf_data data);
|
||||
|
||||
/* end "C"-specific dictionary key iteration */
|
||||
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_has_key(qpdf_data data, qpdf_oh oh, char const* key);
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_get_key(qpdf_data data, qpdf_oh oh, char const* key);
|
||||
|
||||
QPDF_DLL
|
||||
QPDF_BOOL qpdf_oh_is_or_has_name(
|
||||
qpdf_data data, qpdf_oh oh, char const* key);
|
||||
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_new_null(qpdf_data data);
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_new_bool(qpdf_data data, QPDF_BOOL value);
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_new_integer(qpdf_data data, long long value);
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_new_real_from_string(qpdf_data data, char const* value);
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_new_real_from_double(qpdf_data data,
|
||||
double value, int decimal_places);
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_new_name(qpdf_data data, char const* name);
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_new_string(qpdf_data data, char const* str);
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_new_unicode_string(qpdf_data data, char const* utf8_str);
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_new_array(qpdf_data data);
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_new_dictionary(qpdf_data data);
|
||||
|
||||
QPDF_DLL
|
||||
void qpdf_oh_make_direct(qpdf_data data, qpdf_oh oh);
|
||||
|
||||
QPDF_DLL
|
||||
void qpdf_oh_set_array_item(qpdf_data data, qpdf_oh oh,
|
||||
int at, qpdf_oh item);
|
||||
QPDF_DLL
|
||||
void qpdf_oh_insert_item(qpdf_data data, qpdf_oh oh, int at, qpdf_oh item);
|
||||
QPDF_DLL
|
||||
void qpdf_oh_append_item(qpdf_data data, qpdf_oh oh, qpdf_oh item);
|
||||
QPDF_DLL
|
||||
void qpdf_oh_erase_item(qpdf_data data, qpdf_oh oh, int at);
|
||||
|
||||
QPDF_DLL
|
||||
void qpdf_oh_replace_key(qpdf_data data, qpdf_oh oh,
|
||||
char const* key, qpdf_oh item);
|
||||
QPDF_DLL
|
||||
void qpdf_oh_remove_key(qpdf_data data, qpdf_oh oh, char const* key);
|
||||
QPDF_DLL
|
||||
void qpdf_oh_replace_or_remove_key(qpdf_data data, qpdf_oh oh,
|
||||
char const* key, qpdf_oh item);
|
||||
|
||||
QPDF_DLL
|
||||
qpdf_oh qpdf_oh_get_dict(qpdf_data data, qpdf_oh oh);
|
||||
|
||||
QPDF_DLL
|
||||
int qpdf_oh_get_object_id(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
int qpdf_oh_get_generation(qpdf_data data, qpdf_oh oh);
|
||||
|
||||
QPDF_DLL
|
||||
char const* qpdf_oh_unparse(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
char const* qpdf_oh_unparse_resolved(qpdf_data data, qpdf_oh oh);
|
||||
QPDF_DLL
|
||||
char const* qpdf_oh_unparse_binary(qpdf_data data, qpdf_oh oh);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <qpdf/QPDFExc.hh>
|
||||
#include <qpdf/Pl_Discard.hh>
|
||||
#include <qpdf/QIntC.hh>
|
||||
#include <qpdf/QUtil.hh>
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
@ -37,10 +38,18 @@ struct _qpdf_data
|
||||
char const* password;
|
||||
bool write_memory;
|
||||
PointerHolder<Buffer> output_buffer;
|
||||
|
||||
// QPDFObjectHandle support
|
||||
std::map<qpdf_oh, PointerHolder<QPDFObjectHandle>> oh_cache;
|
||||
qpdf_oh next_oh;
|
||||
std::set<std::string> cur_iter_dict_keys;
|
||||
std::set<std::string>::const_iterator dict_iter;
|
||||
std::string cur_dict_key;
|
||||
};
|
||||
|
||||
_qpdf_data::_qpdf_data() :
|
||||
write_memory(false)
|
||||
write_memory(false),
|
||||
next_oh(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -134,6 +143,7 @@ qpdf_data qpdf_init()
|
||||
void qpdf_cleanup(qpdf_data* qpdf)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_cleanup");
|
||||
qpdf_oh_release_all(*qpdf);
|
||||
delete *qpdf;
|
||||
*qpdf = 0;
|
||||
}
|
||||
@ -749,3 +759,592 @@ QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf)
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_write", (status == 0) ? 0 : 1);
|
||||
return status;
|
||||
}
|
||||
|
||||
static qpdf_oh
|
||||
new_object(qpdf_data qpdf, QPDFObjectHandle const& qoh)
|
||||
{
|
||||
qpdf_oh oh = ++qpdf->next_oh; // never return 0
|
||||
qpdf->oh_cache[oh] = new QPDFObjectHandle(qoh);
|
||||
return oh;
|
||||
}
|
||||
|
||||
void qpdf_oh_release(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_release");
|
||||
qpdf->oh_cache.erase(oh);
|
||||
}
|
||||
|
||||
void qpdf_oh_release_all(qpdf_data qpdf)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_release_all");
|
||||
qpdf->oh_cache.clear();
|
||||
}
|
||||
|
||||
qpdf_oh qpdf_get_trailer(qpdf_data qpdf)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_get_trailer");
|
||||
return new_object(qpdf, qpdf->qpdf->getTrailer());
|
||||
}
|
||||
|
||||
qpdf_oh qpdf_get_root(qpdf_data qpdf)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_get_root");
|
||||
return new_object(qpdf, qpdf->qpdf->getRoot());
|
||||
}
|
||||
|
||||
static bool
|
||||
qpdf_oh_valid_internal(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
auto i = qpdf->oh_cache.find(oh);
|
||||
bool result = ((i != qpdf->oh_cache.end()) &&
|
||||
(i->second).getPointer() &&
|
||||
(i->second)->isInitialized());
|
||||
if (! result)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c invalid object handle");
|
||||
qpdf->warnings.push_back(
|
||||
QPDFExc(
|
||||
qpdf_e_damaged_pdf,
|
||||
qpdf->qpdf->getFilename(),
|
||||
std::string("C API object handle ") +
|
||||
QUtil::uint_to_string(oh),
|
||||
0, "attempted access to unknown/uninitialized object handle"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_is_bool(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_bool");
|
||||
return (qpdf_oh_valid_internal(qpdf, oh) &&
|
||||
qpdf->oh_cache[oh]->isBool());
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_is_null(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_null");
|
||||
return (qpdf_oh_valid_internal(qpdf, oh) &&
|
||||
qpdf->oh_cache[oh]->isNull());
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_is_integer(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_integer");
|
||||
return (qpdf_oh_valid_internal(qpdf, oh) &&
|
||||
qpdf->oh_cache[oh]->isInteger());
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_is_real(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_real");
|
||||
return (qpdf_oh_valid_internal(qpdf, oh) &&
|
||||
qpdf->oh_cache[oh]->isReal());
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_is_name(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_name");
|
||||
return (qpdf_oh_valid_internal(qpdf, oh) &&
|
||||
qpdf->oh_cache[oh]->isName());
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_is_string(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_string");
|
||||
return (qpdf_oh_valid_internal(qpdf, oh) &&
|
||||
qpdf->oh_cache[oh]->isString());
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_is_operator(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_operator");
|
||||
return (qpdf_oh_valid_internal(qpdf, oh) &&
|
||||
qpdf->oh_cache[oh]->isOperator());
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_is_inline_image(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_inline_image");
|
||||
return (qpdf_oh_valid_internal(qpdf, oh) &&
|
||||
qpdf->oh_cache[oh]->isInlineImage());
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_is_array(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_array");
|
||||
return (qpdf_oh_valid_internal(qpdf, oh) &&
|
||||
qpdf->oh_cache[oh]->isArray());
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_is_dictionary(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_dictionary");
|
||||
return (qpdf_oh_valid_internal(qpdf, oh) &&
|
||||
qpdf->oh_cache[oh]->isDictionary());
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_is_stream(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_stream");
|
||||
return (qpdf_oh_valid_internal(qpdf, oh) &&
|
||||
qpdf->oh_cache[oh]->isStream());
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_is_indirect(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_indirect");
|
||||
return (qpdf_oh_valid_internal(qpdf, oh) &&
|
||||
qpdf->oh_cache[oh]->isIndirect());
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_is_scalar(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_scalar");
|
||||
return (qpdf_oh_valid_internal(qpdf, oh) &&
|
||||
qpdf->oh_cache[oh]->isScalar());
|
||||
}
|
||||
|
||||
qpdf_oh qpdf_oh_wrap_in_array(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return qpdf_oh_new_array(qpdf);
|
||||
}
|
||||
auto qoh = qpdf->oh_cache[oh];
|
||||
if (qoh->isArray())
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c array to wrap_in_array");
|
||||
return oh;
|
||||
}
|
||||
else
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c non-array to wrap_in_array");
|
||||
return new_object(qpdf,
|
||||
QPDFObjectHandle::newArray(
|
||||
std::vector<QPDFObjectHandle>{
|
||||
*qpdf->oh_cache[oh]}));
|
||||
}
|
||||
}
|
||||
|
||||
qpdf_oh qpdf_oh_parse(qpdf_data qpdf, char const* object_str)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_parse");
|
||||
return new_object(qpdf, QPDFObjectHandle::parse(object_str));
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_get_bool_value(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return QPDF_FALSE;
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_bool_value");
|
||||
return qpdf->oh_cache[oh]->getBoolValue();
|
||||
}
|
||||
|
||||
long long qpdf_oh_get_int_value(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return 0LL;
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_int_value");
|
||||
return qpdf->oh_cache[oh]->getIntValue();
|
||||
}
|
||||
|
||||
int qpdf_oh_get_int_value_as_int(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_int_value_as_int");
|
||||
return qpdf->oh_cache[oh]->getIntValueAsInt();
|
||||
}
|
||||
|
||||
unsigned long long qpdf_oh_get_uint_value(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return 0ULL;
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_uint_value");
|
||||
return qpdf->oh_cache[oh]->getUIntValue();
|
||||
}
|
||||
|
||||
unsigned int qpdf_oh_get_uint_value_as_uint(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return 0U;
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_uint_value_as_uint");
|
||||
return qpdf->oh_cache[oh]->getUIntValueAsUInt();
|
||||
}
|
||||
|
||||
char const* qpdf_oh_get_real_value(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_real_value");
|
||||
qpdf->tmp_string = qpdf->oh_cache[oh]->getRealValue();
|
||||
return qpdf->tmp_string.c_str();
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_is_number(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return QPDF_FALSE;
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_number");
|
||||
return qpdf->oh_cache[oh]->isNumber();
|
||||
}
|
||||
|
||||
double qpdf_oh_get_numeric_value(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_numeric_value");
|
||||
return qpdf->oh_cache[oh]->getNumericValue();
|
||||
}
|
||||
|
||||
char const* qpdf_oh_get_name(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_name");
|
||||
qpdf->tmp_string = qpdf->oh_cache[oh]->getName();
|
||||
return qpdf->tmp_string.c_str();
|
||||
}
|
||||
|
||||
char const* qpdf_oh_get_string_value(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_string_value");
|
||||
qpdf->tmp_string = qpdf->oh_cache[oh]->getStringValue();
|
||||
return qpdf->tmp_string.c_str();
|
||||
}
|
||||
|
||||
char const* qpdf_oh_get_utf8_value(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_utf8_value");
|
||||
qpdf->tmp_string = qpdf->oh_cache[oh]->getUTF8Value();
|
||||
return qpdf->tmp_string.c_str();
|
||||
}
|
||||
|
||||
int qpdf_oh_get_array_n_items(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_array_n_items");
|
||||
return qpdf->oh_cache[oh]->getArrayNItems();
|
||||
}
|
||||
|
||||
qpdf_oh qpdf_oh_get_array_item(qpdf_data qpdf, qpdf_oh oh, int n)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return qpdf_oh_new_null(qpdf);
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_array_item");
|
||||
return new_object(qpdf, qpdf->oh_cache[oh]->getArrayItem(n));
|
||||
}
|
||||
|
||||
void qpdf_oh_begin_dict_key_iter(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (qpdf_oh_valid_internal(qpdf, oh) &&
|
||||
qpdf_oh_is_dictionary(qpdf, oh))
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_begin_dict_key_iter");
|
||||
qpdf->cur_iter_dict_keys = qpdf->oh_cache[oh]->getKeys();
|
||||
}
|
||||
else
|
||||
{
|
||||
qpdf->cur_iter_dict_keys = {};
|
||||
}
|
||||
qpdf->dict_iter = qpdf->cur_iter_dict_keys.begin();
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_dict_more_keys(qpdf_data qpdf)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_dict_more_keys");
|
||||
return qpdf->dict_iter != qpdf->cur_iter_dict_keys.end();
|
||||
}
|
||||
|
||||
char const* qpdf_oh_dict_next_key(qpdf_data qpdf)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_dict_next_key");
|
||||
if (qpdf_oh_dict_more_keys(qpdf))
|
||||
{
|
||||
qpdf->cur_dict_key = *qpdf->dict_iter;
|
||||
++qpdf->dict_iter;
|
||||
return qpdf->cur_dict_key.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_has_key(qpdf_data qpdf, qpdf_oh oh, char const* key)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return QPDF_FALSE;
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_has_key");
|
||||
return qpdf->oh_cache[oh]->hasKey(key);
|
||||
}
|
||||
|
||||
qpdf_oh qpdf_oh_get_key(qpdf_data qpdf, qpdf_oh oh, char const* key)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return qpdf_oh_new_null(qpdf);
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_key");
|
||||
return new_object(qpdf, qpdf->oh_cache[oh]->getKey(key));
|
||||
}
|
||||
|
||||
QPDF_BOOL qpdf_oh_is_or_has_name(qpdf_data qpdf, qpdf_oh oh, char const* key)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return QPDF_FALSE;
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_or_has_name");
|
||||
return qpdf->oh_cache[oh]->isOrHasName(key);
|
||||
}
|
||||
|
||||
qpdf_oh qpdf_oh_new_null(qpdf_data qpdf)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_null");
|
||||
return new_object(qpdf, QPDFObjectHandle::newNull());
|
||||
}
|
||||
|
||||
qpdf_oh qpdf_oh_new_bool(qpdf_data qpdf, QPDF_BOOL value)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_bool");
|
||||
return new_object(qpdf, QPDFObjectHandle::newBool(value));
|
||||
}
|
||||
|
||||
qpdf_oh qpdf_oh_new_integer(qpdf_data qpdf, long long value)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_integer");
|
||||
return new_object(qpdf, QPDFObjectHandle::newInteger(value));
|
||||
}
|
||||
|
||||
qpdf_oh qpdf_oh_new_real_from_string(qpdf_data qpdf, char const* value)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_real_from_string");
|
||||
return new_object(qpdf, QPDFObjectHandle::newReal(value));
|
||||
}
|
||||
|
||||
qpdf_oh qpdf_oh_new_real_from_double(qpdf_data qpdf,
|
||||
double value, int decimal_places)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_real_from_double");
|
||||
return new_object(qpdf, QPDFObjectHandle::newReal(value, decimal_places));
|
||||
}
|
||||
|
||||
qpdf_oh qpdf_oh_new_name(qpdf_data qpdf, char const* name)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_name");
|
||||
return new_object(qpdf, QPDFObjectHandle::newName(name));
|
||||
}
|
||||
|
||||
qpdf_oh qpdf_oh_new_string(qpdf_data qpdf, char const* str)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_string");
|
||||
return new_object(qpdf, QPDFObjectHandle::newString(str));
|
||||
}
|
||||
|
||||
qpdf_oh qpdf_oh_new_unicode_string(qpdf_data qpdf, char const* utf8_str)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_unicode_string");
|
||||
return new_object(qpdf, QPDFObjectHandle::newUnicodeString(utf8_str));
|
||||
}
|
||||
|
||||
qpdf_oh qpdf_oh_new_array(qpdf_data qpdf)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_array");
|
||||
return new_object(qpdf, QPDFObjectHandle::newArray());
|
||||
}
|
||||
|
||||
qpdf_oh qpdf_oh_new_dictionary(qpdf_data qpdf)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_dictionary");
|
||||
return new_object(qpdf, QPDFObjectHandle::newDictionary());
|
||||
}
|
||||
|
||||
void qpdf_oh_make_direct(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_make_direct");
|
||||
qpdf->oh_cache[oh]->makeDirect();
|
||||
}
|
||||
}
|
||||
|
||||
static QPDFObjectHandle
|
||||
qpdf_oh_item_internal(qpdf_data qpdf, qpdf_oh item)
|
||||
{
|
||||
if (qpdf_oh_valid_internal(qpdf, item))
|
||||
{
|
||||
return *(qpdf->oh_cache[item]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return QPDFObjectHandle::newNull();
|
||||
}
|
||||
}
|
||||
|
||||
void qpdf_oh_set_array_item(qpdf_data qpdf, qpdf_oh oh,
|
||||
int at, qpdf_oh item)
|
||||
{
|
||||
if (qpdf_oh_is_array(qpdf, oh))
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_set_array_item");
|
||||
qpdf->oh_cache[oh]->setArrayItem(
|
||||
at, qpdf_oh_item_internal(qpdf, item));
|
||||
}
|
||||
}
|
||||
|
||||
void qpdf_oh_insert_item(qpdf_data qpdf, qpdf_oh oh, int at, qpdf_oh item)
|
||||
{
|
||||
if (qpdf_oh_is_array(qpdf, oh))
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_insert_item");
|
||||
qpdf->oh_cache[oh]->insertItem(
|
||||
at, qpdf_oh_item_internal(qpdf, item));
|
||||
}
|
||||
}
|
||||
|
||||
void qpdf_oh_append_item(qpdf_data qpdf, qpdf_oh oh, qpdf_oh item)
|
||||
{
|
||||
if (qpdf_oh_is_array(qpdf, oh))
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_append_item");
|
||||
qpdf->oh_cache[oh]->appendItem(
|
||||
qpdf_oh_item_internal(qpdf, item));
|
||||
}
|
||||
}
|
||||
|
||||
void qpdf_oh_erase_item(qpdf_data qpdf, qpdf_oh oh, int at)
|
||||
{
|
||||
if (qpdf_oh_is_array(qpdf, oh))
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_erase_item");
|
||||
qpdf->oh_cache[oh]->eraseItem(at);
|
||||
}
|
||||
}
|
||||
|
||||
void qpdf_oh_replace_key(qpdf_data qpdf, qpdf_oh oh,
|
||||
char const* key, qpdf_oh item)
|
||||
{
|
||||
if (qpdf_oh_is_dictionary(qpdf, oh))
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_replace_key");
|
||||
qpdf->oh_cache[oh]->replaceKey(
|
||||
key, qpdf_oh_item_internal(qpdf, item));
|
||||
}
|
||||
}
|
||||
|
||||
void qpdf_oh_remove_key(qpdf_data qpdf, qpdf_oh oh, char const* key)
|
||||
{
|
||||
if (qpdf_oh_is_dictionary(qpdf, oh))
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_remove_key");
|
||||
qpdf->oh_cache[oh]->removeKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
void qpdf_oh_replace_or_remove_key(qpdf_data qpdf, qpdf_oh oh,
|
||||
char const* key, qpdf_oh item)
|
||||
{
|
||||
if (qpdf_oh_is_dictionary(qpdf, oh))
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_replace_or_remove_key");
|
||||
qpdf->oh_cache[oh]->replaceOrRemoveKey(
|
||||
key, qpdf_oh_item_internal(qpdf, item));
|
||||
}
|
||||
}
|
||||
|
||||
qpdf_oh qpdf_oh_get_dict(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return qpdf_oh_new_null(qpdf);
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_dict");
|
||||
return new_object(qpdf, qpdf->oh_cache[oh]->getDict());
|
||||
}
|
||||
|
||||
int qpdf_oh_get_object_id(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_object_id");
|
||||
return qpdf->oh_cache[oh]->getObjectID();
|
||||
}
|
||||
|
||||
int qpdf_oh_get_generation(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_generation");
|
||||
return qpdf->oh_cache[oh]->getGeneration();
|
||||
}
|
||||
|
||||
char const* qpdf_oh_unparse(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_unparse");
|
||||
qpdf->tmp_string = qpdf->oh_cache[oh]->unparse();
|
||||
return qpdf->tmp_string.c_str();
|
||||
}
|
||||
|
||||
char const* qpdf_oh_unparse_resolved(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_unparse_resolved");
|
||||
qpdf->tmp_string = qpdf->oh_cache[oh]->unparseResolved();
|
||||
return qpdf->tmp_string.c_str();
|
||||
}
|
||||
|
||||
char const* qpdf_oh_unparse_binary(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
if (! qpdf_oh_valid_internal(qpdf, oh))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_unparse_binary");
|
||||
qpdf->tmp_string = qpdf->oh_cache[oh]->unparseBinary();
|
||||
return qpdf->tmp_string.c_str();
|
||||
}
|
||||
|
@ -495,6 +495,177 @@ static void test23(char const* infile,
|
||||
report_errors();
|
||||
}
|
||||
|
||||
static void test24(char const* infile,
|
||||
char const* password,
|
||||
char const* outfile,
|
||||
char const* outfile2)
|
||||
{
|
||||
/* This test case is designed for minimal.pdf. */
|
||||
qpdf_read(qpdf, infile, password);
|
||||
qpdf_oh trailer = qpdf_get_trailer(qpdf);
|
||||
/* The library never returns 0 */
|
||||
assert(trailer == 1);
|
||||
qpdf_oh root = qpdf_get_root(qpdf);
|
||||
assert(qpdf_oh_get_generation(qpdf, root) == 0);
|
||||
qpdf_oh root_from_trailer = qpdf_oh_get_key(qpdf, trailer, "/Root");
|
||||
assert(qpdf_oh_get_object_id(qpdf, root) ==
|
||||
qpdf_oh_get_object_id(qpdf, root_from_trailer));
|
||||
qpdf_oh pages = qpdf_oh_get_key(qpdf, root, "/Pages");
|
||||
assert(qpdf_oh_is_dictionary(qpdf, pages));
|
||||
qpdf_oh kids = qpdf_oh_get_key(qpdf, pages, "/Kids");
|
||||
assert(qpdf_oh_is_array(qpdf, kids));
|
||||
assert(qpdf_oh_get_array_n_items(qpdf, kids) == 1);
|
||||
qpdf_oh page1 = qpdf_oh_get_array_item(qpdf, kids, 0);
|
||||
qpdf_oh_begin_dict_key_iter(qpdf, page1);
|
||||
while (qpdf_oh_dict_more_keys(qpdf))
|
||||
{
|
||||
printf("page dictionary key: %s\n", qpdf_oh_dict_next_key(qpdf));
|
||||
}
|
||||
qpdf_oh type = qpdf_oh_get_key(qpdf, page1, "/Type");
|
||||
assert(qpdf_oh_is_name(qpdf, type));
|
||||
assert(strcmp(qpdf_oh_get_name(qpdf, type), "/Page") == 0);
|
||||
qpdf_oh parent = qpdf_oh_get_key(qpdf, page1, "/Parent");
|
||||
assert(qpdf_oh_is_indirect(qpdf, parent));
|
||||
qpdf_oh mediabox = qpdf_oh_get_key(qpdf, page1, "/MediaBox");
|
||||
assert(! qpdf_oh_is_scalar(qpdf, mediabox));
|
||||
assert(qpdf_oh_is_array(qpdf, mediabox));
|
||||
assert(qpdf_oh_get_array_n_items(qpdf, mediabox) == 4);
|
||||
assert(qpdf_oh_wrap_in_array(qpdf, mediabox) == mediabox);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
qpdf_oh item = qpdf_oh_get_array_item(qpdf, mediabox, i);
|
||||
printf("item %d: %d %.2f\n",
|
||||
i, qpdf_oh_get_int_value_as_int(qpdf, item),
|
||||
qpdf_oh_get_numeric_value(qpdf, item));
|
||||
qpdf_oh_release(qpdf, item);
|
||||
}
|
||||
qpdf_oh i2 = qpdf_oh_get_array_item(qpdf, mediabox, 2);
|
||||
assert(qpdf_oh_get_int_value_as_int(qpdf, i2) == 612);
|
||||
assert(qpdf_oh_get_int_value(qpdf, i2) == 612ll);
|
||||
assert(qpdf_oh_get_uint_value_as_uint(qpdf, i2) == 612u);
|
||||
assert(qpdf_oh_get_uint_value(qpdf, i2) == 612ull);
|
||||
assert(! qpdf_oh_is_operator(qpdf, i2));
|
||||
assert(! qpdf_oh_is_inline_image(qpdf, i2));
|
||||
qpdf_oh encoding = qpdf_oh_get_key(
|
||||
qpdf, qpdf_oh_get_key(
|
||||
qpdf, qpdf_oh_get_key(
|
||||
qpdf, qpdf_oh_get_key(
|
||||
qpdf, page1, "/Resources"),
|
||||
"/Font"),
|
||||
"/F1"),
|
||||
"/Encoding");
|
||||
assert(strcmp(qpdf_oh_get_name(qpdf, encoding), "/WinAnsiEncoding") == 0);
|
||||
qpdf_oh contents = qpdf_oh_get_key(qpdf, page1, "/Contents");
|
||||
assert(qpdf_oh_is_stream(qpdf, contents));
|
||||
qpdf_oh contents_dict = qpdf_oh_get_dict(qpdf, contents);
|
||||
assert(! qpdf_oh_is_scalar(qpdf, contents));
|
||||
assert(! qpdf_oh_is_scalar(qpdf, contents_dict));
|
||||
qpdf_oh contents_length = qpdf_oh_get_key(qpdf, contents_dict, "/Length");
|
||||
assert(qpdf_oh_is_integer(qpdf, contents_length));
|
||||
assert(qpdf_oh_is_scalar(qpdf, contents_length));
|
||||
assert(qpdf_oh_is_number(qpdf, contents_length));
|
||||
qpdf_oh contents_array = qpdf_oh_wrap_in_array(qpdf, contents);
|
||||
assert(qpdf_oh_get_array_n_items(qpdf, contents_array) == 1);
|
||||
assert(qpdf_oh_get_object_id(
|
||||
qpdf, qpdf_oh_get_array_item(qpdf, contents_array, 0)) ==
|
||||
qpdf_oh_get_object_id(qpdf, contents));
|
||||
qpdf_oh resources = qpdf_oh_get_key(qpdf, page1, "/Resources");
|
||||
qpdf_oh procset = qpdf_oh_get_key(qpdf, resources, "/ProcSet");
|
||||
assert(strcmp(qpdf_oh_unparse(qpdf, procset),
|
||||
"5 0 R") == 0);
|
||||
assert(strcmp(qpdf_oh_unparse_resolved(qpdf, procset),
|
||||
"[ /PDF /Text ]") == 0);
|
||||
qpdf_oh_make_direct(qpdf, procset);
|
||||
assert(strcmp(qpdf_oh_unparse(qpdf, procset),
|
||||
"[ /PDF /Text ]") == 0);
|
||||
qpdf_oh_replace_key(qpdf, resources, "/ProcSet", procset);
|
||||
|
||||
qpdf_oh parsed = qpdf_oh_parse(
|
||||
qpdf, "[ 1 2.0 (3\xf7) << /Four [/Five] >> null true ]");
|
||||
qpdf_oh p_int = qpdf_oh_get_array_item(qpdf, parsed, 0);
|
||||
qpdf_oh p_real = qpdf_oh_get_array_item(qpdf, parsed, 1);
|
||||
qpdf_oh p_string = qpdf_oh_get_array_item(qpdf, parsed, 2);
|
||||
qpdf_oh p_dict = qpdf_oh_get_array_item(qpdf, parsed, 3);
|
||||
qpdf_oh p_null = qpdf_oh_get_array_item(qpdf, parsed, 4);
|
||||
qpdf_oh p_bool = qpdf_oh_get_array_item(qpdf, parsed, 5);
|
||||
assert(qpdf_oh_is_integer(qpdf, p_int) &&
|
||||
qpdf_oh_get_int_value_as_int(qpdf, p_int) == 1);
|
||||
assert(qpdf_oh_is_real(qpdf, p_real) &&
|
||||
(strcmp(qpdf_oh_get_real_value(qpdf, p_real), "2.0") == 0) &&
|
||||
qpdf_oh_get_numeric_value(qpdf, p_real) == 2.0);
|
||||
assert(qpdf_oh_is_string(qpdf, p_string) &&
|
||||
(strcmp(qpdf_oh_get_string_value(qpdf, p_string), "3\xf7") == 0) &&
|
||||
(strcmp(qpdf_oh_get_utf8_value(qpdf, p_string), "3\xc3\xb7") == 0) &&
|
||||
(strcmp(qpdf_oh_unparse_binary(qpdf, p_string), "<33f7>") == 0));
|
||||
assert(qpdf_oh_is_dictionary(qpdf, p_dict));
|
||||
qpdf_oh p_five = qpdf_oh_get_key(qpdf, p_dict, "/Four");
|
||||
assert(qpdf_oh_is_or_has_name(qpdf, p_five, "/Five"));
|
||||
assert(qpdf_oh_is_or_has_name(
|
||||
qpdf, qpdf_oh_get_array_item(qpdf, p_five, 0), "/Five"));
|
||||
assert(qpdf_oh_is_null(qpdf, p_null));
|
||||
assert(qpdf_oh_is_bool(qpdf, p_bool) &&
|
||||
(qpdf_oh_get_bool_value(qpdf, p_bool) == QPDF_TRUE));
|
||||
qpdf_oh_erase_item(qpdf, parsed, 4);
|
||||
qpdf_oh_insert_item(
|
||||
qpdf, parsed, 2,
|
||||
qpdf_oh_parse(qpdf, "<</A 1 /B 2 /C 3 /D 4>>"));
|
||||
qpdf_oh new_dict = qpdf_oh_get_array_item(qpdf, parsed, 2);
|
||||
assert(qpdf_oh_has_key(qpdf, new_dict, "/A"));
|
||||
assert(qpdf_oh_has_key(qpdf, new_dict, "/D"));
|
||||
qpdf_oh new_array = qpdf_oh_new_array(qpdf);
|
||||
qpdf_oh_replace_or_remove_key(
|
||||
qpdf, new_dict, "/A", qpdf_oh_new_null(qpdf));
|
||||
qpdf_oh_replace_or_remove_key(
|
||||
qpdf, new_dict, "/B", new_array);
|
||||
qpdf_oh_replace_key(
|
||||
qpdf, new_dict, "/C", qpdf_oh_new_dictionary(qpdf));
|
||||
qpdf_oh_remove_key(qpdf, new_dict, "/D");
|
||||
assert(! qpdf_oh_has_key(qpdf, new_dict, "/A"));
|
||||
assert(! qpdf_oh_has_key(qpdf, new_dict, "/D"));
|
||||
qpdf_oh_append_item(
|
||||
qpdf, new_array, qpdf_oh_new_string(qpdf, "potato"));
|
||||
qpdf_oh_append_item(
|
||||
qpdf, new_array,
|
||||
qpdf_oh_new_unicode_string(qpdf, "qww\xc3\xb7\xcf\x80"));
|
||||
qpdf_oh_append_item(qpdf, new_array, qpdf_oh_new_null(qpdf)); /* 2 */
|
||||
qpdf_oh_append_item(qpdf, new_array, qpdf_oh_new_null(qpdf)); /* 3 */
|
||||
qpdf_oh_set_array_item(
|
||||
qpdf, new_array, 2,
|
||||
qpdf_oh_new_name(qpdf, "/Quack"));
|
||||
qpdf_oh_append_item(
|
||||
qpdf, new_array,
|
||||
qpdf_oh_new_real_from_double(qpdf, 4.0, 2));
|
||||
qpdf_oh_append_item(
|
||||
qpdf, new_array,
|
||||
qpdf_oh_new_real_from_string(qpdf, "5.0"));
|
||||
qpdf_oh_append_item(
|
||||
qpdf, new_array,
|
||||
qpdf_oh_new_integer(qpdf, 6));
|
||||
qpdf_oh_append_item(
|
||||
qpdf, new_array, qpdf_oh_new_bool(qpdf, QPDF_TRUE));
|
||||
qpdf_oh_replace_key(qpdf, root, "/QTest", new_dict);
|
||||
|
||||
/* Release and access to exercise warnings */
|
||||
qpdf_oh_release(qpdf, page1);
|
||||
contents = qpdf_oh_get_key(qpdf, page1, "/Contents");
|
||||
assert(qpdf_oh_is_null(qpdf, contents));
|
||||
assert(qpdf_oh_is_array(qpdf, mediabox));
|
||||
qpdf_oh_release_all(qpdf);
|
||||
assert(! qpdf_oh_is_null(qpdf, mediabox));
|
||||
assert(! qpdf_oh_is_array(qpdf, mediabox));
|
||||
/* Make sure something is assigned when we exit so we check that
|
||||
* it gets properl freed.
|
||||
*/
|
||||
qpdf_get_root(qpdf);
|
||||
|
||||
qpdf_init_write(qpdf, outfile);
|
||||
qpdf_set_static_ID(qpdf, QPDF_TRUE);
|
||||
qpdf_set_qdf_mode(qpdf, QPDF_TRUE);
|
||||
qpdf_set_suppress_original_object_IDs(qpdf, QPDF_TRUE);
|
||||
qpdf_write(qpdf);
|
||||
report_errors();
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
char* p = 0;
|
||||
@ -558,6 +729,7 @@ int main(int argc, char* argv[])
|
||||
(n == 21) ? test21 :
|
||||
(n == 22) ? test22 :
|
||||
(n == 23) ? test23 :
|
||||
(n == 24) ? test24 :
|
||||
0);
|
||||
|
||||
if (fn == 0)
|
||||
|
@ -457,3 +457,67 @@ QPDF copy foreign with data 1
|
||||
QPDF copy foreign with foreign_stream 1
|
||||
QPDFObjectHandle need_newline 1
|
||||
qpdf pages range omitted with . 0
|
||||
qpdf-c invalid object handle 0
|
||||
qpdf-c called qpdf_oh_release 0
|
||||
qpdf-c called qpdf_oh_release_all 0
|
||||
qpdf-c called qpdf_get_trailer 0
|
||||
qpdf-c called qpdf_get_root 0
|
||||
qpdf-c called qpdf_oh_is_bool 0
|
||||
qpdf-c called qpdf_oh_is_null 0
|
||||
qpdf-c called qpdf_oh_is_integer 0
|
||||
qpdf-c called qpdf_oh_is_real 0
|
||||
qpdf-c called qpdf_oh_is_name 0
|
||||
qpdf-c called qpdf_oh_is_string 0
|
||||
qpdf-c called qpdf_oh_is_operator 0
|
||||
qpdf-c called qpdf_oh_is_inline_image 0
|
||||
qpdf-c called qpdf_oh_is_array 0
|
||||
qpdf-c called qpdf_oh_is_dictionary 0
|
||||
qpdf-c called qpdf_oh_is_stream 0
|
||||
qpdf-c called qpdf_oh_is_indirect 0
|
||||
qpdf-c called qpdf_oh_is_scalar 0
|
||||
qpdf-c array to wrap_in_array 0
|
||||
qpdf-c non-array to wrap_in_array 0
|
||||
qpdf-c called qpdf_oh_parse 0
|
||||
qpdf-c called qpdf_oh_get_bool_value 0
|
||||
qpdf-c called qpdf_oh_get_int_value 0
|
||||
qpdf-c called qpdf_oh_get_int_value_as_int 0
|
||||
qpdf-c called qpdf_oh_get_uint_value 0
|
||||
qpdf-c called qpdf_oh_get_uint_value_as_uint 0
|
||||
qpdf-c called qpdf_oh_get_real_value 0
|
||||
qpdf-c called qpdf_oh_is_number 0
|
||||
qpdf-c called qpdf_oh_get_numeric_value 0
|
||||
qpdf-c called qpdf_oh_get_name 0
|
||||
qpdf-c called qpdf_oh_get_string_value 0
|
||||
qpdf-c called qpdf_oh_get_utf8_value 0
|
||||
qpdf-c called qpdf_oh_get_array_n_items 0
|
||||
qpdf-c called qpdf_oh_get_array_item 0
|
||||
qpdf-c called qpdf_oh_begin_dict_key_iter 0
|
||||
qpdf-c called qpdf_oh_dict_more_keys 0
|
||||
qpdf-c called qpdf_oh_dict_next_key 0
|
||||
qpdf-c called qpdf_oh_has_key 0
|
||||
qpdf-c called qpdf_oh_get_key 0
|
||||
qpdf-c called qpdf_oh_is_or_has_name 0
|
||||
qpdf-c called qpdf_oh_new_null 0
|
||||
qpdf-c called qpdf_oh_new_bool 0
|
||||
qpdf-c called qpdf_oh_new_integer 0
|
||||
qpdf-c called qpdf_oh_new_real_from_string 0
|
||||
qpdf-c called qpdf_oh_new_real_from_double 0
|
||||
qpdf-c called qpdf_oh_new_name 0
|
||||
qpdf-c called qpdf_oh_new_string 0
|
||||
qpdf-c called qpdf_oh_new_unicode_string 0
|
||||
qpdf-c called qpdf_oh_new_array 0
|
||||
qpdf-c called qpdf_oh_new_dictionary 0
|
||||
qpdf-c called qpdf_oh_make_direct 0
|
||||
qpdf-c called qpdf_oh_set_array_item 0
|
||||
qpdf-c called qpdf_oh_insert_item 0
|
||||
qpdf-c called qpdf_oh_append_item 0
|
||||
qpdf-c called qpdf_oh_erase_item 0
|
||||
qpdf-c called qpdf_oh_replace_key 0
|
||||
qpdf-c called qpdf_oh_remove_key 0
|
||||
qpdf-c called qpdf_oh_replace_or_remove_key 0
|
||||
qpdf-c called qpdf_oh_get_dict 0
|
||||
qpdf-c called qpdf_oh_get_object_id 0
|
||||
qpdf-c called qpdf_oh_get_generation 0
|
||||
qpdf-c called qpdf_oh_unparse 0
|
||||
qpdf-c called qpdf_oh_unparse_resolved 0
|
||||
qpdf-c called qpdf_oh_unparse_binary 0
|
||||
|
@ -4118,6 +4118,21 @@ foreach my $i (@c_check_types)
|
||||
$td->NORMALIZE_NEWLINES);
|
||||
}
|
||||
|
||||
show_ntests();
|
||||
# ----------
|
||||
$td->notify("--- C API Object Handle ---");
|
||||
$n_tests += scalar(@c_check_types);
|
||||
|
||||
$td->runtest("C check object handles",
|
||||
{$td->COMMAND => "qpdf-ctest 24 minimal.pdf '' a.pdf"},
|
||||
{$td->FILE => "c-object-handles.out",
|
||||
$td->EXIT_STATUS => 0},
|
||||
$td->NORMALIZE_NEWLINES);
|
||||
|
||||
$td->runtest("check output",
|
||||
{$td->FILE => 'a.pdf'},
|
||||
{$td->FILE => 'c-object-handles-out.pdf'});
|
||||
|
||||
show_ntests();
|
||||
# ----------
|
||||
$td->notify("--- Content Preservation Tests ---");
|
||||
|
104
qpdf/qtest/qpdf/c-object-handles-out.pdf
Normal file
104
qpdf/qtest/qpdf/c-object-handles-out.pdf
Normal file
@ -0,0 +1,104 @@
|
||||
%PDF-1.3
|
||||
%¿÷¢þ
|
||||
%QDF-1.0
|
||||
|
||||
1 0 obj
|
||||
<<
|
||||
/Pages 2 0 R
|
||||
/QTest <<
|
||||
/B [
|
||||
(potato)
|
||||
<feff00710077007700f703c0>
|
||||
/Quack
|
||||
null
|
||||
4.00
|
||||
5.0
|
||||
6
|
||||
true
|
||||
]
|
||||
/C <<
|
||||
>>
|
||||
>>
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
2 0 obj
|
||||
<<
|
||||
/Count 1
|
||||
/Kids [
|
||||
3 0 R
|
||||
]
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
%% Page 1
|
||||
3 0 obj
|
||||
<<
|
||||
/Contents 4 0 R
|
||||
/MediaBox [
|
||||
0
|
||||
0
|
||||
612
|
||||
792
|
||||
]
|
||||
/Parent 2 0 R
|
||||
/Resources <<
|
||||
/Font <<
|
||||
/F1 6 0 R
|
||||
>>
|
||||
/ProcSet [
|
||||
/PDF
|
||||
/Text
|
||||
]
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
endobj
|
||||
|
||||
%% Contents for page 1
|
||||
4 0 obj
|
||||
<<
|
||||
/Length 5 0 R
|
||||
>>
|
||||
stream
|
||||
BT
|
||||
/F1 24 Tf
|
||||
72 720 Td
|
||||
(Potato) Tj
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
|
||||
5 0 obj
|
||||
44
|
||||
endobj
|
||||
|
||||
6 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica
|
||||
/Encoding /WinAnsiEncoding
|
||||
/Name /F1
|
||||
/Subtype /Type1
|
||||
/Type /Font
|
||||
>>
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 7
|
||||
0000000000 65535 f
|
||||
0000000025 00000 n
|
||||
0000000240 00000 n
|
||||
0000000322 00000 n
|
||||
0000000562 00000 n
|
||||
0000000661 00000 n
|
||||
0000000680 00000 n
|
||||
trailer <<
|
||||
/Root 1 0 R
|
||||
/Size 7
|
||||
/ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
|
||||
>>
|
||||
startxref
|
||||
798
|
||||
%%EOF
|
24
qpdf/qtest/qpdf/c-object-handles.out
Normal file
24
qpdf/qtest/qpdf/c-object-handles.out
Normal file
@ -0,0 +1,24 @@
|
||||
page dictionary key: /Contents
|
||||
page dictionary key: /MediaBox
|
||||
page dictionary key: /Parent
|
||||
page dictionary key: /Resources
|
||||
page dictionary key: /Type
|
||||
item 0: 0 0.00
|
||||
item 1: 0 0.00
|
||||
item 2: 612 612.00
|
||||
item 3: 792 792.00
|
||||
warning: minimal.pdf (C API object handle 6): attempted access to unknown/uninitialized object handle
|
||||
code: 5
|
||||
file: minimal.pdf
|
||||
pos : 0
|
||||
text: attempted access to unknown/uninitialized object handle
|
||||
warning: minimal.pdf (C API object handle 9): attempted access to unknown/uninitialized object handle
|
||||
code: 5
|
||||
file: minimal.pdf
|
||||
pos : 0
|
||||
text: attempted access to unknown/uninitialized object handle
|
||||
warning: minimal.pdf (C API object handle 9): attempted access to unknown/uninitialized object handle
|
||||
code: 5
|
||||
file: minimal.pdf
|
||||
pos : 0
|
||||
text: attempted access to unknown/uninitialized object handle
|
Loading…
Reference in New Issue
Block a user