Commit a72ce95c922228e624e47bb43a68c55a9dd8eab2
1 parent
9f444ffe
setOutputStreams
git-svn-id: svn+q:///qpdf/trunk@1035 71b93d88-0707-0410-a8cf-f5a4172ac649
Showing
11 changed files
with
276 additions
and
45 deletions
ChangeLog
| 1 | 1 | 2010-10-01 Jay Berkenbilt <ejb@ql.org> |
| 2 | 2 | |
| 3 | + * include/qpdf/QPDF.hh: Add setOutputStreams method to allow | |
| 4 | + redirection of library-generated output/error to alternative | |
| 5 | + streams. | |
| 6 | + | |
| 3 | 7 | * include/qpdf/QPDF.hh: Add processMemoryFile method for |
| 4 | 8 | processing a PDF file from a memory buffer instead of a file. |
| 5 | 9 | ... | ... |
TODO
| 1 | -General | |
| 2 | -======= | |
| 1 | +2.2.1 | |
| 2 | +===== | |
| 3 | + | |
| 4 | + * Remove cerr and cout from QPDF*.cc | |
| 3 | 5 | |
| 4 | 6 | * QPDF::checkLinearization writes things to std::cout, which makes it |
| 5 | 7 | hard for GUIs that want to display the result. Go through all |
| ... | ... | @@ -12,6 +14,10 @@ General |
| 12 | 14 | rethrow if needed. The old version should call the ostream version |
| 13 | 15 | with std::cout. |
| 14 | 16 | |
| 17 | + | |
| 18 | +General | |
| 19 | +======= | |
| 20 | + | |
| 15 | 21 | * In general, take a fresh look at private methods to see which, if |
| 16 | 22 | any, should be protected. |
| 17 | 23 | ... | ... |
include/qpdf/QPDF.hh
| ... | ... | @@ -12,6 +12,7 @@ |
| 12 | 12 | #include <string> |
| 13 | 13 | #include <map> |
| 14 | 14 | #include <list> |
| 15 | +#include <iostream> | |
| 15 | 16 | |
| 16 | 17 | #include <qpdf/DLL.h> |
| 17 | 18 | |
| ... | ... | @@ -61,6 +62,21 @@ class QPDF |
| 61 | 62 | |
| 62 | 63 | // Parameter settings |
| 63 | 64 | |
| 65 | + // By default, warning messages are issued to std::cerr and output | |
| 66 | + // messages printed by certain check calls are issued to | |
| 67 | + // std::cout. This method allows you to specify alternative | |
| 68 | + // streams for this purpose. Note that no normal QPDF operations | |
| 69 | + // generate output to std::cout, so for applications that just | |
| 70 | + // wish to avoid creating output and don't call any check | |
| 71 | + // functions, calling setSuppressWarnings(true) is sufficient. | |
| 72 | + // Applications that wish to present check or warning information | |
| 73 | + // to users may replace the output and error streams to capture | |
| 74 | + // the output and errors for other use. A null value for either | |
| 75 | + // stream will cause QPDF to use std::cout or std::cerr as | |
| 76 | + // appropriate. | |
| 77 | + QPDF_DLL | |
| 78 | + void setOutputStreams(std::ostream* out_stream, std::ostream* err_stream); | |
| 79 | + | |
| 64 | 80 | // If true, ignore any cross-reference streams in a hybrid file |
| 65 | 81 | // (one that contains both cross-reference streams and |
| 66 | 82 | // cross-reference tables). This can be useful for testing to |
| ... | ... | @@ -68,7 +84,8 @@ class QPDF |
| 68 | 84 | QPDF_DLL |
| 69 | 85 | void setIgnoreXRefStreams(bool); |
| 70 | 86 | |
| 71 | - // By default, any warnings are issued to stderr as they are | |
| 87 | + // By default, any warnings are issued to std::cerr or the error | |
| 88 | + // stream specified in a call to setOutputStreams as they are | |
| 72 | 89 | // encountered. If this is called with a true value, reporting of |
| 73 | 90 | // warnings is suppressed. You may still retrieve warnings by |
| 74 | 91 | // calling getWarnings. |
| ... | ... | @@ -88,7 +105,7 @@ class QPDF |
| 88 | 105 | // clear the list. This method may be called even if processFile |
| 89 | 106 | // throws an exception. Note that if setSuppressWarnings was not |
| 90 | 107 | // called or was called with a false value, any warnings retrieved |
| 91 | - // here will have already been issued to stderr. | |
| 108 | + // here will have already been output. | |
| 92 | 109 | QPDF_DLL |
| 93 | 110 | std::vector<QPDFExc> getWarnings(); |
| 94 | 111 | |
| ... | ... | @@ -204,12 +221,14 @@ class QPDF |
| 204 | 221 | |
| 205 | 222 | // Performs various sanity checks on a linearized file. Return |
| 206 | 223 | // true if no errors or warnings. Otherwise, return false and |
| 207 | - // output errors and warnings to stdout. | |
| 224 | + // output errors and warnings to std::cout or the output stream | |
| 225 | + // specified in a call to setOutputStreams. | |
| 208 | 226 | QPDF_DLL |
| 209 | 227 | bool checkLinearization(); |
| 210 | 228 | |
| 211 | 229 | // Calls checkLinearization() and, if possible, prints normalized |
| 212 | - // contents of some of the hints tables to stdout. Normalization | |
| 230 | + // contents of some of the hints tables to std::cout or the output | |
| 231 | + // stream specified in a call to setOutputStreams. Normalization | |
| 213 | 232 | // includes adding min values to delta values and adjusting |
| 214 | 233 | // offsets based on the location and size of the primary hint |
| 215 | 234 | // stream. |
| ... | ... | @@ -803,6 +822,8 @@ class QPDF |
| 803 | 822 | bool encryption_initialized; |
| 804 | 823 | bool ignore_xref_streams; |
| 805 | 824 | bool suppress_warnings; |
| 825 | + std::ostream* out_stream; | |
| 826 | + std::ostream* err_stream; | |
| 806 | 827 | bool attempt_recovery; |
| 807 | 828 | int encryption_V; |
| 808 | 829 | bool encrypt_metadata; | ... | ... |
libqpdf/QPDF.cc
| ... | ... | @@ -267,6 +267,8 @@ QPDF::QPDF() : |
| 267 | 267 | encryption_initialized(false), |
| 268 | 268 | ignore_xref_streams(false), |
| 269 | 269 | suppress_warnings(false), |
| 270 | + out_stream(&std::cout), | |
| 271 | + err_stream(&std::cerr), | |
| 270 | 272 | attempt_recovery(true), |
| 271 | 273 | encryption_V(0), |
| 272 | 274 | encrypt_metadata(true), |
| ... | ... | @@ -333,6 +335,13 @@ QPDF::setIgnoreXRefStreams(bool val) |
| 333 | 335 | } |
| 334 | 336 | |
| 335 | 337 | void |
| 338 | +QPDF::setOutputStreams(std::ostream* out, std::ostream* err) | |
| 339 | +{ | |
| 340 | + this->out_stream = out ? out : &std::cout; | |
| 341 | + this->err_stream = err ? err : &std::cerr; | |
| 342 | +} | |
| 343 | + | |
| 344 | +void | |
| 336 | 345 | QPDF::setSuppressWarnings(bool val) |
| 337 | 346 | { |
| 338 | 347 | this->suppress_warnings = val; |
| ... | ... | @@ -449,7 +458,8 @@ QPDF::warn(QPDFExc const& e) |
| 449 | 458 | this->warnings.push_back(e); |
| 450 | 459 | if (! this->suppress_warnings) |
| 451 | 460 | { |
| 452 | - std::cerr << "WARNING: " << this->warnings.back().what() << std::endl; | |
| 461 | + *err_stream << "WARNING: " | |
| 462 | + << this->warnings.back().what() << std::endl; | |
| 453 | 463 | } |
| 454 | 464 | } |
| 455 | 465 | |
| ... | ... | @@ -1045,16 +1055,16 @@ QPDF::showXRefTable() |
| 1045 | 1055 | { |
| 1046 | 1056 | ObjGen const& og = (*iter).first; |
| 1047 | 1057 | QPDFXRefEntry const& entry = (*iter).second; |
| 1048 | - std::cout << og.obj << "/" << og.gen << ": "; | |
| 1058 | + *out_stream << og.obj << "/" << og.gen << ": "; | |
| 1049 | 1059 | switch (entry.getType()) |
| 1050 | 1060 | { |
| 1051 | 1061 | case 1: |
| 1052 | - std::cout << "uncompressed; offset = " << entry.getOffset(); | |
| 1062 | + *out_stream << "uncompressed; offset = " << entry.getOffset(); | |
| 1053 | 1063 | break; |
| 1054 | 1064 | |
| 1055 | 1065 | case 2: |
| 1056 | - std::cout << "compressed; stream = " << entry.getObjStreamNumber() | |
| 1057 | - << ", index = " << entry.getObjStreamIndex(); | |
| 1066 | + *out_stream << "compressed; stream = " << entry.getObjStreamNumber() | |
| 1067 | + << ", index = " << entry.getObjStreamIndex(); | |
| 1058 | 1068 | break; |
| 1059 | 1069 | |
| 1060 | 1070 | default: |
| ... | ... | @@ -1062,7 +1072,7 @@ QPDF::showXRefTable() |
| 1062 | 1072 | " showing xref_table"); |
| 1063 | 1073 | break; |
| 1064 | 1074 | } |
| 1065 | - std::cout << std::endl; | |
| 1075 | + *out_stream << std::endl; | |
| 1066 | 1076 | } |
| 1067 | 1077 | } |
| 1068 | 1078 | ... | ... |
libqpdf/QPDF_linearization.cc
| ... | ... | @@ -64,7 +64,7 @@ QPDF::checkLinearization() |
| 64 | 64 | } |
| 65 | 65 | catch (QPDFExc& e) |
| 66 | 66 | { |
| 67 | - std::cout << e.what() << std::endl; | |
| 67 | + *out_stream << e.what() << std::endl; | |
| 68 | 68 | } |
| 69 | 69 | return result; |
| 70 | 70 | } |
| ... | ... | @@ -351,9 +351,9 @@ QPDF::readHintStream(Pipeline& pl, off_t offset, size_t length) |
| 351 | 351 | if ((computed_end < min_end_offset) || |
| 352 | 352 | (computed_end > max_end_offset)) |
| 353 | 353 | { |
| 354 | - std::cout << "expected = " << computed_end | |
| 355 | - << "; actual = " << min_end_offset << ".." | |
| 356 | - << max_end_offset << std::endl; | |
| 354 | + *out_stream << "expected = " << computed_end | |
| 355 | + << "; actual = " << min_end_offset << ".." | |
| 356 | + << max_end_offset << std::endl; | |
| 357 | 357 | throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), |
| 358 | 358 | "linearization dictionary", |
| 359 | 359 | this->file->getLastOffset(), |
| ... | ... | @@ -617,7 +617,7 @@ QPDF::checkLinearizationInternal() |
| 617 | 617 | for (std::list<std::string>::iterator iter = errors.begin(); |
| 618 | 618 | iter != errors.end(); ++iter) |
| 619 | 619 | { |
| 620 | - std::cout << "ERROR: " << (*iter) << std::endl; | |
| 620 | + *out_stream << "ERROR: " << (*iter) << std::endl; | |
| 621 | 621 | } |
| 622 | 622 | } |
| 623 | 623 | |
| ... | ... | @@ -627,7 +627,7 @@ QPDF::checkLinearizationInternal() |
| 627 | 627 | for (std::list<std::string>::iterator iter = warnings.begin(); |
| 628 | 628 | iter != warnings.end(); ++iter) |
| 629 | 629 | { |
| 630 | - std::cout << "WARNING: " << (*iter) << std::endl; | |
| 630 | + *out_stream << "WARNING: " << (*iter) << std::endl; | |
| 631 | 631 | } |
| 632 | 632 | } |
| 633 | 633 | |
| ... | ... | @@ -1008,17 +1008,17 @@ QPDF::showLinearizationData() |
| 1008 | 1008 | } |
| 1009 | 1009 | catch (QPDFExc& e) |
| 1010 | 1010 | { |
| 1011 | - std::cout << e.what() << std::endl; | |
| 1011 | + *out_stream << e.what() << std::endl; | |
| 1012 | 1012 | } |
| 1013 | 1013 | } |
| 1014 | 1014 | |
| 1015 | 1015 | void |
| 1016 | 1016 | QPDF::dumpLinearizationDataInternal() |
| 1017 | 1017 | { |
| 1018 | - std::cout << this->file->getName() << ": linearization data:" << std::endl | |
| 1019 | - << std::endl; | |
| 1018 | + *out_stream << this->file->getName() << ": linearization data:" << std::endl | |
| 1019 | + << std::endl; | |
| 1020 | 1020 | |
| 1021 | - std::cout | |
| 1021 | + *out_stream | |
| 1022 | 1022 | << "file_size: " << this->linp.file_size << std::endl |
| 1023 | 1023 | << "first_page_object: " << this->linp.first_page_object << std::endl |
| 1024 | 1024 | << "first_page_end: " << this->linp.first_page_end << std::endl |
| ... | ... | @@ -1029,19 +1029,19 @@ QPDF::dumpLinearizationDataInternal() |
| 1029 | 1029 | << "H_length: " << this->linp.H_length << std::endl |
| 1030 | 1030 | << std::endl; |
| 1031 | 1031 | |
| 1032 | - std::cout << "Page Offsets Hint Table" << std::endl | |
| 1033 | - << std::endl; | |
| 1032 | + *out_stream << "Page Offsets Hint Table" << std::endl | |
| 1033 | + << std::endl; | |
| 1034 | 1034 | dumpHPageOffset(); |
| 1035 | - std::cout << std::endl | |
| 1036 | - << "Shared Objects Hint Table" << std::endl | |
| 1037 | - << std::endl; | |
| 1035 | + *out_stream << std::endl | |
| 1036 | + << "Shared Objects Hint Table" << std::endl | |
| 1037 | + << std::endl; | |
| 1038 | 1038 | dumpHSharedObject(); |
| 1039 | 1039 | |
| 1040 | 1040 | if (this->outline_hints.nobjects > 0) |
| 1041 | 1041 | { |
| 1042 | - std::cout << std::endl | |
| 1043 | - << "Outlines Hint Table" << std::endl | |
| 1044 | - << std::endl; | |
| 1042 | + *out_stream << std::endl | |
| 1043 | + << "Outlines Hint Table" << std::endl | |
| 1044 | + << std::endl; | |
| 1045 | 1045 | dumpHGeneric(this->outline_hints); |
| 1046 | 1046 | } |
| 1047 | 1047 | } |
| ... | ... | @@ -1064,7 +1064,7 @@ void |
| 1064 | 1064 | QPDF::dumpHPageOffset() |
| 1065 | 1065 | { |
| 1066 | 1066 | HPageOffset& t = this->page_offset_hints; |
| 1067 | - std::cout | |
| 1067 | + *out_stream | |
| 1068 | 1068 | << "min_nobjects: " << t.min_nobjects |
| 1069 | 1069 | << std::endl |
| 1070 | 1070 | << "first_page_offset: " << adjusted_offset(t.first_page_offset) |
| ... | ... | @@ -1095,7 +1095,7 @@ QPDF::dumpHPageOffset() |
| 1095 | 1095 | for (int i1 = 0; i1 < this->linp.npages; ++i1) |
| 1096 | 1096 | { |
| 1097 | 1097 | HPageOffsetEntry& pe = t.entries[i1]; |
| 1098 | - std::cout | |
| 1098 | + *out_stream | |
| 1099 | 1099 | << "Page " << i1 << ":" << std::endl |
| 1100 | 1100 | << " nobjects: " << pe.delta_nobjects + t.min_nobjects |
| 1101 | 1101 | << std::endl |
| ... | ... | @@ -1109,10 +1109,10 @@ QPDF::dumpHPageOffset() |
| 1109 | 1109 | << " nshared_objects: " << pe.nshared_objects << std::endl; |
| 1110 | 1110 | for (int i2 = 0; i2 < pe.nshared_objects; ++i2) |
| 1111 | 1111 | { |
| 1112 | - std::cout << " identifier " << i2 << ": " | |
| 1113 | - << pe.shared_identifiers[i2] << std::endl; | |
| 1114 | - std::cout << " numerator " << i2 << ": " | |
| 1115 | - << pe.shared_numerators[i2] << std::endl; | |
| 1112 | + *out_stream << " identifier " << i2 << ": " | |
| 1113 | + << pe.shared_identifiers[i2] << std::endl; | |
| 1114 | + *out_stream << " numerator " << i2 << ": " | |
| 1115 | + << pe.shared_numerators[i2] << std::endl; | |
| 1116 | 1116 | } |
| 1117 | 1117 | } |
| 1118 | 1118 | } |
| ... | ... | @@ -1121,7 +1121,7 @@ void |
| 1121 | 1121 | QPDF::dumpHSharedObject() |
| 1122 | 1122 | { |
| 1123 | 1123 | HSharedObject& t = this->shared_object_hints; |
| 1124 | - std::cout | |
| 1124 | + *out_stream | |
| 1125 | 1125 | << "first_shared_obj: " << t.first_shared_obj |
| 1126 | 1126 | << std::endl |
| 1127 | 1127 | << "first_shared_offset: " << adjusted_offset(t.first_shared_offset) |
| ... | ... | @@ -1140,19 +1140,19 @@ QPDF::dumpHSharedObject() |
| 1140 | 1140 | for (int i = 0; i < t.nshared_total; ++i) |
| 1141 | 1141 | { |
| 1142 | 1142 | HSharedObjectEntry& se = t.entries[i]; |
| 1143 | - std::cout << "Shared Object " << i << ":" << std::endl; | |
| 1144 | - std::cout << " group length: " | |
| 1145 | - << se.delta_group_length + t.min_group_length << std::endl; | |
| 1143 | + *out_stream << "Shared Object " << i << ":" << std::endl; | |
| 1144 | + *out_stream << " group length: " | |
| 1145 | + << se.delta_group_length + t.min_group_length << std::endl; | |
| 1146 | 1146 | // PDF spec says signature present nobjects_minus_one are |
| 1147 | 1147 | // always 0, so print them only if they have a non-zero value. |
| 1148 | 1148 | if (se.signature_present) |
| 1149 | 1149 | { |
| 1150 | - std::cout << " signature present" << std::endl; | |
| 1150 | + *out_stream << " signature present" << std::endl; | |
| 1151 | 1151 | } |
| 1152 | 1152 | if (se.nobjects_minus_one != 0) |
| 1153 | 1153 | { |
| 1154 | - std::cout << " nobjects: " | |
| 1155 | - << se.nobjects_minus_one + 1 << std::endl; | |
| 1154 | + *out_stream << " nobjects: " | |
| 1155 | + << se.nobjects_minus_one + 1 << std::endl; | |
| 1156 | 1156 | } |
| 1157 | 1157 | } |
| 1158 | 1158 | } |
| ... | ... | @@ -1160,7 +1160,7 @@ QPDF::dumpHSharedObject() |
| 1160 | 1160 | void |
| 1161 | 1161 | QPDF::dumpHGeneric(HGeneric& t) |
| 1162 | 1162 | { |
| 1163 | - std::cout | |
| 1163 | + *out_stream | |
| 1164 | 1164 | << "first_object: " << t.first_object |
| 1165 | 1165 | << std::endl |
| 1166 | 1166 | << "first_object_offset: " << adjusted_offset(t.first_object_offset) | ... | ... |
manual/qpdf-manual.xml
| ... | ... | @@ -2075,6 +2075,61 @@ print "\n"; |
| 2075 | 2075 | </para> |
| 2076 | 2076 | <variablelist> |
| 2077 | 2077 | <varlistentry> |
| 2078 | + <term>2.2.1: XXX</term> | |
| 2079 | + <listitem> | |
| 2080 | + <itemizedlist> | |
| 2081 | + <listitem> | |
| 2082 | + <para> | |
| 2083 | + Add new method <classname>QPDF::processMemoryFile</classname> | |
| 2084 | + for operating on PDF files that are loaded into memory rather | |
| 2085 | + than in a file on disk. | |
| 2086 | + </para> | |
| 2087 | + </listitem> | |
| 2088 | + <listitem> | |
| 2089 | + <para> | |
| 2090 | + Add new method <classname>QPDF::setOutputStreams</classname> | |
| 2091 | + to replace <varname>std::cout</varname> and | |
| 2092 | + <varname>std::cerr</varname> with other streams for generation | |
| 2093 | + of diagnostic messages and error messages. This can be useful | |
| 2094 | + for GUIs or other applications that want to capture any output | |
| 2095 | + generated by the library to present to the user in some other | |
| 2096 | + way. Note that QPDF does not write to | |
| 2097 | + <varname>std::cout</varname> (or the specified output stream) | |
| 2098 | + except where explicitly mentioned in | |
| 2099 | + <filename>QPDF.hh</filename>, and that the only use of the | |
| 2100 | + error stream is for warnings. Note also that output of | |
| 2101 | + warnings is suppressed when | |
| 2102 | + <literal>setSuppressWarnings(true)</literal> is called. | |
| 2103 | + </para> | |
| 2104 | + </listitem> | |
| 2105 | + <listitem> | |
| 2106 | + <para> | |
| 2107 | + Give a warning but otherwise ignore empty PDF objects by | |
| 2108 | + treating them as null. Empty object are not permitted by the | |
| 2109 | + PDF specification but have been known to appear in some actual | |
| 2110 | + PDF files. | |
| 2111 | + </para> | |
| 2112 | + </listitem> | |
| 2113 | + <listitem> | |
| 2114 | + <para> | |
| 2115 | + Handle inline image filter abbreviations when the appear as | |
| 2116 | + stream filter abbreviations. The PDF specification does not | |
| 2117 | + allow use of stream filter abbreviations in this way, but | |
| 2118 | + Adobe Reader and some other PDF readers accept them since they | |
| 2119 | + sometimes appear incorrectly in actual PDF files. | |
| 2120 | + </para> | |
| 2121 | + </listitem> | |
| 2122 | + <listitem> | |
| 2123 | + <para> | |
| 2124 | + Implement miscellaneous enhancements to | |
| 2125 | + <classname>PointerHolder</classname> and | |
| 2126 | + <classname>Buffer</classname> to support other changes. | |
| 2127 | + </para> | |
| 2128 | + </listitem> | |
| 2129 | + </itemizedlist> | |
| 2130 | + </listitem> | |
| 2131 | + </varlistentry> | |
| 2132 | + <varlistentry> | |
| 2078 | 2133 | <term>2.2.0: August 14, 2010</term> |
| 2079 | 2134 | <listitem> |
| 2080 | 2135 | <itemizedlist> | ... | ... |
qpdf/qtest/qpdf.test
| ... | ... | @@ -111,7 +111,7 @@ $td->runtest("new stream", |
| 111 | 111 | show_ntests(); |
| 112 | 112 | # ---------- |
| 113 | 113 | $td->notify("--- Miscellaneous Tests ---"); |
| 114 | -$n_tests += 26; | |
| 114 | +$n_tests += 28; | |
| 115 | 115 | |
| 116 | 116 | $td->runtest("qpdf version", |
| 117 | 117 | {$td->COMMAND => "qpdf --version"}, |
| ... | ... | @@ -245,6 +245,18 @@ $td->runtest("empty object", |
| 245 | 245 | $td->EXIT_STATUS => 3}, |
| 246 | 246 | $td->NORMALIZE_NEWLINES); |
| 247 | 247 | |
| 248 | +$td->runtest("error/output redirection to null", | |
| 249 | + {$td->COMMAND => "test_driver 12 linearized-and-warnings.pdf"}, | |
| 250 | + {$td->FILE => "linearized-and-warnings-1.out", | |
| 251 | + $td->EXIT_STATUS => 0}, | |
| 252 | + $td->NORMALIZE_NEWLINES); | |
| 253 | + | |
| 254 | +$td->runtest("error/output redirection to strings", | |
| 255 | + {$td->COMMAND => "test_driver 13 linearized-and-warnings.pdf"}, | |
| 256 | + {$td->FILE => "linearized-and-warnings-2.out", | |
| 257 | + $td->EXIT_STATUS => 0}, | |
| 258 | + $td->NORMALIZE_NEWLINES); | |
| 259 | + | |
| 248 | 260 | show_ntests(); |
| 249 | 261 | # ---------- |
| 250 | 262 | $td->notify("--- Error Condition Tests ---"); | ... | ... |
qpdf/qtest/qpdf/linearized-and-warnings-1.out
0 → 100644
| 1 | +WARNING: linearized-and-warnings.pdf (object 2 0, file position 1117): empty object treated as null | |
| 2 | +linearized-and-warnings.pdf: linearization data: | |
| 3 | + | |
| 4 | +file_size: 1310 | |
| 5 | +first_page_object: 6 | |
| 6 | +first_page_end: 1044 | |
| 7 | +npages: 1 | |
| 8 | +xref_zero_offset: 1132 | |
| 9 | +first_page: 0 | |
| 10 | +H_offset: 528 | |
| 11 | +H_length: 118 | |
| 12 | + | |
| 13 | +Page Offsets Hint Table | |
| 14 | + | |
| 15 | +min_nobjects: 4 | |
| 16 | +first_page_offset: 646 | |
| 17 | +nbits_delta_nobjects: 0 | |
| 18 | +min_page_length: 398 | |
| 19 | +nbits_delta_page_length: 0 | |
| 20 | +min_content_offset: 0 | |
| 21 | +nbits_delta_content_offset: 0 | |
| 22 | +min_content_length: 398 | |
| 23 | +nbits_delta_content_length: 0 | |
| 24 | +nbits_nshared_objects: 0 | |
| 25 | +nbits_shared_identifier: 3 | |
| 26 | +nbits_shared_numerator: 0 | |
| 27 | +shared_denominator: 4 | |
| 28 | +Page 0: | |
| 29 | + nobjects: 4 | |
| 30 | + length: 398 | |
| 31 | + content_offset: 0 | |
| 32 | + content_length: 398 | |
| 33 | + nshared_objects: 0 | |
| 34 | + | |
| 35 | +Shared Objects Hint Table | |
| 36 | + | |
| 37 | +first_shared_obj: 0 | |
| 38 | +first_shared_offset: 0 | |
| 39 | +nshared_first_page: 4 | |
| 40 | +nshared_total: 4 | |
| 41 | +nbits_nobjects: 0 | |
| 42 | +min_group_length: 30 | |
| 43 | +nbits_delta_group_length: 7 | |
| 44 | +Shared Object 0: | |
| 45 | + group length: 143 | |
| 46 | +Shared Object 1: | |
| 47 | + group length: 118 | |
| 48 | +Shared Object 2: | |
| 49 | + group length: 30 | |
| 50 | +Shared Object 3: | |
| 51 | + group length: 107 | |
| 52 | +test 12 done | ... | ... |
qpdf/qtest/qpdf/linearized-and-warnings-2.out
0 → 100644
| 1 | +---output--- | |
| 2 | +linearized-and-warnings.pdf: linearization data: | |
| 3 | + | |
| 4 | +file_size: 1310 | |
| 5 | +first_page_object: 6 | |
| 6 | +first_page_end: 1044 | |
| 7 | +npages: 1 | |
| 8 | +xref_zero_offset: 1132 | |
| 9 | +first_page: 0 | |
| 10 | +H_offset: 528 | |
| 11 | +H_length: 118 | |
| 12 | + | |
| 13 | +Page Offsets Hint Table | |
| 14 | + | |
| 15 | +min_nobjects: 4 | |
| 16 | +first_page_offset: 646 | |
| 17 | +nbits_delta_nobjects: 0 | |
| 18 | +min_page_length: 398 | |
| 19 | +nbits_delta_page_length: 0 | |
| 20 | +min_content_offset: 0 | |
| 21 | +nbits_delta_content_offset: 0 | |
| 22 | +min_content_length: 398 | |
| 23 | +nbits_delta_content_length: 0 | |
| 24 | +nbits_nshared_objects: 0 | |
| 25 | +nbits_shared_identifier: 3 | |
| 26 | +nbits_shared_numerator: 0 | |
| 27 | +shared_denominator: 4 | |
| 28 | +Page 0: | |
| 29 | + nobjects: 4 | |
| 30 | + length: 398 | |
| 31 | + content_offset: 0 | |
| 32 | + content_length: 398 | |
| 33 | + nshared_objects: 0 | |
| 34 | + | |
| 35 | +Shared Objects Hint Table | |
| 36 | + | |
| 37 | +first_shared_obj: 0 | |
| 38 | +first_shared_offset: 0 | |
| 39 | +nshared_first_page: 4 | |
| 40 | +nshared_total: 4 | |
| 41 | +nbits_nobjects: 0 | |
| 42 | +min_group_length: 30 | |
| 43 | +nbits_delta_group_length: 7 | |
| 44 | +Shared Object 0: | |
| 45 | + group length: 143 | |
| 46 | +Shared Object 1: | |
| 47 | + group length: 118 | |
| 48 | +Shared Object 2: | |
| 49 | + group length: 30 | |
| 50 | +Shared Object 3: | |
| 51 | + group length: 107 | |
| 52 | +---error--- | |
| 53 | +WARNING: linearized-and-warnings.pdf (object 2 0, file position 1117): empty object treated as null | |
| 54 | +test 13 done | ... | ... |
qpdf/qtest/qpdf/linearized-and-warnings.pdf
0 → 100644
No preview for this file type
qpdf/test_driver.cc
| ... | ... | @@ -10,6 +10,7 @@ |
| 10 | 10 | #include <qpdf/Pl_Flate.hh> |
| 11 | 11 | #include <qpdf/QPDFWriter.hh> |
| 12 | 12 | #include <iostream> |
| 13 | +#include <sstream> | |
| 13 | 14 | #include <stdio.h> |
| 14 | 15 | #include <string.h> |
| 15 | 16 | #include <stdlib.h> |
| ... | ... | @@ -502,6 +503,22 @@ void runtest(int n, char const* filename) |
| 502 | 503 | std::cout << "raw stream data okay" << std::endl; |
| 503 | 504 | } |
| 504 | 505 | } |
| 506 | + else if (n == 12) | |
| 507 | + { | |
| 508 | + pdf.setOutputStreams(0, 0); | |
| 509 | + pdf.showLinearizationData(); | |
| 510 | + } | |
| 511 | + else if (n == 13) | |
| 512 | + { | |
| 513 | + std::ostringstream out; | |
| 514 | + std::ostringstream err; | |
| 515 | + pdf.setOutputStreams(&out, &err); | |
| 516 | + pdf.showLinearizationData(); | |
| 517 | + std::cout << "---output---" << std::endl | |
| 518 | + << out.str() | |
| 519 | + << "---error---" << std::endl | |
| 520 | + << err.str(); | |
| 521 | + } | |
| 505 | 522 | else |
| 506 | 523 | { |
| 507 | 524 | throw std::runtime_error(std::string("invalid test ") + | ... | ... |