summaryrefslogtreecommitdiffstats
path: root/libqpdf/qpdf
diff options
context:
space:
mode:
Diffstat (limited to 'libqpdf/qpdf')
-rw-r--r--libqpdf/qpdf/BitStream.hh23
-rw-r--r--libqpdf/qpdf/BitWriter.hh24
-rw-r--r--libqpdf/qpdf/MD5.hh73
-rw-r--r--libqpdf/qpdf/PCRE.hh107
-rw-r--r--libqpdf/qpdf/Pl_ASCII85Decoder.hh23
-rw-r--r--libqpdf/qpdf/Pl_ASCIIHexDecoder.hh23
-rw-r--r--libqpdf/qpdf/Pl_LZWDecoder.hh40
-rw-r--r--libqpdf/qpdf/Pl_MD5.hh30
-rw-r--r--libqpdf/qpdf/Pl_PNGFilter.hh62
-rw-r--r--libqpdf/qpdf/Pl_QPDFTokenizer.hh40
-rw-r--r--libqpdf/qpdf/Pl_RC4.hh42
-rw-r--r--libqpdf/qpdf/QPDF_Array.hh24
-rw-r--r--libqpdf/qpdf/QPDF_Bool.hh19
-rw-r--r--libqpdf/qpdf/QPDF_Dictionary.hh35
-rw-r--r--libqpdf/qpdf/QPDF_Integer.hh19
-rw-r--r--libqpdf/qpdf/QPDF_Name.hh22
-rw-r--r--libqpdf/qpdf/QPDF_Null.hh14
-rw-r--r--libqpdf/qpdf/QPDF_Real.hh20
-rw-r--r--libqpdf/qpdf/QPDF_Stream.hh42
-rw-r--r--libqpdf/qpdf/QPDF_String.hh23
-rw-r--r--libqpdf/qpdf/RC4.hh26
21 files changed, 731 insertions, 0 deletions
diff --git a/libqpdf/qpdf/BitStream.hh b/libqpdf/qpdf/BitStream.hh
new file mode 100644
index 00000000..d02eea42
--- /dev/null
+++ b/libqpdf/qpdf/BitStream.hh
@@ -0,0 +1,23 @@
+// Read bits from a bit stream. See BitWriter for writing.
+
+#ifndef __BITSTREAM_HH__
+#define __BITSTREAM_HH__
+
+class BitStream
+{
+ public:
+ BitStream(unsigned char const* p, int nbytes);
+ void reset();
+ unsigned long getBits(int nbits);
+ void skipToNextByte();
+
+ private:
+ unsigned char const* start;
+ int nbytes;
+
+ unsigned char const* p;
+ unsigned int bit_offset;
+ unsigned int bits_available;
+};
+
+#endif // __BITSTREAM_HH__
diff --git a/libqpdf/qpdf/BitWriter.hh b/libqpdf/qpdf/BitWriter.hh
new file mode 100644
index 00000000..1efd498a
--- /dev/null
+++ b/libqpdf/qpdf/BitWriter.hh
@@ -0,0 +1,24 @@
+// Write bits into a bit stream. See BitStream for reading.
+
+#ifndef __THIS_FILE_Q__
+#define __THIS_FILE_Q__
+
+class Pipeline;
+
+class BitWriter
+{
+ public:
+ // Write bits to the pipeline. It is the caller's responsibility
+ // to eventually call finish on the pipeline.
+ BitWriter(Pipeline* pl);
+ void writeBits(unsigned long val, int bits);
+ // Force any partial byte to be written to the pipeline.
+ void flush();
+
+ private:
+ Pipeline* pl;
+ unsigned char ch;
+ unsigned int bit_offset;
+};
+
+#endif // __THIS_FILE_Q__
diff --git a/libqpdf/qpdf/MD5.hh b/libqpdf/qpdf/MD5.hh
new file mode 100644
index 00000000..0ae15da9
--- /dev/null
+++ b/libqpdf/qpdf/MD5.hh
@@ -0,0 +1,73 @@
+
+#ifndef __MD5_HH__
+#define __MD5_HH__
+
+#include <string>
+#include <qpdf/QEXC.hh>
+
+class MD5
+{
+ public:
+ typedef unsigned char Digest[16];
+
+ MD5();
+ void reset();
+
+ // encodes string and finalizes
+ void encodeString(char const* input_string);
+
+ // encodes file and finalizes
+ void encodeFile(char const* filename, int up_to_size = -1)
+ throw(QEXC::System);
+
+ // appends string to current md5 object
+ void appendString(char const* input_string);
+
+ // appends arbitrary data to current md5 object
+ void encodeDataIncrementally(char const* input_data, int len);
+
+ // computes a raw digest
+ void digest(Digest);
+
+ // prints the digest to stdout terminated with \r\n (primarily for
+ // testing)
+ void print();
+
+ // returns the digest as a hexademical string
+ std::string unparse();
+
+ // Convenience functions
+ static std::string getDataChecksum(char const* buf, int len);
+ static std::string getFileChecksum(char const* filename, int up_to_size = -1);
+ static bool checkDataChecksum(char const* const checksum,
+ char const* buf, int len);
+ static bool checkFileChecksum(char const* const checksum,
+ char const* filename, int up_to_size = -1);
+
+ private:
+ // POINTER defines a generic pointer type
+ typedef void *POINTER;
+
+ // UINT2 defines a two byte word
+ typedef unsigned short int UINT2;
+
+ // UINT4 defines a four byte word
+ typedef unsigned long int UINT4;
+
+ void init();
+ void update(unsigned char *, unsigned int);
+ void final();
+
+ static void transform(UINT4 [4], unsigned char [64]);
+ static void encode(unsigned char *, UINT4 *, unsigned int);
+ static void decode(UINT4 *, unsigned char *, unsigned int);
+
+ UINT4 state[4]; // state (ABCD)
+ UINT4 count[2]; // number of bits, modulo 2^64 (lsb first)
+ unsigned char buffer[64]; // input buffer
+
+ bool finalized;
+ Digest digest_val;
+};
+
+#endif // __MD5_HH__
diff --git a/libqpdf/qpdf/PCRE.hh b/libqpdf/qpdf/PCRE.hh
new file mode 100644
index 00000000..a226aa19
--- /dev/null
+++ b/libqpdf/qpdf/PCRE.hh
@@ -0,0 +1,107 @@
+// This is a C++ wrapper class around Philip Hazel's perl-compatible
+// regular expressions library.
+//
+
+#ifndef __PCRE_HH__
+#define __PCRE_HH__
+
+#include <pcre.h>
+#include <string>
+
+#include <qpdf/QEXC.hh>
+
+// Note: this class does not encapsulate all features of the PCRE
+// package -- only those that I actually need right now are here.
+
+class PCRE
+{
+ public:
+ class Exception: public QEXC::General
+ {
+ public:
+ Exception(std::string const& message);
+ virtual ~Exception() throw() {}
+ };
+
+ // This is thrown when an attempt is made to access a non-existent
+ // back reference.
+ class NoBackref: public Exception
+ {
+ public:
+ NoBackref();
+ virtual ~NoBackref() throw() {}
+ };
+
+ class Match
+ {
+ friend class PCRE;
+ public:
+ Match(int nbackrefs, char const* subject);
+ Match(Match const&);
+ Match& operator=(Match const&);
+ ~Match();
+ operator bool();
+
+ // All the back reference accessing routines may throw the
+ // special exception NoBackref (derived from Exception) if the
+ // back reference does not exist. Exception will be thrown
+ // for other error conditions. This allows callers to trap
+ // this condition explicitly when they care about the
+ // difference between a backreference matching an empty string
+ // and not matching at all.
+
+ // see getMatch flags below
+ std::string getMatch(int n, int flags = 0)
+ throw(QEXC::General, Exception);
+ void getOffsetLength(int n, int& offset, int& length) throw(Exception);
+ int getOffset(int n) throw(Exception);
+ int getLength(int n) throw(Exception);
+
+ // nMatches returns the number of available matches including
+ // match 0 which is the whole string. In other words, if you
+ // have one backreference in your expression and the
+ // expression matches, nMatches() will return 2, getMatch(0)
+ // will return the whole string, getMatch(1) will return the
+ // text that matched the backreference, and getMatch(2) will
+ // throw an exception because it is out of range.
+ int nMatches() const;
+
+ // Flags for getMatch
+
+ // getMatch on a substring that didn't match should return
+ // empty string instead of throwing an exception
+ static int const gm_no_substring_returns_empty = (1 << 0);
+
+ private:
+ void init(int nmatches, int nbackrefs, char const* subject);
+ void copy(Match const&);
+ void destroy();
+
+ int nbackrefs;
+ char const* subject;
+ int* ovector;
+ int ovecsize;
+ int nmatches;
+ };
+
+ // The value passed in as options is passed to pcre_exec. See man
+ // pcreapi for details.
+ PCRE(char const* pattern, int options = 0) throw(Exception);
+ ~PCRE();
+
+ Match match(char const* subject, int options = 0, int startoffset = 0,
+ int size = -1)
+ throw(QEXC::General, Exception);
+
+ static void test(int n = 0);
+
+ private:
+ // prohibit copying and assignment
+ PCRE(PCRE const&);
+ PCRE& operator=(PCRE const&);
+
+ pcre* code;
+ int nbackrefs;
+};
+
+#endif // __PCRE_HH__
diff --git a/libqpdf/qpdf/Pl_ASCII85Decoder.hh b/libqpdf/qpdf/Pl_ASCII85Decoder.hh
new file mode 100644
index 00000000..9883a58e
--- /dev/null
+++ b/libqpdf/qpdf/Pl_ASCII85Decoder.hh
@@ -0,0 +1,23 @@
+
+#ifndef __PL_ASCII85DECODER_HH__
+#define __PL_ASCII85DECODER_HH__
+
+#include <qpdf/Pipeline.hh>
+
+class Pl_ASCII85Decoder: public Pipeline
+{
+ public:
+ Pl_ASCII85Decoder(char const* identifier, Pipeline* next);
+ virtual ~Pl_ASCII85Decoder();
+ virtual void write(unsigned char* buf, int len);
+ virtual void finish();
+
+ private:
+ void flush();
+
+ char inbuf[5];
+ int pos;
+ int eod;
+};
+
+#endif // __PL_ASCII85DECODER_HH__
diff --git a/libqpdf/qpdf/Pl_ASCIIHexDecoder.hh b/libqpdf/qpdf/Pl_ASCIIHexDecoder.hh
new file mode 100644
index 00000000..36272328
--- /dev/null
+++ b/libqpdf/qpdf/Pl_ASCIIHexDecoder.hh
@@ -0,0 +1,23 @@
+
+#ifndef __PL_ASCIIHEXDECODER_HH__
+#define __PL_ASCIIHEXDECODER_HH__
+
+#include <qpdf/Pipeline.hh>
+
+class Pl_ASCIIHexDecoder: public Pipeline
+{
+ public:
+ Pl_ASCIIHexDecoder(char const* identifier, Pipeline* next);
+ virtual ~Pl_ASCIIHexDecoder();
+ virtual void write(unsigned char* buf, int len);
+ virtual void finish();
+
+ private:
+ void flush();
+
+ char inbuf[3];
+ int pos;
+ bool eod;
+};
+
+#endif // __PL_ASCIIHEXDECODER_HH__
diff --git a/libqpdf/qpdf/Pl_LZWDecoder.hh b/libqpdf/qpdf/Pl_LZWDecoder.hh
new file mode 100644
index 00000000..95ec55b3
--- /dev/null
+++ b/libqpdf/qpdf/Pl_LZWDecoder.hh
@@ -0,0 +1,40 @@
+
+#ifndef __PL_LZWDECODER_HH__
+#define __PL_LZWDECODER_HH__
+
+#include <qpdf/Pipeline.hh>
+
+#include <qpdf/Buffer.hh>
+#include <vector>
+
+class Pl_LZWDecoder: public Pipeline
+{
+ public:
+ Pl_LZWDecoder(char const* identifier, Pipeline* next,
+ bool early_code_change);
+ virtual ~Pl_LZWDecoder();
+ virtual void write(unsigned char* buf, int len);
+ virtual void finish();
+
+ private:
+ void sendNextCode();
+ void handleCode(int code);
+ unsigned char getFirstChar(int code);
+ void addToTable(unsigned char next);
+
+ // members used for converting bits to codes
+ unsigned char buf[3];
+ int code_size;
+ int next;
+ int byte_pos;
+ int bit_pos; // left to right: 01234567
+ int bits_available;
+
+ // members used for handle LZW decompression
+ bool code_change_delta;
+ bool eod;
+ std::vector<Buffer> table;
+ int last_code;
+};
+
+#endif // __PL_LZWDECODER_HH__
diff --git a/libqpdf/qpdf/Pl_MD5.hh b/libqpdf/qpdf/Pl_MD5.hh
new file mode 100644
index 00000000..2d9d11fd
--- /dev/null
+++ b/libqpdf/qpdf/Pl_MD5.hh
@@ -0,0 +1,30 @@
+
+#ifndef __PL_MD5_HH__
+#define __PL_MD5_HH__
+
+// This pipeline sends its output to its successor unmodified. After
+// calling finish, the MD5 checksum of the data that passed through
+// the pipeline is available.
+
+// This pipeline is reusable; i.e., it is safe to call write() after
+// calling finish(). The first call to write() after a call to
+// finish() initializes a new MD5 object.
+
+#include <qpdf/Pipeline.hh>
+#include <qpdf/MD5.hh>
+
+class Pl_MD5: public Pipeline
+{
+ public:
+ Pl_MD5(char const* identifier, Pipeline* next);
+ virtual ~Pl_MD5();
+ virtual void write(unsigned char*, int);
+ virtual void finish();
+ std::string getHexDigest();
+
+ private:
+ bool in_progress;
+ MD5 md5;
+};
+
+#endif // __PL_MD5_HH__
diff --git a/libqpdf/qpdf/Pl_PNGFilter.hh b/libqpdf/qpdf/Pl_PNGFilter.hh
new file mode 100644
index 00000000..1ecc7060
--- /dev/null
+++ b/libqpdf/qpdf/Pl_PNGFilter.hh
@@ -0,0 +1,62 @@
+
+#ifndef __PL_PNGFILTER_HH__
+#define __PL_PNGFILTER_HH__
+
+// This pipeline applies or reverses the application of a PNG filter
+// as described in the PNG specification.
+
+// NOTE: In its initial implementation, it only encodes and decodes
+// filters "none" and "up". The primary motivation of this code is to
+// encode and decode PDF 1.5+ XRef streams which are often encoded
+// with Flate predictor 12, which corresponds to the PNG up filter.
+// At present, the bytes_per_pixel parameter is ignored, and an
+// exception is thrown if any row of the file has a filter of other
+// than 0 or 2. Finishing the implementation would not be difficult.
+// See chapter 6 of the PNG specification for a description of the
+// filter algorithms.
+
+#include <qpdf/Pipeline.hh>
+
+class Pl_PNGFilter: public Pipeline
+{
+ public:
+ class Exception: public Pipeline::Exception
+ {
+ public:
+ Exception(std::string const& message) :
+ Pipeline::Exception(message)
+ {
+ }
+
+ virtual ~Exception() throw ()
+ {
+ }
+ };
+
+ // Encoding is not presently supported
+ enum action_e { a_encode, a_decode };
+
+ Pl_PNGFilter(char const* identifier, Pipeline* next,
+ action_e action, unsigned int columns,
+ unsigned int bytes_per_pixel);
+ virtual ~Pl_PNGFilter();
+
+ virtual void write(unsigned char* data, int len);
+ virtual void finish();
+
+ private:
+ void processRow();
+ void encodeRow();
+ void decodeRow();
+
+ action_e action;
+ unsigned int columns;
+ unsigned char* cur_row;
+ unsigned char* prev_row;
+ unsigned char* buf1;
+ unsigned char* buf2;
+ int pos;
+ int incoming;
+};
+
+#endif // __PL_PNGFILTER_HH__
diff --git a/libqpdf/qpdf/Pl_QPDFTokenizer.hh b/libqpdf/qpdf/Pl_QPDFTokenizer.hh
new file mode 100644
index 00000000..448dbb18
--- /dev/null
+++ b/libqpdf/qpdf/Pl_QPDFTokenizer.hh
@@ -0,0 +1,40 @@
+
+#ifndef __PL_QPDFTOKENIZER_HH__
+#define __PL_QPDFTOKENIZER_HH__
+
+#include <qpdf/Pipeline.hh>
+
+#include <qpdf/QPDFTokenizer.hh>
+
+//
+// Treat incoming text as a stream consisting of valid PDF tokens, but
+// output bad tokens just the same. The idea here is to be able to
+// use pipeline for content streams to normalize newlines without
+// interfering with meaningful newlines such as those that occur
+// inside of strings.
+//
+
+class Pl_QPDFTokenizer: public Pipeline
+{
+ public:
+ Pl_QPDFTokenizer(char const* identifier, Pipeline* next);
+ virtual ~Pl_QPDFTokenizer();
+ virtual void write(unsigned char* buf, int len);
+ virtual void finish();
+
+ private:
+ void processChar(char ch);
+ void checkUnread();
+ void writeNext(char const*, int len);
+ void writeToken(QPDFTokenizer::Token&);
+
+ QPDFTokenizer tokenizer;
+ bool newline_after_next_token;
+ bool just_wrote_nl;
+ bool last_char_was_cr;
+ bool unread_char;
+ char char_to_unread;
+ bool pass_through;
+};
+
+#endif // __PL_QPDFTOKENIZER_HH__
diff --git a/libqpdf/qpdf/Pl_RC4.hh b/libqpdf/qpdf/Pl_RC4.hh
new file mode 100644
index 00000000..6bebe5aa
--- /dev/null
+++ b/libqpdf/qpdf/Pl_RC4.hh
@@ -0,0 +1,42 @@
+
+#ifndef __PL_RC4_HH__
+#define __PL_RC4_HH__
+
+#include <qpdf/Pipeline.hh>
+
+#include <qpdf/RC4.hh>
+
+class Pl_RC4: public Pipeline
+{
+ public:
+ class Exception: public Pipeline::Exception
+ {
+ public:
+ Exception(std::string const& message) :
+ Pipeline::Exception(message)
+ {
+ }
+
+ virtual ~Exception() throw()
+ {
+ }
+ };
+
+ static int const def_bufsize = 65536;
+
+ // key_len of -1 means treat key_data as a null-terminated string
+ Pl_RC4(char const* identifier, Pipeline* next,
+ unsigned char const* key_data, int key_len = -1,
+ int out_bufsize = def_bufsize);
+ virtual ~Pl_RC4();
+
+ virtual void write(unsigned char* data, int len);
+ virtual void finish();
+
+ private:
+ unsigned char* outbuf;
+ int out_bufsize;
+ RC4 rc4;
+};
+
+#endif // __PL_RC4_HH__
diff --git a/libqpdf/qpdf/QPDF_Array.hh b/libqpdf/qpdf/QPDF_Array.hh
new file mode 100644
index 00000000..371be50e
--- /dev/null
+++ b/libqpdf/qpdf/QPDF_Array.hh
@@ -0,0 +1,24 @@
+
+#ifndef __QPDF_ARRAY_HH__
+#define __QPDF_ARRAY_HH__
+
+#include <qpdf/QPDFObject.hh>
+
+#include <vector>
+#include <qpdf/QPDFObjectHandle.hh>
+
+class QPDF_Array: public QPDFObject
+{
+ public:
+ QPDF_Array(std::vector<QPDFObjectHandle> const& items);
+ virtual ~QPDF_Array();
+ virtual std::string unparse();
+ int getNItems() const;
+ QPDFObjectHandle getItem(int n) const;
+ void setItem(int, QPDFObjectHandle const&);
+
+ private:
+ std::vector<QPDFObjectHandle> items;
+};
+
+#endif // __QPDF_ARRAY_HH__
diff --git a/libqpdf/qpdf/QPDF_Bool.hh b/libqpdf/qpdf/QPDF_Bool.hh
new file mode 100644
index 00000000..06aca822
--- /dev/null
+++ b/libqpdf/qpdf/QPDF_Bool.hh
@@ -0,0 +1,19 @@
+
+#ifndef __QPDF_BOOL_HH__
+#define __QPDF_BOOL_HH__
+
+#include <qpdf/QPDFObject.hh>
+
+class QPDF_Bool: public QPDFObject
+{
+ public:
+ QPDF_Bool(bool val);
+ virtual ~QPDF_Bool();
+ virtual std::string unparse();
+ bool getVal() const;
+
+ private:
+ bool val;
+};
+
+#endif // __QPDF_BOOL_HH__
diff --git a/libqpdf/qpdf/QPDF_Dictionary.hh b/libqpdf/qpdf/QPDF_Dictionary.hh
new file mode 100644
index 00000000..6a79fb69
--- /dev/null
+++ b/libqpdf/qpdf/QPDF_Dictionary.hh
@@ -0,0 +1,35 @@
+
+#ifndef __QPDF_DICTIONARY_HH__
+#define __QPDF_DICTIONARY_HH__
+
+#include <qpdf/QPDFObject.hh>
+
+#include <set>
+#include <map>
+
+#include <qpdf/QPDFObjectHandle.hh>
+
+class QPDF_Dictionary: public QPDFObject
+{
+ public:
+ QPDF_Dictionary(std::map<std::string, QPDFObjectHandle> const& items);
+ virtual ~QPDF_Dictionary();
+ virtual std::string unparse();
+
+ // hasKey() and getKeys() treat keys with null values as if they
+ // aren't there. getKey() returns null for the value of a
+ // non-existent key. This is as per the PDF spec.
+ bool hasKey(std::string const&);
+ QPDFObjectHandle getKey(std::string const&);
+ std::set<std::string> getKeys();
+
+ // Repalce value of key, adding it if it does not exist
+ void replaceKey(std::string const& key, QPDFObjectHandle const&);
+ // Remove key, doing nothing if key does not exist
+ void removeKey(std::string const& key);
+
+ private:
+ std::map<std::string, QPDFObjectHandle> items;
+};
+
+#endif // __QPDF_DICTIONARY_HH__
diff --git a/libqpdf/qpdf/QPDF_Integer.hh b/libqpdf/qpdf/QPDF_Integer.hh
new file mode 100644
index 00000000..fb6360b2
--- /dev/null
+++ b/libqpdf/qpdf/QPDF_Integer.hh
@@ -0,0 +1,19 @@
+
+#ifndef __QPDF_INTEGER_HH__
+#define __QPDF_INTEGER_HH__
+
+#include <qpdf/QPDFObject.hh>
+
+class QPDF_Integer: public QPDFObject
+{
+ public:
+ QPDF_Integer(int val);
+ virtual ~QPDF_Integer();
+ virtual std::string unparse();
+ int getVal() const;
+
+ private:
+ int val;
+};
+
+#endif // __QPDF_INTEGER_HH__
diff --git a/libqpdf/qpdf/QPDF_Name.hh b/libqpdf/qpdf/QPDF_Name.hh
new file mode 100644
index 00000000..a32f6f4f
--- /dev/null
+++ b/libqpdf/qpdf/QPDF_Name.hh
@@ -0,0 +1,22 @@
+
+#ifndef __QPDF_NAME_HH__
+#define __QPDF_NAME_HH__
+
+#include <qpdf/QPDFObject.hh>
+
+class QPDF_Name: public QPDFObject
+{
+ public:
+ QPDF_Name(std::string const& name);
+ virtual ~QPDF_Name();
+ virtual std::string unparse();
+ std::string getName() const;
+
+ // Put # into strings with characters unsuitable for name token
+ static std::string normalizeName(std::string const& name);
+
+ private:
+ std::string name;
+};
+
+#endif // __QPDF_NAME_HH__
diff --git a/libqpdf/qpdf/QPDF_Null.hh b/libqpdf/qpdf/QPDF_Null.hh
new file mode 100644
index 00000000..60c1ae35
--- /dev/null
+++ b/libqpdf/qpdf/QPDF_Null.hh
@@ -0,0 +1,14 @@
+
+#ifndef __QPDF_NULL_HH__
+#define __QPDF_NULL_HH__
+
+#include <qpdf/QPDFObject.hh>
+
+class QPDF_Null: public QPDFObject
+{
+ public:
+ virtual ~QPDF_Null();
+ std::string unparse();
+};
+
+#endif // __QPDF_NULL_HH__
diff --git a/libqpdf/qpdf/QPDF_Real.hh b/libqpdf/qpdf/QPDF_Real.hh
new file mode 100644
index 00000000..b950c569
--- /dev/null
+++ b/libqpdf/qpdf/QPDF_Real.hh
@@ -0,0 +1,20 @@
+
+#ifndef __QPDF_REAL_HH__
+#define __QPDF_REAL_HH__
+
+#include <qpdf/QPDFObject.hh>
+
+class QPDF_Real: public QPDFObject
+{
+ public:
+ QPDF_Real(std::string const& val);
+ virtual ~QPDF_Real();
+ std::string unparse();
+ std::string getVal();
+
+ private:
+ // Store reals as strings to avoid roundoff errors.
+ std::string val;
+};
+
+#endif // __QPDF_REAL_HH__
diff --git a/libqpdf/qpdf/QPDF_Stream.hh b/libqpdf/qpdf/QPDF_Stream.hh
new file mode 100644
index 00000000..71381fd3
--- /dev/null
+++ b/libqpdf/qpdf/QPDF_Stream.hh
@@ -0,0 +1,42 @@
+
+#ifndef __QPDF_STREAM_HH__
+#define __QPDF_STREAM_HH__
+
+#include <qpdf/QPDFObject.hh>
+
+#include <qpdf/QPDFObjectHandle.hh>
+
+class Pipeline;
+class QPDF;
+
+class QPDF_Stream: public QPDFObject
+{
+ public:
+ QPDF_Stream(QPDF*, int objid, int generation,
+ QPDFObjectHandle stream_dict,
+ off_t offset, int length);
+ virtual ~QPDF_Stream();
+ virtual std::string unparse();
+ QPDFObjectHandle getDict() const;
+
+ // See comments in QPDFObjectHandle.hh
+ bool pipeStreamData(Pipeline*, bool filter,
+ bool normalize, bool compress);
+
+ // See comments in QPDFObjectHandle.hh
+ PointerHolder<Buffer> getStreamData();
+
+ private:
+ bool filterable(std::vector<std::string>& filters,
+ int& predictor, int& columns, bool& early_code_change);
+
+
+ QPDF* qpdf;
+ int objid;
+ int generation;
+ QPDFObjectHandle stream_dict;
+ off_t offset;
+ int length;
+};
+
+#endif // __QPDF_STREAM_HH__
diff --git a/libqpdf/qpdf/QPDF_String.hh b/libqpdf/qpdf/QPDF_String.hh
new file mode 100644
index 00000000..f3063c50
--- /dev/null
+++ b/libqpdf/qpdf/QPDF_String.hh
@@ -0,0 +1,23 @@
+
+#ifndef __QPDF_STRING_HH__
+#define __QPDF_STRING_HH__
+
+#include <qpdf/QPDFObject.hh>
+
+// QPDF_Strings may included embedded null characters.
+
+class QPDF_String: public QPDFObject
+{
+ public:
+ QPDF_String(std::string const& val);
+ virtual ~QPDF_String();
+ virtual std::string unparse();
+ std::string unparse(bool force_binary);
+ std::string getVal() const;
+ std::string getUTF8Val() const;
+
+ private:
+ std::string val;
+};
+
+#endif // __QPDF_STRING_HH__
diff --git a/libqpdf/qpdf/RC4.hh b/libqpdf/qpdf/RC4.hh
new file mode 100644
index 00000000..657bf35b
--- /dev/null
+++ b/libqpdf/qpdf/RC4.hh
@@ -0,0 +1,26 @@
+
+#ifndef __RC4_HH__
+#define __RC4_HH__
+
+class RC4
+{
+ public:
+ // key_len of -1 means treat key_data as a null-terminated string
+ RC4(unsigned char const* key_data, int key_len = -1);
+
+ // out_data = 0 means to encrypt/decrypt in place
+ void process(unsigned char* in_data, int len, unsigned char* out_data = 0);
+
+ private:
+ class RC4Key
+ {
+ public:
+ unsigned char state[256];
+ unsigned char x;
+ unsigned char y;
+ };
+
+ RC4Key key;
+};
+
+#endif // __RC4_HH__