1 //========================================================================
5 // Copyright 1996-2003 Glyph & Cog, LLC
7 //========================================================================
14 #ifdef USE_GCC_PRAGMAS
27 //------------------------------------------------------------------------
39 strWeird // internal-use stream types
42 //------------------------------------------------------------------------
43 // Stream (base class)
44 //------------------------------------------------------------------------
55 // Reference counting.
56 int incRef() { return ++ref; }
57 int decRef() { return --ref; }
59 // Get kind of stream.
60 virtual StreamKind getKind() = 0;
62 // Reset stream to beginning.
63 virtual void reset() = 0;
65 // Close down the stream.
68 // Get next char from stream.
69 virtual int getChar() = 0;
71 // Peek at next char in stream.
72 virtual int lookChar() = 0;
74 // Get next char from stream without using the predictor.
75 // This is only used by StreamPredictor.
76 virtual int getRawChar();
78 // Get next line from stream.
79 virtual char *getLine(char *buf, int size);
81 // Get current position in file.
82 virtual int getPos() = 0;
84 // Go to a position in the stream. If <dir> is negative, the
85 // position is from the end of the file; otherwise the position is
86 // from the start of the file.
87 virtual void setPos(Guint pos, int dir = 0) = 0;
89 // Get PostScript command for the filter(s).
90 virtual GString *getPSFilter(int psLevel, char *indent);
92 // Does this stream type potentially contain non-printable chars?
93 virtual GBool isBinary(GBool last = gTrue) = 0;
95 // Get the BaseStream or EmbedStream of this stream.
96 virtual BaseStream *getBaseStream() = 0;
98 // Get the dictionary associated with this stream.
99 virtual Dict *getDict() = 0;
101 // Is this an encoding filter?
102 virtual GBool isEncoder() { return gFalse; }
104 // Add filters to this stream according to the parameters in <dict>.
105 // Returns the new stream.
106 Stream *addFilters(Object *dict);
108 // Tell this stream to ignore any length limitation -- this only
109 // applies to BaseStream subclasses, and is used as a hack to work
110 // around broken PDF files with incorrect stream lengths.
111 virtual void ignoreLength() {}
115 Stream *makeFilter(char *name, Stream *str, Object *params);
117 int ref; // reference count
120 //------------------------------------------------------------------------
123 // This is the base class for all streams that read directly from a file.
124 //------------------------------------------------------------------------
126 class BaseStream: public Stream {
129 BaseStream(Object *dictA);
130 virtual ~BaseStream();
131 virtual Stream *makeSubStream(Guint start, GBool limited,
132 Guint length, Object *dict) = 0;
133 virtual void setPos(Guint pos, int dir = 0) = 0;
134 virtual BaseStream *getBaseStream() { return this; }
135 virtual Dict *getDict() { return dict.getDict(); }
137 // Get/set position of first byte of stream within the file.
138 virtual Guint getStart() = 0;
139 virtual void moveStart(int delta) = 0;
141 #ifndef NO_DECRYPTION
142 // Set decryption for this stream.
143 virtual void doDecryption(Guchar *fileKey, int keyLength,
144 int objNum, int objGen);
147 #ifndef NO_DECRYPTION
158 //------------------------------------------------------------------------
161 // This is the base class for all streams that filter another stream.
162 //------------------------------------------------------------------------
164 class FilterStream: public Stream {
167 FilterStream(Stream *strA);
168 virtual ~FilterStream();
169 virtual void close();
170 virtual int getPos() { return str->getPos(); }
171 virtual void setPos(Guint pos, int dir = 0);
172 virtual BaseStream *getBaseStream() { return str->getBaseStream(); }
173 virtual Dict *getDict() { return str->getDict(); }
174 virtual void ignoreLength() { str->ignoreLength(); }
181 //------------------------------------------------------------------------
183 //------------------------------------------------------------------------
188 // Create an image stream object for an image with the specified
189 // parameters. Note that these are the actual image parameters,
190 // which may be different from the predictor parameters.
191 ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA);
198 // Gets the next pixel from the stream. <pix> should be able to hold
199 // at least nComps elements. Returns false at end of file.
200 GBool getPixel(Guchar *pix);
202 // Returns a pointer to the next line of pixels. Returns NULL at
206 // Skip an entire line from the image.
211 Stream *str; // base stream
212 int width; // pixels per line
213 int nComps; // components per pixel
214 int nBits; // bits per component
215 int nVals; // components per line
216 Guchar *imgLine; // line buffer
217 int imgIdx; // current index in imgLine
220 //------------------------------------------------------------------------
222 //------------------------------------------------------------------------
224 class StreamPredictor {
227 // Create a predictor object. Note that the parameters are for the
228 // predictor, and may not match the actual image parameters.
229 StreamPredictor(Stream *strA, int predictorA,
230 int widthA, int nCompsA, int nBitsA);
241 Stream *str; // base stream
242 int predictor; // predictor
243 int width; // pixels per line
244 int nComps; // components per pixel
245 int nBits; // bits per component
246 int nVals; // components per line
247 int pixBytes; // bytes per pixel
248 int rowBytes; // bytes per line
249 Guchar *predLine; // line buffer
250 int predIdx; // current index in predLine
253 //------------------------------------------------------------------------
255 //------------------------------------------------------------------------
257 #define fileStreamBufSize 256
259 class FileStream: public BaseStream {
262 FileStream(FILE *fA, Guint startA, GBool limitedA,
263 Guint lengthA, Object *dictA);
264 virtual ~FileStream();
265 virtual Stream *makeSubStream(Guint startA, GBool limitedA,
266 Guint lengthA, Object *dictA);
267 virtual StreamKind getKind() { return strFile; }
268 virtual void reset();
269 virtual void close();
270 virtual int getChar()
271 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
272 virtual int lookChar()
273 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
274 virtual int getPos() { return bufPos + (bufPtr - buf); }
275 virtual void setPos(Guint pos, int dir = 0);
276 virtual GBool isBinary(GBool last = gTrue) { return last; }
277 virtual void ignoreLength() { limited = gFalse; }
278 virtual Guint getStart() { return start; }
279 virtual void moveStart(int delta);
289 char buf[fileStreamBufSize];
297 //------------------------------------------------------------------------
299 //------------------------------------------------------------------------
301 class MemStream: public BaseStream {
304 MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA);
305 virtual ~MemStream();
306 virtual Stream *makeSubStream(Guint start, GBool limited,
307 Guint lengthA, Object *dictA);
308 virtual StreamKind getKind() { return strWeird; }
309 virtual void reset();
310 virtual void close();
311 virtual int getChar()
312 { return (bufPtr < bufEnd) ? (*bufPtr++ & 0xff) : EOF; }
313 virtual int lookChar()
314 { return (bufPtr < bufEnd) ? (*bufPtr & 0xff) : EOF; }
315 virtual int getPos() { return (int)(bufPtr - buf); }
316 virtual void setPos(Guint pos, int dir = 0);
317 virtual GBool isBinary(GBool last = gTrue) { return last; }
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);
349 virtual ~EmbedStream();
350 virtual Stream *makeSubStream(Guint start, GBool limited,
351 Guint length, Object *dictA);
352 virtual StreamKind getKind() { return str->getKind(); }
353 virtual void reset() {}
354 virtual int getChar() { return str->getChar(); }
355 virtual int lookChar() { return str->lookChar(); }
356 virtual int getPos() { return str->getPos(); }
357 virtual void setPos(Guint pos, int dir = 0);
358 virtual GBool isBinary(GBool last = gTrue) { return last; }
359 virtual Guint getStart();
360 virtual void moveStart(int delta);
367 //------------------------------------------------------------------------
369 //------------------------------------------------------------------------
371 class ASCIIHexStream: public FilterStream {
374 ASCIIHexStream(Stream *strA);
375 virtual ~ASCIIHexStream();
376 virtual StreamKind getKind() { return strASCIIHex; }
377 virtual void reset();
378 virtual int getChar()
379 { int c = lookChar(); buf = EOF; return c; }
380 virtual int lookChar();
381 virtual GString *getPSFilter(int psLevel, char *indent);
382 virtual GBool isBinary(GBool last = gTrue);
390 //------------------------------------------------------------------------
392 //------------------------------------------------------------------------
394 class ASCII85Stream: public FilterStream {
397 ASCII85Stream(Stream *strA);
398 virtual ~ASCII85Stream();
399 virtual StreamKind getKind() { return strASCII85; }
400 virtual void reset();
401 virtual int getChar()
402 { int ch = lookChar(); ++index; return ch; }
403 virtual int lookChar();
404 virtual GString *getPSFilter(int psLevel, char *indent);
405 virtual GBool isBinary(GBool last = gTrue);
415 //------------------------------------------------------------------------
417 //------------------------------------------------------------------------
419 class LZWStream: public FilterStream {
422 LZWStream(Stream *strA, int predictor, int columns, int colors,
423 int bits, int earlyA);
424 virtual ~LZWStream();
425 virtual StreamKind getKind() { return strLZW; }
426 virtual void reset();
427 virtual int getChar();
428 virtual int lookChar();
429 virtual int getRawChar();
430 virtual GString *getPSFilter(int psLevel, char *indent);
431 virtual GBool isBinary(GBool last = gTrue);
435 StreamPredictor *pred; // predictor
436 int early; // early parameter
437 GBool eof; // true if at eof
438 int inputBuf; // input buffer
439 int inputBits; // number of bits in input buffer
440 struct { // decoding table
445 int nextCode; // next code to be used
446 int nextBits; // number of bits in next code word
447 int prevCode; // previous code used in stream
448 int newChar; // next char to be added to table
449 Guchar seqBuf[4097]; // buffer for current sequence
450 int seqLength; // length of current sequence
451 int seqIndex; // index into current sequence
452 GBool first; // first code after a table clear
454 GBool processNextCode();
459 //------------------------------------------------------------------------
461 //------------------------------------------------------------------------
463 class RunLengthStream: public FilterStream {
466 RunLengthStream(Stream *strA);
467 virtual ~RunLengthStream();
468 virtual StreamKind getKind() { return strRunLength; }
469 virtual void reset();
470 virtual int getChar()
471 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
472 virtual int lookChar()
473 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
474 virtual GString *getPSFilter(int psLevel, char *indent);
475 virtual GBool isBinary(GBool last = gTrue);
479 char buf[128]; // buffer
480 char *bufPtr; // next char to read
481 char *bufEnd; // end of buffer
487 //------------------------------------------------------------------------
489 //------------------------------------------------------------------------
491 struct CCITTCodeTable;
493 class CCITTFaxStream: public FilterStream {
496 CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA,
497 GBool byteAlignA, int columnsA, int rowsA,
498 GBool endOfBlockA, GBool blackA);
499 virtual ~CCITTFaxStream();
500 virtual StreamKind getKind() { return strCCITTFax; }
501 virtual void reset();
502 virtual int getChar()
503 { int c = lookChar(); buf = EOF; return c; }
504 virtual int lookChar();
505 virtual GString *getPSFilter(int psLevel, char *indent);
506 virtual GBool isBinary(GBool last = gTrue);
510 int encoding; // 'K' parameter
511 GBool endOfLine; // 'EndOfLine' parameter
512 GBool byteAlign; // 'EncodedByteAlign' parameter
513 int columns; // 'Columns' parameter
514 int rows; // 'Rows' parameter
515 GBool endOfBlock; // 'EndOfBlock' parameter
516 GBool black; // 'BlackIs1' parameter
517 GBool eof; // true if at eof
518 GBool nextLine2D; // true if next line uses 2D encoding
519 int row; // current row
520 int inputBuf; // input buffer
521 int inputBits; // number of bits in input buffer
522 short *refLine; // reference line changing elements
523 int b1; // index into refLine
524 short *codingLine; // coding line changing elements
525 int a0; // index into codingLine
526 int outputBits; // remaining ouput bits
527 int buf; // character buffer
529 short getTwoDimCode();
530 short getWhiteCode();
531 short getBlackCode();
532 short lookBits(int n);
533 void eatBits(int n) { inputBits -= n; }
536 //------------------------------------------------------------------------
538 //------------------------------------------------------------------------
540 // DCT component info
542 int id; // component ID
543 int hSample, vSample; // horiz/vert sampling resolutions
544 int quantTable; // quantization table number
545 int prevDC; // DC coefficient accumulator
549 GBool comp[4]; // comp[i] is set if component i is
550 // included in this scan
551 int numComps; // number of components in the scan
552 int dcHuffTable[4]; // DC Huffman table numbers
553 int acHuffTable[4]; // AC Huffman table numbers
554 int firstCoeff, lastCoeff; // first and last DCT coefficient
555 int ah, al; // successive approximation parameters
558 // DCT Huffman decoding table
559 struct DCTHuffTable {
560 Guchar firstSym[17]; // first symbol for this bit length
561 Gushort firstCode[17]; // first code for this bit length
562 Gushort numCodes[17]; // number of codes of this bit length
563 Guchar sym[256]; // symbols
566 class DCTStream: public FilterStream {
569 DCTStream(Stream *strA);
570 virtual ~DCTStream();
571 virtual StreamKind getKind() { return strDCT; }
572 virtual void reset();
573 virtual int getChar();
574 virtual int lookChar();
575 virtual GString *getPSFilter(int psLevel, char *indent);
576 virtual GBool isBinary(GBool last = gTrue);
577 Stream *getRawStream() { return str; }
581 GBool progressive; // set if in progressive mode
582 GBool interleaved; // set if in interleaved mode
583 int width, height; // image size
584 int mcuWidth, mcuHeight; // size of min coding unit, in data units
585 int bufWidth, bufHeight; // frameBuf size
586 DCTCompInfo compInfo[4]; // info for each component
587 DCTScanInfo scanInfo; // info for the current scan
588 int numComps; // number of components in image
589 int colorXform; // need YCbCr-to-RGB transform?
590 GBool gotJFIFMarker; // set if APP0 JFIF marker was present
591 GBool gotAdobeMarker; // set if APP14 Adobe marker was present
592 int restartInterval; // restart interval, in MCUs
593 Guchar quantTables[4][64]; // quantization tables
594 int numQuantTables; // number of quantization tables
595 DCTHuffTable dcHuffTables[4]; // DC Huffman tables
596 DCTHuffTable acHuffTables[4]; // AC Huffman tables
597 int numDCHuffTables; // number of DC Huffman tables
598 int numACHuffTables; // number of AC Huffman tables
599 Guchar *rowBuf[4][32]; // buffer for one MCU (non-progressive mode)
600 int *frameBuf[4]; // buffer for frame (progressive mode)
601 int comp, x, y, dy; // current position within image/MCU
602 int restartCtr; // MCUs left until restart
603 int restartMarker; // next restart marker
604 int eobRun; // number of EOBs left in the current run
605 int inputBuf; // input buffer for variable length codes
606 int inputBits; // number of valid bits in input buffer
611 GBool readDataUnit(DCTHuffTable *dcHuffTable,
612 DCTHuffTable *acHuffTable,
613 int *prevDC, int data[64]);
614 GBool readProgressiveDataUnit(DCTHuffTable *dcHuffTable,
615 DCTHuffTable *acHuffTable,
616 int *prevDC, int data[64]);
618 void transformDataUnit(Guchar *quantTable,
619 int dataIn[64], Guchar dataOut[64]);
620 int readHuffSym(DCTHuffTable *table);
621 int readAmp(int size);
624 GBool readBaselineSOF();
625 GBool readProgressiveSOF();
626 GBool readScanInfo();
627 GBool readQuantTables();
628 GBool readHuffmanTables();
629 GBool readRestartInterval();
630 GBool readJFIFMarker();
631 GBool readAdobeMarker();
637 //------------------------------------------------------------------------
639 //------------------------------------------------------------------------
641 #define flateWindow 32768 // buffer size
642 #define flateMask (flateWindow-1)
643 #define flateMaxHuffman 15 // max Huffman code length
644 #define flateMaxCodeLenCodes 19 // max # code length codes
645 #define flateMaxLitCodes 288 // max # literal codes
646 #define flateMaxDistCodes 30 // max # distance codes
648 // Huffman code table entry
650 Gushort len; // code length, in bits
651 Gushort val; // value represented by this code
654 struct FlateHuffmanTab {
659 // Decoding info for length and distance code words
661 int bits; // # extra bits
662 int first; // first length/distance
665 class FlateStream: public FilterStream {
668 FlateStream(Stream *strA, int predictor, int columns,
669 int colors, int bits);
670 virtual ~FlateStream();
671 virtual StreamKind getKind() { return strFlate; }
672 virtual void reset();
673 virtual int getChar();
674 virtual int lookChar();
675 virtual int getRawChar();
676 virtual GString *getPSFilter(int psLevel, char *indent);
677 virtual GBool isBinary(GBool last = gTrue);
681 StreamPredictor *pred; // predictor
682 Guchar buf[flateWindow]; // output data buffer
683 int index; // current index into output buffer
684 int remain; // number valid bytes in output buffer
685 int codeBuf; // input buffer
686 int codeSize; // number of bits in input buffer
687 int // literal and distance code lengths
688 codeLengths[flateMaxLitCodes + flateMaxDistCodes];
689 FlateHuffmanTab litCodeTab; // literal code table
690 FlateHuffmanTab distCodeTab; // distance code table
691 GBool compressedBlock; // set if reading a compressed block
692 int blockLen; // remaining length of uncompressed block
693 GBool endOfBlock; // set when end of block is reached
694 GBool eof; // set when end of stream is reached
696 static int // code length code reordering
697 codeLenCodeMap[flateMaxCodeLenCodes];
698 static FlateDecode // length decoding info
699 lengthDecode[flateMaxLitCodes-257];
700 static FlateDecode // distance decoding info
701 distDecode[flateMaxDistCodes];
705 void loadFixedCodes();
706 GBool readDynamicCodes();
707 void compHuffmanCodes(int *lengths, int n, FlateHuffmanTab *tab);
708 int getHuffmanCodeWord(FlateHuffmanTab *tab);
709 int getCodeWord(int bits);
712 //------------------------------------------------------------------------
714 //------------------------------------------------------------------------
716 class EOFStream: public FilterStream {
719 EOFStream(Stream *strA);
720 virtual ~EOFStream();
721 virtual StreamKind getKind() { return strWeird; }
722 virtual void reset() {}
723 virtual int getChar() { return EOF; }
724 virtual int lookChar() { return EOF; }
725 virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; }
726 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
729 //------------------------------------------------------------------------
730 // FixedLengthEncoder
731 //------------------------------------------------------------------------
733 class FixedLengthEncoder: public FilterStream {
736 FixedLengthEncoder(Stream *strA, int lengthA);
737 ~FixedLengthEncoder();
738 virtual StreamKind getKind() { return strWeird; }
739 virtual void reset();
740 virtual int getChar();
741 virtual int lookChar();
742 virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; }
743 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
744 virtual GBool isEncoder() { return gTrue; }
752 //------------------------------------------------------------------------
754 //------------------------------------------------------------------------
756 class ASCIIHexEncoder: public FilterStream {
759 ASCIIHexEncoder(Stream *strA);
760 virtual ~ASCIIHexEncoder();
761 virtual StreamKind getKind() { return strWeird; }
762 virtual void reset();
763 virtual int getChar()
764 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
765 virtual int lookChar()
766 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
767 virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; }
768 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
769 virtual GBool isEncoder() { return gTrue; }
782 //------------------------------------------------------------------------
784 //------------------------------------------------------------------------
786 class ASCII85Encoder: public FilterStream {
789 ASCII85Encoder(Stream *strA);
790 virtual ~ASCII85Encoder();
791 virtual StreamKind getKind() { return strWeird; }
792 virtual void reset();
793 virtual int getChar()
794 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
795 virtual int lookChar()
796 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
797 virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; }
798 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
799 virtual GBool isEncoder() { return gTrue; }
812 //------------------------------------------------------------------------
814 //------------------------------------------------------------------------
816 class RunLengthEncoder: public FilterStream {
819 RunLengthEncoder(Stream *strA);
820 virtual ~RunLengthEncoder();
821 virtual StreamKind getKind() { return strWeird; }
822 virtual void reset();
823 virtual int getChar()
824 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
825 virtual int lookChar()
826 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
827 virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; }
828 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
829 virtual GBool isEncoder() { return gTrue; }