]> www.fi.muni.cz Git - evince.git/blob - pdf/xpdf/Stream.h
06af0d7ac3ffb4a3f740ee5a5e4bf6c3f7c3f666
[evince.git] / pdf / xpdf / Stream.h
1 //========================================================================
2 //
3 // Stream.h
4 //
5 // Copyright 1996 Derek B. Noonburg
6 //
7 //========================================================================
8
9 #ifndef STREAM_H
10 #define STREAM_H
11
12 #ifdef __GNUC__
13 #pragma interface
14 #endif
15
16 #include <stdio.h>
17 #include "gtypes.h"
18 #include "Object.h"
19
20 //------------------------------------------------------------------------
21
22 enum StreamKind {
23   strFile,
24   strASCIIHex,
25   strASCII85,
26   strLZW,
27   strRunLength,
28   strCCITTFax,
29   strDCT,
30   strFlate,
31   strWeird                      // internal-use stream types
32 };
33
34 //------------------------------------------------------------------------
35 // Stream (base class)
36 //------------------------------------------------------------------------
37
38 class Stream {
39 public:
40
41   // Constructor.
42   Stream();
43
44   // Destructor.
45   virtual ~Stream();
46
47   // Reference counting.
48   int incRef() { return ++ref; }
49   int decRef() { return --ref; }
50
51   // Get kind of stream.
52   virtual StreamKind getKind() = 0;
53
54   // Reset stream to beginning.
55   virtual void reset() = 0;
56
57   // Get next char from stream.
58   virtual int getChar() = 0;
59
60   // Peek at next char in stream.
61   virtual int lookChar() = 0;
62
63   // Get next char from stream without using the predictor.
64   // This is only used by StreamPredictor.
65   virtual int getRawChar();
66
67   // Get next line from stream.
68   virtual char *getLine(char *buf, int size);
69
70   // Get current position in file.
71   virtual int getPos() = 0;
72
73   // Go to a position in the stream.
74   virtual void setPos(int pos1);
75
76   // Get PostScript command for the filter(s).
77   virtual GString *getPSFilter(char *indent);
78
79   // Does this stream type potentially contain non-printable chars?
80   virtual GBool isBinary(GBool last = gTrue) = 0;
81
82   // Get the base FileStream or SubStream of this stream.
83   virtual Stream *getBaseStream() = 0;
84
85   // Get a substream of this stream.
86   virtual Stream *subStream (int start1, int length1, Object *dict1) = 0;
87
88   // Get start offset of a stream's data.
89   virtual int     getStart  () = 0;
90
91   // Get the dictionary associated with this stream.
92   virtual Dict *getDict() = 0;
93
94   // Is this an encoding filter?
95   virtual GBool isEncoder() { return gFalse; }
96
97   // Add filters to this stream according to the parameters in <dict>.
98   // Returns the new stream.
99   Stream *addFilters(Object *dict);
100
101 private:
102
103   Stream *makeFilter(char *name, Stream *str, Object *params);
104
105   int ref;                      // reference count
106 };
107
108 //------------------------------------------------------------------------
109 // ImageStream
110 //------------------------------------------------------------------------
111
112 class ImageStream {
113 public:
114
115   // Create an image stream object for an image with the specified
116   // parameters.  Note that these are the actual image parameters,
117   // which may be different from the predictor parameters.
118   ImageStream(Stream *str, int width, int nComps, int nBits);
119
120   ~ImageStream();
121
122   // Reset the stream.
123   void reset();
124
125   // Gets the next pixel from the stream.  <pix> should be able to hold
126   // at least nComps elements.  Returns false at end of file.
127   GBool getPixel(Guchar *pix);
128
129   // Skip an entire line from the image.
130   void skipLine();
131
132 private:
133
134   Stream *str;                  // base stream
135   int width;                    // pixels per line
136   int nComps;                   // components per pixel
137   int nBits;                    // bits per component
138   int nVals;                    // components per line
139   Guchar *imgLine;              // line buffer
140   int imgIdx;                   // current index in imgLine
141 };
142
143 //------------------------------------------------------------------------
144 // StreamPredictor
145 //------------------------------------------------------------------------
146
147 class StreamPredictor {
148 public:
149
150   // Create a predictor object.  Note that the parameters are for the
151   // predictor, and may not match the actual image parameters.
152   StreamPredictor(Stream *str, int predictor,
153                   int width, int nComps, int nBits);
154
155   ~StreamPredictor();
156
157   int lookChar();
158   int getChar();
159
160 private:
161
162   GBool getNextLine();
163
164   Stream *str;                  // base stream
165   int predictor;                // predictor
166   int width;                    // pixels per line
167   int nComps;                   // components per pixel
168   int nBits;                    // bits per component
169   int nVals;                    // components per line
170   int pixBytes;                 // bytes per pixel
171   int rowBytes;                 // bytes per line
172   Guchar *predLine;             // line buffer
173   int predIdx;                  // current index in predLine
174 };
175
176 //------------------------------------------------------------------------
177 // FileStream
178 //------------------------------------------------------------------------
179
180 // Portable pdf open helper function.
181 extern FILE *fileOpen (GString *fileName1);
182
183 class FileStream: public Stream {
184 public:
185   FileStream(FILE *f1);
186   virtual ~FileStream();
187   virtual StreamKind getKind() { return strFile; }
188   virtual void reset();
189   virtual int getChar()
190     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
191   virtual int lookChar()
192     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
193   virtual int getPos() { return bufPos + (bufPtr - buf); }
194   virtual void setPos(int pos1);
195   virtual GBool isBinary(GBool last = gTrue) { return last; }
196   virtual Stream *getBaseStream() { return this; }
197   virtual Stream *subStream (int start1, int length1, Object *dict1);
198   virtual int     getStart  () { return start; }
199   virtual Dict *getDict() { return dict.getDict(); }
200
201 private:
202
203   GBool fillBuf();
204   GBool checkHeader();
205
206   FILE *f;
207   int start;
208   int length;
209   char buf[256];
210   char *bufPtr;
211   char *bufEnd;
212   int bufPos;
213   int savePos;
214   Object dict;
215 };
216
217 //------------------------------------------------------------------------
218 // SubStream
219 //------------------------------------------------------------------------
220
221 class SubStream: public Stream {
222 public:
223
224   SubStream(Stream *str1, Object *dict1);
225   virtual ~SubStream();
226   virtual StreamKind getKind() { return str->getKind(); }
227   virtual void reset() {}
228   virtual int getChar() { return str->getChar(); }
229   virtual int lookChar() { return str->lookChar(); }
230   virtual int getPos() { return str->getPos(); }
231   virtual GBool isBinary(GBool last = gTrue) { return last; }
232   virtual Stream *getBaseStream() { return this; }
233   virtual Stream *subStream (int start1, int length1, Object *dict1)
234     { return str->subStream (start1, length1, dict1); }
235   virtual int     getStart  () { return str->getStart (); }
236   virtual Dict *getDict() { return dict.getDict(); }
237
238 private:
239
240   Stream *str;
241   Object dict;
242 };
243
244 //------------------------------------------------------------------------
245 // ASCIIHexStream
246 //------------------------------------------------------------------------
247
248 class ASCIIHexStream: public Stream {
249 public:
250
251   ASCIIHexStream(Stream *str1);
252   virtual ~ASCIIHexStream();
253   virtual StreamKind getKind() { return strASCIIHex; }
254   virtual void reset();
255   virtual int getChar()
256     { int c = lookChar(); buf = EOF; return c; }
257   virtual int lookChar();
258   virtual int getPos() { return str->getPos(); }
259   virtual GString *getPSFilter(char *indent);
260   virtual GBool isBinary(GBool last = gTrue);
261   virtual Stream *getBaseStream() { return str->getBaseStream(); }
262   virtual Stream *subStream (int start1, int length1, Object *dict1)
263     { return str->subStream (start1, length1, dict1); }
264   virtual int     getStart  () { return str->getStart (); }
265   virtual Dict *getDict() { return str->getDict(); }
266
267 private:
268
269   Stream *str;
270   int buf;
271   GBool eof;
272 };
273
274 //------------------------------------------------------------------------
275 // ASCII85Stream
276 //------------------------------------------------------------------------
277
278 class ASCII85Stream: public Stream {
279 public:
280
281   ASCII85Stream(Stream *str1);
282   virtual ~ASCII85Stream();
283   virtual StreamKind getKind() { return strASCII85; }
284   virtual void reset();
285   virtual int getChar()
286     { int ch = lookChar(); ++index; return ch; }
287   virtual int lookChar();
288   virtual int getPos() { return str->getPos(); }
289   virtual GString *getPSFilter(char *indent);
290   virtual GBool isBinary(GBool last = gTrue);
291   virtual Stream *getBaseStream() { return str->getBaseStream(); }
292   virtual Stream *subStream (int start1, int length1, Object *dict1)
293     { return str->subStream (start1, length1, dict1); }
294   virtual int     getStart  () { return str->getStart (); }
295   virtual Dict *getDict() { return str->getDict(); }
296
297 private:
298
299   Stream *str;
300   int c[5];
301   int b[4];
302   int index, n;
303   GBool eof;
304 };
305
306 //------------------------------------------------------------------------
307 // LZWStream
308 //------------------------------------------------------------------------
309
310 class LZWStream: public Stream {
311 public:
312
313   LZWStream(Stream *str1, int predictor1, int columns1, int colors1,
314             int bits1, int early1);
315   virtual ~LZWStream();
316   virtual StreamKind getKind() { return strLZW; }
317   virtual void reset();
318   virtual int getChar();
319   virtual int lookChar();
320   virtual int getRawChar();
321   virtual int getPos() { return str->getPos(); }
322   virtual GString *getPSFilter(char *indent);
323   virtual GBool isBinary(GBool last = gTrue);
324   virtual Stream *getBaseStream() { return str->getBaseStream(); }
325   virtual Stream *subStream (int start1, int length1, Object *dict1)
326     { return str->subStream (start1, length1, dict1); }
327   virtual int     getStart  () { return str->getStart (); }
328   virtual Dict *getDict() { return str->getDict(); }
329
330 private:
331
332   Stream *str;                  // stream
333   StreamPredictor *pred;        // predictor
334   int early;                    // early parameter
335   char zCmd[256];               // uncompress command
336   FILE *zPipe;                  // uncompress pipe
337   char *zName;                  // .Z file name (in zCmd)
338   int inputBuf;                 // input buffer
339   int inputBits;                // number of bits in input buffer
340   int inCodeBits;               // size of input code
341   char buf[256];                // buffer
342   char *bufPtr;                 // next char to read
343   char *bufEnd;                 // end of buffer
344
345   void dumpFile(FILE *f);
346   int getCode();
347   GBool fillBuf();
348 };
349
350 //------------------------------------------------------------------------
351 // RunLengthStream
352 //------------------------------------------------------------------------
353
354 class RunLengthStream: public Stream {
355 public:
356
357   RunLengthStream(Stream *str1);
358   virtual ~RunLengthStream();
359   virtual StreamKind getKind() { return strRunLength; }
360   virtual void reset();
361   virtual int getChar()
362     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
363   virtual int lookChar()
364     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
365   virtual int getPos() { return str->getPos(); }
366   virtual GString *getPSFilter(char *indent);
367   virtual GBool isBinary(GBool last = gTrue);
368   virtual Stream *getBaseStream() { return str->getBaseStream(); }
369   virtual Stream *subStream (int start1, int length1, Object *dict1)
370     { return str->subStream (start1, length1, dict1); }
371   virtual int     getStart  () { return str->getStart (); }
372   virtual Dict *getDict() { return str->getDict(); }
373
374 private:
375
376   Stream *str;
377   char buf[128];                // buffer
378   char *bufPtr;                 // next char to read
379   char *bufEnd;                 // end of buffer
380   GBool eof;
381
382   GBool fillBuf();
383 };
384
385 //------------------------------------------------------------------------
386 // CCITTFaxStream
387 //------------------------------------------------------------------------
388
389 struct CCITTCodeTable;
390
391 class CCITTFaxStream: public Stream {
392 public:
393
394   CCITTFaxStream(Stream *str, int encoding, GBool endOfLine,
395                  GBool byteAlign, int columns, int rows,
396                  GBool endOfBlock, GBool black);
397   virtual ~CCITTFaxStream();
398   virtual StreamKind getKind() { return strCCITTFax; }
399   virtual void reset();
400   virtual int getChar()
401     { int c = lookChar(); buf = EOF; return c; }
402   virtual int lookChar();
403   virtual int getPos() { return str->getPos(); }
404   virtual GString *getPSFilter(char *indent);
405   virtual GBool isBinary(GBool last = gTrue);
406   virtual Stream *getBaseStream() { return str->getBaseStream(); }
407   virtual Stream *subStream (int start1, int length1, Object *dict1)
408     { return str->subStream (start1, length1, dict1); }
409   virtual int     getStart  () { return str->getStart (); }
410   virtual Dict *getDict() { return str->getDict(); }
411
412 private:
413
414   Stream *str;                  // stream
415   int encoding;                 // 'K' parameter
416   GBool endOfLine;              // 'EndOfLine' parameter
417   GBool byteAlign;              // 'EncodedByteAlign' parameter
418   int columns;                  // 'Columns' parameter
419   int rows;                     // 'Rows' parameter
420   GBool endOfBlock;             // 'EndOfBlock' parameter
421   GBool black;                  // 'BlackIs1' parameter
422   GBool eof;                    // true if at eof
423   GBool nextLine2D;             // true if next line uses 2D encoding
424   int row;                      // current row
425   int inputBuf;                 // input buffer
426   int inputBits;                // number of bits in input buffer
427   short *refLine;               // reference line changing elements
428   int b1;                       // index into refLine
429   short *codingLine;            // coding line changing elements
430   int a0;                       // index into codingLine
431   int outputBits;               // remaining ouput bits
432   int buf;                      // character buffer
433
434   short getTwoDimCode();
435   short getWhiteCode();
436   short getBlackCode();
437   short lookBits(int n);
438   void eatBits(int n) { inputBits -= n; }
439 };
440
441 //------------------------------------------------------------------------
442 // DCTStream
443 //------------------------------------------------------------------------
444
445 // DCT component info
446 struct DCTCompInfo {
447   int id;                       // component ID
448   GBool inScan;                 // is this component in the current scan?
449   int hSample, vSample;         // horiz/vert sampling resolutions
450   int quantTable;               // quantization table number
451   int dcHuffTable, acHuffTable; // Huffman table numbers
452   int prevDC;                   // DC coefficient accumulator
453 };
454
455 // DCT Huffman decoding table
456 struct DCTHuffTable {
457   Guchar firstSym[17];          // first symbol for this bit length
458   Gushort firstCode[17];        // first code for this bit length
459   Gushort numCodes[17];         // number of codes of this bit length
460   Guchar sym[256];              // symbols
461 };
462
463 class DCTStream: public Stream {
464 public:
465
466   DCTStream(Stream *str1);
467   virtual ~DCTStream();
468   virtual StreamKind getKind() { return strDCT; }
469   virtual void reset();
470   virtual int getChar();
471   virtual int lookChar();
472   virtual int getPos() { return str->getPos(); }
473   virtual GString *getPSFilter(char *indent);
474   virtual GBool isBinary(GBool last = gTrue);
475   virtual Stream *getBaseStream() { return str->getBaseStream(); }
476   virtual Stream *subStream (int start1, int length1, Object *dict1)
477     { return str->subStream (start1, length1, dict1); }
478   virtual int     getStart  () { return str->getStart (); }
479   virtual Dict *getDict() { return str->getDict(); }
480   Stream *getRawStream() { return str; }
481
482 private:
483
484   Stream *str;                  // stream
485   int width, height;            // image size
486   int mcuWidth, mcuHeight;      // size of min coding unit, in data units
487   DCTCompInfo compInfo[4];      // info for each component
488   int numComps;                 // number of components in image
489   int colorXform;               // need YCbCr-to-RGB transform?
490   GBool gotAdobeMarker;         // set if APP14 Adobe marker was present
491   int restartInterval;          // restart interval, in MCUs
492   Guchar quantTables[4][64];    // quantization tables
493   int numQuantTables;           // number of quantization tables
494   DCTHuffTable dcHuffTables[4]; // DC Huffman tables
495   DCTHuffTable acHuffTables[4]; // AC Huffman tables
496   int numDCHuffTables;          // number of DC Huffman tables
497   int numACHuffTables;          // number of AC Huffman tables
498   Guchar *rowBuf[4][32];        // buffer for one MCU
499   int comp, x, y, dy;           // current position within image/MCU
500   int restartCtr;               // MCUs left until restart
501   int restartMarker;            // next restart marker
502   int inputBuf;                 // input buffer for variable length codes
503   int inputBits;                // number of valid bits in input buffer
504
505   void restart();
506   GBool readMCURow();
507   GBool readDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable,
508                      Guchar quantTable[64], int *prevDC, Guchar data[64]);
509   int readHuffSym(DCTHuffTable *table);
510   int readAmp(int size);
511   int readBit();
512   GBool readHeader();
513   GBool readFrameInfo();
514   GBool readScanInfo();
515   GBool readQuantTables();
516   GBool readHuffmanTables();
517   GBool readRestartInterval();
518   GBool readAdobeMarker();
519   GBool readTrailer();
520   int readMarker();
521   int read16();
522 };
523
524 //------------------------------------------------------------------------
525 // FlateStream
526 //------------------------------------------------------------------------
527
528 #define flateWindow          32768    // buffer size
529 #define flateMask            (flateWindow-1)
530 #define flateMaxHuffman         15    // max Huffman code length
531 #define flateMaxCodeLenCodes    19    // max # code length codes
532 #define flateMaxLitCodes       288    // max # literal codes
533 #define flateMaxDistCodes       30    // max # distance codes
534
535 // Huffman code table entry
536 struct FlateCode {
537   int len;                      // code length in bits
538   int code;                     // code word
539   int val;                      // value represented by this code
540 };
541
542 // Huffman code table
543 struct FlateHuffmanTab {
544   int start[flateMaxHuffman+2]; // indexes of first code of each length
545   FlateCode *codes;             // codes, sorted by length and code word
546 };
547
548 // Decoding info for length and distance code words
549 struct FlateDecode {
550   int bits;                     // # extra bits
551   int first;                    // first length/distance
552 };
553
554 class FlateStream: public Stream {
555 public:
556
557   FlateStream(Stream *str1, int predictor1, int columns1,
558               int colors1, int bits1);
559   virtual ~FlateStream();
560   virtual StreamKind getKind() { return strFlate; }
561   virtual void reset();
562   virtual int getChar();
563   virtual int lookChar();
564   virtual int getRawChar();
565   virtual int getPos() { return str->getPos(); }
566   virtual GString *getPSFilter(char *indent);
567   virtual GBool isBinary(GBool last = gTrue);
568   virtual Stream *getBaseStream() { return str->getBaseStream(); }
569   virtual Stream *subStream (int start1, int length1, Object *dict1)
570     { return str->subStream (start1, length1, dict1); }
571   virtual int     getStart  () { return str->getStart (); }
572   virtual Dict *getDict() { return str->getDict(); }
573
574 private:
575
576   Stream *str;                  // stream
577   StreamPredictor *pred;        // predictor
578   Guchar buf[flateWindow];      // output data buffer
579   int index;                    // current index into output buffer
580   int remain;                   // number valid bytes in output buffer
581   int codeBuf;                  // input buffer
582   int codeSize;                 // number of bits in input buffer
583   FlateCode                     // literal and distance codes
584     allCodes[flateMaxLitCodes + flateMaxDistCodes];
585   FlateHuffmanTab litCodeTab;   // literal code table
586   FlateHuffmanTab distCodeTab;  // distance code table
587   GBool compressedBlock;        // set if reading a compressed block
588   int blockLen;                 // remaining length of uncompressed block
589   GBool endOfBlock;             // set when end of block is reached
590   GBool eof;                    // set when end of stream is reached
591
592   static int                    // code length code reordering
593     codeLenCodeMap[flateMaxCodeLenCodes];
594   static FlateDecode            // length decoding info
595     lengthDecode[flateMaxLitCodes-257];
596   static FlateDecode            // distance decoding info
597     distDecode[flateMaxDistCodes];
598
599   void readSome();
600   GBool startBlock();
601   void loadFixedCodes();
602   GBool readDynamicCodes();
603   void compHuffmanCodes(FlateHuffmanTab *tab, int n);
604   int getHuffmanCodeWord(FlateHuffmanTab *tab);
605   int getCodeWord(int bits);
606 };
607
608 //------------------------------------------------------------------------
609 // EOFStream
610 //------------------------------------------------------------------------
611
612 class EOFStream: public Stream {
613 public:
614
615   EOFStream(Stream *str1);
616   virtual ~EOFStream();
617   virtual StreamKind getKind() { return strWeird; }
618   virtual void reset() {}
619   virtual int getChar() { return EOF; }
620   virtual int lookChar() { return EOF; }
621   virtual int getPos() { return str->getPos(); }
622   virtual GString *getPSFilter(char *indent)  { return NULL; }
623   virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
624   virtual Stream *getBaseStream() { return str->getBaseStream(); }
625   virtual Stream *subStream (int start1, int length1, Object *dict1)
626     { return str->subStream (start1, length1, dict1); }
627   virtual int     getStart  () { return str->getStart (); }
628   virtual Dict *getDict() { return str->getDict(); }
629
630 private:
631
632   Stream *str;
633 };
634
635 //------------------------------------------------------------------------
636 // FixedLengthEncoder
637 //------------------------------------------------------------------------
638
639 class FixedLengthEncoder: public Stream {
640 public:
641
642   FixedLengthEncoder(Stream *str1, int length1);
643   ~FixedLengthEncoder();
644   virtual StreamKind getKind() { return strWeird; }
645   virtual void reset();
646   virtual int getChar();
647   virtual int lookChar();
648   virtual int getPos() { return str->getPos(); }
649   virtual GString *getPSFilter(char *indent) { return NULL; }
650   virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
651   virtual Stream *getBaseStream() { return str->getBaseStream(); }
652   virtual Stream *subStream (int start1, int length1, Object *dict1)
653     { return str->subStream (start1, length1, dict1); }
654   virtual int     getStart  () { return str->getStart (); }
655   virtual Dict *getDict() { return str->getDict(); }
656   virtual GBool isEncoder() { return gTrue; }
657
658 private:
659
660   Stream *str;
661   int length;
662   int count;
663 };
664
665 //------------------------------------------------------------------------
666 // ASCII85Encoder
667 //------------------------------------------------------------------------
668
669 class ASCII85Encoder: public Stream {
670 public:
671
672   ASCII85Encoder(Stream *str1);
673   virtual ~ASCII85Encoder();
674   virtual StreamKind getKind() { return strWeird; }
675   virtual void reset();
676   virtual int getChar()
677     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
678   virtual int lookChar()
679     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
680   virtual int getPos() { return str->getPos(); }
681   virtual GString *getPSFilter(char *indent) { return NULL; }
682   virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
683   virtual Stream *getBaseStream() { return str->getBaseStream(); }
684   virtual Stream *subStream (int start1, int length1, Object *dict1)
685     { return str->subStream (start1, length1, dict1); }
686   virtual int     getStart  () { return str->getStart (); }
687   virtual Dict *getDict() { return str->getDict(); }
688   virtual GBool isEncoder() { return gTrue; }
689
690 private:
691
692   Stream *str;
693   char buf[8];
694   char *bufPtr;
695   char *bufEnd;
696   int lineLen;
697   GBool eof;
698
699   GBool fillBuf();
700 };
701
702 //------------------------------------------------------------------------
703 // RunLengthEncoder
704 //------------------------------------------------------------------------
705
706 class RunLengthEncoder: public Stream {
707 public:
708
709   RunLengthEncoder(Stream *str1);
710   virtual ~RunLengthEncoder();
711   virtual StreamKind getKind() { return strWeird; }
712   virtual void reset();
713   virtual int getChar()
714     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
715   virtual int lookChar()
716     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
717   virtual int getPos() { return str->getPos(); }
718   virtual GString *getPSFilter(char *indent) { return NULL; }
719   virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
720   virtual Stream *getBaseStream() { return str->getBaseStream(); }
721   virtual Stream *subStream (int start1, int length1, Object *dict1)
722     { return str->subStream (start1, length1, dict1); }
723   virtual int     getStart  () { return str->getStart (); }
724   virtual Dict *getDict() { return str->getDict(); }
725   virtual GBool isEncoder() { return gTrue; }
726
727 private:
728
729   Stream *str;
730   char buf[131];
731   char *bufPtr;
732   char *bufEnd;
733   char *nextEnd;
734   GBool eof;
735
736   GBool fillBuf();
737 };
738
739 #endif