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