1 //========================================================================
5 // Copyright 1996-2003 Glyph & Cog, LLC
7 //========================================================================
14 #ifdef USE_GCC_PRAGMAS
24 //------------------------------------------------------------------------
37 strWeird
// internal-use stream types
40 enum StreamColorSpaceMode
{
47 //------------------------------------------------------------------------
49 // This is in Stream.h instead of Decrypt.h to avoid really annoying
50 // include file dependency loops.
56 //------------------------------------------------------------------------
57 // Stream (base class)
58 //------------------------------------------------------------------------
69 // Reference counting.
70 int incRef() { return ++ref
; }
71 int decRef() { return --ref
; }
73 // Get kind of stream.
74 virtual StreamKind
getKind() = 0;
76 // Reset stream to beginning.
77 virtual void reset() = 0;
79 // Close down the stream.
82 // Get next char from stream.
83 virtual int getChar() = 0;
85 // Peek at next char in stream.
86 virtual int lookChar() = 0;
88 // Get next char from stream without using the predictor.
89 // This is only used by StreamPredictor.
90 virtual int getRawChar();
92 // Get next line from stream.
93 virtual char *getLine(char *buf
, int size
);
95 // Get current position in file.
96 virtual int getPos() = 0;
98 // Go to a position in the stream. If <dir> is negative, the
99 // position is from the end of the file; otherwise the position is
100 // from the start of the file.
101 virtual void setPos(Guint pos
, int dir
= 0) = 0;
103 // Get PostScript command for the filter(s).
104 virtual GString
*getPSFilter(int psLevel
, char *indent
);
106 // Does this stream type potentially contain non-printable chars?
107 virtual GBool
isBinary(GBool last
= gTrue
) = 0;
109 // Get the BaseStream of this stream.
110 virtual BaseStream
*getBaseStream() = 0;
112 // Get the stream after the last decoder (this may be a BaseStream
113 // or a DecryptStream).
114 virtual Stream
*getUndecodedStream() = 0;
116 // Get the dictionary associated with this stream.
117 virtual Dict
*getDict() = 0;
119 // Is this an encoding filter?
120 virtual GBool
isEncoder() { return gFalse
; }
122 // Get image parameters which are defined by the stream contents.
123 virtual void getImageParams(int *bitsPerComponent
,
124 StreamColorSpaceMode
*csMode
) {}
126 // Return the next stream in the "stack".
127 virtual Stream
*getNextStream() { return NULL
; }
129 // Add filters to this stream according to the parameters in <dict>.
130 // Returns the new stream.
131 Stream
*addFilters(xObject
*dict
);
135 Stream
*makeFilter(char *name
, Stream
*str
, xObject
*params
);
137 int ref
; // reference count
140 //------------------------------------------------------------------------
143 // This is the base class for all streams that read directly from a file.
144 //------------------------------------------------------------------------
146 class BaseStream
: public Stream
{
149 BaseStream(xObject
*dictA
);
150 virtual ~BaseStream();
151 virtual Stream
*makeSubStream(Guint start
, GBool limited
,
152 Guint length
, xObject
*dict
) = 0;
153 virtual void setPos(Guint pos
, int dir
= 0) = 0;
154 virtual GBool
isBinary(GBool last
= gTrue
) { return last
; }
155 virtual BaseStream
*getBaseStream() { return this; }
156 virtual Stream
*getUndecodedStream() { return this; }
157 virtual Dict
*getDict() { return dict
.getDict(); }
158 virtual GString
*getFileName() { return NULL
; }
160 // Get/set position of first byte of stream within the file.
161 virtual Guint
getStart() = 0;
162 virtual void moveStart(int delta
) = 0;
169 //------------------------------------------------------------------------
172 // This is the base class for all streams that filter another stream.
173 //------------------------------------------------------------------------
175 class FilterStream
: public Stream
{
178 FilterStream(Stream
*strA
);
179 virtual ~FilterStream();
180 virtual void close();
181 virtual int getPos() { return str
->getPos(); }
182 virtual void setPos(Guint pos
, int dir
= 0);
183 virtual BaseStream
*getBaseStream() { return str
->getBaseStream(); }
184 virtual Stream
*getUndecodedStream() { return str
->getUndecodedStream(); }
185 virtual Dict
*getDict() { return str
->getDict(); }
186 virtual Stream
*getNextStream() { return str
; }
193 //------------------------------------------------------------------------
195 //------------------------------------------------------------------------
200 // Create an image stream xObject for an image with the specified
201 // parameters. Note that these are the actual image parameters,
202 // which may be different from the predictor parameters.
203 ImageStream(Stream
*strA
, int widthA
, int nCompsA
, int nBitsA
);
210 // Gets the next pixel from the stream. <pix> should be able to hold
211 // at least nComps elements. Returns false at end of file.
212 GBool
getPixel(Guchar
*pix
);
214 // Returns a pointer to the next line of pixels. Returns NULL at
218 // Skip an entire line from the image.
223 Stream
*str
; // base stream
224 int width
; // pixels per line
225 int nComps
; // components per pixel
226 int nBits
; // bits per component
227 int nVals
; // components per line
228 Guchar
*imgLine
; // line buffer
229 int imgIdx
; // current index in imgLine
232 //------------------------------------------------------------------------
234 //------------------------------------------------------------------------
236 class StreamPredictor
{
239 // Create a predictor xObject. Note that the parameters are for the
240 // predictor, and may not match the actual image parameters.
241 StreamPredictor(Stream
*strA
, int predictorA
,
242 int widthA
, int nCompsA
, int nBitsA
);
246 GBool
isOk() { return ok
; }
255 Stream
*str
; // base stream
256 int predictor
; // predictor
257 int width
; // pixels per line
258 int nComps
; // components per pixel
259 int nBits
; // bits per component
260 int nVals
; // components per line
261 int pixBytes
; // bytes per pixel
262 int rowBytes
; // bytes per line
263 Guchar
*predLine
; // line buffer
264 int predIdx
; // current index in predLine
268 //------------------------------------------------------------------------
270 //------------------------------------------------------------------------
272 #define fileStreamBufSize 256
274 class FileStream
: public BaseStream
{
277 FileStream(FILE *fA
, Guint startA
, GBool limitedA
,
278 Guint lengthA
, xObject
*dictA
);
279 virtual ~FileStream();
280 virtual Stream
*makeSubStream(Guint startA
, GBool limitedA
,
281 Guint lengthA
, xObject
*dictA
);
282 virtual StreamKind
getKind() { return strFile
; }
283 virtual void reset();
284 virtual void close();
285 virtual int getChar()
286 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
287 virtual int lookChar()
288 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
289 virtual int getPos() { return bufPos
+ (bufPtr
- buf
); }
290 virtual void setPos(Guint pos
, int dir
= 0);
291 virtual Guint
getStart() { return start
; }
292 virtual void moveStart(int delta
);
302 char buf
[fileStreamBufSize
];
310 //------------------------------------------------------------------------
312 //------------------------------------------------------------------------
314 class MemStream
: public BaseStream
{
317 MemStream(char *bufA
, Guint startA
, Guint lengthA
, xObject
*dictA
);
318 virtual ~MemStream();
319 virtual Stream
*makeSubStream(Guint start
, GBool limited
,
320 Guint lengthA
, xObject
*dictA
);
321 virtual StreamKind
getKind() { return strWeird
; }
322 virtual void reset();
323 virtual void close();
324 virtual int getChar()
325 { return (bufPtr
< bufEnd
) ? (*bufPtr
++ & 0xff) : EOF
; }
326 virtual int lookChar()
327 { return (bufPtr
< bufEnd
) ? (*bufPtr
& 0xff) : EOF
; }
328 virtual int getPos() { return (int)(bufPtr
- buf
); }
329 virtual void setPos(Guint pos
, int dir
= 0);
330 virtual Guint
getStart() { return start
; }
331 virtual void moveStart(int delta
);
343 //------------------------------------------------------------------------
346 // This is a special stream type used for embedded streams (inline
347 // images). It reads directly from the base stream -- after the
348 // EmbedStream is deleted, reads from the base stream will proceed where
349 // the BaseStream left off. Note that this is very different behavior
350 // that creating a new FileStream (using makeSubStream).
351 //------------------------------------------------------------------------
353 class EmbedStream
: public BaseStream
{
356 EmbedStream(Stream
*strA
, xObject
*dictA
, GBool limitedA
, Guint lengthA
);
357 virtual ~EmbedStream();
358 virtual Stream
*makeSubStream(Guint start
, GBool limitedA
,
359 Guint lengthA
, xObject
*dictA
);
360 virtual StreamKind
getKind() { return str
->getKind(); }
361 virtual void reset() {}
362 virtual int getChar();
363 virtual int lookChar();
364 virtual int getPos() { return str
->getPos(); }
365 virtual void setPos(Guint pos
, int dir
= 0);
366 virtual Guint
getStart();
367 virtual void moveStart(int delta
);
376 //------------------------------------------------------------------------
378 //------------------------------------------------------------------------
380 class ASCIIHexStream
: public FilterStream
{
383 ASCIIHexStream(Stream
*strA
);
384 virtual ~ASCIIHexStream();
385 virtual StreamKind
getKind() { return strASCIIHex
; }
386 virtual void reset();
387 virtual int getChar()
388 { int c
= lookChar(); buf
= EOF
; return c
; }
389 virtual int lookChar();
390 virtual GString
*getPSFilter(int psLevel
, char *indent
);
391 virtual GBool
isBinary(GBool last
= gTrue
);
399 //------------------------------------------------------------------------
401 //------------------------------------------------------------------------
403 class ASCII85Stream
: public FilterStream
{
406 ASCII85Stream(Stream
*strA
);
407 virtual ~ASCII85Stream();
408 virtual StreamKind
getKind() { return strASCII85
; }
409 virtual void reset();
410 virtual int getChar()
411 { int ch
= lookChar(); ++index
; return ch
; }
412 virtual int lookChar();
413 virtual GString
*getPSFilter(int psLevel
, char *indent
);
414 virtual GBool
isBinary(GBool last
= gTrue
);
424 //------------------------------------------------------------------------
426 //------------------------------------------------------------------------
428 class LZWStream
: public FilterStream
{
431 LZWStream(Stream
*strA
, int predictor
, int columns
, int colors
,
432 int bits
, int earlyA
);
433 virtual ~LZWStream();
434 virtual StreamKind
getKind() { return strLZW
; }
435 virtual void reset();
436 virtual int getChar();
437 virtual int lookChar();
438 virtual int getRawChar();
439 virtual GString
*getPSFilter(int psLevel
, char *indent
);
440 virtual GBool
isBinary(GBool last
= gTrue
);
444 StreamPredictor
*pred
; // predictor
445 int early
; // early parameter
446 GBool eof
; // true if at eof
447 int inputBuf
; // input buffer
448 int inputBits
; // number of bits in input buffer
449 struct { // decoding table
454 int nextCode
; // next code to be used
455 int nextBits
; // number of bits in next code word
456 int prevCode
; // previous code used in stream
457 int newChar
; // next char to be added to table
458 Guchar seqBuf
[4097]; // buffer for current sequence
459 int seqLength
; // length of current sequence
460 int seqIndex
; // index into current sequence
461 GBool first
; // first code after a table clear
463 GBool
processNextCode();
468 //------------------------------------------------------------------------
470 //------------------------------------------------------------------------
472 class RunLengthStream
: public FilterStream
{
475 RunLengthStream(Stream
*strA
);
476 virtual ~RunLengthStream();
477 virtual StreamKind
getKind() { return strRunLength
; }
478 virtual void reset();
479 virtual int getChar()
480 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
481 virtual int lookChar()
482 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
483 virtual GString
*getPSFilter(int psLevel
, char *indent
);
484 virtual GBool
isBinary(GBool last
= gTrue
);
488 char buf
[128]; // buffer
489 char *bufPtr
; // next char to read
490 char *bufEnd
; // end of buffer
496 //------------------------------------------------------------------------
498 //------------------------------------------------------------------------
500 struct CCITTCodeTable
;
502 class CCITTFaxStream
: public FilterStream
{
505 CCITTFaxStream(Stream
*strA
, int encodingA
, GBool endOfLineA
,
506 GBool byteAlignA
, int columnsA
, int rowsA
,
507 GBool endOfBlockA
, GBool blackA
);
508 virtual ~CCITTFaxStream();
509 virtual StreamKind
getKind() { return strCCITTFax
; }
510 virtual void reset();
511 virtual int getChar()
512 { int c
= lookChar(); buf
= EOF
; return c
; }
513 virtual int lookChar();
514 virtual GString
*getPSFilter(int psLevel
, char *indent
);
515 virtual GBool
isBinary(GBool last
= gTrue
);
519 int encoding
; // 'K' parameter
520 GBool endOfLine
; // 'EndOfLine' parameter
521 GBool byteAlign
; // 'EncodedByteAlign' parameter
522 int columns
; // 'Columns' parameter
523 int rows
; // 'Rows' parameter
524 GBool endOfBlock
; // 'EndOfBlock' parameter
525 GBool black
; // 'BlackIs1' parameter
526 GBool eof
; // true if at eof
527 GBool nextLine2D
; // true if next line uses 2D encoding
528 int row
; // current row
529 int inputBuf
; // input buffer
530 int inputBits
; // number of bits in input buffer
531 short *refLine
; // reference line changing elements
532 int b1
; // index into refLine
533 short *codingLine
; // coding line changing elements
534 int a0
; // index into codingLine
535 int outputBits
; // remaining ouput bits
536 int buf
; // character buffer
538 short getTwoDimCode();
539 short getWhiteCode();
540 short getBlackCode();
541 short lookBits(int n
);
542 void eatBits(int n
) { if ((inputBits
-= n
) < 0) inputBits
= 0; }
545 //------------------------------------------------------------------------
547 //------------------------------------------------------------------------
549 // DCT component info
551 int id
; // component ID
552 int hSample
, vSample
; // horiz/vert sampling resolutions
553 int quantTable
; // quantization table number
554 int prevDC
; // DC coefficient accumulator
558 GBool comp
[4]; // comp[i] is set if component i is
559 // included in this scan
560 int numComps
; // number of components in the scan
561 int dcHuffTable
[4]; // DC Huffman table numbers
562 int acHuffTable
[4]; // AC Huffman table numbers
563 int firstCoeff
, lastCoeff
; // first and last DCT coefficient
564 int ah
, al
; // successive approximation parameters
567 // DCT Huffman decoding table
568 struct DCTHuffTable
{
569 Guchar firstSym
[17]; // first symbol for this bit length
570 Gushort firstCode
[17]; // first code for this bit length
571 Gushort numCodes
[17]; // number of codes of this bit length
572 Guchar sym
[256]; // symbols
575 class DCTStream
: public FilterStream
{
578 DCTStream(Stream
*strA
, int colorXformA
);
579 virtual ~DCTStream();
580 virtual StreamKind
getKind() { return strDCT
; }
581 virtual void reset();
582 virtual void close();
583 virtual int getChar();
584 virtual int lookChar();
585 virtual GString
*getPSFilter(int psLevel
, char *indent
);
586 virtual GBool
isBinary(GBool last
= gTrue
);
587 Stream
*getRawStream() { return str
; }
591 GBool progressive
; // set if in progressive mode
592 GBool interleaved
; // set if in interleaved mode
593 int width
, height
; // image size
594 int mcuWidth
, mcuHeight
; // size of min coding unit, in data units
595 int bufWidth
, bufHeight
; // frameBuf size
596 DCTCompInfo compInfo
[4]; // info for each component
597 DCTScanInfo scanInfo
; // info for the current scan
598 int numComps
; // number of components in image
599 int colorXform
; // color transform: -1 = unspecified
601 // 1 = YUV/YUVK -> RGB/CMYK
602 GBool gotJFIFMarker
; // set if APP0 JFIF marker was present
603 GBool gotAdobeMarker
; // set if APP14 Adobe marker was present
604 int restartInterval
; // restart interval, in MCUs
605 Gushort quantTables
[4][64]; // quantization tables
606 int numQuantTables
; // number of quantization tables
607 DCTHuffTable dcHuffTables
[4]; // DC Huffman tables
608 DCTHuffTable acHuffTables
[4]; // AC Huffman tables
609 int numDCHuffTables
; // number of DC Huffman tables
610 int numACHuffTables
; // number of AC Huffman tables
611 Guchar
*rowBuf
[4][32]; // buffer for one MCU (non-progressive mode)
612 int *frameBuf
[4]; // buffer for frame (progressive mode)
613 int comp
, x
, y
, dy
; // current position within image/MCU
614 int restartCtr
; // MCUs left until restart
615 int restartMarker
; // next restart marker
616 int eobRun
; // number of EOBs left in the current run
617 int inputBuf
; // input buffer for variable length codes
618 int inputBits
; // number of valid bits in input buffer
623 GBool
readDataUnit(DCTHuffTable
*dcHuffTable
,
624 DCTHuffTable
*acHuffTable
,
625 int *prevDC
, int data
[64]);
626 GBool
readProgressiveDataUnit(DCTHuffTable
*dcHuffTable
,
627 DCTHuffTable
*acHuffTable
,
628 int *prevDC
, int data
[64]);
630 void transformDataUnit(Gushort
*quantTable
,
631 int dataIn
[64], Guchar dataOut
[64]);
632 int readHuffSym(DCTHuffTable
*table
);
633 int readAmp(int size
);
636 GBool
readBaselineSOF();
637 GBool
readProgressiveSOF();
638 GBool
readScanInfo();
639 GBool
readQuantTables();
640 GBool
readHuffmanTables();
641 GBool
readRestartInterval();
642 GBool
readJFIFMarker();
643 GBool
readAdobeMarker();
649 //------------------------------------------------------------------------
651 //------------------------------------------------------------------------
653 #define flateWindow 32768 // buffer size
654 #define flateMask (flateWindow-1)
655 #define flateMaxHuffman 15 // max Huffman code length
656 #define flateMaxCodeLenCodes 19 // max # code length codes
657 #define flateMaxLitCodes 288 // max # literal codes
658 #define flateMaxDistCodes 30 // max # distance codes
660 // Huffman code table entry
662 Gushort len
; // code length, in bits
663 Gushort val
; // value represented by this code
666 struct FlateHuffmanTab
{
671 // Decoding info for length and distance code words
673 int bits
; // # extra bits
674 int first
; // first length/distance
677 class FlateStream
: public FilterStream
{
680 FlateStream(Stream
*strA
, int predictor
, int columns
,
681 int colors
, int bits
);
682 virtual ~FlateStream();
683 virtual StreamKind
getKind() { return strFlate
; }
684 virtual void reset();
685 virtual int getChar();
686 virtual int lookChar();
687 virtual int getRawChar();
688 virtual GString
*getPSFilter(int psLevel
, char *indent
);
689 virtual GBool
isBinary(GBool last
= gTrue
);
693 StreamPredictor
*pred
; // predictor
694 Guchar buf
[flateWindow
]; // output data buffer
695 int index
; // current index into output buffer
696 int remain
; // number valid bytes in output buffer
697 int codeBuf
; // input buffer
698 int codeSize
; // number of bits in input buffer
699 int // literal and distance code lengths
700 codeLengths
[flateMaxLitCodes
+ flateMaxDistCodes
];
701 FlateHuffmanTab litCodeTab
; // literal code table
702 FlateHuffmanTab distCodeTab
; // distance code table
703 GBool compressedBlock
; // set if reading a compressed block
704 int blockLen
; // remaining length of uncompressed block
705 GBool endOfBlock
; // set when end of block is reached
706 GBool eof
; // set when end of stream is reached
708 static int // code length code reordering
709 codeLenCodeMap
[flateMaxCodeLenCodes
];
710 static FlateDecode
// length decoding info
711 lengthDecode
[flateMaxLitCodes
-257];
712 static FlateDecode
// distance decoding info
713 distDecode
[flateMaxDistCodes
];
714 static FlateHuffmanTab
// fixed literal code table
716 static FlateHuffmanTab
// fixed distance code table
721 void loadFixedCodes();
722 GBool
readDynamicCodes();
723 void compHuffmanCodes(int *lengths
, int n
, FlateHuffmanTab
*tab
);
724 int getHuffmanCodeWord(FlateHuffmanTab
*tab
);
725 int getCodeWord(int bits
);
728 //------------------------------------------------------------------------
730 //------------------------------------------------------------------------
732 class EOFStream
: public FilterStream
{
735 EOFStream(Stream
*strA
);
736 virtual ~EOFStream();
737 virtual StreamKind
getKind() { return strWeird
; }
738 virtual void reset() {}
739 virtual int getChar() { return EOF
; }
740 virtual int lookChar() { return EOF
; }
741 virtual GString
*getPSFilter(int psLevel
, char *indent
) { return NULL
; }
742 virtual GBool
isBinary(GBool last
= gTrue
) { return gFalse
; }
745 //------------------------------------------------------------------------
746 // FixedLengthEncoder
747 //------------------------------------------------------------------------
749 class FixedLengthEncoder
: public FilterStream
{
752 FixedLengthEncoder(Stream
*strA
, int lengthA
);
753 ~FixedLengthEncoder();
754 virtual StreamKind
getKind() { return strWeird
; }
755 virtual void reset();
756 virtual int getChar();
757 virtual int lookChar();
758 virtual GString
*getPSFilter(int psLevel
, char *indent
) { return NULL
; }
759 virtual GBool
isBinary(GBool last
= gTrue
);
760 virtual GBool
isEncoder() { return gTrue
; }
768 //------------------------------------------------------------------------
770 //------------------------------------------------------------------------
772 class ASCIIHexEncoder
: public FilterStream
{
775 ASCIIHexEncoder(Stream
*strA
);
776 virtual ~ASCIIHexEncoder();
777 virtual StreamKind
getKind() { return strWeird
; }
778 virtual void reset();
779 virtual int getChar()
780 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
781 virtual int lookChar()
782 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
783 virtual GString
*getPSFilter(int psLevel
, char *indent
) { return NULL
; }
784 virtual GBool
isBinary(GBool last
= gTrue
) { return gFalse
; }
785 virtual GBool
isEncoder() { return gTrue
; }
798 //------------------------------------------------------------------------
800 //------------------------------------------------------------------------
802 class ASCII85Encoder
: public FilterStream
{
805 ASCII85Encoder(Stream
*strA
);
806 virtual ~ASCII85Encoder();
807 virtual StreamKind
getKind() { return strWeird
; }
808 virtual void reset();
809 virtual int getChar()
810 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
811 virtual int lookChar()
812 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
813 virtual GString
*getPSFilter(int psLevel
, char *indent
) { return NULL
; }
814 virtual GBool
isBinary(GBool last
= gTrue
) { return gFalse
; }
815 virtual GBool
isEncoder() { return gTrue
; }
828 //------------------------------------------------------------------------
830 //------------------------------------------------------------------------
832 class RunLengthEncoder
: public FilterStream
{
835 RunLengthEncoder(Stream
*strA
);
836 virtual ~RunLengthEncoder();
837 virtual StreamKind
getKind() { return strWeird
; }
838 virtual void reset();
839 virtual int getChar()
840 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
841 virtual int lookChar()
842 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
843 virtual GString
*getPSFilter(int psLevel
, char *indent
) { return NULL
; }
844 virtual GBool
isBinary(GBool last
= gTrue
) { return gTrue
; }
845 virtual GBool
isEncoder() { return gTrue
; }