1 //========================================================================
5 // Copyright 1996 Derek B. Noonburg
7 //========================================================================
25 //------------------------------------------------------------------------
36 strWeird
// internal-use stream types
39 //------------------------------------------------------------------------
40 // Stream (base class)
41 //------------------------------------------------------------------------
52 // Reference counting.
53 int incRef() { return ++ref
; }
54 int decRef() { return --ref
; }
56 // Get kind of stream.
57 virtual StreamKind
getKind() = 0;
59 // Reset stream to beginning.
60 virtual void reset() = 0;
62 // Close down the stream.
65 // Get next char from stream.
66 virtual int getChar() = 0;
68 // Peek at next char in stream.
69 virtual int lookChar() = 0;
71 // Get next char from stream without using the predictor.
72 // This is only used by StreamPredictor.
73 virtual int getRawChar();
75 // Get next line from stream.
76 virtual char *getLine(char *buf
, int size
);
78 // Get current position in file.
79 virtual int getPos() = 0;
81 // Go to a position in the stream.
82 virtual void setPos(int pos1
) = 0;
84 // Get PostScript command for the filter(s).
85 virtual GString
*getPSFilter(const char *indent
);
87 // Does this stream type potentially contain non-printable chars?
88 virtual GBool
isBinary(GBool last
= gTrue
) = 0;
90 // Get the BaseStream or EmbedStream of this stream.
91 virtual BaseStream
*getBaseStream() = 0;
93 // Get the dictionary associated with this stream.
94 virtual Dict
*getDict() = 0;
96 // Is this an encoding filter?
97 virtual GBool
isEncoder() { return gFalse
; }
99 // Add filters to this stream according to the parameters in <dict>.
100 // Returns the new stream.
101 Stream
*addFilters(Object
*dict
);
105 Stream
*makeFilter(const char *name
, Stream
*str
, Object
*params
);
107 int ref
; // reference count
110 //------------------------------------------------------------------------
113 // This is the base class for all streams that read directly from a file.
114 //------------------------------------------------------------------------
116 class BaseStream
: public Stream
{
119 BaseStream(Object
*dict
);
120 virtual ~BaseStream();
121 virtual Stream
*makeSubStream(int start
, int length
, Object
*dict
) = 0;
122 virtual void setPos(int pos1
) = 0;
123 virtual BaseStream
*getBaseStream() { return this; }
124 virtual Dict
*getDict() { return dict
.getDict(); }
126 // Get/set position of first byte of stream within the file.
127 virtual int getStart() = 0;
128 virtual void moveStart(int delta
) = 0;
130 #ifndef NO_DECRYPTION
131 // Set decryption for this stream.
132 void doDecryption(Guchar
*fileKey
, int objNum
, int objGen
);
135 #ifndef NO_DECRYPTION
146 //------------------------------------------------------------------------
149 // This is the base class for all streams that filter another stream.
150 //------------------------------------------------------------------------
152 class FilterStream
: public Stream
{
155 FilterStream(Stream
*str
);
156 virtual ~FilterStream();
157 virtual void close();
158 virtual int getPos() { return str
->getPos(); }
159 virtual void setPos(int pos
);
160 virtual BaseStream
*getBaseStream() { return str
->getBaseStream(); }
161 virtual Dict
*getDict() { return str
->getDict(); }
168 //------------------------------------------------------------------------
170 //------------------------------------------------------------------------
175 // Create an image stream object for an image with the specified
176 // parameters. Note that these are the actual image parameters,
177 // which may be different from the predictor parameters.
178 ImageStream(Stream
*str
, int width
, int nComps
, int nBits
);
185 // Gets the next pixel from the stream. <pix> should be able to hold
186 // at least nComps elements. Returns false at end of file.
187 GBool
getPixel(Guchar
*pix
);
189 // Skip an entire line from the image.
194 Stream
*str
; // base stream
195 int width
; // pixels per line
196 int nComps
; // components per pixel
197 int nBits
; // bits per component
198 int nVals
; // components per line
199 Guchar
*imgLine
; // line buffer
200 int imgIdx
; // current index in imgLine
203 //------------------------------------------------------------------------
205 //------------------------------------------------------------------------
207 class StreamPredictor
{
210 // Create a predictor object. Note that the parameters are for the
211 // predictor, and may not match the actual image parameters.
212 StreamPredictor(Stream
*str
, int predictor
,
213 int width
, int nComps
, int nBits
);
224 Stream
*str
; // base stream
225 int predictor
; // predictor
226 int width
; // pixels per line
227 int nComps
; // components per pixel
228 int nBits
; // bits per component
229 int nVals
; // components per line
230 int pixBytes
; // bytes per pixel
231 int rowBytes
; // bytes per line
232 Guchar
*predLine
; // line buffer
233 int predIdx
; // current index in predLine
236 //------------------------------------------------------------------------
238 //------------------------------------------------------------------------
240 #define fileStreamBufSize 256
242 class FileStream
: public BaseStream
{
245 FileStream(FILE *f
, int start
, int length
, Object
*dict
);
246 virtual ~FileStream();
247 virtual Stream
*makeSubStream(int start
, int length
, Object
*dict
);
248 virtual StreamKind
getKind() { return strFile
; }
249 virtual void reset();
250 virtual void close();
251 virtual int getChar()
252 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
253 virtual int lookChar()
254 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
255 virtual int getPos() { return bufPos
+ (bufPtr
- buf
); }
256 virtual void setPos(int pos1
);
257 virtual GBool
isBinary(GBool last
= gTrue
) { return last
; }
258 virtual int getStart() { return start
; }
259 virtual void moveStart(int delta
);
268 char buf
[fileStreamBufSize
];
275 //------------------------------------------------------------------------
278 // This is a special stream type used for embedded streams (inline
279 // images). It reads directly from the base stream -- after the
280 // EmbedStream is deleted, reads from the base stream will proceed where
281 // the BaseStream left off. Note that this is very different behavior
282 // that creating a new FileStream (using makeSubStream).
283 //------------------------------------------------------------------------
285 class EmbedStream
: public BaseStream
{
288 EmbedStream(Stream
*str
, Object
*dict
);
289 virtual ~EmbedStream();
290 virtual Stream
*makeSubStream(int start
, int length
, Object
*dict
);
291 virtual StreamKind
getKind() { return str
->getKind(); }
292 virtual void reset() {}
293 virtual int getChar() { return str
->getChar(); }
294 virtual int lookChar() { return str
->lookChar(); }
295 virtual int getPos() { return str
->getPos(); }
296 virtual void setPos(int pos
);
297 virtual GBool
isBinary(GBool last
= gTrue
) { return last
; }
298 virtual int getStart();
299 virtual void moveStart(int delta
);
306 //------------------------------------------------------------------------
308 //------------------------------------------------------------------------
310 class ASCIIHexStream
: public FilterStream
{
313 ASCIIHexStream(Stream
*str
);
314 virtual ~ASCIIHexStream();
315 virtual StreamKind
getKind() { return strASCIIHex
; }
316 virtual void reset();
317 virtual int getChar()
318 { int c
= lookChar(); buf
= EOF
; return c
; }
319 virtual int lookChar();
320 virtual GString
*getPSFilter(const char *indent
);
321 virtual GBool
isBinary(GBool last
= gTrue
);
329 //------------------------------------------------------------------------
331 //------------------------------------------------------------------------
333 class ASCII85Stream
: public FilterStream
{
336 ASCII85Stream(Stream
*str
);
337 virtual ~ASCII85Stream();
338 virtual StreamKind
getKind() { return strASCII85
; }
339 virtual void reset();
340 virtual int getChar()
341 { int ch
= lookChar(); ++index
; return ch
; }
342 virtual int lookChar();
343 virtual GString
*getPSFilter(const char *indent
);
344 virtual GBool
isBinary(GBool last
= gTrue
);
354 //------------------------------------------------------------------------
356 //------------------------------------------------------------------------
358 class LZWStream
: public FilterStream
{
361 LZWStream(Stream
*str
, int predictor1
, int columns1
, int colors1
,
362 int bits1
, int early1
);
363 virtual ~LZWStream();
364 virtual StreamKind
getKind() { return strLZW
; }
365 virtual void reset();
366 virtual int getChar();
367 virtual int lookChar();
368 virtual int getRawChar();
369 virtual GString
*getPSFilter(const char *indent
);
370 virtual GBool
isBinary(GBool last
= gTrue
);
374 StreamPredictor
*pred
; // predictor
375 int early
; // early parameter
376 FILE *zPipe
; // uncompress pipe
377 GString
*zName
; // .Z file name
378 int inputBuf
; // input buffer
379 int inputBits
; // number of bits in input buffer
380 int inCodeBits
; // size of input code
381 char buf
[256]; // buffer
382 char *bufPtr
; // next char to read
383 char *bufEnd
; // end of buffer
385 void dumpFile(FILE *f
);
390 //------------------------------------------------------------------------
392 //------------------------------------------------------------------------
394 class RunLengthStream
: public FilterStream
{
397 RunLengthStream(Stream
*str
);
398 virtual ~RunLengthStream();
399 virtual StreamKind
getKind() { return strRunLength
; }
400 virtual void reset();
401 virtual int getChar()
402 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
403 virtual int lookChar()
404 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
405 virtual GString
*getPSFilter(const char *indent
);
406 virtual GBool
isBinary(GBool last
= gTrue
);
410 char buf
[128]; // buffer
411 char *bufPtr
; // next char to read
412 char *bufEnd
; // end of buffer
418 //------------------------------------------------------------------------
420 //------------------------------------------------------------------------
422 struct CCITTCodeTable
;
424 class CCITTFaxStream
: public FilterStream
{
427 CCITTFaxStream(Stream
*str
, int encoding
, GBool endOfLine
,
428 GBool byteAlign
, int columns
, int rows
,
429 GBool endOfBlock
, GBool black
);
430 virtual ~CCITTFaxStream();
431 virtual StreamKind
getKind() { return strCCITTFax
; }
432 virtual void reset();
433 virtual int getChar()
434 { int c
= lookChar(); buf
= EOF
; return c
; }
435 virtual int lookChar();
436 virtual GString
*getPSFilter(const char *indent
);
437 virtual GBool
isBinary(GBool last
= gTrue
);
441 int encoding
; // 'K' parameter
442 GBool endOfLine
; // 'EndOfLine' parameter
443 GBool byteAlign
; // 'EncodedByteAlign' parameter
444 int columns
; // 'Columns' parameter
445 int rows
; // 'Rows' parameter
446 GBool endOfBlock
; // 'EndOfBlock' parameter
447 GBool black
; // 'BlackIs1' parameter
448 GBool eof
; // true if at eof
449 GBool nextLine2D
; // true if next line uses 2D encoding
450 int row
; // current row
451 int inputBuf
; // input buffer
452 int inputBits
; // number of bits in input buffer
453 short *refLine
; // reference line changing elements
454 int b1
; // index into refLine
455 short *codingLine
; // coding line changing elements
456 int a0
; // index into codingLine
457 int outputBits
; // remaining ouput bits
458 int buf
; // character buffer
460 short getTwoDimCode();
461 short getWhiteCode();
462 short getBlackCode();
463 short lookBits(int n
);
464 void eatBits(int n
) { inputBits
-= n
; }
467 //------------------------------------------------------------------------
469 //------------------------------------------------------------------------
471 // DCT component info
473 int id
; // component ID
474 GBool inScan
; // is this component in the current scan?
475 int hSample
, vSample
; // horiz/vert sampling resolutions
476 int quantTable
; // quantization table number
477 int dcHuffTable
, acHuffTable
; // Huffman table numbers
478 int prevDC
; // DC coefficient accumulator
481 // DCT Huffman decoding table
482 struct DCTHuffTable
{
483 Guchar firstSym
[17]; // first symbol for this bit length
484 Gushort firstCode
[17]; // first code for this bit length
485 Gushort numCodes
[17]; // number of codes of this bit length
486 Guchar sym
[256]; // symbols
489 class DCTStream
: public FilterStream
{
492 DCTStream(Stream
*str
);
493 virtual ~DCTStream();
494 virtual StreamKind
getKind() { return strDCT
; }
495 virtual void reset();
496 virtual int getChar();
497 virtual int lookChar();
498 virtual GString
*getPSFilter(const char *indent
);
499 virtual GBool
isBinary(GBool last
= gTrue
);
500 Stream
*getRawStream() { return str
; }
504 int width
, height
; // image size
505 int mcuWidth
, mcuHeight
; // size of min coding unit, in data units
506 DCTCompInfo compInfo
[4]; // info for each component
507 int numComps
; // number of components in image
508 int colorXform
; // need YCbCr-to-RGB transform?
509 GBool gotAdobeMarker
; // set if APP14 Adobe marker was present
510 int restartInterval
; // restart interval, in MCUs
511 Guchar quantTables
[4][64]; // quantization tables
512 int numQuantTables
; // number of quantization tables
513 DCTHuffTable dcHuffTables
[4]; // DC Huffman tables
514 DCTHuffTable acHuffTables
[4]; // AC Huffman tables
515 int numDCHuffTables
; // number of DC Huffman tables
516 int numACHuffTables
; // number of AC Huffman tables
517 Guchar
*rowBuf
[4][32]; // buffer for one MCU
518 int comp
, x
, y
, dy
; // current position within image/MCU
519 int restartCtr
; // MCUs left until restart
520 int restartMarker
; // next restart marker
521 int inputBuf
; // input buffer for variable length codes
522 int inputBits
; // number of valid bits in input buffer
526 GBool
readDataUnit(DCTHuffTable
*dcHuffTable
, DCTHuffTable
*acHuffTable
,
527 Guchar quantTable
[64], int *prevDC
, Guchar data
[64]);
528 int readHuffSym(DCTHuffTable
*table
);
529 int readAmp(int size
);
532 GBool
readFrameInfo();
533 GBool
readScanInfo();
534 GBool
readQuantTables();
535 GBool
readHuffmanTables();
536 GBool
readRestartInterval();
537 GBool
readAdobeMarker();
543 //------------------------------------------------------------------------
545 //------------------------------------------------------------------------
547 #define flateWindow 32768 // buffer size
548 #define flateMask (flateWindow-1)
549 #define flateMaxHuffman 15 // max Huffman code length
550 #define flateMaxCodeLenCodes 19 // max # code length codes
551 #define flateMaxLitCodes 288 // max # literal codes
552 #define flateMaxDistCodes 30 // max # distance codes
554 // Huffman code table entry
556 int len
; // code length in bits
557 int code
; // code word
558 int val
; // value represented by this code
561 // Huffman code table
562 struct FlateHuffmanTab
{
563 int start
[flateMaxHuffman
+2]; // indexes of first code of each length
564 FlateCode
*codes
; // codes, sorted by length and code word
567 // Decoding info for length and distance code words
569 int bits
; // # extra bits
570 int first
; // first length/distance
573 class FlateStream
: public FilterStream
{
576 FlateStream(Stream
*str
, int predictor1
, int columns1
,
577 int colors1
, int bits1
);
578 virtual ~FlateStream();
579 virtual StreamKind
getKind() { return strFlate
; }
580 virtual void reset();
581 virtual int getChar();
582 virtual int lookChar();
583 virtual int getRawChar();
584 virtual GString
*getPSFilter(const char *indent
);
585 virtual GBool
isBinary(GBool last
= gTrue
);
589 StreamPredictor
*pred
; // predictor
590 Guchar buf
[flateWindow
]; // output data buffer
591 int index
; // current index into output buffer
592 int remain
; // number valid bytes in output buffer
593 int codeBuf
; // input buffer
594 int codeSize
; // number of bits in input buffer
595 FlateCode
// literal and distance codes
596 allCodes
[flateMaxLitCodes
+ flateMaxDistCodes
];
597 FlateHuffmanTab litCodeTab
; // literal code table
598 FlateHuffmanTab distCodeTab
; // distance code table
599 GBool compressedBlock
; // set if reading a compressed block
600 int blockLen
; // remaining length of uncompressed block
601 GBool endOfBlock
; // set when end of block is reached
602 GBool eof
; // set when end of stream is reached
604 static int // code length code reordering
605 codeLenCodeMap
[flateMaxCodeLenCodes
];
606 static FlateDecode
// length decoding info
607 lengthDecode
[flateMaxLitCodes
-257];
608 static FlateDecode
// distance decoding info
609 distDecode
[flateMaxDistCodes
];
613 void loadFixedCodes();
614 GBool
readDynamicCodes();
615 void compHuffmanCodes(FlateHuffmanTab
*tab
, int n
);
616 int getHuffmanCodeWord(FlateHuffmanTab
*tab
);
617 int getCodeWord(int bits
);
620 //------------------------------------------------------------------------
622 //------------------------------------------------------------------------
624 class EOFStream
: public FilterStream
{
627 EOFStream(Stream
*str
);
628 virtual ~EOFStream();
629 virtual StreamKind
getKind() { return strWeird
; }
630 virtual void reset() {}
631 virtual int getChar() { return EOF
; }
632 virtual int lookChar() { return EOF
; }
633 virtual GString
*getPSFilter(const char *indent
) { (void)indent
; return NULL
; }
634 virtual GBool
isBinary(GBool last
= gTrue
) { (void)last
; return gFalse
; }
637 //------------------------------------------------------------------------
638 // FixedLengthEncoder
639 //------------------------------------------------------------------------
641 class FixedLengthEncoder
: public FilterStream
{
644 FixedLengthEncoder(Stream
*str
, int length1
);
645 ~FixedLengthEncoder();
646 virtual StreamKind
getKind() { return strWeird
; }
647 virtual void reset();
648 virtual void close();
649 virtual int getChar();
650 virtual int lookChar();
651 virtual GString
*getPSFilter(const char *indent
) { (void)indent
; return NULL
; }
652 virtual GBool
isBinary(GBool last
= gTrue
) { (void)last
; return gFalse
; }
653 virtual GBool
isEncoder() { return gTrue
; }
661 //------------------------------------------------------------------------
663 //------------------------------------------------------------------------
665 class ASCII85Encoder
: public FilterStream
{
668 ASCII85Encoder(Stream
*str
);
669 virtual ~ASCII85Encoder();
670 virtual StreamKind
getKind() { return strWeird
; }
671 virtual void reset();
672 virtual void close();
673 virtual int getChar()
674 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
675 virtual int lookChar()
676 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
677 virtual GString
*getPSFilter(const char *indent
) { (void)indent
; return NULL
; }
678 virtual GBool
isBinary(GBool last
= gTrue
) { (void)last
; return gFalse
; }
679 virtual GBool
isEncoder() { return gTrue
; }
692 //------------------------------------------------------------------------
694 //------------------------------------------------------------------------
696 class RunLengthEncoder
: public FilterStream
{
699 RunLengthEncoder(Stream
*str
);
700 virtual ~RunLengthEncoder();
701 virtual StreamKind
getKind() { return strWeird
; }
702 virtual void reset();
703 virtual void close();
704 virtual int getChar()
705 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
706 virtual int lookChar()
707 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
708 virtual GString
*getPSFilter(const char *indent
) { (void)indent
; return NULL
; }
709 virtual GBool
isBinary(GBool last
= gTrue
) { (void)last
; return gFalse
; }
710 virtual GBool
isEncoder() { return gTrue
; }