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