From bd7261da9b3735688e8dcaeefe21294a1d13afd6 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Mon, 9 Aug 2010 23:33:40 +0000 Subject: [PATCH] getRawStreamData() git-svn-id: svn+q:///qpdf/trunk@1010 71b93d88-0707-0410-a8cf-f5a4172ac649 --- ChangeLog | 5 ++ TODO | 2 - include/qpdf/QPDFObjectHandle.hh | 3 + libqpdf/QPDFObjectHandle.cc | 7 ++ libqpdf/QPDF_Stream.cc | 10 +++ libqpdf/qpdf/QPDF_Stream.hh | 1 + manual/qpdf-manual.xml | 10 +++ qpdf/qpdf.testcov | 2 + qpdf/qtest/qpdf.test | 7 +- qpdf/qtest/qpdf/stream-data.pdf | 112 +++++++++++++++++++++++++++++++ qpdf/qtest/qpdf/test11.out | 3 + qpdf/test_driver.cc | 17 +++++ 12 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 qpdf/qtest/qpdf/stream-data.pdf create mode 100644 qpdf/qtest/qpdf/test11.out diff --git a/ChangeLog b/ChangeLog index cfd8e806..05fe61f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-08-09 Jay Berkenbilt + + * Add QPDFObjectHandle::getRawStreamData to return raw + (unfiltered) stream data. + 2010-08-08 Jay Berkenbilt * 2.2.rc1: release diff --git a/TODO b/TODO index 66923ef2..d0b425d6 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,6 @@ 2.2.0 ===== - * Add QPDFObjectHandle::getRawStreamData() - * shared library version information already bumped for 2.2.rc1; replace 2.2.rc1 with 2.2.0 in manual and update in other places for 2.2.0. diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh index b7df3750..a3d7fcce 100644 --- a/include/qpdf/QPDFObjectHandle.hh +++ b/include/qpdf/QPDFObjectHandle.hh @@ -216,6 +216,9 @@ class QPDFObjectHandle // exception if the stream is filtered and we can't decode it. QPDF_DLL PointerHolder getStreamData(); + // Returns unfiltered (raw) stream data. + QPDF_DLL + PointerHolder getRawStreamData(); // Write stream data through the given pipeline. A null pipeline // value may be used if all you want to do is determine whether a diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 143a3f42..658f4393 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -343,6 +343,13 @@ QPDFObjectHandle::getStreamData() return dynamic_cast(obj.getPointer())->getStreamData(); } +PointerHolder +QPDFObjectHandle::getRawStreamData() +{ + assertType("Stream", isStream()); + return dynamic_cast(obj.getPointer())->getRawStreamData(); +} + bool QPDFObjectHandle::pipeStreamData(Pipeline* p, bool filter, bool normalize, bool compress) diff --git a/libqpdf/QPDF_Stream.cc b/libqpdf/QPDF_Stream.cc index 87c2daa9..72be2e32 100644 --- a/libqpdf/QPDF_Stream.cc +++ b/libqpdf/QPDF_Stream.cc @@ -75,6 +75,16 @@ QPDF_Stream::getStreamData() { throw std::logic_error("getStreamData called on unfilterable stream"); } + QTC::TC("qpdf", "QPDF_Stream getStreamData"); + return buf.getBuffer(); +} + +PointerHolder +QPDF_Stream::getRawStreamData() +{ + Pl_Buffer buf("stream data buffer"); + pipeStreamData(&buf, false, false, false); + QTC::TC("qpdf", "QPDF_Stream getRawStreamData"); return buf.getBuffer(); } diff --git a/libqpdf/qpdf/QPDF_Stream.hh b/libqpdf/qpdf/QPDF_Stream.hh index 73261f39..ed70ae8f 100644 --- a/libqpdf/qpdf/QPDF_Stream.hh +++ b/libqpdf/qpdf/QPDF_Stream.hh @@ -22,6 +22,7 @@ class QPDF_Stream: public QPDFObject bool pipeStreamData(Pipeline*, bool filter, bool normalize, bool compress); PointerHolder getStreamData(); + PointerHolder getRawStreamData(); void replaceStreamData(PointerHolder data, QPDFObjectHandle const& filter, QPDFObjectHandle const& decode_parms); diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml index 8d9f12d3..54e7a70b 100644 --- a/manual/qpdf-manual.xml +++ b/manual/qpdf-manual.xml @@ -2105,6 +2105,16 @@ print "\n"; removes the key instead. + + + Add new method in QPDFObjectHandle: + getRawStreamData, which returns the raw + (unfiltered) stream data into a buffer. This complements the + getStreamData method, which returns the + filtered (uncompressed) stream data and can only be used when + the stream's data is filterable. + + Provide two new examples: diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov index 4a868227..f4354891 100644 --- a/qpdf/qpdf.testcov +++ b/qpdf/qpdf.testcov @@ -183,3 +183,5 @@ QPDFObjectHandle newStream with data 0 QPDF_Stream pipe no stream data 0 QPDFObjectHandle prepend page contents 0 QPDFObjectHandle append page contents 0 +QPDF_Stream getRawStreamData 0 +QPDF_Stream getStreamData 0 diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index 7d14722e..35b2be51 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -111,7 +111,7 @@ $td->runtest("new stream", show_ntests(); # ---------- $td->notify("--- Miscellaneous Tests ---"); -$n_tests += 22; +$n_tests += 23; $td->runtest("qpdf version", {$td->COMMAND => "qpdf --version"}, @@ -131,6 +131,11 @@ foreach (my $i = 1; $i <= 3; ++$i) $td->NORMALIZE_NEWLINES); } +$td->runtest("get stream data", + {$td->COMMAND => "test_driver 11 stream-data.pdf"}, + {$td->FILE => "test11.out", $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); + # Make sure we ignore decode parameters that we don't understand $td->runtest("unknown decode parameters", {$td->COMMAND => "qpdf --check fax-decode-parms.pdf"}, diff --git a/qpdf/qtest/qpdf/stream-data.pdf b/qpdf/qtest/qpdf/stream-data.pdf new file mode 100644 index 00000000..61100863 --- /dev/null +++ b/qpdf/qtest/qpdf/stream-data.pdf @@ -0,0 +1,112 @@ +%PDF-1.3 +%¿÷¢þ +%QDF-1.0 + +1 0 obj +<< + /Pages 2 0 R + /QStream 3 0 R + /Type /Catalog +>> +endobj + +2 0 obj +<< + /Count 1 + /Kids [ + 5 0 R + ] + /Type /Pages +>> +endobj + +3 0 obj +<< + /Length 4 0 R + /Filter /ASCIIHexDecode +>> +stream +706F7461746F0A +endstream +endobj + +4 0 obj +15 +endobj + +%% Page 1 +5 0 obj +<< + /Contents 6 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Resources << + /Font << + /F1 8 0 R + >> + /ProcSet 9 0 R + >> + /Type /Page +>> +endobj + +%% Contents for page 1 +6 0 obj +<< + /Length 7 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Potato) Tj +ET +endstream +endobj + +7 0 obj +44 +endobj + +8 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +9 0 obj +[ + /PDF + /Text +] +endobj + +xref +0 10 +0000000000 65535 f +0000000025 00000 n +0000000096 00000 n +0000000168 00000 n +0000000264 00000 n +0000000293 00000 n +0000000508 00000 n +0000000607 00000 n +0000000626 00000 n +0000000744 00000 n +trailer << + /Root 1 0 R + /Size 10 + /ID [<422061d5d2701ad547ece6eb89b05b77><422061d5d2701ad547ece6eb89b05b77>] +>> +startxref +779 +%%EOF diff --git a/qpdf/qtest/qpdf/test11.out b/qpdf/qtest/qpdf/test11.out new file mode 100644 index 00000000..170f6b3d --- /dev/null +++ b/qpdf/qtest/qpdf/test11.out @@ -0,0 +1,3 @@ +filtered stream data okay +raw stream data okay +test 11 done diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc index 710f4c6e..6eaec4bc 100644 --- a/qpdf/test_driver.cc +++ b/qpdf/test_driver.cc @@ -445,6 +445,23 @@ void runtest(int n, char const* filename) w.setStreamDataMode(qpdf_s_preserve); w.write(); } + else if (n == 11) + { + QPDFObjectHandle root = pdf.getRoot(); + QPDFObjectHandle qstream = root.getKey("/QStream"); + PointerHolder b1 = qstream.getStreamData(); + PointerHolder b2 = qstream.getRawStreamData(); + if ((b1.getPointer()->getSize() == 7) && + (memcmp(b1.getPointer()->getBuffer(), "potato\n", 7) == 0)) + { + std::cout << "filtered stream data okay" << std::endl; + } + if ((b2.getPointer()->getSize() == 15) && + (memcmp(b2.getPointer()->getBuffer(), "706F7461746F0A\n", 15) == 0)) + { + std::cout << "raw stream data okay" << std::endl; + } + } else { throw std::runtime_error(std::string("invalid test ") +