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 // Reset stream and allocate buffers for use by getPixel().
58 // The image has <width1> pixels per line, <nComps1> components per
59 // pixel, and <nBits1> bits per component.
60 virtual void resetImage(int width1, int nComps1, int nBits1);
62 // Get next char from stream.
63 virtual int getChar() = 0;
65 // Peek at next char in stream.
66 virtual int lookChar() = 0;
68 // Get next line from stream.
69 virtual char *getLine(char *buf, int size);
71 // Gets the next pixel from the stream. (resetImage() must be called
72 // first.) <pix> should be able to hold at least nComps elements.
73 // Returns false at end of file.
74 virtual GBool getImagePixel(Guchar *pix);
76 // Skip an entire line from the image.
77 virtual void skipImageLine();
79 // Get current position in file.
80 virtual int getPos() = 0;
82 // Go to a position in the stream.
83 virtual void setPos(int pos1);
85 // Get PostScript command for the filter(s).
86 virtual GString *getPSFilter(char *indent);
88 // Does this stream type potentially contain non-printable chars?
89 virtual GBool isBinary(GBool last = gTrue) = 0;
91 // Get the base FileStream or SubStream of this stream.
92 virtual Stream *getBaseStream() = 0;
94 // Get the base file of this stream.
95 virtual FILE *getFile() = 0;
97 // Get the dictionary associated with this stream.
98 virtual Dict *getDict() = 0;
100 // Is this an encoding filter?
101 virtual GBool isEncoder() { return gFalse; }
103 // Add filters to this stream according to the parameters in <dict>.
104 // Returns the new stream.
105 Stream *addFilters(Object *dict);
109 Stream *makeFilter(char *name, Stream *str, Object *params);
111 int ref; // reference count
116 int predictor; // predictor
117 int width; // pixels per line
118 int nComps; // components per pixel
119 int nBits; // bits per component
120 int nVals; // components per line
121 int pixBytes; // bytes per pixel
122 int rowBytes; // bytes per line
123 Guchar *rawLine; // raw line buffer
124 Guchar *pixLine; // pixel line buffer
125 int pixIdx; // current index in line buffer
128 //------------------------------------------------------------------------
130 //------------------------------------------------------------------------
132 class FileStream: public Stream {
135 FileStream(FILE *f1, int start1, int length1, Object *dict1);
136 virtual ~FileStream();
137 virtual StreamKind getKind() { return strFile; }
138 virtual void reset();
139 virtual int getChar()
140 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
141 virtual int lookChar()
142 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
143 virtual int getPos() { return bufPos + (bufPtr - buf); }
144 virtual void setPos(int pos1);
145 virtual GBool isBinary(GBool last = gTrue) { return last; }
146 virtual Stream *getBaseStream() { return this; }
147 virtual FILE *getFile() { return f; }
148 virtual Dict *getDict() { return dict.getDict(); }
150 // Check for a PDF header on this stream. Skip past some garbage
154 // Get position of first byte of stream within the file.
155 int getStart() { return start; }
172 //------------------------------------------------------------------------
174 //------------------------------------------------------------------------
176 class SubStream: public Stream {
179 SubStream(Stream *str1, Object *dict1);
180 virtual ~SubStream();
181 virtual StreamKind getKind() { return str->getKind(); }
182 virtual void reset() {}
183 virtual int getChar() { return str->getChar(); }
184 virtual int lookChar() { return str->lookChar(); }
185 virtual int getPos() { return str->getPos(); }
186 virtual GBool isBinary(GBool last = gTrue) { return last; }
187 virtual Stream *getBaseStream() { return this; }
188 virtual FILE *getFile() { return str->getFile(); }
189 virtual Dict *getDict() { return dict.getDict(); }
197 //------------------------------------------------------------------------
199 //------------------------------------------------------------------------
201 class ASCIIHexStream: public Stream {
204 ASCIIHexStream(Stream *str1);
205 virtual ~ASCIIHexStream();
206 virtual StreamKind getKind() { return strASCIIHex; }
207 virtual void reset();
208 virtual int getChar()
209 { int c = lookChar(); buf = EOF; return c; }
210 virtual int lookChar();
211 virtual int getPos() { return str->getPos(); }
212 virtual GString *getPSFilter(char *indent);
213 virtual GBool isBinary(GBool last = gTrue);
214 virtual Stream *getBaseStream() { return str->getBaseStream(); }
215 virtual FILE *getFile() { return str->getFile(); }
216 virtual Dict *getDict() { return str->getDict(); }
225 //------------------------------------------------------------------------
227 //------------------------------------------------------------------------
229 class ASCII85Stream: public Stream {
232 ASCII85Stream(Stream *str1);
233 virtual ~ASCII85Stream();
234 virtual StreamKind getKind() { return strASCII85; }
235 virtual void reset();
236 virtual int getChar()
237 { int ch = lookChar(); ++index; return ch; }
238 virtual int lookChar();
239 virtual int getPos() { return str->getPos(); }
240 virtual GString *getPSFilter(char *indent);
241 virtual GBool isBinary(GBool last = gTrue);
242 virtual Stream *getBaseStream() { return str->getBaseStream(); }
243 virtual FILE *getFile() { return str->getFile(); }
244 virtual Dict *getDict() { return str->getDict(); }
255 //------------------------------------------------------------------------
257 //------------------------------------------------------------------------
259 class LZWStream: public Stream {
262 LZWStream(Stream *str1, int predictor1, int columns1, int colors1,
263 int bits1, int early1);
264 virtual ~LZWStream();
265 virtual StreamKind getKind() { return strLZW; }
266 virtual void reset();
267 virtual int getChar();
268 virtual int lookChar();
269 virtual int getPos() { return str->getPos(); }
270 virtual GString *getPSFilter(char *indent);
271 virtual GBool isBinary(GBool last = gTrue);
272 virtual Stream *getBaseStream() { return str->getBaseStream(); }
273 virtual FILE *getFile() { return str->getFile(); }
274 virtual Dict *getDict() { return str->getDict(); }
278 Stream *str; // stream
279 int early; // early parameter
280 char zCmd[256]; // uncompress command
281 FILE *zPipe; // uncompress pipe
282 char *zName; // .Z file name (in zCmd)
283 int inputBuf; // input buffer
284 int inputBits; // number of bits in input buffer
285 int inCodeBits; // size of input code
286 char buf[256]; // buffer
287 char *bufPtr; // next char to read
288 char *bufEnd; // end of buffer
290 void dumpFile(FILE *f);
295 //------------------------------------------------------------------------
297 //------------------------------------------------------------------------
299 class RunLengthStream: public Stream {
302 RunLengthStream(Stream *str1);
303 virtual ~RunLengthStream();
304 virtual StreamKind getKind() { return strRunLength; }
305 virtual void reset();
306 virtual int getChar()
307 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
308 virtual int lookChar()
309 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
310 virtual int getPos() { return str->getPos(); }
311 virtual GString *getPSFilter(char *indent);
312 virtual GBool isBinary(GBool last = gTrue);
313 virtual Stream *getBaseStream() { return str->getBaseStream(); }
314 virtual FILE *getFile() { return str->getFile(); }
315 virtual Dict *getDict() { return str->getDict(); }
320 char buf[128]; // buffer
321 char *bufPtr; // next char to read
322 char *bufEnd; // end of buffer
328 //------------------------------------------------------------------------
330 //------------------------------------------------------------------------
332 struct CCITTCodeTable;
334 class CCITTFaxStream: public Stream {
337 CCITTFaxStream(Stream *str1, int encoding1, GBool byteAlign1,
338 int columns1, int rows1, GBool black1);
339 virtual ~CCITTFaxStream();
340 virtual StreamKind getKind() { return strCCITTFax; }
341 virtual void reset();
342 virtual int getChar()
343 { int c = lookChar(); buf = EOF; return c; }
344 virtual int lookChar();
345 virtual int getPos() { return str->getPos(); }
346 virtual GString *getPSFilter(char *indent);
347 virtual GBool isBinary(GBool last = gTrue);
348 virtual Stream *getBaseStream() { return str->getBaseStream(); }
349 virtual FILE *getFile() { return str->getFile(); }
350 virtual Dict *getDict() { return str->getDict(); }
354 Stream *str; // stream
355 int encoding; // 'K' parameter
356 GBool byteAlign; // 'EncodedByteAlign' parameter
357 int columns; // 'Columns' parameter
358 int rows; // 'Rows' parameter
359 GBool black; // 'BlackIs1' parameter
360 GBool eof; // true if at eof
361 GBool nextLine2D; // true if next line uses 2D encoding
362 int inputBuf; // input buffer
363 int inputBits; // number of bits in input buffer
364 short *refLine; // reference line changing elements
365 int b1; // index into refLine
366 short *codingLine; // coding line changing elements
367 int a0; // index into codingLine
368 int outputBits; // remaining ouput bits
369 int buf; // character buffer
371 short getTwoDimCode();
372 short getWhiteCode();
373 short getBlackCode();
375 void eatBits(int bits) { inputBits -= bits; }
378 //------------------------------------------------------------------------
380 //------------------------------------------------------------------------
382 // DCT component info
384 int id; // component ID
385 GBool inScan; // is this component in the current scan?
386 int hSample, vSample; // horiz/vert sampling resolutions
387 int quantTable; // quantization table number
388 int dcHuffTable, acHuffTable; // Huffman table numbers
389 int prevDC; // DC coefficient accumulator
392 // DCT Huffman decoding table
393 struct DCTHuffTable {
394 Guchar firstSym[17]; // first symbol for this bit length
395 Gushort firstCode[17]; // first code for this bit length
396 Gushort numCodes[17]; // number of codes of this bit length
397 Guchar sym[256]; // symbols
400 class DCTStream: public Stream {
403 DCTStream(Stream *str1);
404 virtual ~DCTStream();
405 virtual StreamKind getKind() { return strDCT; }
406 virtual void reset();
407 virtual int getChar();
408 virtual int lookChar();
409 virtual int getPos() { return str->getPos(); }
410 virtual GString *getPSFilter(char *indent);
411 virtual GBool isBinary(GBool last = gTrue);
412 virtual Stream *getBaseStream() { return str->getBaseStream(); }
413 virtual FILE *getFile() { return str->getFile(); }
414 virtual Dict *getDict() { return str->getDict(); }
415 Stream *getRawStream() { return str; }
419 Stream *str; // stream
420 int width, height; // image size
421 int mcuWidth, mcuHeight; // size of min coding unit, in data units
422 DCTCompInfo compInfo[4]; // info for each component
423 int numComps; // number of components in image
424 int colorXform; // need YCbCr-to-RGB transform?
425 int restartInterval; // restart interval, in MCUs
426 Guchar quantTables[4][64]; // quantization tables
427 int numQuantTables; // number of quantization tables
428 DCTHuffTable dcHuffTables[4]; // DC Huffman tables
429 DCTHuffTable acHuffTables[4]; // AC Huffman tables
430 int numDCHuffTables; // number of DC Huffman tables
431 int numACHuffTables; // number of AC Huffman tables
432 Guchar *rowBuf[4][32]; // buffer for one MCU
433 int comp, x, y, dy; // current position within image/MCU
434 int restartCtr; // MCUs left until restart
435 int restartMarker; // next restart marker
436 int inputBuf; // input buffer for variable length codes
437 int inputBits; // number of valid bits in input buffer
441 GBool readDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable,
442 Guchar quantTable[64], int *prevDC, Guchar data[64]);
443 int readHuffSym(DCTHuffTable *table);
444 int readAmp(int size);
447 GBool readFrameInfo();
448 GBool readScanInfo();
449 GBool readQuantTables();
450 GBool readHuffmanTables();
451 GBool readRestartInterval();
452 GBool readAdobeMarker();
458 //------------------------------------------------------------------------
460 //------------------------------------------------------------------------
462 #define flateWindow 32768 // buffer size
463 #define flateMask (flateWindow-1)
464 #define flateMaxHuffman 15 // max Huffman code length
465 #define flateMaxCodeLenCodes 19 // max # code length codes
466 #define flateMaxLitCodes 288 // max # literal codes
467 #define flateMaxDistCodes 30 // max # distance codes
469 // Huffman code table entry
471 int len; // code length in bits
472 int code; // code word
473 int val; // value represented by this code
476 // Huffman code table
477 struct FlateHuffmanTab {
478 int start[flateMaxHuffman+2]; // indexes of first code of each length
479 FlateCode *codes; // codes, sorted by length and code word
482 // Decoding info for length and distance code words
484 int bits; // # extra bits
485 int first; // first length/distance
488 class FlateStream: public Stream {
491 FlateStream(Stream *str1, int predictor1, int columns1,
492 int colors1, int bits1);
493 virtual ~FlateStream();
494 virtual StreamKind getKind() { return strFlate; }
495 virtual void reset();
496 virtual int getChar();
497 virtual int lookChar();
498 virtual int getPos() { return str->getPos(); }
499 virtual GString *getPSFilter(char *indent);
500 virtual GBool isBinary(GBool last = gTrue);
501 virtual Stream *getBaseStream() { return str->getBaseStream(); }
502 virtual FILE *getFile() { return str->getFile(); }
503 virtual Dict *getDict() { return str->getDict(); }
507 Stream *str; // stream
508 Guchar buf[flateWindow]; // output data buffer
509 int index; // current index into output buffer
510 int remain; // number valid bytes in output buffer
511 int codeBuf; // input buffer
512 int codeSize; // number of bits in input buffer
513 FlateCode // literal and distance codes
514 allCodes[flateMaxLitCodes + flateMaxDistCodes];
515 FlateHuffmanTab litCodeTab; // literal code table
516 FlateHuffmanTab distCodeTab; // distance code table
517 GBool compressedBlock; // set if reading a compressed block
518 int blockLen; // remaining length of uncompressed block
519 GBool endOfBlock; // set when end of block is reached
520 GBool eof; // set when end of stream is reached
522 static int // code length code reordering
523 codeLenCodeMap[flateMaxCodeLenCodes];
524 static FlateDecode // length decoding info
525 lengthDecode[flateMaxLitCodes-257];
526 static FlateDecode // distance decoding info
527 distDecode[flateMaxDistCodes];
531 void loadFixedCodes();
532 GBool readDynamicCodes();
533 void compHuffmanCodes(FlateHuffmanTab *tab, int n);
534 int getHuffmanCodeWord(FlateHuffmanTab *tab);
535 int getCodeWord(int bits);
538 //------------------------------------------------------------------------
540 //------------------------------------------------------------------------
542 class EOFStream: public Stream {
545 EOFStream(Stream *str1);
546 virtual ~EOFStream();
547 virtual StreamKind getKind() { return strWeird; }
548 virtual void reset() {}
549 virtual int getChar() { return EOF; }
550 virtual int lookChar() { return EOF; }
551 virtual int getPos() { return str->getPos(); }
552 virtual GString *getPSFilter(char *indent) { return NULL; }
553 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
554 virtual Stream *getBaseStream() { return str->getBaseStream(); }
555 virtual FILE *getFile() { return str->getFile(); }
556 virtual Dict *getDict() { return str->getDict(); }
563 //------------------------------------------------------------------------
564 // FixedLengthEncoder
565 //------------------------------------------------------------------------
567 class FixedLengthEncoder: public Stream {
570 FixedLengthEncoder(Stream *str1, int length1);
571 ~FixedLengthEncoder();
572 virtual StreamKind getKind() { return strWeird; }
573 virtual void reset();
574 virtual int getChar();
575 virtual int lookChar();
576 virtual int getPos() { return str->getPos(); }
577 virtual GString *getPSFilter(char *indent) { return NULL; }
578 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
579 virtual Stream *getBaseStream() { return str->getBaseStream(); }
580 virtual FILE *getFile() { return str->getFile(); }
581 virtual Dict *getDict() { return str->getDict(); }
582 virtual GBool isEncoder() { return gTrue; }
591 //------------------------------------------------------------------------
593 //------------------------------------------------------------------------
595 class ASCII85Encoder: public Stream {
598 ASCII85Encoder(Stream *str1);
599 virtual ~ASCII85Encoder();
600 virtual StreamKind getKind() { return strWeird; }
601 virtual void reset();
602 virtual int getChar()
603 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
604 virtual int lookChar()
605 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
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 FILE *getFile() { return str->getFile(); }
611 virtual Dict *getDict() { return str->getDict(); }
612 virtual GBool isEncoder() { return gTrue; }
626 //------------------------------------------------------------------------
628 //------------------------------------------------------------------------
630 class RunLengthEncoder: public Stream {
633 RunLengthEncoder(Stream *str1);
634 virtual ~RunLengthEncoder();
635 virtual StreamKind getKind() { return strWeird; }
636 virtual void reset();
637 virtual int getChar()
638 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
639 virtual int lookChar()
640 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
641 virtual int getPos() { return str->getPos(); }
642 virtual GString *getPSFilter(char *indent) { return NULL; }
643 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
644 virtual Stream *getBaseStream() { return str->getBaseStream(); }
645 virtual FILE *getFile() { return str->getFile(); }
646 virtual Dict *getDict() { return str->getDict(); }
647 virtual GBool isEncoder() { return gTrue; }