1 //========================================================================
5 // Copyright 1996 Derek B. Noonburg
7 //========================================================================
20 //------------------------------------------------------------------------
31 strWeird // internal-use stream types
34 //------------------------------------------------------------------------
35 // Stream (base class)
36 //------------------------------------------------------------------------
47 // Reference counting.
48 int incRef() { return ++ref; }
49 int decRef() { return --ref; }
51 // Get kind of stream.
52 virtual StreamKind getKind() = 0;
54 // Reset stream to beginning.
55 virtual void reset() = 0;
57 // Get next char from stream.
58 virtual int getChar() = 0;
60 // Peek at next char in stream.
61 virtual int lookChar() = 0;
63 // Get next char from stream without using the predictor.
64 // This is only used by StreamPredictor.
65 virtual int getRawChar();
67 // Get next line from stream.
68 virtual char *getLine(char *buf, int size);
70 // Get current position in file.
71 virtual int getPos() = 0;
73 // Go to a position in the stream.
74 virtual void setPos(int pos1);
76 // Get PostScript command for the filter(s).
77 virtual GString *getPSFilter(char *indent);
79 // Does this stream type potentially contain non-printable chars?
80 virtual GBool isBinary(GBool last = gTrue) = 0;
82 // Get the base FileStream or SubStream of this stream.
83 virtual Stream *getBaseStream() = 0;
85 // Get a substream of this stream.
86 virtual Stream *subStream (int start1, int length1, Object *dict1) = 0;
88 // Get start offset of a stream's data.
89 virtual int getStart () = 0;
91 // Get the dictionary associated with this stream.
92 virtual Dict *getDict() = 0;
94 // Is this an encoding filter?
95 virtual GBool isEncoder() { return gFalse; }
97 // Add filters to this stream according to the parameters in <dict>.
98 // Returns the new stream.
99 Stream *addFilters(Object *dict);
103 Stream *makeFilter(char *name, Stream *str, Object *params);
105 int ref; // reference count
108 //------------------------------------------------------------------------
110 //------------------------------------------------------------------------
115 // Create an image stream object for an image with the specified
116 // parameters. Note that these are the actual image parameters,
117 // which may be different from the predictor parameters.
118 ImageStream(Stream *str, int width, int nComps, int nBits);
125 // Gets the next pixel from the stream. <pix> should be able to hold
126 // at least nComps elements. Returns false at end of file.
127 GBool getPixel(Guchar *pix);
129 // Skip an entire line from the image.
134 Stream *str; // base stream
135 int width; // pixels per line
136 int nComps; // components per pixel
137 int nBits; // bits per component
138 int nVals; // components per line
139 Guchar *imgLine; // line buffer
140 int imgIdx; // current index in imgLine
143 //------------------------------------------------------------------------
145 //------------------------------------------------------------------------
147 class StreamPredictor {
150 // Create a predictor object. Note that the parameters are for the
151 // predictor, and may not match the actual image parameters.
152 StreamPredictor(Stream *str, int predictor,
153 int width, int nComps, int nBits);
164 Stream *str; // base stream
165 int predictor; // predictor
166 int width; // pixels per line
167 int nComps; // components per pixel
168 int nBits; // bits per component
169 int nVals; // components per line
170 int pixBytes; // bytes per pixel
171 int rowBytes; // bytes per line
172 Guchar *predLine; // line buffer
173 int predIdx; // current index in predLine
176 //------------------------------------------------------------------------
178 //------------------------------------------------------------------------
180 // Portable pdf open helper function.
181 extern FILE *fileOpen (GString *fileName1);
183 class FileStream: public Stream {
185 FileStream(FILE *f1);
186 virtual ~FileStream();
187 virtual StreamKind getKind() { return strFile; }
188 virtual void reset();
189 virtual int getChar()
190 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
191 virtual int lookChar()
192 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
193 virtual int getPos() { return bufPos + (bufPtr - buf); }
194 virtual void setPos(int pos1);
195 virtual GBool isBinary(GBool last = gTrue) { return last; }
196 virtual Stream *getBaseStream() { return this; }
197 virtual Stream *subStream (int start1, int length1, Object *dict1);
198 virtual int getStart () { return start; }
199 virtual Dict *getDict() { return dict.getDict(); }
217 //------------------------------------------------------------------------
219 //------------------------------------------------------------------------
221 class SubStream: public Stream {
224 SubStream(Stream *str1, Object *dict1);
225 virtual ~SubStream();
226 virtual StreamKind getKind() { return str->getKind(); }
227 virtual void reset() {}
228 virtual int getChar() { return str->getChar(); }
229 virtual int lookChar() { return str->lookChar(); }
230 virtual int getPos() { return str->getPos(); }
231 virtual GBool isBinary(GBool last = gTrue) { return last; }
232 virtual Stream *getBaseStream() { return this; }
233 virtual Stream *subStream (int start1, int length1, Object *dict1)
234 { return str->subStream (start1, length1, dict1); }
235 virtual int getStart () { return str->getStart (); }
236 virtual Dict *getDict() { return dict.getDict(); }
244 //------------------------------------------------------------------------
246 //------------------------------------------------------------------------
248 class ASCIIHexStream: public Stream {
251 ASCIIHexStream(Stream *str1);
252 virtual ~ASCIIHexStream();
253 virtual StreamKind getKind() { return strASCIIHex; }
254 virtual void reset();
255 virtual int getChar()
256 { int c = lookChar(); buf = EOF; return c; }
257 virtual int lookChar();
258 virtual int getPos() { return str->getPos(); }
259 virtual GString *getPSFilter(char *indent);
260 virtual GBool isBinary(GBool last = gTrue);
261 virtual Stream *getBaseStream() { return str->getBaseStream(); }
262 virtual Stream *subStream (int start1, int length1, Object *dict1)
263 { return str->subStream (start1, length1, dict1); }
264 virtual int getStart () { return str->getStart (); }
265 virtual Dict *getDict() { return str->getDict(); }
274 //------------------------------------------------------------------------
276 //------------------------------------------------------------------------
278 class ASCII85Stream: public Stream {
281 ASCII85Stream(Stream *str1);
282 virtual ~ASCII85Stream();
283 virtual StreamKind getKind() { return strASCII85; }
284 virtual void reset();
285 virtual int getChar()
286 { int ch = lookChar(); ++index; return ch; }
287 virtual int lookChar();
288 virtual int getPos() { return str->getPos(); }
289 virtual GString *getPSFilter(char *indent);
290 virtual GBool isBinary(GBool last = gTrue);
291 virtual Stream *getBaseStream() { return str->getBaseStream(); }
292 virtual Stream *subStream (int start1, int length1, Object *dict1)
293 { return str->subStream (start1, length1, dict1); }
294 virtual int getStart () { return str->getStart (); }
295 virtual Dict *getDict() { return str->getDict(); }
306 //------------------------------------------------------------------------
308 //------------------------------------------------------------------------
310 class LZWStream: public Stream {
313 LZWStream(Stream *str1, int predictor1, int columns1, int colors1,
314 int bits1, int early1);
315 virtual ~LZWStream();
316 virtual StreamKind getKind() { return strLZW; }
317 virtual void reset();
318 virtual int getChar();
319 virtual int lookChar();
320 virtual int getRawChar();
321 virtual int getPos() { return str->getPos(); }
322 virtual GString *getPSFilter(char *indent);
323 virtual GBool isBinary(GBool last = gTrue);
324 virtual Stream *getBaseStream() { return str->getBaseStream(); }
325 virtual Stream *subStream (int start1, int length1, Object *dict1)
326 { return str->subStream (start1, length1, dict1); }
327 virtual int getStart () { return str->getStart (); }
328 virtual Dict *getDict() { return str->getDict(); }
332 Stream *str; // stream
333 StreamPredictor *pred; // predictor
334 int early; // early parameter
335 char zCmd[256]; // uncompress command
336 FILE *zPipe; // uncompress pipe
337 char *zName; // .Z file name (in zCmd)
338 int inputBuf; // input buffer
339 int inputBits; // number of bits in input buffer
340 int inCodeBits; // size of input code
341 char buf[256]; // buffer
342 char *bufPtr; // next char to read
343 char *bufEnd; // end of buffer
345 void dumpFile(FILE *f);
350 //------------------------------------------------------------------------
352 //------------------------------------------------------------------------
354 class RunLengthStream: public Stream {
357 RunLengthStream(Stream *str1);
358 virtual ~RunLengthStream();
359 virtual StreamKind getKind() { return strRunLength; }
360 virtual void reset();
361 virtual int getChar()
362 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
363 virtual int lookChar()
364 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
365 virtual int getPos() { return str->getPos(); }
366 virtual GString *getPSFilter(char *indent);
367 virtual GBool isBinary(GBool last = gTrue);
368 virtual Stream *getBaseStream() { return str->getBaseStream(); }
369 virtual Stream *subStream (int start1, int length1, Object *dict1)
370 { return str->subStream (start1, length1, dict1); }
371 virtual int getStart () { return str->getStart (); }
372 virtual Dict *getDict() { return str->getDict(); }
377 char buf[128]; // buffer
378 char *bufPtr; // next char to read
379 char *bufEnd; // end of buffer
385 //------------------------------------------------------------------------
387 //------------------------------------------------------------------------
389 struct CCITTCodeTable;
391 class CCITTFaxStream: public Stream {
394 CCITTFaxStream(Stream *str, int encoding, GBool endOfLine,
395 GBool byteAlign, int columns, int rows,
396 GBool endOfBlock, GBool black);
397 virtual ~CCITTFaxStream();
398 virtual StreamKind getKind() { return strCCITTFax; }
399 virtual void reset();
400 virtual int getChar()
401 { int c = lookChar(); buf = EOF; return c; }
402 virtual int lookChar();
403 virtual int getPos() { return str->getPos(); }
404 virtual GString *getPSFilter(char *indent);
405 virtual GBool isBinary(GBool last = gTrue);
406 virtual Stream *getBaseStream() { return str->getBaseStream(); }
407 virtual Stream *subStream (int start1, int length1, Object *dict1)
408 { return str->subStream (start1, length1, dict1); }
409 virtual int getStart () { return str->getStart (); }
410 virtual Dict *getDict() { return str->getDict(); }
414 Stream *str; // stream
415 int encoding; // 'K' parameter
416 GBool endOfLine; // 'EndOfLine' parameter
417 GBool byteAlign; // 'EncodedByteAlign' parameter
418 int columns; // 'Columns' parameter
419 int rows; // 'Rows' parameter
420 GBool endOfBlock; // 'EndOfBlock' parameter
421 GBool black; // 'BlackIs1' parameter
422 GBool eof; // true if at eof
423 GBool nextLine2D; // true if next line uses 2D encoding
424 int row; // current row
425 int inputBuf; // input buffer
426 int inputBits; // number of bits in input buffer
427 short *refLine; // reference line changing elements
428 int b1; // index into refLine
429 short *codingLine; // coding line changing elements
430 int a0; // index into codingLine
431 int outputBits; // remaining ouput bits
432 int buf; // character buffer
434 short getTwoDimCode();
435 short getWhiteCode();
436 short getBlackCode();
437 short lookBits(int n);
438 void eatBits(int n) { inputBits -= n; }
441 //------------------------------------------------------------------------
443 //------------------------------------------------------------------------
445 // DCT component info
447 int id; // component ID
448 GBool inScan; // is this component in the current scan?
449 int hSample, vSample; // horiz/vert sampling resolutions
450 int quantTable; // quantization table number
451 int dcHuffTable, acHuffTable; // Huffman table numbers
452 int prevDC; // DC coefficient accumulator
455 // DCT Huffman decoding table
456 struct DCTHuffTable {
457 Guchar firstSym[17]; // first symbol for this bit length
458 Gushort firstCode[17]; // first code for this bit length
459 Gushort numCodes[17]; // number of codes of this bit length
460 Guchar sym[256]; // symbols
463 class DCTStream: public Stream {
466 DCTStream(Stream *str1);
467 virtual ~DCTStream();
468 virtual StreamKind getKind() { return strDCT; }
469 virtual void reset();
470 virtual int getChar();
471 virtual int lookChar();
472 virtual int getPos() { return str->getPos(); }
473 virtual GString *getPSFilter(char *indent);
474 virtual GBool isBinary(GBool last = gTrue);
475 virtual Stream *getBaseStream() { return str->getBaseStream(); }
476 virtual Stream *subStream (int start1, int length1, Object *dict1)
477 { return str->subStream (start1, length1, dict1); }
478 virtual int getStart () { return str->getStart (); }
479 virtual Dict *getDict() { return str->getDict(); }
480 Stream *getRawStream() { return str; }
484 Stream *str; // stream
485 int width, height; // image size
486 int mcuWidth, mcuHeight; // size of min coding unit, in data units
487 DCTCompInfo compInfo[4]; // info for each component
488 int numComps; // number of components in image
489 int colorXform; // need YCbCr-to-RGB transform?
490 GBool gotAdobeMarker; // set if APP14 Adobe marker was present
491 int restartInterval; // restart interval, in MCUs
492 Guchar quantTables[4][64]; // quantization tables
493 int numQuantTables; // number of quantization tables
494 DCTHuffTable dcHuffTables[4]; // DC Huffman tables
495 DCTHuffTable acHuffTables[4]; // AC Huffman tables
496 int numDCHuffTables; // number of DC Huffman tables
497 int numACHuffTables; // number of AC Huffman tables
498 Guchar *rowBuf[4][32]; // buffer for one MCU
499 int comp, x, y, dy; // current position within image/MCU
500 int restartCtr; // MCUs left until restart
501 int restartMarker; // next restart marker
502 int inputBuf; // input buffer for variable length codes
503 int inputBits; // number of valid bits in input buffer
507 GBool readDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable,
508 Guchar quantTable[64], int *prevDC, Guchar data[64]);
509 int readHuffSym(DCTHuffTable *table);
510 int readAmp(int size);
513 GBool readFrameInfo();
514 GBool readScanInfo();
515 GBool readQuantTables();
516 GBool readHuffmanTables();
517 GBool readRestartInterval();
518 GBool readAdobeMarker();
524 //------------------------------------------------------------------------
526 //------------------------------------------------------------------------
528 #define flateWindow 32768 // buffer size
529 #define flateMask (flateWindow-1)
530 #define flateMaxHuffman 15 // max Huffman code length
531 #define flateMaxCodeLenCodes 19 // max # code length codes
532 #define flateMaxLitCodes 288 // max # literal codes
533 #define flateMaxDistCodes 30 // max # distance codes
535 // Huffman code table entry
537 int len; // code length in bits
538 int code; // code word
539 int val; // value represented by this code
542 // Huffman code table
543 struct FlateHuffmanTab {
544 int start[flateMaxHuffman+2]; // indexes of first code of each length
545 FlateCode *codes; // codes, sorted by length and code word
548 // Decoding info for length and distance code words
550 int bits; // # extra bits
551 int first; // first length/distance
554 class FlateStream: public Stream {
557 FlateStream(Stream *str1, int predictor1, int columns1,
558 int colors1, int bits1);
559 virtual ~FlateStream();
560 virtual StreamKind getKind() { return strFlate; }
561 virtual void reset();
562 virtual int getChar();
563 virtual int lookChar();
564 virtual int getRawChar();
565 virtual int getPos() { return str->getPos(); }
566 virtual GString *getPSFilter(char *indent);
567 virtual GBool isBinary(GBool last = gTrue);
568 virtual Stream *getBaseStream() { return str->getBaseStream(); }
569 virtual Stream *subStream (int start1, int length1, Object *dict1)
570 { return str->subStream (start1, length1, dict1); }
571 virtual int getStart () { return str->getStart (); }
572 virtual Dict *getDict() { return str->getDict(); }
576 Stream *str; // stream
577 StreamPredictor *pred; // predictor
578 Guchar buf[flateWindow]; // output data buffer
579 int index; // current index into output buffer
580 int remain; // number valid bytes in output buffer
581 int codeBuf; // input buffer
582 int codeSize; // number of bits in input buffer
583 FlateCode // literal and distance codes
584 allCodes[flateMaxLitCodes + flateMaxDistCodes];
585 FlateHuffmanTab litCodeTab; // literal code table
586 FlateHuffmanTab distCodeTab; // distance code table
587 GBool compressedBlock; // set if reading a compressed block
588 int blockLen; // remaining length of uncompressed block
589 GBool endOfBlock; // set when end of block is reached
590 GBool eof; // set when end of stream is reached
592 static int // code length code reordering
593 codeLenCodeMap[flateMaxCodeLenCodes];
594 static FlateDecode // length decoding info
595 lengthDecode[flateMaxLitCodes-257];
596 static FlateDecode // distance decoding info
597 distDecode[flateMaxDistCodes];
601 void loadFixedCodes();
602 GBool readDynamicCodes();
603 void compHuffmanCodes(FlateHuffmanTab *tab, int n);
604 int getHuffmanCodeWord(FlateHuffmanTab *tab);
605 int getCodeWord(int bits);
608 //------------------------------------------------------------------------
610 //------------------------------------------------------------------------
612 class EOFStream: public Stream {
615 EOFStream(Stream *str1);
616 virtual ~EOFStream();
617 virtual StreamKind getKind() { return strWeird; }
618 virtual void reset() {}
619 virtual int getChar() { return EOF; }
620 virtual int lookChar() { return EOF; }
621 virtual int getPos() { return str->getPos(); }
622 virtual GString *getPSFilter(char *indent) { return NULL; }
623 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
624 virtual Stream *getBaseStream() { return str->getBaseStream(); }
625 virtual Stream *subStream (int start1, int length1, Object *dict1)
626 { return str->subStream (start1, length1, dict1); }
627 virtual int getStart () { return str->getStart (); }
628 virtual Dict *getDict() { return str->getDict(); }
635 //------------------------------------------------------------------------
636 // FixedLengthEncoder
637 //------------------------------------------------------------------------
639 class FixedLengthEncoder: public Stream {
642 FixedLengthEncoder(Stream *str1, int length1);
643 ~FixedLengthEncoder();
644 virtual StreamKind getKind() { return strWeird; }
645 virtual void reset();
646 virtual int getChar();
647 virtual int lookChar();
648 virtual int getPos() { return str->getPos(); }
649 virtual GString *getPSFilter(char *indent) { return NULL; }
650 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
651 virtual Stream *getBaseStream() { return str->getBaseStream(); }
652 virtual Stream *subStream (int start1, int length1, Object *dict1)
653 { return str->subStream (start1, length1, dict1); }
654 virtual int getStart () { return str->getStart (); }
655 virtual Dict *getDict() { return str->getDict(); }
656 virtual GBool isEncoder() { return gTrue; }
665 //------------------------------------------------------------------------
667 //------------------------------------------------------------------------
669 class ASCII85Encoder: public Stream {
672 ASCII85Encoder(Stream *str1);
673 virtual ~ASCII85Encoder();
674 virtual StreamKind getKind() { return strWeird; }
675 virtual void reset();
676 virtual int getChar()
677 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
678 virtual int lookChar()
679 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
680 virtual int getPos() { return str->getPos(); }
681 virtual GString *getPSFilter(char *indent) { return NULL; }
682 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
683 virtual Stream *getBaseStream() { return str->getBaseStream(); }
684 virtual Stream *subStream (int start1, int length1, Object *dict1)
685 { return str->subStream (start1, length1, dict1); }
686 virtual int getStart () { return str->getStart (); }
687 virtual Dict *getDict() { return str->getDict(); }
688 virtual GBool isEncoder() { return gTrue; }
702 //------------------------------------------------------------------------
704 //------------------------------------------------------------------------
706 class RunLengthEncoder: public Stream {
709 RunLengthEncoder(Stream *str1);
710 virtual ~RunLengthEncoder();
711 virtual StreamKind getKind() { return strWeird; }
712 virtual void reset();
713 virtual int getChar()
714 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
715 virtual int lookChar()
716 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
717 virtual int getPos() { return str->getPos(); }
718 virtual GString *getPSFilter(char *indent) { return NULL; }
719 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
720 virtual Stream *getBaseStream() { return str->getBaseStream(); }
721 virtual Stream *subStream (int start1, int length1, Object *dict1)
722 { return str->subStream (start1, length1, dict1); }
723 virtual int getStart () { return str->getStart (); }
724 virtual Dict *getDict() { return str->getDict(); }
725 virtual GBool isEncoder() { return gTrue; }