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