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