1 //========================================================================
5 // Copyright 1996 Derek B. Noonburg
7 //========================================================================
22 //------------------------------------------------------------------------
33 strWeird // internal-use stream types
36 //------------------------------------------------------------------------
37 // Stream (base class)
38 //------------------------------------------------------------------------
49 // Reference counting.
50 int incRef() { return ++ref; }
51 int decRef() { return --ref; }
53 // Get kind of stream.
54 virtual StreamKind getKind() = 0;
56 // Reset stream to beginning.
57 virtual void reset() = 0;
59 // Get next char from stream.
60 virtual int getChar() = 0;
62 // Peek at next char in stream.
63 virtual int lookChar() = 0;
65 // Get next char from stream without using the predictor.
66 // This is only used by StreamPredictor.
67 virtual int getRawChar();
69 // Get next line from stream.
70 virtual char *getLine(char *buf, int size);
72 // Get current position in file.
73 virtual int getPos() = 0;
75 // Go to a position in the stream.
76 virtual void setPos(int pos1) = 0;
78 // Get PostScript command for the filter(s).
79 virtual GString *getPSFilter(char *indent);
81 // Does this stream type potentially contain non-printable chars?
82 virtual GBool isBinary(GBool last = gTrue) = 0;
84 // Get the BaseStream or EmbedStream of this stream.
85 virtual BaseStream *getBaseStream() = 0;
87 // Get the dictionary associated with this stream.
88 virtual Dict *getDict() = 0;
90 // Is this an encoding filter?
91 virtual GBool isEncoder() { return gFalse; }
93 // Add filters to this stream according to the parameters in <dict>.
94 // Returns the new stream.
95 Stream *addFilters(Object *dict);
99 Stream *makeFilter(char *name, Stream *str, Object *params);
101 int ref; // reference count
104 //------------------------------------------------------------------------
107 // This is the base class for all streams that read directly from a file.
108 //------------------------------------------------------------------------
110 class BaseStream: public Stream {
113 BaseStream(Object *dict);
114 virtual ~BaseStream();
115 virtual Stream *makeSubStream(int start, int length, Object *dict) = 0;
116 virtual void setPos(int pos1) = 0;
117 virtual BaseStream *getBaseStream() { return this; }
118 virtual Dict *getDict() { return dict.getDict(); }
120 // Get/set position of first byte of stream within the file.
121 virtual int getStart() = 0;
122 virtual void moveStart(int delta) = 0;
129 //------------------------------------------------------------------------
132 // This is the base class for all streams that filter another stream.
133 //------------------------------------------------------------------------
135 class FilterStream: public Stream {
138 FilterStream(Stream *str);
139 virtual ~FilterStream();
140 virtual int getPos() { return str->getPos(); }
141 virtual void setPos(int pos);
142 virtual BaseStream *getBaseStream() { return str->getBaseStream(); }
143 virtual Dict *getDict() { return str->getDict(); }
150 //------------------------------------------------------------------------
152 //------------------------------------------------------------------------
157 // Create an image stream object for an image with the specified
158 // parameters. Note that these are the actual image parameters,
159 // which may be different from the predictor parameters.
160 ImageStream(Stream *str, int width, int nComps, int nBits);
167 // Gets the next pixel from the stream. <pix> should be able to hold
168 // at least nComps elements. Returns false at end of file.
169 GBool getPixel(Guchar *pix);
171 // Skip an entire line from the image.
176 Stream *str; // base stream
177 int width; // pixels per line
178 int nComps; // components per pixel
179 int nBits; // bits per component
180 int nVals; // components per line
181 Guchar *imgLine; // line buffer
182 int imgIdx; // current index in imgLine
185 //------------------------------------------------------------------------
187 //------------------------------------------------------------------------
189 class StreamPredictor {
192 // Create a predictor object. Note that the parameters are for the
193 // predictor, and may not match the actual image parameters.
194 StreamPredictor(Stream *str, int predictor,
195 int width, int nComps, int nBits);
206 Stream *str; // base stream
207 int predictor; // predictor
208 int width; // pixels per line
209 int nComps; // components per pixel
210 int nBits; // bits per component
211 int nVals; // components per line
212 int pixBytes; // bytes per pixel
213 int rowBytes; // bytes per line
214 Guchar *predLine; // line buffer
215 int predIdx; // current index in predLine
218 //------------------------------------------------------------------------
220 //------------------------------------------------------------------------
222 class FileStream: public BaseStream {
225 FileStream(FILE *f, int start, int length, Object *dict);
226 virtual ~FileStream();
227 virtual Stream *makeSubStream(int start, int length, Object *dict);
228 virtual StreamKind getKind() { return strFile; }
229 virtual void reset();
230 virtual int getChar()
231 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
232 virtual int lookChar()
233 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
234 virtual int getPos() { return bufPos + (bufPtr - buf); }
235 virtual void setPos(int pos1);
236 virtual GBool isBinary(GBool last = gTrue) { return last; }
237 virtual int getStart() { return start; }
238 virtual void moveStart(int delta);
254 //------------------------------------------------------------------------
257 // This is a special stream type used for embedded streams (inline
258 // images). It reads directly from the base stream -- after the
259 // EmbedStream is deleted, reads from the base stream will proceed where
260 // the BaseStream left off. Note that this is very different behavior
261 // that creating a new FileStream (using makeSubStream).
262 //------------------------------------------------------------------------
264 class EmbedStream: public BaseStream {
267 EmbedStream(Stream *str, Object *dict);
268 virtual ~EmbedStream();
269 virtual Stream *makeSubStream(int start, int length, Object *dict);
270 virtual StreamKind getKind() { return str->getKind(); }
271 virtual void reset() {}
272 virtual int getChar() { return str->getChar(); }
273 virtual int lookChar() { return str->lookChar(); }
274 virtual int getPos() { return str->getPos(); }
275 virtual void setPos(int pos);
276 virtual GBool isBinary(GBool last = gTrue) { return last; }
277 virtual int getStart();
278 virtual void moveStart(int delta);
285 //------------------------------------------------------------------------
287 //------------------------------------------------------------------------
289 class ASCIIHexStream: public FilterStream {
292 ASCIIHexStream(Stream *str);
293 virtual ~ASCIIHexStream();
294 virtual StreamKind getKind() { return strASCIIHex; }
295 virtual void reset();
296 virtual int getChar()
297 { int c = lookChar(); buf = EOF; return c; }
298 virtual int lookChar();
299 virtual GString *getPSFilter(char *indent);
300 virtual GBool isBinary(GBool last = gTrue);
308 //------------------------------------------------------------------------
310 //------------------------------------------------------------------------
312 class ASCII85Stream: public FilterStream {
315 ASCII85Stream(Stream *str);
316 virtual ~ASCII85Stream();
317 virtual StreamKind getKind() { return strASCII85; }
318 virtual void reset();
319 virtual int getChar()
320 { int ch = lookChar(); ++index; return ch; }
321 virtual int lookChar();
322 virtual GString *getPSFilter(char *indent);
323 virtual GBool isBinary(GBool last = gTrue);
333 //------------------------------------------------------------------------
335 //------------------------------------------------------------------------
337 class LZWStream: public FilterStream {
340 LZWStream(Stream *str, int predictor1, int columns1, int colors1,
341 int bits1, int early1);
342 virtual ~LZWStream();
343 virtual StreamKind getKind() { return strLZW; }
344 virtual void reset();
345 virtual int getChar();
346 virtual int lookChar();
347 virtual int getRawChar();
348 virtual GString *getPSFilter(char *indent);
349 virtual GBool isBinary(GBool last = gTrue);
353 StreamPredictor *pred; // predictor
354 int early; // early parameter
355 char zCmd[256]; // uncompress command
356 FILE *zPipe; // uncompress pipe
357 char *zName; // .Z file name (in zCmd)
358 int inputBuf; // input buffer
359 int inputBits; // number of bits in input buffer
360 int inCodeBits; // size of input code
361 char buf[256]; // buffer
362 char *bufPtr; // next char to read
363 char *bufEnd; // end of buffer
365 void dumpFile(FILE *f);
370 //------------------------------------------------------------------------
372 //------------------------------------------------------------------------
374 class RunLengthStream: public FilterStream {
377 RunLengthStream(Stream *str);
378 virtual ~RunLengthStream();
379 virtual StreamKind getKind() { return strRunLength; }
380 virtual void reset();
381 virtual int getChar()
382 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
383 virtual int lookChar()
384 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
385 virtual GString *getPSFilter(char *indent);
386 virtual GBool isBinary(GBool last = gTrue);
390 char buf[128]; // buffer
391 char *bufPtr; // next char to read
392 char *bufEnd; // end of buffer
398 //------------------------------------------------------------------------
400 //------------------------------------------------------------------------
402 struct CCITTCodeTable;
404 class CCITTFaxStream: public FilterStream {
407 CCITTFaxStream(Stream *str, int encoding, GBool endOfLine,
408 GBool byteAlign, int columns, int rows,
409 GBool endOfBlock, GBool black);
410 virtual ~CCITTFaxStream();
411 virtual StreamKind getKind() { return strCCITTFax; }
412 virtual void reset();
413 virtual int getChar()
414 { int c = lookChar(); buf = EOF; return c; }
415 virtual int lookChar();
416 virtual GString *getPSFilter(char *indent);
417 virtual GBool isBinary(GBool last = gTrue);
421 int encoding; // 'K' parameter
422 GBool endOfLine; // 'EndOfLine' parameter
423 GBool byteAlign; // 'EncodedByteAlign' parameter
424 int columns; // 'Columns' parameter
425 int rows; // 'Rows' parameter
426 GBool endOfBlock; // 'EndOfBlock' parameter
427 GBool black; // 'BlackIs1' parameter
428 GBool eof; // true if at eof
429 GBool nextLine2D; // true if next line uses 2D encoding
430 int row; // current row
431 int inputBuf; // input buffer
432 int inputBits; // number of bits in input buffer
433 short *refLine; // reference line changing elements
434 int b1; // index into refLine
435 short *codingLine; // coding line changing elements
436 int a0; // index into codingLine
437 int outputBits; // remaining ouput bits
438 int buf; // character buffer
440 short getTwoDimCode();
441 short getWhiteCode();
442 short getBlackCode();
443 short lookBits(int n);
444 void eatBits(int n) { inputBits -= n; }
447 //------------------------------------------------------------------------
449 //------------------------------------------------------------------------
451 // DCT component info
453 int id; // component ID
454 GBool inScan; // is this component in the current scan?
455 int hSample, vSample; // horiz/vert sampling resolutions
456 int quantTable; // quantization table number
457 int dcHuffTable, acHuffTable; // Huffman table numbers
458 int prevDC; // DC coefficient accumulator
461 // DCT Huffman decoding table
462 struct DCTHuffTable {
463 Guchar firstSym[17]; // first symbol for this bit length
464 Gushort firstCode[17]; // first code for this bit length
465 Gushort numCodes[17]; // number of codes of this bit length
466 Guchar sym[256]; // symbols
469 class DCTStream: public FilterStream {
472 DCTStream(Stream *str);
473 virtual ~DCTStream();
474 virtual StreamKind getKind() { return strDCT; }
475 virtual void reset();
476 virtual int getChar();
477 virtual int lookChar();
478 virtual GString *getPSFilter(char *indent);
479 virtual GBool isBinary(GBool last = gTrue);
480 Stream *getRawStream() { return str; }
484 int width, height; // image size
485 int mcuWidth, mcuHeight; // size of min coding unit, in data units
486 DCTCompInfo compInfo[4]; // info for each component
487 int numComps; // number of components in image
488 int colorXform; // need YCbCr-to-RGB transform?
489 GBool gotAdobeMarker; // set if APP14 Adobe marker was present
490 int restartInterval; // restart interval, in MCUs
491 Guchar quantTables[4][64]; // quantization tables
492 int numQuantTables; // number of quantization tables
493 DCTHuffTable dcHuffTables[4]; // DC Huffman tables
494 DCTHuffTable acHuffTables[4]; // AC Huffman tables
495 int numDCHuffTables; // number of DC Huffman tables
496 int numACHuffTables; // number of AC Huffman tables
497 Guchar *rowBuf[4][32]; // buffer for one MCU
498 int comp, x, y, dy; // current position within image/MCU
499 int restartCtr; // MCUs left until restart
500 int restartMarker; // next restart marker
501 int inputBuf; // input buffer for variable length codes
502 int inputBits; // number of valid bits in input buffer
506 GBool readDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable,
507 Guchar quantTable[64], int *prevDC, Guchar data[64]);
508 int readHuffSym(DCTHuffTable *table);
509 int readAmp(int size);
512 GBool readFrameInfo();
513 GBool readScanInfo();
514 GBool readQuantTables();
515 GBool readHuffmanTables();
516 GBool readRestartInterval();
517 GBool readAdobeMarker();
523 //------------------------------------------------------------------------
525 //------------------------------------------------------------------------
527 #define flateWindow 32768 // buffer size
528 #define flateMask (flateWindow-1)
529 #define flateMaxHuffman 15 // max Huffman code length
530 #define flateMaxCodeLenCodes 19 // max # code length codes
531 #define flateMaxLitCodes 288 // max # literal codes
532 #define flateMaxDistCodes 30 // max # distance codes
534 // Huffman code table entry
536 int len; // code length in bits
537 int code; // code word
538 int val; // value represented by this code
541 // Huffman code table
542 struct FlateHuffmanTab {
543 int start[flateMaxHuffman+2]; // indexes of first code of each length
544 FlateCode *codes; // codes, sorted by length and code word
547 // Decoding info for length and distance code words
549 int bits; // # extra bits
550 int first; // first length/distance
553 class FlateStream: public FilterStream {
556 FlateStream(Stream *str, int predictor1, int columns1,
557 int colors1, int bits1);
558 virtual ~FlateStream();
559 virtual StreamKind getKind() { return strFlate; }
560 virtual void reset();
561 virtual int getChar();
562 virtual int lookChar();
563 virtual int getRawChar();
564 virtual GString *getPSFilter(char *indent);
565 virtual GBool isBinary(GBool last = gTrue);
569 StreamPredictor *pred; // predictor
570 Guchar buf[flateWindow]; // output data buffer
571 int index; // current index into output buffer
572 int remain; // number valid bytes in output buffer
573 int codeBuf; // input buffer
574 int codeSize; // number of bits in input buffer
575 FlateCode // literal and distance codes
576 allCodes[flateMaxLitCodes + flateMaxDistCodes];
577 FlateHuffmanTab litCodeTab; // literal code table
578 FlateHuffmanTab distCodeTab; // distance code table
579 GBool compressedBlock; // set if reading a compressed block
580 int blockLen; // remaining length of uncompressed block
581 GBool endOfBlock; // set when end of block is reached
582 GBool eof; // set when end of stream is reached
584 static int // code length code reordering
585 codeLenCodeMap[flateMaxCodeLenCodes];
586 static FlateDecode // length decoding info
587 lengthDecode[flateMaxLitCodes-257];
588 static FlateDecode // distance decoding info
589 distDecode[flateMaxDistCodes];
593 void loadFixedCodes();
594 GBool readDynamicCodes();
595 void compHuffmanCodes(FlateHuffmanTab *tab, int n);
596 int getHuffmanCodeWord(FlateHuffmanTab *tab);
597 int getCodeWord(int bits);
600 //------------------------------------------------------------------------
602 //------------------------------------------------------------------------
604 class EOFStream: public FilterStream {
607 EOFStream(Stream *str);
608 virtual ~EOFStream();
609 virtual StreamKind getKind() { return strWeird; }
610 virtual void reset() {}
611 virtual int getChar() { return EOF; }
612 virtual int lookChar() { return EOF; }
613 virtual GString *getPSFilter(char *indent) { return NULL; }
614 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
617 //------------------------------------------------------------------------
618 // FixedLengthEncoder
619 //------------------------------------------------------------------------
621 class FixedLengthEncoder: public FilterStream {
624 FixedLengthEncoder(Stream *str, int length1);
625 ~FixedLengthEncoder();
626 virtual StreamKind getKind() { return strWeird; }
627 virtual void reset();
628 virtual int getChar();
629 virtual int lookChar();
630 virtual GString *getPSFilter(char *indent) { return NULL; }
631 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
632 virtual GBool isEncoder() { return gTrue; }
640 //------------------------------------------------------------------------
642 //------------------------------------------------------------------------
644 class ASCII85Encoder: public FilterStream {
647 ASCII85Encoder(Stream *str);
648 virtual ~ASCII85Encoder();
649 virtual StreamKind getKind() { return strWeird; }
650 virtual void reset();
651 virtual int getChar()
652 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
653 virtual int lookChar()
654 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
655 virtual GString *getPSFilter(char *indent) { return NULL; }
656 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
657 virtual GBool isEncoder() { return gTrue; }
670 //------------------------------------------------------------------------
672 //------------------------------------------------------------------------
674 class RunLengthEncoder: public FilterStream {
677 RunLengthEncoder(Stream *str);
678 virtual ~RunLengthEncoder();
679 virtual StreamKind getKind() { return strWeird; }
680 virtual void reset();
681 virtual int getChar()
682 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
683 virtual int lookChar()
684 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
685 virtual GString *getPSFilter(char *indent) { return NULL; }
686 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
687 virtual GBool isEncoder() { return gTrue; }