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