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