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 the base file of this stream.
86 virtual FILE *getFile() = 0;
88 // Get the dictionary associated with this stream.
89 virtual Dict *getDict() = 0;
91 // Is this an encoding filter?
92 virtual GBool isEncoder() { return gFalse; }
94 // Add filters to this stream according to the parameters in <dict>.
95 // Returns the new stream.
96 Stream *addFilters(Object *dict);
100 Stream *makeFilter(char *name, Stream *str, Object *params);
102 int ref; // reference count
105 //------------------------------------------------------------------------
107 //------------------------------------------------------------------------
112 // Create an image stream object for an image with the specified
113 // parameters. Note that these are the actual image parameters,
114 // which may be different from the predictor parameters.
115 ImageStream(Stream *str, int width, int nComps, int nBits);
122 // Gets the next pixel from the stream. <pix> should be able to hold
123 // at least nComps elements. Returns false at end of file.
124 GBool getPixel(Guchar *pix);
126 // Skip an entire line from the image.
131 Stream *str; // base stream
132 int width; // pixels per line
133 int nComps; // components per pixel
134 int nBits; // bits per component
135 int nVals; // components per line
136 Guchar *imgLine; // line buffer
137 int imgIdx; // current index in imgLine
140 //------------------------------------------------------------------------
142 //------------------------------------------------------------------------
144 class StreamPredictor {
147 // Create a predictor object. Note that the parameters are for the
148 // predictor, and may not match the actual image parameters.
149 StreamPredictor(Stream *str, int predictor,
150 int width, int nComps, int nBits);
161 Stream *str; // base stream
162 int predictor; // predictor
163 int width; // pixels per line
164 int nComps; // components per pixel
165 int nBits; // bits per component
166 int nVals; // components per line
167 int pixBytes; // bytes per pixel
168 int rowBytes; // bytes per line
169 Guchar *predLine; // line buffer
170 int predIdx; // current index in predLine
173 //------------------------------------------------------------------------
175 //------------------------------------------------------------------------
177 class FileStream: public Stream {
180 FileStream(FILE *f1, int start1, int length1, Object *dict1);
181 virtual ~FileStream();
182 virtual StreamKind getKind() { return strFile; }
183 virtual void reset();
184 virtual int getChar()
185 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
186 virtual int lookChar()
187 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
188 virtual int getPos() { return bufPos + (bufPtr - buf); }
189 virtual void setPos(int pos1);
190 virtual GBool isBinary(GBool last = gTrue) { return last; }
191 virtual Stream *getBaseStream() { return this; }
192 virtual FILE *getFile() { return f; }
193 virtual Dict *getDict() { return dict.getDict(); }
195 // Check for a PDF header on this stream. Skip past some garbage
199 // Get position of first byte of stream within the file.
200 int getStart() { return start; }
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 FILE *getFile() { return str->getFile(); }
234 virtual Dict *getDict() { return dict.getDict(); }
242 //------------------------------------------------------------------------
244 //------------------------------------------------------------------------
246 class ASCIIHexStream: public Stream {
249 ASCIIHexStream(Stream *str1);
250 virtual ~ASCIIHexStream();
251 virtual StreamKind getKind() { return strASCIIHex; }
252 virtual void reset();
253 virtual int getChar()
254 { int c = lookChar(); buf = EOF; return c; }
255 virtual int lookChar();
256 virtual int getPos() { return str->getPos(); }
257 virtual GString *getPSFilter(char *indent);
258 virtual GBool isBinary(GBool last = gTrue);
259 virtual Stream *getBaseStream() { return str->getBaseStream(); }
260 virtual FILE *getFile() { return str->getFile(); }
261 virtual Dict *getDict() { return str->getDict(); }
270 //------------------------------------------------------------------------
272 //------------------------------------------------------------------------
274 class ASCII85Stream: public Stream {
277 ASCII85Stream(Stream *str1);
278 virtual ~ASCII85Stream();
279 virtual StreamKind getKind() { return strASCII85; }
280 virtual void reset();
281 virtual int getChar()
282 { int ch = lookChar(); ++index; return ch; }
283 virtual int lookChar();
284 virtual int getPos() { return str->getPos(); }
285 virtual GString *getPSFilter(char *indent);
286 virtual GBool isBinary(GBool last = gTrue);
287 virtual Stream *getBaseStream() { return str->getBaseStream(); }
288 virtual FILE *getFile() { return str->getFile(); }
289 virtual Dict *getDict() { return str->getDict(); }
300 //------------------------------------------------------------------------
302 //------------------------------------------------------------------------
304 class LZWStream: public Stream {
307 LZWStream(Stream *str1, int predictor1, int columns1, int colors1,
308 int bits1, int early1);
309 virtual ~LZWStream();
310 virtual StreamKind getKind() { return strLZW; }
311 virtual void reset();
312 virtual int getChar();
313 virtual int lookChar();
314 virtual int getRawChar();
315 virtual int getPos() { return str->getPos(); }
316 virtual GString *getPSFilter(char *indent);
317 virtual GBool isBinary(GBool last = gTrue);
318 virtual Stream *getBaseStream() { return str->getBaseStream(); }
319 virtual FILE *getFile() { return str->getFile(); }
320 virtual Dict *getDict() { return str->getDict(); }
324 Stream *str; // stream
325 StreamPredictor *pred; // predictor
326 int early; // early parameter
327 char zCmd[256]; // uncompress command
328 FILE *zPipe; // uncompress pipe
329 char *zName; // .Z file name (in zCmd)
330 int inputBuf; // input buffer
331 int inputBits; // number of bits in input buffer
332 int inCodeBits; // size of input code
333 char buf[256]; // buffer
334 char *bufPtr; // next char to read
335 char *bufEnd; // end of buffer
337 void dumpFile(FILE *f);
342 //------------------------------------------------------------------------
344 //------------------------------------------------------------------------
346 class RunLengthStream: public Stream {
349 RunLengthStream(Stream *str1);
350 virtual ~RunLengthStream();
351 virtual StreamKind getKind() { return strRunLength; }
352 virtual void reset();
353 virtual int getChar()
354 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
355 virtual int lookChar()
356 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
357 virtual int getPos() { return str->getPos(); }
358 virtual GString *getPSFilter(char *indent);
359 virtual GBool isBinary(GBool last = gTrue);
360 virtual Stream *getBaseStream() { return str->getBaseStream(); }
361 virtual FILE *getFile() { return str->getFile(); }
362 virtual Dict *getDict() { return str->getDict(); }
367 char buf[128]; // buffer
368 char *bufPtr; // next char to read
369 char *bufEnd; // end of buffer
375 //------------------------------------------------------------------------
377 //------------------------------------------------------------------------
379 struct CCITTCodeTable;
381 class CCITTFaxStream: public Stream {
384 CCITTFaxStream(Stream *str, int encoding, GBool endOfLine,
385 GBool byteAlign, int columns, int rows,
386 GBool endOfBlock, GBool black);
387 virtual ~CCITTFaxStream();
388 virtual StreamKind getKind() { return strCCITTFax; }
389 virtual void reset();
390 virtual int getChar()
391 { int c = lookChar(); buf = EOF; return c; }
392 virtual int lookChar();
393 virtual int getPos() { return str->getPos(); }
394 virtual GString *getPSFilter(char *indent);
395 virtual GBool isBinary(GBool last = gTrue);
396 virtual Stream *getBaseStream() { return str->getBaseStream(); }
397 virtual FILE *getFile() { return str->getFile(); }
398 virtual Dict *getDict() { return str->getDict(); }
402 Stream *str; // stream
403 int encoding; // 'K' parameter
404 GBool endOfLine; // 'EndOfLine' parameter
405 GBool byteAlign; // 'EncodedByteAlign' parameter
406 int columns; // 'Columns' parameter
407 int rows; // 'Rows' parameter
408 GBool endOfBlock; // 'EndOfBlock' parameter
409 GBool black; // 'BlackIs1' parameter
410 GBool eof; // true if at eof
411 GBool nextLine2D; // true if next line uses 2D encoding
412 int row; // current row
413 int inputBuf; // input buffer
414 int inputBits; // number of bits in input buffer
415 short *refLine; // reference line changing elements
416 int b1; // index into refLine
417 short *codingLine; // coding line changing elements
418 int a0; // index into codingLine
419 int outputBits; // remaining ouput bits
420 int buf; // character buffer
422 short getTwoDimCode();
423 short getWhiteCode();
424 short getBlackCode();
425 short lookBits(int n);
426 void eatBits(int n) { inputBits -= n; }
429 //------------------------------------------------------------------------
431 //------------------------------------------------------------------------
433 // DCT component info
435 int id; // component ID
436 GBool inScan; // is this component in the current scan?
437 int hSample, vSample; // horiz/vert sampling resolutions
438 int quantTable; // quantization table number
439 int dcHuffTable, acHuffTable; // Huffman table numbers
440 int prevDC; // DC coefficient accumulator
443 // DCT Huffman decoding table
444 struct DCTHuffTable {
445 Guchar firstSym[17]; // first symbol for this bit length
446 Gushort firstCode[17]; // first code for this bit length
447 Gushort numCodes[17]; // number of codes of this bit length
448 Guchar sym[256]; // symbols
451 class DCTStream: public Stream {
454 DCTStream(Stream *str1);
455 virtual ~DCTStream();
456 virtual StreamKind getKind() { return strDCT; }
457 virtual void reset();
458 virtual int getChar();
459 virtual int lookChar();
460 virtual int getPos() { return str->getPos(); }
461 virtual GString *getPSFilter(char *indent);
462 virtual GBool isBinary(GBool last = gTrue);
463 virtual Stream *getBaseStream() { return str->getBaseStream(); }
464 virtual FILE *getFile() { return str->getFile(); }
465 virtual Dict *getDict() { return str->getDict(); }
466 Stream *getRawStream() { return str; }
470 Stream *str; // stream
471 int width, height; // image size
472 int mcuWidth, mcuHeight; // size of min coding unit, in data units
473 DCTCompInfo compInfo[4]; // info for each component
474 int numComps; // number of components in image
475 int colorXform; // need YCbCr-to-RGB transform?
476 GBool gotAdobeMarker; // set if APP14 Adobe marker was present
477 int restartInterval; // restart interval, in MCUs
478 Guchar quantTables[4][64]; // quantization tables
479 int numQuantTables; // number of quantization tables
480 DCTHuffTable dcHuffTables[4]; // DC Huffman tables
481 DCTHuffTable acHuffTables[4]; // AC Huffman tables
482 int numDCHuffTables; // number of DC Huffman tables
483 int numACHuffTables; // number of AC Huffman tables
484 Guchar *rowBuf[4][32]; // buffer for one MCU
485 int comp, x, y, dy; // current position within image/MCU
486 int restartCtr; // MCUs left until restart
487 int restartMarker; // next restart marker
488 int inputBuf; // input buffer for variable length codes
489 int inputBits; // number of valid bits in input buffer
493 GBool readDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable,
494 Guchar quantTable[64], int *prevDC, Guchar data[64]);
495 int readHuffSym(DCTHuffTable *table);
496 int readAmp(int size);
499 GBool readFrameInfo();
500 GBool readScanInfo();
501 GBool readQuantTables();
502 GBool readHuffmanTables();
503 GBool readRestartInterval();
504 GBool readAdobeMarker();
510 //------------------------------------------------------------------------
512 //------------------------------------------------------------------------
514 #define flateWindow 32768 // buffer size
515 #define flateMask (flateWindow-1)
516 #define flateMaxHuffman 15 // max Huffman code length
517 #define flateMaxCodeLenCodes 19 // max # code length codes
518 #define flateMaxLitCodes 288 // max # literal codes
519 #define flateMaxDistCodes 30 // max # distance codes
521 // Huffman code table entry
523 int len; // code length in bits
524 int code; // code word
525 int val; // value represented by this code
528 // Huffman code table
529 struct FlateHuffmanTab {
530 int start[flateMaxHuffman+2]; // indexes of first code of each length
531 FlateCode *codes; // codes, sorted by length and code word
534 // Decoding info for length and distance code words
536 int bits; // # extra bits
537 int first; // first length/distance
540 class FlateStream: public Stream {
543 FlateStream(Stream *str1, int predictor1, int columns1,
544 int colors1, int bits1);
545 virtual ~FlateStream();
546 virtual StreamKind getKind() { return strFlate; }
547 virtual void reset();
548 virtual int getChar();
549 virtual int lookChar();
550 virtual int getRawChar();
551 virtual int getPos() { return str->getPos(); }
552 virtual GString *getPSFilter(char *indent);
553 virtual GBool isBinary(GBool last = gTrue);
554 virtual Stream *getBaseStream() { return str->getBaseStream(); }
555 virtual FILE *getFile() { return str->getFile(); }
556 virtual Dict *getDict() { return str->getDict(); }
560 Stream *str; // stream
561 StreamPredictor *pred; // predictor
562 Guchar buf[flateWindow]; // output data buffer
563 int index; // current index into output buffer
564 int remain; // number valid bytes in output buffer
565 int codeBuf; // input buffer
566 int codeSize; // number of bits in input buffer
567 FlateCode // literal and distance codes
568 allCodes[flateMaxLitCodes + flateMaxDistCodes];
569 FlateHuffmanTab litCodeTab; // literal code table
570 FlateHuffmanTab distCodeTab; // distance code table
571 GBool compressedBlock; // set if reading a compressed block
572 int blockLen; // remaining length of uncompressed block
573 GBool endOfBlock; // set when end of block is reached
574 GBool eof; // set when end of stream is reached
576 static int // code length code reordering
577 codeLenCodeMap[flateMaxCodeLenCodes];
578 static FlateDecode // length decoding info
579 lengthDecode[flateMaxLitCodes-257];
580 static FlateDecode // distance decoding info
581 distDecode[flateMaxDistCodes];
585 void loadFixedCodes();
586 GBool readDynamicCodes();
587 void compHuffmanCodes(FlateHuffmanTab *tab, int n);
588 int getHuffmanCodeWord(FlateHuffmanTab *tab);
589 int getCodeWord(int bits);
592 //------------------------------------------------------------------------
594 //------------------------------------------------------------------------
596 class EOFStream: public Stream {
599 EOFStream(Stream *str1);
600 virtual ~EOFStream();
601 virtual StreamKind getKind() { return strWeird; }
602 virtual void reset() {}
603 virtual int getChar() { return EOF; }
604 virtual int lookChar() { return EOF; }
605 virtual int getPos() { return str->getPos(); }
606 virtual GString *getPSFilter(char *indent) { return NULL; }
607 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
608 virtual Stream *getBaseStream() { return str->getBaseStream(); }
609 virtual FILE *getFile() { return str->getFile(); }
610 virtual Dict *getDict() { return str->getDict(); }
617 //------------------------------------------------------------------------
618 // FixedLengthEncoder
619 //------------------------------------------------------------------------
621 class FixedLengthEncoder: public Stream {
624 FixedLengthEncoder(Stream *str1, int length1);
625 ~FixedLengthEncoder();
626 virtual StreamKind getKind() { return strWeird; }
627 virtual void reset();
628 virtual int getChar();
629 virtual int lookChar();
630 virtual int getPos() { return str->getPos(); }
631 virtual GString *getPSFilter(char *indent) { return NULL; }
632 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
633 virtual Stream *getBaseStream() { return str->getBaseStream(); }
634 virtual FILE *getFile() { return str->getFile(); }
635 virtual Dict *getDict() { return str->getDict(); }
636 virtual GBool isEncoder() { return gTrue; }
645 //------------------------------------------------------------------------
647 //------------------------------------------------------------------------
649 class ASCII85Encoder: public Stream {
652 ASCII85Encoder(Stream *str1);
653 virtual ~ASCII85Encoder();
654 virtual StreamKind getKind() { return strWeird; }
655 virtual void reset();
656 virtual int getChar()
657 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
658 virtual int lookChar()
659 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
660 virtual int getPos() { return str->getPos(); }
661 virtual GString *getPSFilter(char *indent) { return NULL; }
662 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
663 virtual Stream *getBaseStream() { return str->getBaseStream(); }
664 virtual FILE *getFile() { return str->getFile(); }
665 virtual Dict *getDict() { return str->getDict(); }
666 virtual GBool isEncoder() { return gTrue; }
680 //------------------------------------------------------------------------
682 //------------------------------------------------------------------------
684 class RunLengthEncoder: public Stream {
687 RunLengthEncoder(Stream *str1);
688 virtual ~RunLengthEncoder();
689 virtual StreamKind getKind() { return strWeird; }
690 virtual void reset();
691 virtual int getChar()
692 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
693 virtual int lookChar()
694 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
695 virtual int getPos() { return str->getPos(); }
696 virtual GString *getPSFilter(char *indent) { return NULL; }
697 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
698 virtual Stream *getBaseStream() { return str->getBaseStream(); }
699 virtual FILE *getFile() { return str->getFile(); }
700 virtual Dict *getDict() { return str->getDict(); }
701 virtual GBool isEncoder() { return gTrue; }