1 //========================================================================
5 // Copyright 1996 Derek B. Noonburg
7 //========================================================================
21 //------------------------------------------------------------------------
32 strWeird // internal-use stream types
35 //------------------------------------------------------------------------
36 // Stream (base class)
37 //------------------------------------------------------------------------
48 // Reference counting.
49 int incRef() { return ++ref; }
50 int decRef() { return --ref; }
52 // Get kind of stream.
53 virtual StreamKind getKind() = 0;
55 // Reset stream to beginning.
56 virtual void reset() = 0;
58 // Get next char from stream.
59 virtual int getChar() = 0;
61 // Peek at next char in stream.
62 virtual int lookChar() = 0;
64 // Get next char from stream without using the predictor.
65 // This is only used by StreamPredictor.
66 virtual int getRawChar();
68 // Get next line from stream.
69 virtual char *getLine(char *buf, int size);
71 // Get current position in file.
72 virtual int getPos() = 0;
74 // Go to a position in the stream.
75 virtual void setPos(int pos1);
77 // Get PostScript command for the filter(s).
78 virtual GString *getPSFilter(char *indent);
80 // Does this stream type potentially contain non-printable chars?
81 virtual GBool isBinary(GBool last = gTrue) = 0;
83 // Get the base FileStream or SubStream of this stream.
84 virtual Stream *getBaseStream() = 0;
86 // Get the base file of this stream.
87 virtual BaseFile getFile() = 0;
89 // Get the dictionary associated with this stream.
90 virtual Dict *getDict() = 0;
92 // Is this an encoding filter?
93 virtual GBool isEncoder() { return gFalse; }
95 // Add filters to this stream according to the parameters in <dict>.
96 // Returns the new stream.
97 Stream *addFilters(Object *dict);
101 Stream *makeFilter(char *name, Stream *str, Object *params);
103 int ref; // reference count
106 //------------------------------------------------------------------------
108 //------------------------------------------------------------------------
113 // Create an image stream object for an image with the specified
114 // parameters. Note that these are the actual image parameters,
115 // which may be different from the predictor parameters.
116 ImageStream(Stream *str, int width, int nComps, int nBits);
123 // Gets the next pixel from the stream. <pix> should be able to hold
124 // at least nComps elements. Returns false at end of file.
125 GBool getPixel(Guchar *pix);
127 // Skip an entire line from the image.
132 Stream *str; // base stream
133 int width; // pixels per line
134 int nComps; // components per pixel
135 int nBits; // bits per component
136 int nVals; // components per line
137 Guchar *imgLine; // line buffer
138 int imgIdx; // current index in imgLine
141 //------------------------------------------------------------------------
143 //------------------------------------------------------------------------
145 class StreamPredictor {
148 // Create a predictor object. Note that the parameters are for the
149 // predictor, and may not match the actual image parameters.
150 StreamPredictor(Stream *str, int predictor,
151 int width, int nComps, int nBits);
162 Stream *str; // base stream
163 int predictor; // predictor
164 int width; // pixels per line
165 int nComps; // components per pixel
166 int nBits; // bits per component
167 int nVals; // components per line
168 int pixBytes; // bytes per pixel
169 int rowBytes; // bytes per line
170 Guchar *predLine; // line buffer
171 int predIdx; // current index in predLine
174 //------------------------------------------------------------------------
176 //------------------------------------------------------------------------
178 class FileStream: public Stream {
181 FileStream(BaseFile f1, int start1, int length1, Object *dict1);
182 virtual ~FileStream();
183 virtual StreamKind getKind() { return strFile; }
184 virtual void reset();
185 virtual int getChar()
186 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
187 virtual int lookChar()
188 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
189 virtual int getPos() { return bufPos + (bufPtr - buf); }
190 virtual void setPos(int pos1);
191 virtual GBool isBinary(GBool last = gTrue) { return last; }
192 virtual Stream *getBaseStream() { return this; }
193 virtual BaseFile getFile() { return f; }
194 virtual Dict *getDict() { return dict.getDict(); }
196 // Check for a PDF header on this stream. Skip past some garbage
200 // Get position of first byte of stream within the file.
201 int getStart() { return start; }
218 //------------------------------------------------------------------------
220 //------------------------------------------------------------------------
222 class SubStream: public Stream {
225 SubStream(Stream *str1, Object *dict1);
226 virtual ~SubStream();
227 virtual StreamKind getKind() { return str->getKind(); }
228 virtual void reset() {}
229 virtual int getChar() { return str->getChar(); }
230 virtual int lookChar() { return str->lookChar(); }
231 virtual int getPos() { return str->getPos(); }
232 virtual GBool isBinary(GBool last = gTrue) { return last; }
233 virtual Stream *getBaseStream() { return this; }
234 virtual BaseFile getFile() { return str->getFile(); }
235 virtual Dict *getDict() { return dict.getDict(); }
243 //------------------------------------------------------------------------
245 //------------------------------------------------------------------------
247 class ASCIIHexStream: public Stream {
250 ASCIIHexStream(Stream *str1);
251 virtual ~ASCIIHexStream();
252 virtual StreamKind getKind() { return strASCIIHex; }
253 virtual void reset();
254 virtual int getChar()
255 { int c = lookChar(); buf = EOF; return c; }
256 virtual int lookChar();
257 virtual int getPos() { return str->getPos(); }
258 virtual GString *getPSFilter(char *indent);
259 virtual GBool isBinary(GBool last = gTrue);
260 virtual Stream *getBaseStream() { return str->getBaseStream(); }
261 virtual BaseFile getFile() { return str->getFile(); }
262 virtual Dict *getDict() { return str->getDict(); }
271 //------------------------------------------------------------------------
273 //------------------------------------------------------------------------
275 class ASCII85Stream: public Stream {
278 ASCII85Stream(Stream *str1);
279 virtual ~ASCII85Stream();
280 virtual StreamKind getKind() { return strASCII85; }
281 virtual void reset();
282 virtual int getChar()
283 { int ch = lookChar(); ++index; return ch; }
284 virtual int lookChar();
285 virtual int getPos() { return str->getPos(); }
286 virtual GString *getPSFilter(char *indent);
287 virtual GBool isBinary(GBool last = gTrue);
288 virtual Stream *getBaseStream() { return str->getBaseStream(); }
289 virtual BaseFile getFile() { return str->getFile(); }
290 virtual Dict *getDict() { return str->getDict(); }
301 //------------------------------------------------------------------------
303 //------------------------------------------------------------------------
305 class LZWStream: public Stream {
308 LZWStream(Stream *str1, int predictor1, int columns1, int colors1,
309 int bits1, int early1);
310 virtual ~LZWStream();
311 virtual StreamKind getKind() { return strLZW; }
312 virtual void reset();
313 virtual int getChar();
314 virtual int lookChar();
315 virtual int getRawChar();
316 virtual int getPos() { return str->getPos(); }
317 virtual GString *getPSFilter(char *indent);
318 virtual GBool isBinary(GBool last = gTrue);
319 virtual Stream *getBaseStream() { return str->getBaseStream(); }
320 virtual BaseFile getFile() { return str->getFile(); }
321 virtual Dict *getDict() { return str->getDict(); }
325 Stream *str; // stream
326 StreamPredictor *pred; // predictor
327 int early; // early parameter
328 char zCmd[256]; // uncompress command
329 FILE *zPipe; // uncompress pipe
330 char *zName; // .Z file name (in zCmd)
331 int inputBuf; // input buffer
332 int inputBits; // number of bits in input buffer
333 int inCodeBits; // size of input code
334 char buf[256]; // buffer
335 char *bufPtr; // next char to read
336 char *bufEnd; // end of buffer
338 void dumpFile(FILE *f);
343 //------------------------------------------------------------------------
345 //------------------------------------------------------------------------
347 class RunLengthStream: public Stream {
350 RunLengthStream(Stream *str1);
351 virtual ~RunLengthStream();
352 virtual StreamKind getKind() { return strRunLength; }
353 virtual void reset();
354 virtual int getChar()
355 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
356 virtual int lookChar()
357 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
358 virtual int getPos() { return str->getPos(); }
359 virtual GString *getPSFilter(char *indent);
360 virtual GBool isBinary(GBool last = gTrue);
361 virtual Stream *getBaseStream() { return str->getBaseStream(); }
362 virtual BaseFile getFile() { return str->getFile(); }
363 virtual Dict *getDict() { return str->getDict(); }
368 char buf[128]; // buffer
369 char *bufPtr; // next char to read
370 char *bufEnd; // end of buffer
376 //------------------------------------------------------------------------
378 //------------------------------------------------------------------------
380 struct CCITTCodeTable;
382 class CCITTFaxStream: public Stream {
385 CCITTFaxStream(Stream *str, int encoding, GBool endOfLine,
386 GBool byteAlign, int columns, int rows,
387 GBool endOfBlock, GBool black);
388 virtual ~CCITTFaxStream();
389 virtual StreamKind getKind() { return strCCITTFax; }
390 virtual void reset();
391 virtual int getChar()
392 { int c = lookChar(); buf = EOF; return c; }
393 virtual int lookChar();
394 virtual int getPos() { return str->getPos(); }
395 virtual GString *getPSFilter(char *indent);
396 virtual GBool isBinary(GBool last = gTrue);
397 virtual Stream *getBaseStream() { return str->getBaseStream(); }
398 virtual BaseFile getFile() { return str->getFile(); }
399 virtual Dict *getDict() { return str->getDict(); }
403 Stream *str; // stream
404 int encoding; // 'K' parameter
405 GBool endOfLine; // 'EndOfLine' parameter
406 GBool byteAlign; // 'EncodedByteAlign' parameter
407 int columns; // 'Columns' parameter
408 int rows; // 'Rows' parameter
409 GBool endOfBlock; // 'EndOfBlock' parameter
410 GBool black; // 'BlackIs1' parameter
411 GBool eof; // true if at eof
412 GBool nextLine2D; // true if next line uses 2D encoding
413 int row; // current row
414 int inputBuf; // input buffer
415 int inputBits; // number of bits in input buffer
416 short *refLine; // reference line changing elements
417 int b1; // index into refLine
418 short *codingLine; // coding line changing elements
419 int a0; // index into codingLine
420 int outputBits; // remaining ouput bits
421 int buf; // character buffer
423 short getTwoDimCode();
424 short getWhiteCode();
425 short getBlackCode();
426 short lookBits(int n);
427 void eatBits(int n) { inputBits -= n; }
430 //------------------------------------------------------------------------
432 //------------------------------------------------------------------------
434 // DCT component info
436 int id; // component ID
437 GBool inScan; // is this component in the current scan?
438 int hSample, vSample; // horiz/vert sampling resolutions
439 int quantTable; // quantization table number
440 int dcHuffTable, acHuffTable; // Huffman table numbers
441 int prevDC; // DC coefficient accumulator
444 // DCT Huffman decoding table
445 struct DCTHuffTable {
446 Guchar firstSym[17]; // first symbol for this bit length
447 Gushort firstCode[17]; // first code for this bit length
448 Gushort numCodes[17]; // number of codes of this bit length
449 Guchar sym[256]; // symbols
452 class DCTStream: public Stream {
455 DCTStream(Stream *str1);
456 virtual ~DCTStream();
457 virtual StreamKind getKind() { return strDCT; }
458 virtual void reset();
459 virtual int getChar();
460 virtual int lookChar();
461 virtual int getPos() { return str->getPos(); }
462 virtual GString *getPSFilter(char *indent);
463 virtual GBool isBinary(GBool last = gTrue);
464 virtual Stream *getBaseStream() { return str->getBaseStream(); }
465 virtual BaseFile getFile() { return str->getFile(); }
466 virtual Dict *getDict() { return str->getDict(); }
467 Stream *getRawStream() { return str; }
471 Stream *str; // stream
472 int width, height; // image size
473 int mcuWidth, mcuHeight; // size of min coding unit, in data units
474 DCTCompInfo compInfo[4]; // info for each component
475 int numComps; // number of components in image
476 int colorXform; // need YCbCr-to-RGB transform?
477 GBool gotAdobeMarker; // set if APP14 Adobe marker was present
478 int restartInterval; // restart interval, in MCUs
479 Guchar quantTables[4][64]; // quantization tables
480 int numQuantTables; // number of quantization tables
481 DCTHuffTable dcHuffTables[4]; // DC Huffman tables
482 DCTHuffTable acHuffTables[4]; // AC Huffman tables
483 int numDCHuffTables; // number of DC Huffman tables
484 int numACHuffTables; // number of AC Huffman tables
485 Guchar *rowBuf[4][32]; // buffer for one MCU
486 int comp, x, y, dy; // current position within image/MCU
487 int restartCtr; // MCUs left until restart
488 int restartMarker; // next restart marker
489 int inputBuf; // input buffer for variable length codes
490 int inputBits; // number of valid bits in input buffer
494 GBool readDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable,
495 Guchar quantTable[64], int *prevDC, Guchar data[64]);
496 int readHuffSym(DCTHuffTable *table);
497 int readAmp(int size);
500 GBool readFrameInfo();
501 GBool readScanInfo();
502 GBool readQuantTables();
503 GBool readHuffmanTables();
504 GBool readRestartInterval();
505 GBool readAdobeMarker();
511 //------------------------------------------------------------------------
513 //------------------------------------------------------------------------
515 #define flateWindow 32768 // buffer size
516 #define flateMask (flateWindow-1)
517 #define flateMaxHuffman 15 // max Huffman code length
518 #define flateMaxCodeLenCodes 19 // max # code length codes
519 #define flateMaxLitCodes 288 // max # literal codes
520 #define flateMaxDistCodes 30 // max # distance codes
522 // Huffman code table entry
524 int len; // code length in bits
525 int code; // code word
526 int val; // value represented by this code
529 // Huffman code table
530 struct FlateHuffmanTab {
531 int start[flateMaxHuffman+2]; // indexes of first code of each length
532 FlateCode *codes; // codes, sorted by length and code word
535 // Decoding info for length and distance code words
537 int bits; // # extra bits
538 int first; // first length/distance
541 class FlateStream: public Stream {
544 FlateStream(Stream *str1, int predictor1, int columns1,
545 int colors1, int bits1);
546 virtual ~FlateStream();
547 virtual StreamKind getKind() { return strFlate; }
548 virtual void reset();
549 virtual int getChar();
550 virtual int lookChar();
551 virtual int getRawChar();
552 virtual int getPos() { return str->getPos(); }
553 virtual GString *getPSFilter(char *indent);
554 virtual GBool isBinary(GBool last = gTrue);
555 virtual Stream *getBaseStream() { return str->getBaseStream(); }
556 virtual BaseFile getFile() { return str->getFile(); }
557 virtual Dict *getDict() { return str->getDict(); }
561 Stream *str; // stream
562 StreamPredictor *pred; // predictor
563 Guchar buf[flateWindow]; // output data buffer
564 int index; // current index into output buffer
565 int remain; // number valid bytes in output buffer
566 int codeBuf; // input buffer
567 int codeSize; // number of bits in input buffer
568 FlateCode // literal and distance codes
569 allCodes[flateMaxLitCodes + flateMaxDistCodes];
570 FlateHuffmanTab litCodeTab; // literal code table
571 FlateHuffmanTab distCodeTab; // distance code table
572 GBool compressedBlock; // set if reading a compressed block
573 int blockLen; // remaining length of uncompressed block
574 GBool endOfBlock; // set when end of block is reached
575 GBool eof; // set when end of stream is reached
577 static int // code length code reordering
578 codeLenCodeMap[flateMaxCodeLenCodes];
579 static FlateDecode // length decoding info
580 lengthDecode[flateMaxLitCodes-257];
581 static FlateDecode // distance decoding info
582 distDecode[flateMaxDistCodes];
586 void loadFixedCodes();
587 GBool readDynamicCodes();
588 void compHuffmanCodes(FlateHuffmanTab *tab, int n);
589 int getHuffmanCodeWord(FlateHuffmanTab *tab);
590 int getCodeWord(int bits);
593 //------------------------------------------------------------------------
595 //------------------------------------------------------------------------
597 class EOFStream: public Stream {
600 EOFStream(Stream *str1);
601 virtual ~EOFStream();
602 virtual StreamKind getKind() { return strWeird; }
603 virtual void reset() {}
604 virtual int getChar() { return EOF; }
605 virtual int lookChar() { return EOF; }
606 virtual int getPos() { return str->getPos(); }
607 virtual GString *getPSFilter(char *indent) { return NULL; }
608 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
609 virtual Stream *getBaseStream() { return str->getBaseStream(); }
610 virtual BaseFile getFile() { return str->getFile(); }
611 virtual Dict *getDict() { return str->getDict(); }
618 //------------------------------------------------------------------------
619 // FixedLengthEncoder
620 //------------------------------------------------------------------------
622 class FixedLengthEncoder: public Stream {
625 FixedLengthEncoder(Stream *str1, int length1);
626 ~FixedLengthEncoder();
627 virtual StreamKind getKind() { return strWeird; }
628 virtual void reset();
629 virtual int getChar();
630 virtual int lookChar();
631 virtual int getPos() { return str->getPos(); }
632 virtual GString *getPSFilter(char *indent) { return NULL; }
633 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
634 virtual Stream *getBaseStream() { return str->getBaseStream(); }
635 virtual BaseFile getFile() { return str->getFile(); }
636 virtual Dict *getDict() { return str->getDict(); }
637 virtual GBool isEncoder() { return gTrue; }
646 //------------------------------------------------------------------------
648 //------------------------------------------------------------------------
650 class ASCII85Encoder: public Stream {
653 ASCII85Encoder(Stream *str1);
654 virtual ~ASCII85Encoder();
655 virtual StreamKind getKind() { return strWeird; }
656 virtual void reset();
657 virtual int getChar()
658 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
659 virtual int lookChar()
660 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
661 virtual int getPos() { return str->getPos(); }
662 virtual GString *getPSFilter(char *indent) { return NULL; }
663 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
664 virtual Stream *getBaseStream() { return str->getBaseStream(); }
665 virtual BaseFile getFile() { return str->getFile(); }
666 virtual Dict *getDict() { return str->getDict(); }
667 virtual GBool isEncoder() { return gTrue; }
681 //------------------------------------------------------------------------
683 //------------------------------------------------------------------------
685 class RunLengthEncoder: public Stream {
688 RunLengthEncoder(Stream *str1);
689 virtual ~RunLengthEncoder();
690 virtual StreamKind getKind() { return strWeird; }
691 virtual void reset();
692 virtual int getChar()
693 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
694 virtual int lookChar()
695 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
696 virtual int getPos() { return str->getPos(); }
697 virtual GString *getPSFilter(char *indent) { return NULL; }
698 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
699 virtual Stream *getBaseStream() { return str->getBaseStream(); }
700 virtual BaseFile getFile() { return str->getFile(); }
701 virtual Dict *getDict() { return str->getDict(); }
702 virtual GBool isEncoder() { return gTrue; }