handle stream filter abbreviations from table H.1

git-svn-id: svn+q:///qpdf/trunk@1025 71b93d88-0707-0410-a8cf-f5a4172ac649
This commit is contained in:
Jay Berkenbilt 2010-09-05 15:00:44 +00:00
parent 0c1dab0cea
commit b1e0dcff16
8 changed files with 51 additions and 3 deletions

View File

@ -1,3 +1,12 @@
2010-09-05 Jay Berkenbilt <ejb@ql.org>
* libqpdf/QPDF_Stream.cc (filterable): Handle inline image filter
abbreviations as stream filter abbreviations. Although this is
not technically allowed by the PDF specification, table H.1 in the
pre-ISO spec indicates that Adobe's readers accept them. Thanks
to Jian Ma <stronghorse@tom.com> for bringing this to my
attention.
2010-08-14 Jay Berkenbilt <ejb@ql.org>
* 2.2.0: release

View File

@ -993,7 +993,9 @@ QPDFWriter::unparseObject(QPDFObjectHandle object, int level,
// compressed with a lossy compression scheme, but we
// don't support any of those right now.
QPDFObjectHandle filter_obj = stream_dict.getKey("/Filter");
if (filter_obj.isName() && (filter_obj.getName() == "/FlateDecode"))
if (filter_obj.isName() &&
((filter_obj.getName() == "/FlateDecode") ||
(filter_obj.getName() == "/Fl")))
{
QTC::TC("qpdf", "QPDFWriter not recompressing /FlateDecode");
filter = false;

View File

@ -18,6 +18,8 @@
#include <stdexcept>
std::map<std::string, std::string> QPDF_Stream::filter_abbreviations;
QPDF_Stream::QPDF_Stream(QPDF* qpdf, int objid, int generation,
QPDFObjectHandle stream_dict,
off_t offset, int length) :
@ -93,6 +95,21 @@ QPDF_Stream::filterable(std::vector<std::string>& filters,
int& predictor, int& columns,
bool& early_code_change)
{
if (filter_abbreviations.empty())
{
// The PDF specification provides these filter abbreviations
// for use in inline images, but according to table H.1 in the
// pre-ISO versions of the PDF specification, Adobe Reader
// also accepts them for stream filters.
filter_abbreviations["/AHx"] = "/ASCIIHexDecode";
filter_abbreviations["/A85"] = "/ASCII85Decode";
filter_abbreviations["/LZW"] = "/LZWDecode";
filter_abbreviations["/Fl"] = "/FlateDecode";
filter_abbreviations["/RL"] = "/RunLengthDecode";
filter_abbreviations["/CCF"] = "/CCITTFaxDecode";
filter_abbreviations["/DCT"] = "/DCTDecode";
}
// Initialize values to their defaults as per the PDF spec
predictor = 1;
columns = 0;
@ -243,7 +260,14 @@ QPDF_Stream::filterable(std::vector<std::string>& filters,
for (std::vector<std::string>::iterator iter = filters.begin();
iter != filters.end(); ++iter)
{
std::string const& filter = *iter;
std::string& filter = *iter;
if (filter_abbreviations.count(filter))
{
QTC::TC("qpdf", "QPDF_Stream expand filter abbreviation");
filter = filter_abbreviations[filter];
}
if (! ((filter == "/Crypt") ||
(filter == "/FlateDecode") ||
(filter == "/LZWDecode") ||

View File

@ -38,6 +38,8 @@ class QPDF_Stream: public QPDFObject
void setObjGen(int objid, int generation);
private:
static std::map<std::string, std::string> filter_abbreviations;
void replaceFilterData(QPDFObjectHandle const& filter,
QPDFObjectHandle const& decode_parms,
size_t length);

View File

@ -185,3 +185,4 @@ QPDFObjectHandle prepend page contents 0
QPDFObjectHandle append page contents 0
QPDF_Stream getRawStreamData 0
QPDF_Stream getStreamData 0
QPDF_Stream expand filter abbreviation 0

View File

@ -111,7 +111,7 @@ $td->runtest("new stream",
show_ntests();
# ----------
$td->notify("--- Miscellaneous Tests ---");
$n_tests += 23;
$n_tests += 25;
$td->runtest("qpdf version",
{$td->COMMAND => "qpdf --version"},
@ -229,6 +229,16 @@ $td->runtest("C check version 2",
$td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
# Stream filter abbreviations from table H.1
$td->runtest("stream filter abbreviations",
{$td->COMMAND => "qpdf --static-id filter-abbreviation.pdf a.pdf"},
{$td->STRING => "",
$td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
$td->runtest("check output",
{$td->FILE => "a.pdf"},
{$td->FILE => "filter-abbreviation.out"});
show_ntests();
# ----------
$td->notify("--- Error Condition Tests ---");

Binary file not shown.

Binary file not shown.