1 //========================================================================
5 // Copyright 1996-2003 Glyph & Cog, LLC
7 //========================================================================
14 #ifdef USE_GCC_PRAGMAS
25 //------------------------------------------------------------------------
38 strWeird
// internal-use stream types
41 enum StreamColorSpaceMode
{
48 //------------------------------------------------------------------------
49 // Stream (base class)
50 //------------------------------------------------------------------------
61 // Reference counting.
62 int incRef() { return ++ref
; }
63 int decRef() { return --ref
; }
65 // Get kind of stream.
66 virtual StreamKind
getKind() = 0;
68 // Reset stream to beginning.
69 virtual void reset() = 0;
71 // Close down the stream.
74 // Get next char from stream.
75 virtual int getChar() = 0;
77 // Peek at next char in stream.
78 virtual int lookChar() = 0;
80 // Get next char from stream without using the predictor.
81 // This is only used by StreamPredictor.
82 virtual int getRawChar();
84 // Get next line from stream.
85 virtual char *getLine(char *buf
, int size
);
87 // Get current position in file.
88 virtual int getPos() = 0;
90 // Go to a position in the stream. If <dir> is negative, the
91 // position is from the end of the file; otherwise the position is
92 // from the start of the file.
93 virtual void setPos(Guint pos
, int dir
= 0) = 0;
95 // Get PostScript command for the filter(s).
96 virtual GString
*getPSFilter(int psLevel
, char *indent
);
98 // Does this stream type potentially contain non-printable chars?
99 virtual GBool
isBinary(GBool last
= gTrue
) = 0;
101 // Get the BaseStream of this stream.
102 virtual BaseStream
*getBaseStream() = 0;
104 // Get the dictionary associated with this stream.
105 virtual Dict
*getDict() = 0;
107 // Is this an encoding filter?
108 virtual GBool
isEncoder() { return gFalse
; }
110 // Get image parameters which are defined by the stream contents.
111 virtual void getImageParams(int *bitsPerComponent
,
112 StreamColorSpaceMode
*csMode
) {}
114 // Add filters to this stream according to the parameters in <dict>.
115 // Returns the new stream.
116 Stream
*addFilters(Object
*dict
);
120 Stream
*makeFilter(char *name
, Stream
*str
, Object
*params
);
122 int ref
; // reference count
125 //------------------------------------------------------------------------
128 // This is the base class for all streams that read directly from a file.
129 //------------------------------------------------------------------------
131 class BaseStream
: public Stream
{
134 BaseStream(Object
*dictA
);
135 virtual ~BaseStream();
136 virtual Stream
*makeSubStream(Guint start
, GBool limited
,
137 Guint length
, Object
*dict
) = 0;
138 virtual void setPos(Guint pos
, int dir
= 0) = 0;
139 virtual GBool
isBinary(GBool last
= gTrue
) { return last
; }
140 virtual BaseStream
*getBaseStream() { return this; }
141 virtual Dict
*getDict() { return dict
.getDict(); }
143 // Get/set position of first byte of stream within the file.
144 virtual Guint
getStart() = 0;
145 virtual void moveStart(int delta
) = 0;
147 // Set decryption for this stream.
148 virtual void doDecryption(Guchar
*fileKey
, int keyLength
,
149 int objNum
, int objGen
);
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(); }
182 //------------------------------------------------------------------------
184 //------------------------------------------------------------------------
189 // Create an image stream object for an image with the specified
190 // parameters. Note that these are the actual image parameters,
191 // which may be different from the predictor parameters.
192 ImageStream(Stream
*strA
, int widthA
, int nCompsA
, int nBitsA
);
199 // Gets the next pixel from the stream. <pix> should be able to hold
200 // at least nComps elements. Returns false at end of file.
201 GBool
getPixel(Guchar
*pix
);
203 // Returns a pointer to the next line of pixels. Returns NULL at
207 // Skip an entire line from the image.
212 Stream
*str
; // base stream
213 int width
; // pixels per line
214 int nComps
; // components per pixel
215 int nBits
; // bits per component
216 int nVals
; // components per line
217 Guchar
*imgLine
; // line buffer
218 int imgIdx
; // current index in imgLine
221 //------------------------------------------------------------------------
223 //------------------------------------------------------------------------
225 class StreamPredictor
{
228 // Create a predictor object. Note that the parameters are for the
229 // predictor, and may not match the actual image parameters.
230 StreamPredictor(Stream
*strA
, int predictorA
,
231 int widthA
, int nCompsA
, int nBitsA
);
235 GBool
isOk() { return ok
; }
244 Stream
*str
; // base stream
245 int predictor
; // predictor
246 int width
; // pixels per line
247 int nComps
; // components per pixel
248 int nBits
; // bits per component
249 int nVals
; // components per line
250 int pixBytes
; // bytes per pixel
251 int rowBytes
; // bytes per line
252 Guchar
*predLine
; // line buffer
253 int predIdx
; // current index in predLine
257 //------------------------------------------------------------------------
259 //------------------------------------------------------------------------
261 #define fileStreamBufSize 256
263 class FileStream
: public BaseStream
{
266 FileStream(FILE *fA
, Guint startA
, GBool limitedA
,
267 Guint lengthA
, Object
*dictA
);
268 virtual ~FileStream();
269 virtual Stream
*makeSubStream(Guint startA
, GBool limitedA
,
270 Guint lengthA
, Object
*dictA
);
271 virtual StreamKind
getKind() { return strFile
; }
272 virtual void reset();
273 virtual void close();
274 virtual int getChar()
275 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
276 virtual int lookChar()
277 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
278 virtual int getPos() { return bufPos
+ (bufPtr
- buf
); }
279 virtual void setPos(Guint pos
, int dir
= 0);
280 virtual Guint
getStart() { return start
; }
281 virtual void moveStart(int delta
);
291 char buf
[fileStreamBufSize
];
299 //------------------------------------------------------------------------
301 //------------------------------------------------------------------------
303 class MemStream
: public BaseStream
{
306 MemStream(char *bufA
, Guint startA
, Guint lengthA
, Object
*dictA
);
307 virtual ~MemStream();
308 virtual Stream
*makeSubStream(Guint start
, GBool limited
,
309 Guint lengthA
, Object
*dictA
);
310 virtual StreamKind
getKind() { return strWeird
; }
311 virtual void reset();
312 virtual void close();
313 virtual int getChar()
314 { return (bufPtr
< bufEnd
) ? (*bufPtr
++ & 0xff) : EOF
; }
315 virtual int lookChar()
316 { return (bufPtr
< bufEnd
) ? (*bufPtr
& 0xff) : EOF
; }
317 virtual int getPos() { return (int)(bufPtr
- buf
); }
318 virtual void setPos(Guint pos
, int dir
= 0);
319 virtual Guint
getStart() { return start
; }
320 virtual void moveStart(int delta
);
321 virtual void doDecryption(Guchar
*fileKey
, int keyLength
,
322 int objNum
, int objGen
);
334 //------------------------------------------------------------------------
337 // This is a special stream type used for embedded streams (inline
338 // images). It reads directly from the base stream -- after the
339 // EmbedStream is deleted, reads from the base stream will proceed where
340 // the BaseStream left off. Note that this is very different behavior
341 // that creating a new FileStream (using makeSubStream).
342 //------------------------------------------------------------------------
344 class EmbedStream
: public BaseStream
{
347 EmbedStream(Stream
*strA
, Object
*dictA
, GBool limitedA
, Guint lengthA
);
348 virtual ~EmbedStream();
349 virtual Stream
*makeSubStream(Guint start
, GBool limitedA
,
350 Guint lengthA
, Object
*dictA
);
351 virtual StreamKind
getKind() { return str
->getKind(); }
352 virtual void reset() {}
353 virtual int getChar();
354 virtual int lookChar();
355 virtual int getPos() { return str
->getPos(); }
356 virtual void setPos(Guint pos
, int dir
= 0);
357 virtual Guint
getStart();
358 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 int *codingLine
; // coding line changing elements
523 int *refLine
; // reference line changing elements
524 int a0i
; // index into codingLine
525 GBool err
; // error on current line
526 int outputBits
; // remaining ouput bits
527 int buf
; // character buffer
529 void addPixels(int a1
, int black
);
530 void addPixelsNeg(int a1
, int black
);
531 short getTwoDimCode();
532 short getWhiteCode();
533 short getBlackCode();
534 short lookBits(int n
);
535 void eatBits(int n
) { if ((inputBits
-= n
) < 0) inputBits
= 0; }
538 //------------------------------------------------------------------------
540 //------------------------------------------------------------------------
542 // DCT component info
544 int id
; // component ID
545 int hSample
, vSample
; // horiz/vert sampling resolutions
546 int quantTable
; // quantization table number
547 int prevDC
; // DC coefficient accumulator
551 GBool comp
[4]; // comp[i] is set if component i is
552 // included in this scan
553 int numComps
; // number of components in the scan
554 int dcHuffTable
[4]; // DC Huffman table numbers
555 int acHuffTable
[4]; // AC Huffman table numbers
556 int firstCoeff
, lastCoeff
; // first and last DCT coefficient
557 int ah
, al
; // successive approximation parameters
560 // DCT Huffman decoding table
561 struct DCTHuffTable
{
562 Guchar firstSym
[17]; // first symbol for this bit length
563 Gushort firstCode
[17]; // first code for this bit length
564 Gushort numCodes
[17]; // number of codes of this bit length
565 Guchar sym
[256]; // symbols
568 class DCTStream
: public FilterStream
{
571 DCTStream(Stream
*strA
);
572 virtual ~DCTStream();
573 virtual StreamKind
getKind() { return strDCT
; }
574 virtual void reset();
575 virtual int getChar();
576 virtual int lookChar();
577 virtual GString
*getPSFilter(int psLevel
, char *indent
);
578 virtual GBool
isBinary(GBool last
= gTrue
);
579 Stream
*getRawStream() { return str
; }
583 GBool progressive
; // set if in progressive mode
584 GBool interleaved
; // set if in interleaved mode
585 int width
, height
; // image size
586 int mcuWidth
, mcuHeight
; // size of min coding unit, in data units
587 int bufWidth
, bufHeight
; // frameBuf size
588 DCTCompInfo compInfo
[4]; // info for each component
589 DCTScanInfo scanInfo
; // info for the current scan
590 int numComps
; // number of components in image
591 int colorXform
; // need YCbCr-to-RGB transform?
592 GBool gotJFIFMarker
; // set if APP0 JFIF marker was present
593 GBool gotAdobeMarker
; // set if APP14 Adobe marker was present
594 int restartInterval
; // restart interval, in MCUs
595 Gushort quantTables
[4][64]; // quantization tables
596 int numQuantTables
; // number of quantization tables
597 DCTHuffTable dcHuffTables
[4]; // DC Huffman tables
598 DCTHuffTable acHuffTables
[4]; // AC Huffman tables
599 int numDCHuffTables
; // number of DC Huffman tables
600 int numACHuffTables
; // number of AC Huffman tables
601 Guchar
*rowBuf
[4][32]; // buffer for one MCU (non-progressive mode)
602 int *frameBuf
[4]; // buffer for frame (progressive mode)
603 int comp
, x
, y
, dy
; // current position within image/MCU
604 int restartCtr
; // MCUs left until restart
605 int restartMarker
; // next restart marker
606 int eobRun
; // number of EOBs left in the current run
607 int inputBuf
; // input buffer for variable length codes
608 int inputBits
; // number of valid bits in input buffer
613 GBool
readDataUnit(DCTHuffTable
*dcHuffTable
,
614 DCTHuffTable
*acHuffTable
,
615 int *prevDC
, int data
[64]);
616 GBool
readProgressiveDataUnit(DCTHuffTable
*dcHuffTable
,
617 DCTHuffTable
*acHuffTable
,
618 int *prevDC
, int data
[64]);
620 void transformDataUnit(Gushort
*quantTable
,
621 int dataIn
[64], Guchar dataOut
[64]);
622 int readHuffSym(DCTHuffTable
*table
);
623 int readAmp(int size
);
626 GBool
readBaselineSOF();
627 GBool
readProgressiveSOF();
628 GBool
readScanInfo();
629 GBool
readQuantTables();
630 GBool
readHuffmanTables();
631 GBool
readRestartInterval();
632 GBool
readJFIFMarker();
633 GBool
readAdobeMarker();
639 //------------------------------------------------------------------------
641 //------------------------------------------------------------------------
643 #define flateWindow 32768 // buffer size
644 #define flateMask (flateWindow-1)
645 #define flateMaxHuffman 15 // max Huffman code length
646 #define flateMaxCodeLenCodes 19 // max # code length codes
647 #define flateMaxLitCodes 288 // max # literal codes
648 #define flateMaxDistCodes 30 // max # distance codes
650 // Huffman code table entry
652 Gushort len
; // code length, in bits
653 Gushort val
; // value represented by this code
656 struct FlateHuffmanTab
{
661 // Decoding info for length and distance code words
663 int bits
; // # extra bits
664 int first
; // first length/distance
667 class FlateStream
: public FilterStream
{
670 FlateStream(Stream
*strA
, int predictor
, int columns
,
671 int colors
, int bits
);
672 virtual ~FlateStream();
673 virtual StreamKind
getKind() { return strFlate
; }
674 virtual void reset();
675 virtual int getChar();
676 virtual int lookChar();
677 virtual int getRawChar();
678 virtual GString
*getPSFilter(int psLevel
, char *indent
);
679 virtual GBool
isBinary(GBool last
= gTrue
);
683 StreamPredictor
*pred
; // predictor
684 Guchar buf
[flateWindow
]; // output data buffer
685 int index
; // current index into output buffer
686 int remain
; // number valid bytes in output buffer
687 int codeBuf
; // input buffer
688 int codeSize
; // number of bits in input buffer
689 int // literal and distance code lengths
690 codeLengths
[flateMaxLitCodes
+ flateMaxDistCodes
];
691 FlateHuffmanTab litCodeTab
; // literal code table
692 FlateHuffmanTab distCodeTab
; // distance code table
693 GBool compressedBlock
; // set if reading a compressed block
694 int blockLen
; // remaining length of uncompressed block
695 GBool endOfBlock
; // set when end of block is reached
696 GBool eof
; // set when end of stream is reached
698 static int // code length code reordering
699 codeLenCodeMap
[flateMaxCodeLenCodes
];
700 static FlateDecode
// length decoding info
701 lengthDecode
[flateMaxLitCodes
-257];
702 static FlateDecode
// distance decoding info
703 distDecode
[flateMaxDistCodes
];
704 static FlateHuffmanTab
// fixed literal code table
706 static FlateHuffmanTab
// fixed distance code table
711 void loadFixedCodes();
712 GBool
readDynamicCodes();
713 void compHuffmanCodes(int *lengths
, int n
, FlateHuffmanTab
*tab
);
714 int getHuffmanCodeWord(FlateHuffmanTab
*tab
);
715 int getCodeWord(int bits
);
718 //------------------------------------------------------------------------
720 //------------------------------------------------------------------------
722 class EOFStream
: public FilterStream
{
725 EOFStream(Stream
*strA
);
726 virtual ~EOFStream();
727 virtual StreamKind
getKind() { return strWeird
; }
728 virtual void reset() {}
729 virtual int getChar() { return EOF
; }
730 virtual int lookChar() { return EOF
; }
731 virtual GString
*getPSFilter(int psLevel
, char *indent
) { return NULL
; }
732 virtual GBool
isBinary(GBool last
= gTrue
) { return gFalse
; }
735 //------------------------------------------------------------------------
736 // FixedLengthEncoder
737 //------------------------------------------------------------------------
739 class FixedLengthEncoder
: public FilterStream
{
742 FixedLengthEncoder(Stream
*strA
, int lengthA
);
743 ~FixedLengthEncoder();
744 virtual StreamKind
getKind() { return strWeird
; }
745 virtual void reset();
746 virtual int getChar();
747 virtual int lookChar();
748 virtual GString
*getPSFilter(int psLevel
, char *indent
) { return NULL
; }
749 virtual GBool
isBinary(GBool last
= gTrue
);
750 virtual GBool
isEncoder() { return gTrue
; }
758 //------------------------------------------------------------------------
760 //------------------------------------------------------------------------
762 class ASCIIHexEncoder
: public FilterStream
{
765 ASCIIHexEncoder(Stream
*strA
);
766 virtual ~ASCIIHexEncoder();
767 virtual StreamKind
getKind() { return strWeird
; }
768 virtual void reset();
769 virtual int getChar()
770 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
771 virtual int lookChar()
772 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
773 virtual GString
*getPSFilter(int psLevel
, char *indent
) { return NULL
; }
774 virtual GBool
isBinary(GBool last
= gTrue
) { return gFalse
; }
775 virtual GBool
isEncoder() { return gTrue
; }
788 //------------------------------------------------------------------------
790 //------------------------------------------------------------------------
792 class ASCII85Encoder
: public FilterStream
{
795 ASCII85Encoder(Stream
*strA
);
796 virtual ~ASCII85Encoder();
797 virtual StreamKind
getKind() { return strWeird
; }
798 virtual void reset();
799 virtual int getChar()
800 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
801 virtual int lookChar()
802 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
803 virtual GString
*getPSFilter(int psLevel
, char *indent
) { return NULL
; }
804 virtual GBool
isBinary(GBool last
= gTrue
) { return gFalse
; }
805 virtual GBool
isEncoder() { return gTrue
; }
818 //------------------------------------------------------------------------
820 //------------------------------------------------------------------------
822 class RunLengthEncoder
: public FilterStream
{
825 RunLengthEncoder(Stream
*strA
);
826 virtual ~RunLengthEncoder();
827 virtual StreamKind
getKind() { return strWeird
; }
828 virtual void reset();
829 virtual int getChar()
830 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
831 virtual int lookChar()
832 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
833 virtual GString
*getPSFilter(int psLevel
, char *indent
) { return NULL
; }
834 virtual GBool
isBinary(GBool last
= gTrue
) { return gTrue
; }
835 virtual GBool
isEncoder() { return gTrue
; }