1 //========================================================================
5 // Copyright 1996-2003 Glyph & Cog, LLC
7 //========================================================================
14 #ifdef USE_GCC_PRAGMAS
27 //------------------------------------------------------------------------
40 strWeird // internal-use stream types
43 //------------------------------------------------------------------------
44 // Stream (base class)
45 //------------------------------------------------------------------------
56 // Reference counting.
57 int incRef() { return ++ref; }
58 int decRef() { return --ref; }
60 // Get kind of stream.
61 virtual StreamKind getKind() = 0;
63 // Reset stream to beginning.
64 virtual void reset() = 0;
66 // Close down the stream.
69 // Get next char from stream.
70 virtual int getChar() = 0;
72 // Peek at next char in stream.
73 virtual int lookChar() = 0;
75 // Get next char from stream without using the predictor.
76 // This is only used by StreamPredictor.
77 virtual int getRawChar();
79 // Get next line from stream.
80 virtual char *getLine(char *buf, int size);
82 // Get current position in file.
83 virtual int getPos() = 0;
85 // Go to a position in the stream. If <dir> is negative, the
86 // position is from the end of the file; otherwise the position is
87 // from the start of the file.
88 virtual void setPos(Guint pos, int dir = 0) = 0;
90 // Get PostScript command for the filter(s).
91 virtual GString *getPSFilter(int psLevel, char *indent);
93 // Does this stream type potentially contain non-printable chars?
94 virtual GBool isBinary(GBool last = gTrue) = 0;
96 // Get the BaseStream of this stream.
97 virtual BaseStream *getBaseStream() = 0;
99 // Get the dictionary associated with this stream.
100 virtual Dict *getDict() = 0;
102 // Is this an encoding filter?
103 virtual GBool isEncoder() { return gFalse; }
105 // Add filters to this stream according to the parameters in <dict>.
106 // Returns the new stream.
107 Stream *addFilters(Object *dict);
109 // Tell this stream to ignore any length limitation -- this only
110 // applies to BaseStream subclasses, and is used as a hack to work
111 // around broken PDF files with incorrect stream lengths.
112 virtual void ignoreLength() {}
116 Stream *makeFilter(char *name, Stream *str, Object *params);
118 int ref; // reference count
121 //------------------------------------------------------------------------
124 // This is the base class for all streams that read directly from a file.
125 //------------------------------------------------------------------------
127 class BaseStream: public Stream {
130 BaseStream(Object *dictA);
131 virtual ~BaseStream();
132 virtual Stream *makeSubStream(Guint start, GBool limited,
133 Guint length, Object *dict) = 0;
134 virtual void setPos(Guint pos, int dir = 0) = 0;
135 virtual GBool isBinary(GBool last = gTrue) { return last; }
136 virtual BaseStream *getBaseStream() { return this; }
137 virtual Dict *getDict() { return dict.getDict(); }
139 // Get/set position of first byte of stream within the file.
140 virtual Guint getStart() = 0;
141 virtual void moveStart(int delta) = 0;
143 #ifndef NO_DECRYPTION
144 // Set decryption for this stream.
145 virtual void doDecryption(Guchar *fileKey, int keyLength,
146 int objNum, int objGen);
149 #ifndef NO_DECRYPTION
160 //------------------------------------------------------------------------
163 // This is the base class for all streams that filter another stream.
164 //------------------------------------------------------------------------
166 class FilterStream: public Stream {
169 FilterStream(Stream *strA);
170 virtual ~FilterStream();
171 virtual void close();
172 virtual int getPos() { return str->getPos(); }
173 virtual void setPos(Guint pos, int dir = 0);
174 virtual BaseStream *getBaseStream() { return str->getBaseStream(); }
175 virtual Dict *getDict() { return str->getDict(); }
176 virtual void ignoreLength() { str->ignoreLength(); }
183 //------------------------------------------------------------------------
185 //------------------------------------------------------------------------
190 // Create an image stream object for an image with the specified
191 // parameters. Note that these are the actual image parameters,
192 // which may be different from the predictor parameters.
193 ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA);
200 // Gets the next pixel from the stream. <pix> should be able to hold
201 // at least nComps elements. Returns false at end of file.
202 GBool getPixel(Guchar *pix);
204 // Returns a pointer to the next line of pixels. Returns NULL at
208 // Skip an entire line from the image.
213 Stream *str; // base stream
214 int width; // pixels per line
215 int nComps; // components per pixel
216 int nBits; // bits per component
217 int nVals; // components per line
218 Guchar *imgLine; // line buffer
219 int imgIdx; // current index in imgLine
222 //------------------------------------------------------------------------
224 //------------------------------------------------------------------------
226 class StreamPredictor {
229 // Create a predictor object. Note that the parameters are for the
230 // predictor, and may not match the actual image parameters.
231 StreamPredictor(Stream *strA, int predictorA,
232 int widthA, int nCompsA, int nBitsA);
243 Stream *str; // base stream
244 int predictor; // predictor
245 int width; // pixels per line
246 int nComps; // components per pixel
247 int nBits; // bits per component
248 int nVals; // components per line
249 int pixBytes; // bytes per pixel
250 int rowBytes; // bytes per line
251 Guchar *predLine; // line buffer
252 int predIdx; // current index in predLine
255 //------------------------------------------------------------------------
257 //------------------------------------------------------------------------
259 #define fileStreamBufSize 256
261 class FileStream: public BaseStream {
264 FileStream(FILE *fA, Guint startA, GBool limitedA,
265 Guint lengthA, Object *dictA);
266 virtual ~FileStream();
267 virtual Stream *makeSubStream(Guint startA, GBool limitedA,
268 Guint lengthA, Object *dictA);
269 virtual StreamKind getKind() { return strFile; }
270 virtual void reset();
271 virtual void close();
272 virtual int getChar()
273 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
274 virtual int lookChar()
275 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
276 virtual int getPos() { return bufPos + (bufPtr - buf); }
277 virtual void setPos(Guint pos, int dir = 0);
278 virtual void ignoreLength() { limited = gFalse; }
279 virtual Guint getStart() { return start; }
280 virtual void moveStart(int delta);
290 char buf[fileStreamBufSize];
298 //------------------------------------------------------------------------
300 //------------------------------------------------------------------------
302 class MemStream: public BaseStream {
305 MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA);
306 virtual ~MemStream();
307 virtual Stream *makeSubStream(Guint start, GBool limited,
308 Guint lengthA, Object *dictA);
309 virtual StreamKind getKind() { return strWeird; }
310 virtual void reset();
311 virtual void close();
312 virtual int getChar()
313 { return (bufPtr < bufEnd) ? (*bufPtr++ & 0xff) : EOF; }
314 virtual int lookChar()
315 { return (bufPtr < bufEnd) ? (*bufPtr & 0xff) : EOF; }
316 virtual int getPos() { return (int)(bufPtr - buf); }
317 virtual void setPos(Guint pos, int dir = 0);
318 virtual Guint getStart() { return start; }
319 virtual void moveStart(int delta);
320 #ifndef NO_DECRYPTION
321 virtual void doDecryption(Guchar *fileKey, int keyLength,
322 int objNum, int objGen);
335 //------------------------------------------------------------------------
338 // This is a special stream type used for embedded streams (inline
339 // images). It reads directly from the base stream -- after the
340 // EmbedStream is deleted, reads from the base stream will proceed where
341 // the BaseStream left off. Note that this is very different behavior
342 // that creating a new FileStream (using makeSubStream).
343 //------------------------------------------------------------------------
345 class EmbedStream: public BaseStream {
348 EmbedStream(Stream *strA, Object *dictA, GBool limitedA, Guint lengthA);
349 virtual ~EmbedStream();
350 virtual Stream *makeSubStream(Guint start, GBool limitedA,
351 Guint lengthA, Object *dictA);
352 virtual StreamKind getKind() { return str->getKind(); }
353 virtual void reset() {}
354 virtual int getChar();
355 virtual int lookChar();
356 virtual int getPos() { return str->getPos(); }
357 virtual void setPos(Guint pos, int dir = 0);
358 virtual Guint getStart();
359 virtual void moveStart(int delta);
368 //------------------------------------------------------------------------
370 //------------------------------------------------------------------------
372 class ASCIIHexStream: public FilterStream {
375 ASCIIHexStream(Stream *strA);
376 virtual ~ASCIIHexStream();
377 virtual StreamKind getKind() { return strASCIIHex; }
378 virtual void reset();
379 virtual int getChar()
380 { int c = lookChar(); buf = EOF; return c; }
381 virtual int lookChar();
382 virtual GString *getPSFilter(int psLevel, char *indent);
383 virtual GBool isBinary(GBool last = gTrue);
391 //------------------------------------------------------------------------
393 //------------------------------------------------------------------------
395 class ASCII85Stream: public FilterStream {
398 ASCII85Stream(Stream *strA);
399 virtual ~ASCII85Stream();
400 virtual StreamKind getKind() { return strASCII85; }
401 virtual void reset();
402 virtual int getChar()
403 { int ch = lookChar(); ++index; return ch; }
404 virtual int lookChar();
405 virtual GString *getPSFilter(int psLevel, char *indent);
406 virtual GBool isBinary(GBool last = gTrue);
416 //------------------------------------------------------------------------
418 //------------------------------------------------------------------------
420 class LZWStream: public FilterStream {
423 LZWStream(Stream *strA, int predictor, int columns, int colors,
424 int bits, int earlyA);
425 virtual ~LZWStream();
426 virtual StreamKind getKind() { return strLZW; }
427 virtual void reset();
428 virtual int getChar();
429 virtual int lookChar();
430 virtual int getRawChar();
431 virtual GString *getPSFilter(int psLevel, char *indent);
432 virtual GBool isBinary(GBool last = gTrue);
436 StreamPredictor *pred; // predictor
437 int early; // early parameter
438 GBool eof; // true if at eof
439 int inputBuf; // input buffer
440 int inputBits; // number of bits in input buffer
441 struct { // decoding table
446 int nextCode; // next code to be used
447 int nextBits; // number of bits in next code word
448 int prevCode; // previous code used in stream
449 int newChar; // next char to be added to table
450 Guchar seqBuf[4097]; // buffer for current sequence
451 int seqLength; // length of current sequence
452 int seqIndex; // index into current sequence
453 GBool first; // first code after a table clear
455 GBool processNextCode();
460 //------------------------------------------------------------------------
462 //------------------------------------------------------------------------
464 class RunLengthStream: public FilterStream {
467 RunLengthStream(Stream *strA);
468 virtual ~RunLengthStream();
469 virtual StreamKind getKind() { return strRunLength; }
470 virtual void reset();
471 virtual int getChar()
472 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
473 virtual int lookChar()
474 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
475 virtual GString *getPSFilter(int psLevel, char *indent);
476 virtual GBool isBinary(GBool last = gTrue);
480 char buf[128]; // buffer
481 char *bufPtr; // next char to read
482 char *bufEnd; // end of buffer
488 //------------------------------------------------------------------------
490 //------------------------------------------------------------------------
492 struct CCITTCodeTable;
494 class CCITTFaxStream: public FilterStream {
497 CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA,
498 GBool byteAlignA, int columnsA, int rowsA,
499 GBool endOfBlockA, GBool blackA);
500 virtual ~CCITTFaxStream();
501 virtual StreamKind getKind() { return strCCITTFax; }
502 virtual void reset();
503 virtual int getChar()
504 { int c = lookChar(); buf = EOF; return c; }
505 virtual int lookChar();
506 virtual GString *getPSFilter(int psLevel, char *indent);
507 virtual GBool isBinary(GBool last = gTrue);
511 int encoding; // 'K' parameter
512 GBool endOfLine; // 'EndOfLine' parameter
513 GBool byteAlign; // 'EncodedByteAlign' parameter
514 int columns; // 'Columns' parameter
515 int rows; // 'Rows' parameter
516 GBool endOfBlock; // 'EndOfBlock' parameter
517 GBool black; // 'BlackIs1' parameter
518 GBool eof; // true if at eof
519 GBool nextLine2D; // true if next line uses 2D encoding
520 int row; // current row
521 int inputBuf; // input buffer
522 int inputBits; // number of bits in input buffer
523 short *refLine; // reference line changing elements
524 int b1; // index into refLine
525 short *codingLine; // coding line changing elements
526 int a0; // index into codingLine
527 int outputBits; // remaining ouput bits
528 int buf; // character buffer
530 short getTwoDimCode();
531 short getWhiteCode();
532 short getBlackCode();
533 short lookBits(int n);
534 void eatBits(int n) { inputBits -= n; }
537 //------------------------------------------------------------------------
539 //------------------------------------------------------------------------
541 // DCT component info
543 int id; // component ID
544 int hSample, vSample; // horiz/vert sampling resolutions
545 int quantTable; // quantization table number
546 int prevDC; // DC coefficient accumulator
550 GBool comp[4]; // comp[i] is set if component i is
551 // included in this scan
552 int numComps; // number of components in the scan
553 int dcHuffTable[4]; // DC Huffman table numbers
554 int acHuffTable[4]; // AC Huffman table numbers
555 int firstCoeff, lastCoeff; // first and last DCT coefficient
556 int ah, al; // successive approximation parameters
559 // DCT Huffman decoding table
560 struct DCTHuffTable {
561 Guchar firstSym[17]; // first symbol for this bit length
562 Gushort firstCode[17]; // first code for this bit length
563 Gushort numCodes[17]; // number of codes of this bit length
564 Guchar sym[256]; // symbols
567 class DCTStream: public FilterStream {
570 DCTStream(Stream *strA);
571 virtual ~DCTStream();
572 virtual StreamKind getKind() { return strDCT; }
573 virtual void reset();
574 virtual int getChar();
575 virtual int lookChar();
576 virtual GString *getPSFilter(int psLevel, char *indent);
577 virtual GBool isBinary(GBool last = gTrue);
578 Stream *getRawStream() { return str; }
582 GBool progressive; // set if in progressive mode
583 GBool interleaved; // set if in interleaved mode
584 int width, height; // image size
585 int mcuWidth, mcuHeight; // size of min coding unit, in data units
586 int bufWidth, bufHeight; // frameBuf size
587 DCTCompInfo compInfo[4]; // info for each component
588 DCTScanInfo scanInfo; // info for the current scan
589 int numComps; // number of components in image
590 int colorXform; // need YCbCr-to-RGB transform?
591 GBool gotJFIFMarker; // set if APP0 JFIF marker was present
592 GBool gotAdobeMarker; // set if APP14 Adobe marker was present
593 int restartInterval; // restart interval, in MCUs
594 Guchar quantTables[4][64]; // quantization tables
595 int numQuantTables; // number of quantization tables
596 DCTHuffTable dcHuffTables[4]; // DC Huffman tables
597 DCTHuffTable acHuffTables[4]; // AC Huffman tables
598 int numDCHuffTables; // number of DC Huffman tables
599 int numACHuffTables; // number of AC Huffman tables
600 Guchar *rowBuf[4][32]; // buffer for one MCU (non-progressive mode)
601 int *frameBuf[4]; // buffer for frame (progressive mode)
602 int comp, x, y, dy; // current position within image/MCU
603 int restartCtr; // MCUs left until restart
604 int restartMarker; // next restart marker
605 int eobRun; // number of EOBs left in the current run
606 int inputBuf; // input buffer for variable length codes
607 int inputBits; // number of valid bits in input buffer
612 GBool readDataUnit(DCTHuffTable *dcHuffTable,
613 DCTHuffTable *acHuffTable,
614 int *prevDC, int data[64]);
615 GBool readProgressiveDataUnit(DCTHuffTable *dcHuffTable,
616 DCTHuffTable *acHuffTable,
617 int *prevDC, int data[64]);
619 void transformDataUnit(Guchar *quantTable,
620 int dataIn[64], Guchar dataOut[64]);
621 int readHuffSym(DCTHuffTable *table);
622 int readAmp(int size);
625 GBool readBaselineSOF();
626 GBool readProgressiveSOF();
627 GBool readScanInfo();
628 GBool readQuantTables();
629 GBool readHuffmanTables();
630 GBool readRestartInterval();
631 GBool readJFIFMarker();
632 GBool readAdobeMarker();
638 //------------------------------------------------------------------------
640 //------------------------------------------------------------------------
642 #define flateWindow 32768 // buffer size
643 #define flateMask (flateWindow-1)
644 #define flateMaxHuffman 15 // max Huffman code length
645 #define flateMaxCodeLenCodes 19 // max # code length codes
646 #define flateMaxLitCodes 288 // max # literal codes
647 #define flateMaxDistCodes 30 // max # distance codes
649 // Huffman code table entry
651 Gushort len; // code length, in bits
652 Gushort val; // value represented by this code
655 struct FlateHuffmanTab {
660 // Decoding info for length and distance code words
662 int bits; // # extra bits
663 int first; // first length/distance
666 class FlateStream: public FilterStream {
669 FlateStream(Stream *strA, int predictor, int columns,
670 int colors, int bits);
671 virtual ~FlateStream();
672 virtual StreamKind getKind() { return strFlate; }
673 virtual void reset();
674 virtual int getChar();
675 virtual int lookChar();
676 virtual int getRawChar();
677 virtual GString *getPSFilter(int psLevel, char *indent);
678 virtual GBool isBinary(GBool last = gTrue);
682 StreamPredictor *pred; // predictor
683 Guchar buf[flateWindow]; // output data buffer
684 int index; // current index into output buffer
685 int remain; // number valid bytes in output buffer
686 int codeBuf; // input buffer
687 int codeSize; // number of bits in input buffer
688 int // literal and distance code lengths
689 codeLengths[flateMaxLitCodes + flateMaxDistCodes];
690 FlateHuffmanTab litCodeTab; // literal code table
691 FlateHuffmanTab distCodeTab; // distance code table
692 GBool compressedBlock; // set if reading a compressed block
693 int blockLen; // remaining length of uncompressed block
694 GBool endOfBlock; // set when end of block is reached
695 GBool eof; // set when end of stream is reached
697 static int // code length code reordering
698 codeLenCodeMap[flateMaxCodeLenCodes];
699 static FlateDecode // length decoding info
700 lengthDecode[flateMaxLitCodes-257];
701 static FlateDecode // distance decoding info
702 distDecode[flateMaxDistCodes];
706 void loadFixedCodes();
707 GBool readDynamicCodes();
708 void compHuffmanCodes(int *lengths, int n, FlateHuffmanTab *tab);
709 int getHuffmanCodeWord(FlateHuffmanTab *tab);
710 int getCodeWord(int bits);
713 //------------------------------------------------------------------------
715 //------------------------------------------------------------------------
717 class EOFStream: public FilterStream {
720 EOFStream(Stream *strA);
721 virtual ~EOFStream();
722 virtual StreamKind getKind() { return strWeird; }
723 virtual void reset() {}
724 virtual int getChar() { return EOF; }
725 virtual int lookChar() { return EOF; }
726 virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; }
727 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
730 //------------------------------------------------------------------------
731 // FixedLengthEncoder
732 //------------------------------------------------------------------------
734 class FixedLengthEncoder: public FilterStream {
737 FixedLengthEncoder(Stream *strA, int lengthA);
738 ~FixedLengthEncoder();
739 virtual StreamKind getKind() { return strWeird; }
740 virtual void reset();
741 virtual int getChar();
742 virtual int lookChar();
743 virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; }
744 virtual GBool isBinary(GBool last = gTrue);
745 virtual GBool isEncoder() { return gTrue; }
753 //------------------------------------------------------------------------
755 //------------------------------------------------------------------------
757 class ASCIIHexEncoder: public FilterStream {
760 ASCIIHexEncoder(Stream *strA);
761 virtual ~ASCIIHexEncoder();
762 virtual StreamKind getKind() { return strWeird; }
763 virtual void reset();
764 virtual int getChar()
765 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
766 virtual int lookChar()
767 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
768 virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; }
769 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
770 virtual GBool isEncoder() { return gTrue; }
783 //------------------------------------------------------------------------
785 //------------------------------------------------------------------------
787 class ASCII85Encoder: public FilterStream {
790 ASCII85Encoder(Stream *strA);
791 virtual ~ASCII85Encoder();
792 virtual StreamKind getKind() { return strWeird; }
793 virtual void reset();
794 virtual int getChar()
795 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
796 virtual int lookChar()
797 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
798 virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; }
799 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
800 virtual GBool isEncoder() { return gTrue; }
813 //------------------------------------------------------------------------
815 //------------------------------------------------------------------------
817 class RunLengthEncoder: public FilterStream {
820 RunLengthEncoder(Stream *strA);
821 virtual ~RunLengthEncoder();
822 virtual StreamKind getKind() { return strWeird; }
823 virtual void reset();
824 virtual int getChar()
825 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
826 virtual int lookChar()
827 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
828 virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; }
829 virtual GBool isBinary(GBool last = gTrue) { return gTrue; }
830 virtual GBool isEncoder() { return gTrue; }