1 //========================================================================
5 // Copyright 1996-2002 Glyph & Cog, LLC
7 //========================================================================
25 //------------------------------------------------------------------------
36 strWeird // internal-use stream types
39 //------------------------------------------------------------------------
40 // Stream (base class)
41 //------------------------------------------------------------------------
52 // Reference counting.
53 int incRef() { return ++ref; }
54 int decRef() { return --ref; }
56 // Get kind of stream.
57 virtual StreamKind getKind() = 0;
59 // Reset stream to beginning.
60 virtual void reset() = 0;
62 // Close down the stream.
65 // Get next char from stream.
66 virtual int getChar() = 0;
68 // Peek at next char in stream.
69 virtual int lookChar() = 0;
71 // Get next char from stream without using the predictor.
72 // This is only used by StreamPredictor.
73 virtual int getRawChar();
75 // Get next line from stream.
76 virtual char *getLine(char *buf, int size);
78 // Get current position in file.
79 virtual int getPos() = 0;
81 // Go to a position in the stream. If <dir> is negative, the
82 // position is from the end of the file; otherwise the position is
83 // from the start of the file.
84 virtual void setPos(Guint pos, int dir = 0) = 0;
86 // Get PostScript command for the filter(s).
87 virtual GString *getPSFilter(char *indent);
89 // Does this stream type potentially contain non-printable chars?
90 virtual GBool isBinary(GBool last = gTrue) = 0;
92 // Get the BaseStream or EmbedStream of this stream.
93 virtual BaseStream *getBaseStream() = 0;
95 // Get the dictionary associated with this stream.
96 virtual Dict *getDict() = 0;
98 // Is this an encoding filter?
99 virtual GBool isEncoder() { return gFalse; }
101 // Add filters to this stream according to the parameters in <dict>.
102 // Returns the new stream.
103 Stream *addFilters(Object *dict);
107 Stream *makeFilter(char *name, Stream *str, Object *params);
109 int ref; // reference count
112 //------------------------------------------------------------------------
115 // This is the base class for all streams that read directly from a file.
116 //------------------------------------------------------------------------
118 class BaseStream: public Stream {
121 BaseStream(Object *dictA);
122 virtual ~BaseStream();
123 virtual Stream *makeSubStream(Guint start, GBool limited,
124 Guint length, Object *dict) = 0;
125 virtual void setPos(Guint pos, int dir = 0) = 0;
126 virtual BaseStream *getBaseStream() { return this; }
127 virtual Dict *getDict() { return dict.getDict(); }
129 // Get/set position of first byte of stream within the file.
130 virtual Guint getStart() = 0;
131 virtual void moveStart(int delta) = 0;
133 #ifndef NO_DECRYPTION
134 // Set decryption for this stream.
135 virtual void doDecryption(Guchar *fileKey, int keyLength,
136 int objNum, int objGen);
139 #ifndef NO_DECRYPTION
150 //------------------------------------------------------------------------
153 // This is the base class for all streams that filter another stream.
154 //------------------------------------------------------------------------
156 class FilterStream: public Stream {
159 FilterStream(Stream *strA);
160 virtual ~FilterStream();
161 virtual void close();
162 virtual int getPos() { return str->getPos(); }
163 virtual void setPos(Guint pos, int dir = 0);
164 virtual BaseStream *getBaseStream() { return str->getBaseStream(); }
165 virtual Dict *getDict() { return str->getDict(); }
172 //------------------------------------------------------------------------
174 //------------------------------------------------------------------------
179 // Create an image stream object for an image with the specified
180 // parameters. Note that these are the actual image parameters,
181 // which may be different from the predictor parameters.
182 ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA);
189 // Gets the next pixel from the stream. <pix> should be able to hold
190 // at least nComps elements. Returns false at end of file.
191 GBool getPixel(Guchar *pix);
193 // Skip an entire line from the image.
198 Stream *str; // base stream
199 int width; // pixels per line
200 int nComps; // components per pixel
201 int nBits; // bits per component
202 int nVals; // components per line
203 Guchar *imgLine; // line buffer
204 int imgIdx; // current index in imgLine
207 //------------------------------------------------------------------------
209 //------------------------------------------------------------------------
211 class StreamPredictor {
214 // Create a predictor object. Note that the parameters are for the
215 // predictor, and may not match the actual image parameters.
216 StreamPredictor(Stream *strA, int predictorA,
217 int widthA, int nCompsA, int nBitsA);
228 Stream *str; // base stream
229 int predictor; // predictor
230 int width; // pixels per line
231 int nComps; // components per pixel
232 int nBits; // bits per component
233 int nVals; // components per line
234 int pixBytes; // bytes per pixel
235 int rowBytes; // bytes per line
236 Guchar *predLine; // line buffer
237 int predIdx; // current index in predLine
240 //------------------------------------------------------------------------
242 //------------------------------------------------------------------------
244 #define fileStreamBufSize 256
246 class FileStream: public BaseStream {
249 FileStream(FILE *fA, Guint startA, GBool limitedA,
250 Guint lengthA, Object *dictA);
251 virtual ~FileStream();
252 virtual Stream *makeSubStream(Guint startA, GBool limitedA,
253 Guint lengthA, Object *dictA);
254 virtual StreamKind getKind() { return strFile; }
255 virtual void reset();
256 virtual void close();
257 virtual int getChar()
258 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
259 virtual int lookChar()
260 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
261 virtual int getPos() { return bufPos + (bufPtr - buf); }
262 virtual void setPos(Guint pos, int dir = 0);
263 virtual GBool isBinary(GBool last = gTrue) { return last; }
264 virtual Guint getStart() { return start; }
265 virtual void moveStart(int delta);
275 char buf[fileStreamBufSize];
283 //------------------------------------------------------------------------
285 //------------------------------------------------------------------------
287 class MemStream: public BaseStream {
290 MemStream(char *bufA, Guint lengthA, Object *dictA);
291 virtual ~MemStream();
292 virtual Stream *makeSubStream(Guint start, GBool limited,
293 Guint lengthA, Object *dictA);
294 virtual StreamKind getKind() { return strWeird; }
295 virtual void reset();
296 virtual void close();
297 virtual int getChar()
298 { return (bufPtr < bufEnd) ? (*bufPtr++ & 0xff) : EOF; }
299 virtual int lookChar()
300 { return (bufPtr < bufEnd) ? (*bufPtr & 0xff) : EOF; }
301 virtual int getPos() { return bufPtr - buf; }
302 virtual void setPos(Guint pos, int dir = 0);
303 virtual GBool isBinary(GBool last = gTrue) { return last; }
304 virtual Guint getStart() { return 0; }
305 virtual void moveStart(int delta);
306 #ifndef NO_DECRYPTION
307 virtual void doDecryption(Guchar *fileKey, int keyLength,
308 int objNum, int objGen);
320 //------------------------------------------------------------------------
323 // This is a special stream type used for embedded streams (inline
324 // images). It reads directly from the base stream -- after the
325 // EmbedStream is deleted, reads from the base stream will proceed where
326 // the BaseStream left off. Note that this is very different behavior
327 // that creating a new FileStream (using makeSubStream).
328 //------------------------------------------------------------------------
330 class EmbedStream: public BaseStream {
333 EmbedStream(Stream *strA, Object *dictA);
334 virtual ~EmbedStream();
335 virtual Stream *makeSubStream(Guint start, GBool limited,
336 Guint length, Object *dictA);
337 virtual StreamKind getKind() { return str->getKind(); }
338 virtual void reset() {}
339 virtual int getChar() { return str->getChar(); }
340 virtual int lookChar() { return str->lookChar(); }
341 virtual int getPos() { return str->getPos(); }
342 virtual void setPos(Guint pos, int dir = 0);
343 virtual GBool isBinary(GBool last = gTrue) { return last; }
344 virtual Guint getStart();
345 virtual void moveStart(int delta);
352 //------------------------------------------------------------------------
354 //------------------------------------------------------------------------
356 class ASCIIHexStream: public FilterStream {
359 ASCIIHexStream(Stream *strA);
360 virtual ~ASCIIHexStream();
361 virtual StreamKind getKind() { return strASCIIHex; }
362 virtual void reset();
363 virtual int getChar()
364 { int c = lookChar(); buf = EOF; return c; }
365 virtual int lookChar();
366 virtual GString *getPSFilter(char *indent);
367 virtual GBool isBinary(GBool last = gTrue);
375 //------------------------------------------------------------------------
377 //------------------------------------------------------------------------
379 class ASCII85Stream: public FilterStream {
382 ASCII85Stream(Stream *strA);
383 virtual ~ASCII85Stream();
384 virtual StreamKind getKind() { return strASCII85; }
385 virtual void reset();
386 virtual int getChar()
387 { int ch = lookChar(); ++index; return ch; }
388 virtual int lookChar();
389 virtual GString *getPSFilter(char *indent);
390 virtual GBool isBinary(GBool last = gTrue);
400 //------------------------------------------------------------------------
402 //------------------------------------------------------------------------
404 class LZWStream: public FilterStream {
407 LZWStream(Stream *strA, int predictor, int columns, int colors,
408 int bits, int earlyA);
409 virtual ~LZWStream();
410 virtual StreamKind getKind() { return strLZW; }
411 virtual void reset();
412 virtual int getChar();
413 virtual int lookChar();
414 virtual int getRawChar();
415 virtual GString *getPSFilter(char *indent);
416 virtual GBool isBinary(GBool last = gTrue);
420 StreamPredictor *pred; // predictor
421 int early; // early parameter
422 FILE *zPipe; // uncompress pipe
423 GString *zName; // .Z file name
424 int inputBuf; // input buffer
425 int inputBits; // number of bits in input buffer
426 int inCodeBits; // size of input code
427 char buf[256]; // buffer
428 char *bufPtr; // next char to read
429 char *bufEnd; // end of buffer
431 void dumpFile(FILE *f);
436 //------------------------------------------------------------------------
438 //------------------------------------------------------------------------
440 class RunLengthStream: public FilterStream {
443 RunLengthStream(Stream *strA);
444 virtual ~RunLengthStream();
445 virtual StreamKind getKind() { return strRunLength; }
446 virtual void reset();
447 virtual int getChar()
448 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
449 virtual int lookChar()
450 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
451 virtual GString *getPSFilter(char *indent);
452 virtual GBool isBinary(GBool last = gTrue);
456 char buf[128]; // buffer
457 char *bufPtr; // next char to read
458 char *bufEnd; // end of buffer
464 //------------------------------------------------------------------------
466 //------------------------------------------------------------------------
468 struct CCITTCodeTable;
470 class CCITTFaxStream: public FilterStream {
473 CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA,
474 GBool byteAlignA, int columnsA, int rowsA,
475 GBool endOfBlockA, GBool blackA);
476 virtual ~CCITTFaxStream();
477 virtual StreamKind getKind() { return strCCITTFax; }
478 virtual void reset();
479 virtual int getChar()
480 { int c = lookChar(); buf = EOF; return c; }
481 virtual int lookChar();
482 virtual GString *getPSFilter(char *indent);
483 virtual GBool isBinary(GBool last = gTrue);
487 int encoding; // 'K' parameter
488 GBool endOfLine; // 'EndOfLine' parameter
489 GBool byteAlign; // 'EncodedByteAlign' parameter
490 int columns; // 'Columns' parameter
491 int rows; // 'Rows' parameter
492 GBool endOfBlock; // 'EndOfBlock' parameter
493 GBool black; // 'BlackIs1' parameter
494 GBool eof; // true if at eof
495 GBool nextLine2D; // true if next line uses 2D encoding
496 int row; // current row
497 int inputBuf; // input buffer
498 int inputBits; // number of bits in input buffer
499 short *refLine; // reference line changing elements
500 int b1; // index into refLine
501 short *codingLine; // coding line changing elements
502 int a0; // index into codingLine
503 int outputBits; // remaining ouput bits
504 int buf; // character buffer
506 short getTwoDimCode();
507 short getWhiteCode();
508 short getBlackCode();
509 short lookBits(int n);
510 void eatBits(int n) { inputBits -= n; }
513 //------------------------------------------------------------------------
515 //------------------------------------------------------------------------
517 // DCT component info
519 int id; // component ID
520 GBool inScan; // is this component in the current scan?
521 int hSample, vSample; // horiz/vert sampling resolutions
522 int quantTable; // quantization table number
523 int dcHuffTable, acHuffTable; // Huffman table numbers
524 int prevDC; // DC coefficient accumulator
527 // DCT Huffman decoding table
528 struct DCTHuffTable {
529 Guchar firstSym[17]; // first symbol for this bit length
530 Gushort firstCode[17]; // first code for this bit length
531 Gushort numCodes[17]; // number of codes of this bit length
532 Guchar sym[256]; // symbols
535 class DCTStream: public FilterStream {
538 DCTStream(Stream *strA);
539 virtual ~DCTStream();
540 virtual StreamKind getKind() { return strDCT; }
541 virtual void reset();
542 virtual int getChar();
543 virtual int lookChar();
544 virtual GString *getPSFilter(char *indent);
545 virtual GBool isBinary(GBool last = gTrue);
546 Stream *getRawStream() { return str; }
550 int width, height; // image size
551 int mcuWidth, mcuHeight; // size of min coding unit, in data units
552 DCTCompInfo compInfo[4]; // info for each component
553 int numComps; // number of components in image
554 int colorXform; // need YCbCr-to-RGB transform?
555 GBool gotAdobeMarker; // set if APP14 Adobe marker was present
556 int restartInterval; // restart interval, in MCUs
557 Guchar quantTables[4][64]; // quantization tables
558 int numQuantTables; // number of quantization tables
559 DCTHuffTable dcHuffTables[4]; // DC Huffman tables
560 DCTHuffTable acHuffTables[4]; // AC Huffman tables
561 int numDCHuffTables; // number of DC Huffman tables
562 int numACHuffTables; // number of AC Huffman tables
563 Guchar *rowBuf[4][32]; // buffer for one MCU
564 int comp, x, y, dy; // current position within image/MCU
565 int restartCtr; // MCUs left until restart
566 int restartMarker; // next restart marker
567 int inputBuf; // input buffer for variable length codes
568 int inputBits; // number of valid bits in input buffer
572 GBool readDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable,
573 Guchar quantTable[64], int *prevDC, Guchar data[64]);
574 int readHuffSym(DCTHuffTable *table);
575 int readAmp(int size);
578 GBool readFrameInfo();
579 GBool readScanInfo();
580 GBool readQuantTables();
581 GBool readHuffmanTables();
582 GBool readRestartInterval();
583 GBool readAdobeMarker();
589 //------------------------------------------------------------------------
591 //------------------------------------------------------------------------
593 #define flateWindow 32768 // buffer size
594 #define flateMask (flateWindow-1)
595 #define flateMaxHuffman 15 // max Huffman code length
596 #define flateMaxCodeLenCodes 19 // max # code length codes
597 #define flateMaxLitCodes 288 // max # literal codes
598 #define flateMaxDistCodes 30 // max # distance codes
600 // Huffman code table entry
602 int len; // code length in bits
603 int code; // code word
604 int val; // value represented by this code
607 // Huffman code table
608 struct FlateHuffmanTab {
609 int start[flateMaxHuffman+2]; // indexes of first code of each length
610 FlateCode *codes; // codes, sorted by length and code word
613 // Decoding info for length and distance code words
615 int bits; // # extra bits
616 int first; // first length/distance
619 class FlateStream: public FilterStream {
622 FlateStream(Stream *strA, int predictor, int columns,
623 int colors, int bits);
624 virtual ~FlateStream();
625 virtual StreamKind getKind() { return strFlate; }
626 virtual void reset();
627 virtual int getChar();
628 virtual int lookChar();
629 virtual int getRawChar();
630 virtual GString *getPSFilter(char *indent);
631 virtual GBool isBinary(GBool last = gTrue);
635 StreamPredictor *pred; // predictor
636 Guchar buf[flateWindow]; // output data buffer
637 int index; // current index into output buffer
638 int remain; // number valid bytes in output buffer
639 int codeBuf; // input buffer
640 int codeSize; // number of bits in input buffer
641 FlateCode // literal and distance codes
642 allCodes[flateMaxLitCodes + flateMaxDistCodes];
643 FlateHuffmanTab litCodeTab; // literal code table
644 FlateHuffmanTab distCodeTab; // distance code table
645 GBool compressedBlock; // set if reading a compressed block
646 int blockLen; // remaining length of uncompressed block
647 GBool endOfBlock; // set when end of block is reached
648 GBool eof; // set when end of stream is reached
650 static int // code length code reordering
651 codeLenCodeMap[flateMaxCodeLenCodes];
652 static FlateDecode // length decoding info
653 lengthDecode[flateMaxLitCodes-257];
654 static FlateDecode // distance decoding info
655 distDecode[flateMaxDistCodes];
659 void loadFixedCodes();
660 GBool readDynamicCodes();
661 void compHuffmanCodes(FlateHuffmanTab *tab, int n);
662 int getHuffmanCodeWord(FlateHuffmanTab *tab);
663 int getCodeWord(int bits);
666 //------------------------------------------------------------------------
668 //------------------------------------------------------------------------
670 class EOFStream: public FilterStream {
673 EOFStream(Stream *strA);
674 virtual ~EOFStream();
675 virtual StreamKind getKind() { return strWeird; }
676 virtual void reset() {}
677 virtual int getChar() { return EOF; }
678 virtual int lookChar() { return EOF; }
679 virtual GString *getPSFilter(char *indent) { return NULL; }
680 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
683 //------------------------------------------------------------------------
684 // FixedLengthEncoder
685 //------------------------------------------------------------------------
687 class FixedLengthEncoder: public FilterStream {
690 FixedLengthEncoder(Stream *strA, int lengthA);
691 ~FixedLengthEncoder();
692 virtual StreamKind getKind() { return strWeird; }
693 virtual void reset();
694 virtual void close();
695 virtual int getChar();
696 virtual int lookChar();
697 virtual GString *getPSFilter(char *indent) { return NULL; }
698 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
699 virtual GBool isEncoder() { return gTrue; }
707 //------------------------------------------------------------------------
709 //------------------------------------------------------------------------
711 class ASCIIHexEncoder: public FilterStream {
714 ASCIIHexEncoder(Stream *strA);
715 virtual ~ASCIIHexEncoder();
716 virtual StreamKind getKind() { return strWeird; }
717 virtual void reset();
718 virtual void close();
719 virtual int getChar()
720 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
721 virtual int lookChar()
722 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
723 virtual GString *getPSFilter(char *indent) { return NULL; }
724 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
725 virtual GBool isEncoder() { return gTrue; }
738 //------------------------------------------------------------------------
740 //------------------------------------------------------------------------
742 class ASCII85Encoder: public FilterStream {
745 ASCII85Encoder(Stream *strA);
746 virtual ~ASCII85Encoder();
747 virtual StreamKind getKind() { return strWeird; }
748 virtual void reset();
749 virtual void close();
750 virtual int getChar()
751 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
752 virtual int lookChar()
753 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
754 virtual GString *getPSFilter(char *indent) { return NULL; }
755 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
756 virtual GBool isEncoder() { return gTrue; }
769 //------------------------------------------------------------------------
771 //------------------------------------------------------------------------
773 class RunLengthEncoder: public FilterStream {
776 RunLengthEncoder(Stream *strA);
777 virtual ~RunLengthEncoder();
778 virtual StreamKind getKind() { return strWeird; }
779 virtual void reset();
780 virtual void close();
781 virtual int getChar()
782 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
783 virtual int lookChar()
784 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
785 virtual GString *getPSFilter(char *indent) { return NULL; }
786 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
787 virtual GBool isEncoder() { return gTrue; }