Commit b1e0dcff16740d5a99e58c298284c5d589b3034f

Authored by Jay Berkenbilt
1 parent 0c1dab0c

handle stream filter abbreviations from table H.1

git-svn-id: svn+q:///qpdf/trunk@1025 71b93d88-0707-0410-a8cf-f5a4172ac649
ChangeLog
  1 +2010-09-05 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * libqpdf/QPDF_Stream.cc (filterable): Handle inline image filter
  4 + abbreviations as stream filter abbreviations. Although this is
  5 + not technically allowed by the PDF specification, table H.1 in the
  6 + pre-ISO spec indicates that Adobe's readers accept them. Thanks
  7 + to Jian Ma <stronghorse@tom.com> for bringing this to my
  8 + attention.
  9 +
1 2010-08-14 Jay Berkenbilt <ejb@ql.org> 10 2010-08-14 Jay Berkenbilt <ejb@ql.org>
2 11
3 * 2.2.0: release 12 * 2.2.0: release
libqpdf/QPDFWriter.cc
@@ -993,7 +993,9 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level, @@ -993,7 +993,9 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
993 // compressed with a lossy compression scheme, but we 993 // compressed with a lossy compression scheme, but we
994 // don't support any of those right now. 994 // don't support any of those right now.
995 QPDFObjectHandle filter_obj = stream_dict.getKey("/Filter"); 995 QPDFObjectHandle filter_obj = stream_dict.getKey("/Filter");
996 - if (filter_obj.isName() && (filter_obj.getName() == "/FlateDecode")) 996 + if (filter_obj.isName() &&
  997 + ((filter_obj.getName() == "/FlateDecode") ||
  998 + (filter_obj.getName() == "/Fl")))
