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