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