997 { 999 {
998 QTC::TC("qpdf", "QPDFWriter not recompressing /FlateDecode"); 1000 QTC::TC("qpdf", "QPDFWriter not recompressing /FlateDecode");
999 filter = false; 1001 filter = false;
libqpdf/QPDF_Stream.cc
@@ -18,6 +18,8 @@ @@ -18,6 +18,8 @@
18 18
19 #include <stdexcept> 19 #include <stdexcept>
20 20
  21 +std::map<std::string, std::string> QPDF_Stream::filter_abbreviations;
  22 +
21 QPDF_Stream::QPDF_Stream(QPDF* qpdf, int objid, int generation, 23 QPDF_Stream::QPDF_Stream(QPDF* qpdf, int objid, int generation,
22 QPDFObjectHandle stream_dict, 24 QPDFObjectHandle stream_dict,
23 off_t offset, int length) : 25 off_t offset, int length) :
@@ -93,6 +95,21 @@ QPDF_Stream::filterable(std::vector&lt;std::string&gt;&amp; filters, @@ -93,6 +95,21 @@ QPDF_Stream::filterable(std::vector&lt;std::string&gt;&amp; filters,
93 int& predictor, int& columns, 95 int& predictor, int& columns,
94 bool& early_code_change) 96 bool& early_code_change)
95 { 97 {
  98 + if (filter_abbreviations.empty())
  99 + {
  100 + // The PDF specification provides these filter abbreviations
  101 + // for use in inline images, but according to table H.1 in the
  102 + // pre-ISO versions of the PDF specification, Adobe Reader
  103 + // also accepts them for stream filters.
  104 + filter_abbreviations["/AHx"] = "/ASCIIHexDecode";
  105 + filter_abbreviations["/A85"] = "/ASCII85Decode";
  106 + filter_abbreviations["/LZW"] = "/LZWDecode";
  107 + filter_abbreviations["/Fl"] = "/FlateDecode";
  108 + filter_abbreviations["/RL"] = "/RunLengthDecode";
  109 + filter_abbreviations["/CCF"] = "/CCITTFaxDecode";
  110 + filter_abbreviations["/DCT"] = "/DCTDecode";
  111 + }
  112 +
96 // Initialize values to their defaults as per the PDF spec 113 // Initialize values to their defaults as per the PDF spec
97 predictor = 1; 114 predictor = 1;
98 columns = 0; 115 columns = 0;
@@ -243,7 +260,14 @@ QPDF_Stream::filterable(std::vector&lt;std::string&gt;&amp; filters, @@ -243,7 +260,14 @@ QPDF_Stream::filterable(std::vector&lt;std::string&gt;&amp; filters,
243 for (std::vector<std::string>::iterator iter = filters.begin(); 260 for (std::vector<std::string>::iterator iter = filters.begin();
244 iter != filters.end(); ++iter) 261 iter != filters.end(); ++iter)
245 { 262 {
246 - std::string const& filter = *iter; 263 + std::string& filter = *iter;
  264 +
  265 + if (filter_abbreviations.count(filter))
  266 + {
  267 + QTC::TC("qpdf", "QPDF_Stream expand filter abbreviation");
  268 + filter = filter_abbreviations[filter];
  269 + }
  270 +
247 if (! ((filter == "/Crypt") || 271 if (! ((filter == "/Crypt") ||
248 (filter == "/FlateDecode") || 272 (filter == "/FlateDecode") ||
249 (filter == "/LZWDecode") || 273 (filter == "/LZWDecode") ||
libqpdf/qpdf/QPDF_Stream.hh
@@ -38,6 +38,8 @@ class QPDF_Stream: public QPDFObject @@ -38,6 +38,8 @@ class QPDF_Stream: public QPDFObject
38 void setObjGen(int objid, int generation); 38 void setObjGen(int objid, int generation);
39 39
40 private: 40 private:
  41 + static std::map<std::string, std::string> filter_abbreviations;
  42 +
41 void replaceFilterData(QPDFObjectHandle const& filter, 43 void replaceFilterData(QPDFObjectHandle const& filter,
42 QPDFObjectHandle const& decode_parms, 44 QPDFObjectHandle const& decode_parms,
43 size_t length); 45 size_t length);
qpdf/qpdf.testcov
@@ -185,3 +185,4 @@ QPDFObjectHandle prepend page contents 0 @@ -185,3 +185,4 @@ QPDFObjectHandle prepend page contents 0
185 QPDFObjectHandle append page contents 0 185 QPDFObjectHandle append page contents 0
186 QPDF_Stream getRawStreamData 0 186 QPDF_Stream getRawStreamData 0
187 QPDF_Stream getStreamData 0 187 QPDF_Stream getStreamData 0
  188 +QPDF_Stream expand filter abbreviation 0
qpdf/qtest/qpdf.test
@@ -111,7 +111,7 @@ $td-&gt;runtest(&quot;new stream&quot;, @@ -111,7 +111,7 @@ $td-&gt;runtest(&quot;new stream&quot;,
111 show_ntests(); 111 show_ntests();
112 # ---------- 112 # ----------
113 $td->notify("--- Miscellaneous Tests ---"); 113 $td->notify("--- Miscellaneous Tests ---");
114 -$n_tests += 23; 114 +$n_tests += 25;
115 115
116 $td->runtest("qpdf version", 116 $td->runtest("qpdf version",
117 {$td->COMMAND => "qpdf --version"}, 117 {$td->COMMAND => "qpdf --version"},
@@ -229,6 +229,16 @@ $td-&gt;runtest(&quot;C check version 2&quot;, @@ -229,6 +229,16 @@ $td-&gt;runtest(&quot;C check version 2&quot;,
229 $td->EXIT_STATUS => 0}, 229 $td->EXIT_STATUS => 0},
230 $td->NORMALIZE_NEWLINES); 230 $td->NORMALIZE_NEWLINES);
231 231
  232 +# Stream filter abbreviations from table H.1
  233 +$td->runtest("stream filter abbreviations",
  234 + {$td->COMMAND => "qpdf --static-id filter-abbreviation.pdf a.pdf"},
  235 + {$td->STRING => "",
  236 + $td->EXIT_STATUS => 0},
  237 + $td->NORMALIZE_NEWLINES);
  238 +$td->runtest("check output",
  239 + {$td->FILE => "a.pdf"},
  240 + {$td->FILE => "filter-abbreviation.out"});
  241 +
232 show_ntests(); 242 show_ntests();
233 # ---------- 243 # ----------
234 $td->notify("--- Error Condition Tests ---"); 244 $td->notify("--- Error Condition Tests ---");
qpdf/qtest/qpdf/filter-abbreviation.out 0 → 100644
No preview for this file type
qpdf/qtest/qpdf/filter-abbreviation.pdf 0 → 100644
No preview for this file type