*** empty log message ***
[swftools.git] / pdf2swf / xpdf / Stream.h
1 //========================================================================
2 //
3 // Stream.h
4 //
5 // Copyright 1996-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
8
9 #ifndef STREAM_H
10 #define STREAM_H
11
12 #include <aconf.h>
13
14 #ifdef USE_GCC_PRAGMAS
15 #pragma interface
16 #endif
17
18 #include <stdio.h>
19 #include "gtypes.h"
20 #include "Object.h"
21
22 #ifndef NO_DECRYPTION
23 class Decrypt;
24 #endif
25 class BaseStream;
26
27 //------------------------------------------------------------------------
28
29 enum StreamKind {
30   strFile,
31   strASCIIHex,
32   strASCII85,
33   strLZW,
34   strRunLength,
35   strCCITTFax,
36   strDCT,
37   strFlate,
38   strJBIG2,
39   strJPX,
40   strWeird                      // internal-use stream types
41 };
42
43 //------------------------------------------------------------------------
44 // Stream (base class)
45 //------------------------------------------------------------------------
46
47 class Stream {
48 public:
49
50   // Constructor.
51   Stream();
52
53   // Destructor.
54   virtual ~Stream();
55
56   // Reference counting.
57   int incRef() { return ++ref; }
58   int decRef() { return --ref; }
59
60   // Get kind of stream.
61   virtual StreamKind getKind() = 0;
62
63   // Reset stream to beginning.
64   virtual void reset() = 0;
65
66   // Close down the stream.
67   virtual void close();
68
69   // Get next char from stream.
70   virtual int getChar() = 0;
71
72   // Peek at next char in stream.
73   virtual int lookChar() = 0;
74
75   // Get next char from stream without using the predictor.
76   // This is only used by StreamPredictor.
77   virtual int getRawChar();
78
79   // Get next line from stream.
80   virtual char *getLine(char *buf, int size);
81
82   // Get current position in file.
83   virtual int getPos() = 0;
84
85   // Go to a position in the stream.  If <dir> is negative, the
86   // position is from the end of the file; otherwise the position is
87   // from the start of the file.
88   virtual void setPos(Guint pos, int dir = 0) = 0;
89
90   // Get PostScript command for the filter(s).
91   virtual GString *getPSFilter(int psLevel, char *indent);
92
93   // Does this stream type potentially contain non-printable chars?
94   virtual GBool isBinary(GBool last = gTrue) = 0;
95
96   // Get the BaseStream of this stream.
97   virtual BaseStream *getBaseStream() = 0;
98
99   // Get the dictionary associated with this stream.
100   virtual Dict *getDict() = 0;
101
102   // Is this an encoding filter?
103   virtual GBool isEncoder() { return gFalse; }
104
105   // Add filters to this stream according to the parameters in <dict>.
106   // Returns the new stream.
107   Stream *addFilters(Object *dict);
108
109   // Tell this stream to ignore any length limitation -- this only
110   // applies to BaseStream subclasses, and is used as a hack to work
111   // around broken PDF files with incorrect stream lengths.
112   virtual void ignoreLength() {}
113
114 private:
115
116   Stream *makeFilter(char *name, Stream *str, Object *params);
117
118   int ref;                      // reference count
119 };
120
121 //------------------------------------------------------------------------
122 // BaseStream
123 //
124 // This is the base class for all streams that read directly from a file.
125 //------------------------------------------------------------------------
126
127 class BaseStream: public Stream {
128 public:
129
130   BaseStream(Object *dictA);
131   virtual ~BaseStream();
132   virtual Stream *makeSubStream(Guint start, GBool limited,
133                                 Guint length, Object *dict) = 0;
134   virtual void setPos(Guint pos, int dir = 0) = 0;
135   virtual GBool isBinary(GBool last = gTrue) { return last; }
136   virtual BaseStream *getBaseStream() { return this; }
137   virtual Dict *getDict() { return dict.getDict(); }
138
139   // Get/set position of first byte of stream within the file.
140   virtual Guint getStart() = 0;
141   virtual void moveStart(int delta) = 0;
142
143 #ifndef NO_DECRYPTION
144   // Set decryption for this stream.
145   virtual void doDecryption(Guchar *fileKey, int keyLength,
146                             int objNum, int objGen);
147 #endif
148
149 #ifndef NO_DECRYPTION
150 protected:
151
152   Decrypt *decrypt;
153 #endif
154
155 private:
156
157   Object dict;
158 };
159
160 //------------------------------------------------------------------------
161 // FilterStream
162 //
163 // This is the base class for all streams that filter another stream.
164 //------------------------------------------------------------------------
165
166 class FilterStream: public Stream {
167 public:
168
169   FilterStream(Stream *strA);
170   virtual ~FilterStream();
171   virtual void close();
172   virtual int getPos() { return str->getPos(); }
173   virtual void setPos(Guint pos, int dir = 0);
174   virtual BaseStream *getBaseStream() { return str->getBaseStream(); }
175   virtual Dict *getDict() { return str->getDict(); }
176   virtual void ignoreLength() { str->ignoreLength(); }
177
178 protected:
179
180   Stream *str;
181 };
182
183 //------------------------------------------------------------------------
184 // ImageStream
185 //------------------------------------------------------------------------
186
187 class ImageStream {
188 public:
189
190   // Create an image stream object for an image with the specified
191   // parameters.  Note that these are the actual image parameters,
192   // which may be different from the predictor parameters.
193   ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA);
194
195   ~ImageStream();
196
197   // Reset the stream.
198   void reset();
199
200   // Gets the next pixel from the stream.  <pix> should be able to hold
201   // at least nComps elements.  Returns false at end of file.
202   GBool getPixel(Guchar *pix);
203
204   // Returns a pointer to the next line of pixels.  Returns NULL at
205   // end of file.
206   Guchar *getLine();
207
208   // Skip an entire line from the image.
209   void skipLine();
210
211 private:
212
213   Stream *str;                  // base stream
214   int width;                    // pixels per line
215   int nComps;                   // components per pixel
216   int nBits;                    // bits per component
217   int nVals;                    // components per line
218   Guchar *imgLine;              // line buffer
219   int imgIdx;                   // current index in imgLine
220 };
221
222 //------------------------------------------------------------------------
223 // StreamPredictor
224 //------------------------------------------------------------------------
225
226 class StreamPredictor {
227 public:
228
229   // Create a predictor object.  Note that the parameters are for the
230   // predictor, and may not match the actual image parameters.
231   StreamPredictor(Stream *strA, int predictorA,
232                   int widthA, int nCompsA, int nBitsA);
233
234   ~StreamPredictor();
235
236   int lookChar();
237   int getChar();
238
239 private:
240
241   GBool getNextLine();
242
243   Stream *str;                  // base stream
244   int predictor;                // predictor
245   int width;                    // pixels per line
246   int nComps;                   // components per pixel
247   int nBits;                    // bits per component
248   int nVals;                    // components per line
249   int pixBytes;                 // bytes per pixel
250   int rowBytes;                 // bytes per line
251   Guchar *predLine;             // line buffer
252   int predIdx;                  // current index in predLine
253 };
254
255 //------------------------------------------------------------------------
256 // FileStream
257 //------------------------------------------------------------------------
258
259 #define fileStreamBufSize 256
260
261 class FileStream: public BaseStream {
262 public:
263
264   FileStream(FILE *fA, Guint startA, GBool limitedA,
265              Guint lengthA, Object *dictA);
266   virtual ~FileStream();
267   virtual Stream *makeSubStream(Guint startA, GBool limitedA,
268                                 Guint lengthA, Object *dictA);
269   virtual StreamKind getKind() { return strFile; }
270   virtual void reset();
271   virtual void close();
272   virtual int getChar()
273     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
274   virtual int lookChar()
275     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
276   virtual int getPos() { return bufPos + (bufPtr - buf); }
277   virtual void setPos(Guint pos, int dir = 0);
278   virtual void ignoreLength() { limited = gFalse; }
279   virtual Guint getStart() { return start; }
280   virtual void moveStart(int delta);
281
282 private:
283
284   GBool fillBuf();
285
286   FILE *f;
287   Guint start;
288   GBool limited;
289   Guint length;
290   char buf[fileStreamBufSize];
291   char *bufPtr;
292   char *bufEnd;
293   Guint bufPos;
294   int savePos;
295   GBool saved;
296 };
297
298 //------------------------------------------------------------------------
299 // MemStream
300 //------------------------------------------------------------------------
301
302 class MemStream: public BaseStream {
303 public:
304
305   MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA);
306   virtual ~MemStream();
307   virtual Stream *makeSubStream(Guint start, GBool limited,
308                                 Guint lengthA, Object *dictA);
309   virtual StreamKind getKind() { return strWeird; }
310   virtual void reset();
311   virtual void close();
312   virtual int getChar()
313     { return (bufPtr < bufEnd) ? (*bufPtr++ & 0xff) : EOF; }
314   virtual int lookChar()
315     { return (bufPtr < bufEnd) ? (*bufPtr & 0xff) : EOF; }
316   virtual int getPos() { return (int)(bufPtr - buf); }
317   virtual void setPos(Guint pos, int dir = 0);
318   virtual Guint getStart() { return start; }
319   virtual void moveStart(int delta);
320 #ifndef NO_DECRYPTION
321   virtual void doDecryption(Guchar *fileKey, int keyLength,
322                             int objNum, int objGen);
323 #endif
324
325 private:
326
327   char *buf;
328   Guint start;
329   Guint length;
330   char *bufEnd;
331   char *bufPtr;
332   GBool needFree;
333 };
334
335 //------------------------------------------------------------------------
336 // EmbedStream
337 //
338 // This is a special stream type used for embedded streams (inline
339 // images).  It reads directly from the base stream -- after the
340 // EmbedStream is deleted, reads from the base stream will proceed where
341 // the BaseStream left off.  Note that this is very different behavior
342 // that creating a new FileStream (using makeSubStream).
343 //------------------------------------------------------------------------
344
345 class EmbedStream: public BaseStream {
346 public:
347
348   EmbedStream(Stream *strA, Object *dictA, GBool limitedA, Guint lengthA);
349   virtual ~EmbedStream();
350   virtual Stream *makeSubStream(Guint start, GBool limitedA,
351                                 Guint lengthA, Object *dictA);
352   virtual StreamKind getKind() { return str->getKind(); }
353   virtual void reset() {}
354   virtual int getChar();
355   virtual int lookChar();
356   virtual int getPos() { return str->getPos(); }
357   virtual void setPos(Guint pos, int dir = 0);
358   virtual Guint getStart();
359   virtual void moveStart(int delta);
360
361 private:
362
363   Stream *str;
364   GBool limited;
365   Guint length;
366 };
367
368 //------------------------------------------------------------------------
369 // ASCIIHexStream
370 //------------------------------------------------------------------------
371
372 class ASCIIHexStream: public FilterStream {
373 public:
374
375   ASCIIHexStream(Stream *strA);
376   virtual ~ASCIIHexStream();
377   virtual StreamKind getKind() { return strASCIIHex; }
378   virtual void reset();
379   virtual int getChar()
380     { int c = lookChar(); buf = EOF; return c; }
381   virtual int lookChar();
382   virtual GString *getPSFilter(int psLevel, char *indent);
383   virtual GBool isBinary(GBool last = gTrue);
384
385 private:
386
387   int buf;
388   GBool eof;
389 };
390
391 //------------------------------------------------------------------------
392 // ASCII85Stream
393 //------------------------------------------------------------------------
394
395 class ASCII85Stream: public FilterStream {
396 public:
397
398   ASCII85Stream(Stream *strA);
399   virtual ~ASCII85Stream();
400   virtual StreamKind getKind() { return strASCII85; }
401   virtual void reset();
402   virtual int getChar()
403     { int ch = lookChar(); ++index; return ch; }
404   virtual int lookChar();
405   virtual GString *getPSFilter(int psLevel, char *indent);
406   virtual GBool isBinary(GBool last = gTrue);
407
408 private:
409
410   int c[5];
411   int b[4];
412   int index, n;
413   GBool eof;
414 };
415
416 //------------------------------------------------------------------------
417 // LZWStream
418 //------------------------------------------------------------------------
419
420 class LZWStream: public FilterStream {
421 public:
422
423   LZWStream(Stream *strA, int predictor, int columns, int colors,
424             int bits, int earlyA);
425   virtual ~LZWStream();
426   virtual StreamKind getKind() { return strLZW; }
427   virtual void reset();
428   virtual int getChar();
429   virtual int lookChar();
430   virtual int getRawChar();
431   virtual GString *getPSFilter(int psLevel, char *indent);
432   virtual GBool isBinary(GBool last = gTrue);
433
434 private:
435
436   StreamPredictor *pred;        // predictor
437   int early;                    // early parameter
438   GBool eof;                    // true if at eof
439   int inputBuf;                 // input buffer
440   int inputBits;                // number of bits in input buffer
441   struct {                      // decoding table
442     int length;
443     int head;
444     Guchar tail;
445   } table[4097];
446   int nextCode;                 // next code to be used
447   int nextBits;                 // number of bits in next code word
448   int prevCode;                 // previous code used in stream
449   int newChar;                  // next char to be added to table
450   Guchar seqBuf[4097];          // buffer for current sequence
451   int seqLength;                // length of current sequence
452   int seqIndex;                 // index into current sequence
453   GBool first;                  // first code after a table clear
454
455   GBool processNextCode();
456   void clearTable();
457   int getCode();
458 };
459
460 //------------------------------------------------------------------------
461 // RunLengthStream
462 //------------------------------------------------------------------------
463
464 class RunLengthStream: public FilterStream {
465 public:
466
467   RunLengthStream(Stream *strA);
468   virtual ~RunLengthStream();
469   virtual StreamKind getKind() { return strRunLength; }
470   virtual void reset();
471   virtual int getChar()
472     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
473   virtual int lookChar()
474     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
475   virtual GString *getPSFilter(int psLevel, char *indent);
476   virtual GBool isBinary(GBool last = gTrue);
477
478 private:
479
480   char buf[128];                // buffer
481   char *bufPtr;                 // next char to read
482   char *bufEnd;                 // end of buffer
483   GBool eof;
484
485   GBool fillBuf();
486 };
487
488 //------------------------------------------------------------------------
489 // CCITTFaxStream
490 //------------------------------------------------------------------------
491
492 struct CCITTCodeTable;
493
494 class CCITTFaxStream: public FilterStream {
495 public:
496
497   CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA,
498                  GBool byteAlignA, int columnsA, int rowsA,
499                  GBool endOfBlockA, GBool blackA);
500   virtual ~CCITTFaxStream();
501   virtual StreamKind getKind() { return strCCITTFax; }
502   virtual void reset();
503   virtual int getChar()
504     { int c = lookChar(); buf = EOF; return c; }
505   virtual int lookChar();
506   virtual GString *getPSFilter(int psLevel, char *indent);
507   virtual GBool isBinary(GBool last = gTrue);
508
509 private:
510
511   int encoding;                 // 'K' parameter
512   GBool endOfLine;              // 'EndOfLine' parameter
513   GBool byteAlign;              // 'EncodedByteAlign' parameter
514   int columns;                  // 'Columns' parameter
515   int rows;                     // 'Rows' parameter
516   GBool endOfBlock;             // 'EndOfBlock' parameter
517   GBool black;                  // 'BlackIs1' parameter
518   GBool eof;                    // true if at eof
519   GBool nextLine2D;             // true if next line uses 2D encoding
520   int row;                      // current row
521   int inputBuf;                 // input buffer
522   int inputBits;                // number of bits in input buffer
523   short *refLine;               // reference line changing elements
524   int b1;                       // index into refLine
525   short *codingLine;            // coding line changing elements
526   int a0;                       // index into codingLine
527   int outputBits;               // remaining ouput bits
528   int buf;                      // character buffer
529
530   short getTwoDimCode();
531   short getWhiteCode();
532   short getBlackCode();
533   short lookBits(int n);
534   void eatBits(int n) { inputBits -= n; }
535 };
536
537 //------------------------------------------------------------------------
538 // DCTStream
539 //------------------------------------------------------------------------
540
541 // DCT component info
542 struct DCTCompInfo {
543   int id;                       // component ID
544   int hSample, vSample;         // horiz/vert sampling resolutions
545   int quantTable;               // quantization table number
546   int prevDC;                   // DC coefficient accumulator
547 };
548
549 struct DCTScanInfo {
550   GBool comp[4];                // comp[i] is set if component i is
551                                 //   included in this scan
552   int numComps;                 // number of components in the scan
553   int dcHuffTable[4];           // DC Huffman table numbers
554   int acHuffTable[4];           // AC Huffman table numbers
555   int firstCoeff, lastCoeff;    // first and last DCT coefficient
556   int ah, al;                   // successive approximation parameters
557 };
558
559 // DCT Huffman decoding table
560 struct DCTHuffTable {
561   Guchar firstSym[17];          // first symbol for this bit length
562   Gushort firstCode[17];        // first code for this bit length
563   Gushort numCodes[17];         // number of codes of this bit length
564   Guchar sym[256];              // symbols
565 };
566
567 class DCTStream: public FilterStream {
568 public:
569
570   DCTStream(Stream *strA);
571   virtual ~DCTStream();
572   virtual StreamKind getKind() { return strDCT; }
573   virtual void reset();
574   virtual int getChar();
575   virtual int lookChar();
576   virtual GString *getPSFilter(int psLevel, char *indent);
577   virtual GBool isBinary(GBool last = gTrue);
578   Stream *getRawStream() { return str; }
579
580 private:
581
582   GBool progressive;            // set if in progressive mode
583   GBool interleaved;            // set if in interleaved mode
584   int width, height;            // image size
585   int mcuWidth, mcuHeight;      // size of min coding unit, in data units
586   int bufWidth, bufHeight;      // frameBuf size
587   DCTCompInfo compInfo[4];      // info for each component
588   DCTScanInfo scanInfo;         // info for the current scan
589   int numComps;                 // number of components in image
590   int colorXform;               // need YCbCr-to-RGB transform?
591   GBool gotJFIFMarker;          // set if APP0 JFIF marker was present
592   GBool gotAdobeMarker;         // set if APP14 Adobe marker was present
593   int restartInterval;          // restart interval, in MCUs
594   Guchar quantTables[4][64];    // quantization tables
595   int numQuantTables;           // number of quantization tables
596   DCTHuffTable dcHuffTables[4]; // DC Huffman tables
597   DCTHuffTable acHuffTables[4]; // AC Huffman tables
598   int numDCHuffTables;          // number of DC Huffman tables
599   int numACHuffTables;          // number of AC Huffman tables
600   Guchar *rowBuf[4][32];        // buffer for one MCU (non-progressive mode)
601   int *frameBuf[4];             // buffer for frame (progressive mode)
602   int comp, x, y, dy;           // current position within image/MCU
603   int restartCtr;               // MCUs left until restart
604   int restartMarker;            // next restart marker
605   int eobRun;                   // number of EOBs left in the current run
606   int inputBuf;                 // input buffer for variable length codes
607   int inputBits;                // number of valid bits in input buffer
608
609   void restart();
610   GBool readMCURow();
611   void readScan();
612   GBool readDataUnit(DCTHuffTable *dcHuffTable,
613                      DCTHuffTable *acHuffTable,
614                      int *prevDC, int data[64]);
615   GBool readProgressiveDataUnit(DCTHuffTable *dcHuffTable,
616                                 DCTHuffTable *acHuffTable,
617                                 int *prevDC, int data[64]);
618   void decodeImage();
619   void transformDataUnit(Guchar *quantTable,
620                          int dataIn[64], Guchar dataOut[64]);
621   int readHuffSym(DCTHuffTable *table);
622   int readAmp(int size);
623   int readBit();
624   GBool readHeader();
625   GBool readBaselineSOF();
626   GBool readProgressiveSOF();
627   GBool readScanInfo();
628   GBool readQuantTables();
629   GBool readHuffmanTables();
630   GBool readRestartInterval();
631   GBool readJFIFMarker();
632   GBool readAdobeMarker();
633   GBool readTrailer();
634   int readMarker();
635   int read16();
636 };
637
638 //------------------------------------------------------------------------
639 // FlateStream
640 //------------------------------------------------------------------------
641
642 #define flateWindow          32768    // buffer size
643 #define flateMask            (flateWindow-1)
644 #define flateMaxHuffman         15    // max Huffman code length
645 #define flateMaxCodeLenCodes    19    // max # code length codes
646 #define flateMaxLitCodes       288    // max # literal codes
647 #define flateMaxDistCodes       30    // max # distance codes
648
649 // Huffman code table entry
650 struct FlateCode {
651   Gushort len;                  // code length, in bits
652   Gushort val;                  // value represented by this code
653 };
654
655 struct FlateHuffmanTab {
656   FlateCode *codes;
657   int maxLen;
658 };
659
660 // Decoding info for length and distance code words
661 struct FlateDecode {
662   int bits;                     // # extra bits
663   int first;                    // first length/distance
664 };
665
666 class FlateStream: public FilterStream {
667 public:
668
669   FlateStream(Stream *strA, int predictor, int columns,
670               int colors, int bits);
671   virtual ~FlateStream();
672   virtual StreamKind getKind() { return strFlate; }
673   virtual void reset();
674   virtual int getChar();
675   virtual int lookChar();
676   virtual int getRawChar();
677   virtual GString *getPSFilter(int psLevel, char *indent);
678   virtual GBool isBinary(GBool last = gTrue);
679
680 private:
681
682   StreamPredictor *pred;        // predictor
683   Guchar buf[flateWindow];      // output data buffer
684   int index;                    // current index into output buffer
685   int remain;                   // number valid bytes in output buffer
686   int codeBuf;                  // input buffer
687   int codeSize;                 // number of bits in input buffer
688   int                           // literal and distance code lengths
689     codeLengths[flateMaxLitCodes + flateMaxDistCodes];
690   FlateHuffmanTab litCodeTab;   // literal code table
691   FlateHuffmanTab distCodeTab;  // distance code table
692   GBool compressedBlock;        // set if reading a compressed block
693   int blockLen;                 // remaining length of uncompressed block
694   GBool endOfBlock;             // set when end of block is reached
695   GBool eof;                    // set when end of stream is reached
696
697   static int                    // code length code reordering
698     codeLenCodeMap[flateMaxCodeLenCodes];
699   static FlateDecode            // length decoding info
700     lengthDecode[flateMaxLitCodes-257];
701   static FlateDecode            // distance decoding info
702     distDecode[flateMaxDistCodes];
703
704   void readSome();
705   GBool startBlock();
706   void loadFixedCodes();
707   GBool readDynamicCodes();
708   void compHuffmanCodes(int *lengths, int n, FlateHuffmanTab *tab);
709   int getHuffmanCodeWord(FlateHuffmanTab *tab);
710   int getCodeWord(int bits);
711 };
712
713 //------------------------------------------------------------------------
714 // EOFStream
715 //------------------------------------------------------------------------
716
717 class EOFStream: public FilterStream {
718 public:
719
720   EOFStream(Stream *strA);
721   virtual ~EOFStream();
722   virtual StreamKind getKind() { return strWeird; }
723   virtual void reset() {}
724   virtual int getChar() { return EOF; }
725   virtual int lookChar() { return EOF; }
726   virtual GString *getPSFilter(int psLevel, char *indent)  { return NULL; }
727   virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
728 };
729
730 //------------------------------------------------------------------------
731 // FixedLengthEncoder
732 //------------------------------------------------------------------------
733
734 class FixedLengthEncoder: public FilterStream {
735 public:
736
737   FixedLengthEncoder(Stream *strA, int lengthA);
738   ~FixedLengthEncoder();
739   virtual StreamKind getKind() { return strWeird; }
740   virtual void reset();
741   virtual int getChar();
742   virtual int lookChar();
743   virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; }
744   virtual GBool isBinary(GBool last = gTrue);
745   virtual GBool isEncoder() { return gTrue; }
746
747 private:
748
749   int length;
750   int count;
751 };
752
753 //------------------------------------------------------------------------
754 // ASCIIHexEncoder
755 //------------------------------------------------------------------------
756
757 class ASCIIHexEncoder: public FilterStream {
758 public:
759
760   ASCIIHexEncoder(Stream *strA);
761   virtual ~ASCIIHexEncoder();
762   virtual StreamKind getKind() { return strWeird; }
763   virtual void reset();
764   virtual int getChar()
765     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
766   virtual int lookChar()
767     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
768   virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; }
769   virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
770   virtual GBool isEncoder() { return gTrue; }
771
772 private:
773
774   char buf[4];
775   char *bufPtr;
776   char *bufEnd;
777   int lineLen;
778   GBool eof;
779
780   GBool fillBuf();
781 };
782
783 //------------------------------------------------------------------------
784 // ASCII85Encoder
785 //------------------------------------------------------------------------
786
787 class ASCII85Encoder: public FilterStream {
788 public:
789
790   ASCII85Encoder(Stream *strA);
791   virtual ~ASCII85Encoder();
792   virtual StreamKind getKind() { return strWeird; }
793   virtual void reset();
794   virtual int getChar()
795     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
796   virtual int lookChar()
797     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
798   virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; }
799   virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
800   virtual GBool isEncoder() { return gTrue; }
801
802 private:
803
804   char buf[8];
805   char *bufPtr;
806   char *bufEnd;
807   int lineLen;
808   GBool eof;
809
810   GBool fillBuf();
811 };
812
813 //------------------------------------------------------------------------
814 // RunLengthEncoder
815 //------------------------------------------------------------------------
816
817 class RunLengthEncoder: public FilterStream {
818 public:
819
820   RunLengthEncoder(Stream *strA);
821   virtual ~RunLengthEncoder();
822   virtual StreamKind getKind() { return strWeird; }
823   virtual void reset();
824   virtual int getChar()
825     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
826   virtual int lookChar()
827     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
828   virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; }
829   virtual GBool isBinary(GBool last = gTrue) { return gTrue; }
830   virtual GBool isEncoder() { return gTrue; }
831
832 private:
833
834   char buf[131];
835   char *bufPtr;
836   char *bufEnd;
837   char *nextEnd;
838   GBool eof;
839
840   GBool fillBuf();
841 };
842
843 #endif