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