1 //======================================================================== 2 // 3 // Stream.h 4 // 5 // Copyright 1996-2003 Glyph & Cog, LLC 6 // 7 //======================================================================== 8 9 #ifndef STREAM_H 10 #define STREAM_H 11 12 #include <aconf.h> 13 14 #ifdef USE_GCC_PRAGMAS 15 #pragma interface 16 #endif 17 18 #include <stdio.h> 19 #if HAVE_JPEGLIB 20 #include <jpeglib.h> 21 #include <setjmp.h> 22 #endif 23 #include "gtypes.h" 24 #include "gfile.h" 25 #include "Object.h" 26 27 class BaseStream; 28 class SharedFile; 29 30 //------------------------------------------------------------------------ 31 32 enum StreamKind { 33 strFile, 34 strASCIIHex, 35 strASCII85, 36 strLZW, 37 strRunLength, 38 strCCITTFax, 39 strDCT, 40 strFlate, 41 strJBIG2, 42 strJPX, 43 strWeird // internal-use stream types 44 }; 45 46 enum StreamColorSpaceMode { 47 streamCSNone, 48 streamCSDeviceGray, 49 streamCSDeviceRGB, 50 streamCSDeviceCMYK 51 }; 52 53 //------------------------------------------------------------------------ 54 55 // This is in Stream.h instead of Decrypt.h to avoid really annoying 56 // include file dependency loops. 57 enum CryptAlgorithm { 58 cryptRC4, 59 cryptAES, 60 cryptAES256 61 }; 62 63 //------------------------------------------------------------------------ 64 // Stream (base class) 65 //------------------------------------------------------------------------ 66 67 class Stream { 68 public: 69 70 // Constructor. 71 Stream(); 72 73 // Destructor. 74 virtual ~Stream(); 75 76 virtual Stream *copy() = 0; 77 78 // Get kind of stream. 79 virtual StreamKind getKind() = 0; 80 isEmbedStream()81 virtual GBool isEmbedStream() { return gFalse; } 82 83 // Reset stream to beginning. 84 virtual void reset() = 0; 85 86 // Close down the stream. 87 virtual void close(); 88 89 // Get next char from stream. 90 virtual int getChar() = 0; 91 92 // Peek at next char in stream. 93 virtual int lookChar() = 0; 94 95 // Get next char from stream without using the predictor. 96 // This is only used by StreamPredictor. 97 virtual int getRawChar(); 98 99 // Get exactly <size> bytes from stream. Returns the number of 100 // bytes read -- the returned count will be less than <size> at EOF. 101 virtual int getBlock(char *blk, int size); 102 103 // Get next line from stream. 104 virtual char *getLine(char *buf, int size); 105 106 // Discard the next <n> bytes from stream. Returns the number of 107 // bytes discarded, which will be less than <n> only if EOF is 108 // reached. 109 virtual Guint discardChars(Guint n); 110 111 // Get current position in file. 112 virtual GFileOffset getPos() = 0; 113 114 // Go to a position in the stream. If <dir> is negative, the 115 // position is from the end of the file; otherwise the position is 116 // from the start of the file. 117 virtual void setPos(GFileOffset pos, int dir = 0) = 0; 118 119 // Get PostScript command for the filter(s). 120 virtual GString *getPSFilter(int psLevel, const char *indent, 121 GBool okToReadStream); 122 123 // Does this stream type potentially contain non-printable chars? 124 virtual GBool isBinary(GBool last = gTrue) = 0; 125 126 // Get the BaseStream of this stream. 127 virtual BaseStream *getBaseStream() = 0; 128 129 // Get the stream after the last decoder (this may be a BaseStream 130 // or a DecryptStream). 131 virtual Stream *getUndecodedStream() = 0; 132 133 // Get the dictionary associated with this stream. 134 virtual Dict *getDict() = 0; 135 136 // Is this an encoding filter? isEncoder()137 virtual GBool isEncoder() { return gFalse; } 138 139 // Get image parameters which are defined by the stream contents. getImageParams(int * bitsPerComponent,StreamColorSpaceMode * csMode)140 virtual void getImageParams(int *bitsPerComponent, 141 StreamColorSpaceMode *csMode) {} 142 143 // Return the next stream in the "stack". getNextStream()144 virtual Stream *getNextStream() { return NULL; } 145 146 // Add filters to this stream according to the parameters in <dict>. 147 // Returns the new stream. 148 Stream *addFilters(Object *dict, int recursion = 0); 149 150 private: 151 152 Stream *makeFilter(char *name, Stream *str, Object *params, int recursion); 153 }; 154 155 //------------------------------------------------------------------------ 156 // BaseStream 157 // 158 // This is the base class for all streams that read directly from a file. 159 //------------------------------------------------------------------------ 160 161 class BaseStream: public Stream { 162 public: 163 164 BaseStream(Object *dictA); 165 virtual ~BaseStream(); 166 virtual Stream *makeSubStream(GFileOffset start, GBool limited, 167 GFileOffset length, Object *dict) = 0; 168 virtual void setPos(GFileOffset pos, int dir = 0) = 0; 169 virtual GBool isBinary(GBool last = gTrue) { return last; } getBaseStream()170 virtual BaseStream *getBaseStream() { return this; } getUndecodedStream()171 virtual Stream *getUndecodedStream() { return this; } getDict()172 virtual Dict *getDict() { return dict.getDict(); } getFileName()173 virtual GString *getFileName() { return NULL; } 174 175 // Get/set position of first byte of stream within the file. 176 virtual GFileOffset getStart() = 0; 177 virtual void moveStart(int delta) = 0; 178 179 protected: 180 181 Object dict; 182 }; 183 184 //------------------------------------------------------------------------ 185 // FilterStream 186 // 187 // This is the base class for all streams that filter another stream. 188 //------------------------------------------------------------------------ 189 190 class FilterStream: public Stream { 191 public: 192 193 FilterStream(Stream *strA); 194 virtual ~FilterStream(); 195 virtual void close(); getPos()196 virtual GFileOffset getPos() { return str->getPos(); } 197 virtual void setPos(GFileOffset pos, int dir = 0); getBaseStream()198 virtual BaseStream *getBaseStream() { return str->getBaseStream(); } getUndecodedStream()199 virtual Stream *getUndecodedStream() { return str->getUndecodedStream(); } getDict()200 virtual Dict *getDict() { return str->getDict(); } getNextStream()201 virtual Stream *getNextStream() { return str; } 202 203 protected: 204 205 Stream *str; 206 }; 207 208 //------------------------------------------------------------------------ 209 // ImageStream 210 //------------------------------------------------------------------------ 211 212 class ImageStream { 213 public: 214 215 // Create an image stream object for an image with the specified 216 // parameters. Note that these are the actual image parameters, 217 // which may be different from the predictor parameters. 218 ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA); 219 220 ~ImageStream(); 221 222 // Reset the stream. 223 void reset(); 224 225 // Close down the stream. 226 void close(); 227 228 // Gets the next pixel from the stream. <pix> should be able to hold 229 // at least nComps elements. Returns false at end of file. 230 GBool getPixel(Guchar *pix); 231 232 // Returns a pointer to the next line of pixels. Returns NULL at 233 // end of file. 234 Guchar *getLine(); 235 236 // Skip an entire line from the image. 237 void skipLine(); 238 239 private: 240 241 Stream *str; // base stream 242 int width; // pixels per line 243 int nComps; // components per pixel 244 int nBits; // bits per component 245 int nVals; // components per line 246 int inputLineSize; // input line buffer size 247 char *inputLine; // input line buffer 248 Guchar *imgLine; // line buffer 249 int imgIdx; // current index in imgLine 250 }; 251 252 253 //------------------------------------------------------------------------ 254 // StreamPredictor 255 //------------------------------------------------------------------------ 256 257 class StreamPredictor { 258 public: 259 260 // Create a predictor object. Note that the parameters are for the 261 // predictor, and may not match the actual image parameters. 262 StreamPredictor(Stream *strA, int predictorA, 263 int widthA, int nCompsA, int nBitsA); 264 265 ~StreamPredictor(); 266 isOk()267 GBool isOk() { return ok; } 268 269 void reset(); 270 271 int lookChar(); 272 int getChar(); 273 int getBlock(char *blk, int size); 274 getPredictor()275 int getPredictor() { return predictor; } getWidth()276 int getWidth() { return width; } getNComps()277 int getNComps() { return nComps; } getNBits()278 int getNBits() { return nBits; } 279 280 private: 281 282 GBool getNextLine(); 283 284 Stream *str; // base stream 285 int predictor; // predictor 286 int width; // pixels per line 287 int nComps; // components per pixel 288 int nBits; // bits per component 289 int nVals; // components per line 290 int pixBytes; // bytes per pixel 291 int rowBytes; // bytes per line 292 Guchar *predLine; // line buffer 293 int predIdx; // current index in predLine 294 GBool ok; 295 }; 296 297 //------------------------------------------------------------------------ 298 // FileStream 299 //------------------------------------------------------------------------ 300 301 #define fileStreamBufSize 256 302 303 class FileStream: public BaseStream { 304 public: 305 306 FileStream(FILE *fA, GFileOffset startA, GBool limitedA, 307 GFileOffset lengthA, Object *dictA); 308 virtual ~FileStream(); 309 virtual Stream *copy(); 310 virtual Stream *makeSubStream(GFileOffset startA, GBool limitedA, 311 GFileOffset lengthA, Object *dictA); getKind()312 virtual StreamKind getKind() { return strFile; } 313 virtual void reset(); getChar()314 virtual int getChar() 315 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } lookChar()316 virtual int lookChar() 317 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } 318 virtual int getBlock(char *blk, int size); getPos()319 virtual GFileOffset getPos() { return bufPos + (int)(bufPtr - buf); } 320 virtual void setPos(GFileOffset pos, int dir = 0); getStart()321 virtual GFileOffset getStart() { return start; } 322 virtual void moveStart(int delta); 323 324 private: 325 326 FileStream(SharedFile *fA, GFileOffset startA, GBool limitedA, 327 GFileOffset lengthA, Object *dictA); 328 GBool fillBuf(); 329 330 SharedFile *f; 331 GFileOffset start; 332 GBool limited; 333 GFileOffset length; 334 char buf[fileStreamBufSize]; 335 char *bufPtr; 336 char *bufEnd; 337 GFileOffset bufPos; 338 }; 339 340 //------------------------------------------------------------------------ 341 // MemStream 342 //------------------------------------------------------------------------ 343 344 class MemStream: public BaseStream { 345 public: 346 347 MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA); 348 virtual ~MemStream(); 349 virtual Stream *copy(); 350 virtual Stream *makeSubStream(GFileOffset start, GBool limited, 351 GFileOffset lengthA, Object *dictA); getKind()352 virtual StreamKind getKind() { return strWeird; } 353 virtual void reset(); 354 virtual void close(); getChar()355 virtual int getChar() 356 { return (bufPtr < bufEnd) ? (*bufPtr++ & 0xff) : EOF; } lookChar()357 virtual int lookChar() 358 { return (bufPtr < bufEnd) ? (*bufPtr & 0xff) : EOF; } 359 virtual int getBlock(char *blk, int size); getPos()360 virtual GFileOffset getPos() { return (GFileOffset)(bufPtr - buf); } 361 virtual void setPos(GFileOffset pos, int dir = 0); getStart()362 virtual GFileOffset getStart() { return start; } 363 virtual void moveStart(int delta); 364 365 private: 366 367 char *buf; 368 Guint start; 369 Guint length; 370 char *bufEnd; 371 char *bufPtr; 372 GBool needFree; 373 }; 374 375 //------------------------------------------------------------------------ 376 // EmbedStream 377 // 378 // This is a special stream type used for embedded streams (inline 379 // images). It reads directly from the base stream -- after the 380 // EmbedStream is deleted, reads from the base stream will proceed where 381 // the BaseStream left off. Note that this is very different behavior 382 // that creating a new FileStream (using makeSubStream). 383 //------------------------------------------------------------------------ 384 385 class EmbedStream: public BaseStream { 386 public: 387 388 EmbedStream(Stream *strA, Object *dictA, GBool limitedA, GFileOffset lengthA); 389 virtual ~EmbedStream(); 390 virtual Stream *copy(); 391 virtual Stream *makeSubStream(GFileOffset start, GBool limitedA, 392 GFileOffset lengthA, Object *dictA); getKind()393 virtual StreamKind getKind() { return str->getKind(); } isEmbedStream()394 virtual GBool isEmbedStream() { return gTrue; } reset()395 virtual void reset() {} 396 virtual int getChar(); 397 virtual int lookChar(); 398 virtual int getBlock(char *blk, int size); getPos()399 virtual GFileOffset getPos() { return str->getPos(); } 400 virtual void setPos(GFileOffset pos, int dir = 0); 401 virtual GFileOffset getStart(); 402 virtual void moveStart(int delta); 403 404 private: 405 406 Stream *str; 407 GBool limited; 408 GFileOffset length; 409 }; 410 411 //------------------------------------------------------------------------ 412 // ASCIIHexStream 413 //------------------------------------------------------------------------ 414 415 class ASCIIHexStream: public FilterStream { 416 public: 417 418 ASCIIHexStream(Stream *strA); 419 virtual ~ASCIIHexStream(); 420 virtual Stream *copy(); getKind()421 virtual StreamKind getKind() { return strASCIIHex; } 422 virtual void reset(); getChar()423 virtual int getChar() 424 { int c = lookChar(); buf = EOF; return c; } 425 virtual int lookChar(); 426 virtual GString *getPSFilter(int psLevel, const char *indent, 427 GBool okToReadStream); 428 virtual GBool isBinary(GBool last = gTrue); 429 430 private: 431 432 int buf; 433 GBool eof; 434 }; 435 436 //------------------------------------------------------------------------ 437 // ASCII85Stream 438 //------------------------------------------------------------------------ 439 440 class ASCII85Stream: public FilterStream { 441 public: 442 443 ASCII85Stream(Stream *strA); 444 virtual ~ASCII85Stream(); 445 virtual Stream *copy(); getKind()446 virtual StreamKind getKind() { return strASCII85; } 447 virtual void reset(); getChar()448 virtual int getChar() 449 { int ch = lookChar(); ++index; return ch; } 450 virtual int lookChar(); 451 virtual GString *getPSFilter(int psLevel, const char *indent, 452 GBool okToReadStream); 453 virtual GBool isBinary(GBool last = gTrue); 454 455 private: 456 457 int c[5]; 458 int b[4]; 459 int index, n; 460 GBool eof; 461 }; 462 463 //------------------------------------------------------------------------ 464 // LZWStream 465 //------------------------------------------------------------------------ 466 467 class LZWStream: public FilterStream { 468 public: 469 470 LZWStream(Stream *strA, int predictor, int columns, int colors, 471 int bits, int earlyA); 472 virtual ~LZWStream(); 473 virtual Stream *copy(); getKind()474 virtual StreamKind getKind() { return strLZW; } 475 virtual void reset(); 476 virtual int getChar(); 477 virtual int lookChar(); 478 virtual int getRawChar(); 479 virtual int getBlock(char *blk, int size); 480 virtual GString *getPSFilter(int psLevel, const char *indent, 481 GBool okToReadStream); 482 virtual GBool isBinary(GBool last = gTrue); 483 484 private: 485 486 StreamPredictor *pred; // predictor 487 int early; // early parameter 488 GBool eof; // true if at eof 489 int inputBuf; // input buffer 490 int inputBits; // number of bits in input buffer 491 struct { // decoding table 492 int length; 493 int head; 494 Guchar tail; 495 } table[4097]; 496 int nextCode; // next code to be used 497 int nextBits; // number of bits in next code word 498 int prevCode; // previous code used in stream 499 int newChar; // next char to be added to table 500 Guchar seqBuf[4097]; // buffer for current sequence 501 int seqLength; // length of current sequence 502 int seqIndex; // index into current sequence 503 GBool first; // first code after a table clear 504 unsigned long long totalIn; // total number of encoded bytes read so far 505 unsigned long long totalOut; // total number of bytes decoded so far 506 507 GBool processNextCode(); 508 void clearTable(); 509 int getCode(); 510 }; 511 512 //------------------------------------------------------------------------ 513 // RunLengthStream 514 //------------------------------------------------------------------------ 515 516 class RunLengthStream: public FilterStream { 517 public: 518 519 RunLengthStream(Stream *strA); 520 virtual ~RunLengthStream(); 521 virtual Stream *copy(); getKind()522 virtual StreamKind getKind() { return strRunLength; } 523 virtual void reset(); getChar()524 virtual int getChar() 525 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } lookChar()526 virtual int lookChar() 527 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } 528 virtual int getBlock(char *blk, int size); 529 virtual GString *getPSFilter(int psLevel, const char *indent, 530 GBool okToReadStream); 531 virtual GBool isBinary(GBool last = gTrue); 532 533 private: 534 535 char buf[128]; // buffer 536 char *bufPtr; // next char to read 537 char *bufEnd; // end of buffer 538 GBool eof; 539 540 GBool fillBuf(); 541 }; 542 543 //------------------------------------------------------------------------ 544 // CCITTFaxStream 545 //------------------------------------------------------------------------ 546 547 struct CCITTCodeTable; 548 549 class CCITTFaxStream: public FilterStream { 550 public: 551 552 CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA, 553 GBool byteAlignA, int columnsA, int rowsA, 554 GBool endOfBlockA, GBool blackA); 555 virtual ~CCITTFaxStream(); 556 virtual Stream *copy(); getKind()557 virtual StreamKind getKind() { return strCCITTFax; } 558 virtual void reset(); 559 virtual int getChar(); 560 virtual int lookChar(); 561 virtual int getBlock(char *blk, int size); 562 virtual GString *getPSFilter(int psLevel, const char *indent, 563 GBool okToReadStream); 564 virtual GBool isBinary(GBool last = gTrue); 565 566 private: 567 568 int encoding; // 'K' parameter 569 GBool endOfLine; // 'EndOfLine' parameter 570 GBool byteAlign; // 'EncodedByteAlign' parameter 571 int columns; // 'Columns' parameter 572 int rows; // 'Rows' parameter 573 GBool endOfBlock; // 'EndOfBlock' parameter 574 GBool black; // 'BlackIs1' parameter 575 int blackXOR; 576 GBool eof; // true if at eof 577 GBool nextLine2D; // true if next line uses 2D encoding 578 int row; // current row 579 Guint inputBuf; // input buffer 580 int inputBits; // number of bits in input buffer 581 int *codingLine; // coding line changing elements 582 int *refLine; // reference line changing elements 583 int nextCol; // next column to read 584 int a0i; // index into codingLine 585 GBool err; // error on current line 586 int nErrors; // number of errors so far in this stream 587 588 void addPixels(int a1, int blackPixels); 589 void addPixelsNeg(int a1, int blackPixels); 590 GBool readRow(); 591 short getTwoDimCode(); 592 short getWhiteCode(); 593 short getBlackCode(); 594 short lookBits(int n); eatBits(int n)595 void eatBits(int n) { if ((inputBits -= n) < 0) inputBits = 0; } 596 }; 597 598 //------------------------------------------------------------------------ 599 // DCTStream 600 //------------------------------------------------------------------------ 601 602 #if HAVE_JPEGLIB 603 604 class DCTStream; 605 606 #define dctStreamBufSize 4096 607 608 struct DCTSourceMgr { 609 jpeg_source_mgr src; 610 DCTStream *str; 611 char buf[dctStreamBufSize]; 612 }; 613 614 struct DCTErrorMgr { 615 struct jpeg_error_mgr err; 616 jmp_buf setjmpBuf; 617 }; 618 619 #else // HAVE_JPEGLIB 620 621 // DCT component info 622 struct DCTCompInfo { 623 int id; // component ID 624 int hSample, vSample; // horiz/vert sampling resolutions 625 int quantTable; // quantization table number 626 int prevDC; // DC coefficient accumulator 627 }; 628 629 struct DCTScanInfo { 630 GBool comp[4]; // comp[i] is set if component i is 631 // included in this scan 632 int numComps; // number of components in the scan 633 int dcHuffTable[4]; // DC Huffman table numbers 634 int acHuffTable[4]; // AC Huffman table numbers 635 int firstCoeff, lastCoeff; // first and last DCT coefficient 636 int ah, al; // successive approximation parameters 637 }; 638 639 // DCT Huffman decoding table 640 struct DCTHuffTable { 641 Guchar firstSym[17]; // first symbol for this bit length 642 Gushort firstCode[17]; // first code for this bit length 643 Gushort numCodes[17]; // number of codes of this bit length 644 Guchar sym[256]; // symbols 645 }; 646 647 #endif // HAVE_JPEGLIB 648 649 class DCTStream: public FilterStream { 650 public: 651 652 DCTStream(Stream *strA, int colorXformA); 653 virtual ~DCTStream(); 654 virtual Stream *copy(); getKind()655 virtual StreamKind getKind() { return strDCT; } 656 virtual void reset(); 657 virtual void close(); 658 virtual int getChar(); 659 virtual int lookChar(); 660 virtual int getBlock(char *blk, int size); 661 virtual GString *getPSFilter(int psLevel, const char *indent, 662 GBool okToReadStream); 663 virtual GBool isBinary(GBool last = gTrue); getRawStream()664 Stream *getRawStream() { return str; } 665 666 private: 667 668 GBool checkSequentialInterleaved(); 669 670 #if HAVE_JPEGLIB 671 672 int colorXform; // color transform: -1 = unspecified 673 // 0 = none 674 // 1 = YUV/YUVK -> RGB/CMYK 675 jpeg_decompress_struct decomp; 676 DCTErrorMgr errorMgr; 677 DCTSourceMgr sourceMgr; 678 GBool error; 679 char *lineBuf; 680 int lineBufHeight; 681 char *lineBufRows[4]; 682 char *bufPtr; 683 char *bufEnd; 684 GBool inlineImage; 685 686 GBool fillBuf(); 687 static void errorExit(j_common_ptr d); 688 static void errorMessage(j_common_ptr d); 689 static void initSourceCbk(j_decompress_ptr d); 690 static boolean fillInputBufferCbk(j_decompress_ptr d); 691 static void skipInputDataCbk(j_decompress_ptr d, long numBytes); 692 static void termSourceCbk(j_decompress_ptr d); 693 694 #else // HAVE_JPEGLIB 695 696 GBool progressive; // set if in progressive mode 697 GBool interleaved; // set if in interleaved mode 698 int width, height; // image size 699 int mcuWidth, mcuHeight; // size of min coding unit, in data units 700 int bufWidth, bufHeight; // frameBuf size 701 DCTCompInfo compInfo[4]; // info for each component 702 DCTScanInfo scanInfo; // info for the current scan 703 int numComps; // number of components in image 704 int colorXform; // color transform: -1 = unspecified 705 // 0 = none 706 // 1 = YUV/YUVK -> RGB/CMYK 707 GBool gotJFIFMarker; // set if APP0 JFIF marker was present 708 GBool gotAdobeMarker; // set if APP14 Adobe marker was present 709 int restartInterval; // restart interval, in MCUs 710 Gushort quantTables[4][64]; // quantization tables 711 int numQuantTables; // number of quantization tables 712 DCTHuffTable dcHuffTables[4]; // DC Huffman tables 713 DCTHuffTable acHuffTables[4]; // AC Huffman tables 714 int numDCHuffTables; // number of DC Huffman tables 715 int numACHuffTables; // number of AC Huffman tables 716 Guchar *rowBuf; 717 Guchar *rowBufPtr; // current position within rowBuf 718 Guchar *rowBufEnd; // end of valid data in rowBuf 719 int *frameBuf[4]; // buffer for frame (progressive mode) 720 int comp, x, y; // current position within image/MCU 721 int restartCtr; // MCUs left until restart 722 int restartMarker; // next restart marker 723 int eobRun; // number of EOBs left in the current run 724 int inputBuf; // input buffer for variable length codes 725 int inputBits; // number of valid bits in input buffer 726 727 void restart(); 728 GBool readMCURow(); 729 void readScan(); 730 GBool readDataUnit(DCTHuffTable *dcHuffTable, 731 DCTHuffTable *acHuffTable, 732 int *prevDC, int data[64]); 733 GBool readProgressiveDataUnit(DCTHuffTable *dcHuffTable, 734 DCTHuffTable *acHuffTable, 735 int *prevDC, int data[64]); 736 void decodeImage(); 737 void transformDataUnit(Gushort *quantTable, 738 int dataIn[64], Guchar dataOut[64]); 739 int readHuffSym(DCTHuffTable *table); 740 int readAmp(int size); 741 int readBit(); 742 GBool readHeader(GBool frame); 743 GBool readBaselineSOF(); 744 GBool readProgressiveSOF(); 745 GBool readScanInfo(); 746 GBool readQuantTables(); 747 GBool readHuffmanTables(); 748 GBool readRestartInterval(); 749 GBool readJFIFMarker(); 750 GBool readAdobeMarker(); 751 GBool readTrailer(); 752 int readMarker(); 753 int read16(); 754 755 #endif // HAVE_JPEGLIB 756 }; 757 758 //------------------------------------------------------------------------ 759 // FlateStream 760 //------------------------------------------------------------------------ 761 762 #define flateWindow 32768 // buffer size 763 #define flateMask (flateWindow-1) 764 #define flateMaxHuffman 15 // max Huffman code length 765 #define flateMaxCodeLenCodes 19 // max # code length codes 766 #define flateMaxLitCodes 288 // max # literal codes 767 #define flateMaxDistCodes 30 // max # distance codes 768 769 // Huffman code table entry 770 struct FlateCode { 771 Gushort len; // code length, in bits 772 Gushort val; // value represented by this code 773 }; 774 775 struct FlateHuffmanTab { 776 FlateCode *codes; 777 int maxLen; 778 }; 779 780 // Decoding info for length and distance code words 781 struct FlateDecode { 782 int bits; // # extra bits 783 int first; // first length/distance 784 }; 785 786 class FlateStream: public FilterStream { 787 public: 788 789 FlateStream(Stream *strA, int predictor, int columns, 790 int colors, int bits); 791 virtual ~FlateStream(); 792 virtual Stream *copy(); getKind()793 virtual StreamKind getKind() { return strFlate; } 794 virtual void reset(); 795 virtual int getChar(); 796 virtual int lookChar(); 797 virtual int getRawChar(); 798 virtual int getBlock(char *blk, int size); 799 virtual GString *getPSFilter(int psLevel, const char *indent, 800 GBool okToReadStream); 801 virtual GBool isBinary(GBool last = gTrue); 802 803 private: 804 805 StreamPredictor *pred; // predictor 806 Guchar buf[flateWindow]; // output data buffer 807 int index; // current index into output buffer 808 int remain; // number valid bytes in output buffer 809 int codeBuf; // input buffer 810 int codeSize; // number of bits in input buffer 811 int // literal and distance code lengths 812 codeLengths[flateMaxLitCodes + flateMaxDistCodes]; 813 FlateHuffmanTab litCodeTab; // literal code table 814 FlateHuffmanTab distCodeTab; // distance code table 815 GBool compressedBlock; // set if reading a compressed block 816 int blockLen; // remaining length of uncompressed block 817 GBool endOfBlock; // set when end of block is reached 818 GBool eof; // set when end of stream is reached 819 unsigned long long totalIn; // total number of encoded bytes read so far 820 unsigned long long totalOut; // total number of bytes decoded so far 821 822 static int // code length code reordering 823 codeLenCodeMap[flateMaxCodeLenCodes]; 824 static FlateDecode // length decoding info 825 lengthDecode[flateMaxLitCodes-257]; 826 static FlateDecode // distance decoding info 827 distDecode[flateMaxDistCodes]; 828 static FlateHuffmanTab // fixed literal code table 829 fixedLitCodeTab; 830 static FlateHuffmanTab // fixed distance code table 831 fixedDistCodeTab; 832 833 void readSome(); 834 GBool startBlock(); 835 void loadFixedCodes(); 836 GBool readDynamicCodes(); 837 void compHuffmanCodes(int *lengths, int n, FlateHuffmanTab *tab); 838 int getHuffmanCodeWord(FlateHuffmanTab *tab); 839 int getCodeWord(int bits); 840 }; 841 842 //------------------------------------------------------------------------ 843 // EOFStream 844 //------------------------------------------------------------------------ 845 846 class EOFStream: public FilterStream { 847 public: 848 849 EOFStream(Stream *strA); 850 virtual ~EOFStream(); 851 virtual Stream *copy(); getKind()852 virtual StreamKind getKind() { return strWeird; } reset()853 virtual void reset() {} getChar()854 virtual int getChar() { return EOF; } lookChar()855 virtual int lookChar() { return EOF; } getBlock(char * blk,int size)856 virtual int getBlock(char *blk, int size) { return 0; } getPSFilter(int psLevel,const char * indent,GBool okToReadStream)857 virtual GString *getPSFilter(int psLevel, const char *indent, 858 GBool okToReadStream) 859 { return NULL; } 860 virtual GBool isBinary(GBool last = gTrue) { return gFalse; } 861 }; 862 863 //------------------------------------------------------------------------ 864 // BufStream 865 //------------------------------------------------------------------------ 866 867 class BufStream: public FilterStream { 868 public: 869 870 BufStream(Stream *strA, int bufSizeA); 871 virtual ~BufStream(); 872 virtual Stream *copy(); getKind()873 virtual StreamKind getKind() { return strWeird; } 874 virtual void reset(); 875 virtual int getChar(); 876 virtual int lookChar(); getPSFilter(int psLevel,const char * indent,GBool okToReadStream)877 virtual GString *getPSFilter(int psLevel, const char *indent, 878 GBool okToReadStream) 879 { return NULL; } 880 virtual GBool isBinary(GBool last = gTrue); 881 882 int lookChar(int idx); 883 884 private: 885 886 int *buf; 887 int bufSize; 888 }; 889 890 //------------------------------------------------------------------------ 891 // FixedLengthEncoder 892 //------------------------------------------------------------------------ 893 894 class FixedLengthEncoder: public FilterStream { 895 public: 896 897 FixedLengthEncoder(Stream *strA, int lengthA); 898 ~FixedLengthEncoder(); 899 virtual Stream *copy(); getKind()900 virtual StreamKind getKind() { return strWeird; } 901 virtual void reset(); 902 virtual int getChar(); 903 virtual int lookChar(); getPSFilter(int psLevel,const char * indent,GBool okToReadStream)904 virtual GString *getPSFilter(int psLevel, const char *indent, 905 GBool okToReadStream) 906 { return NULL; } 907 virtual GBool isBinary(GBool last = gTrue); isEncoder()908 virtual GBool isEncoder() { return gTrue; } 909 910 private: 911 912 int length; 913 int count; 914 }; 915 916 //------------------------------------------------------------------------ 917 // ASCIIHexEncoder 918 //------------------------------------------------------------------------ 919 920 class ASCIIHexEncoder: public FilterStream { 921 public: 922 923 ASCIIHexEncoder(Stream *strA); 924 virtual ~ASCIIHexEncoder(); 925 virtual Stream *copy(); getKind()926 virtual StreamKind getKind() { return strWeird; } 927 virtual void reset(); getChar()928 virtual int getChar() 929 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } lookChar()930 virtual int lookChar() 931 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } getPSFilter(int psLevel,const char * indent,GBool okToReadStream)932 virtual GString *getPSFilter(int psLevel, const char *indent, 933 GBool okToReadStream) 934 { return NULL; } 935 virtual GBool isBinary(GBool last = gTrue) { return gFalse; } isEncoder()936 virtual GBool isEncoder() { return gTrue; } 937 938 private: 939 940 char buf[4]; 941 char *bufPtr; 942 char *bufEnd; 943 int lineLen; 944 GBool eof; 945 946 GBool fillBuf(); 947 }; 948 949 //------------------------------------------------------------------------ 950 // ASCII85Encoder 951 //------------------------------------------------------------------------ 952 953 class ASCII85Encoder: public FilterStream { 954 public: 955 956 ASCII85Encoder(Stream *strA); 957 virtual ~ASCII85Encoder(); 958 virtual Stream *copy(); getKind()959 virtual StreamKind getKind() { return strWeird; } 960 virtual void reset(); getChar()961 virtual int getChar() 962 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } lookChar()963 virtual int lookChar() 964 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } getPSFilter(int psLevel,const char * indent,GBool okToReadStream)965 virtual GString *getPSFilter(int psLevel, const char *indent, 966 GBool okToReadStream) 967 { return NULL; } 968 virtual GBool isBinary(GBool last = gTrue) { return gFalse; } isEncoder()969 virtual GBool isEncoder() { return gTrue; } 970 971 private: 972 973 char buf[8]; 974 char *bufPtr; 975 char *bufEnd; 976 int lineLen; 977 GBool eof; 978 979 GBool fillBuf(); 980 }; 981 982 //------------------------------------------------------------------------ 983 // RunLengthEncoder 984 //------------------------------------------------------------------------ 985 986 class RunLengthEncoder: public FilterStream { 987 public: 988 989 RunLengthEncoder(Stream *strA); 990 virtual ~RunLengthEncoder(); 991 virtual Stream *copy(); getKind()992 virtual StreamKind getKind() { return strWeird; } 993 virtual void reset(); getChar()994 virtual int getChar() 995 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } lookChar()996 virtual int lookChar() 997 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } getPSFilter(int psLevel,const char * indent,GBool okToReadStream)998 virtual GString *getPSFilter(int psLevel, const char *indent, 999 GBool okToReadStream) 1000 { return NULL; } 1001 virtual GBool isBinary(GBool last = gTrue) { return gTrue; } isEncoder()1002 virtual GBool isEncoder() { return gTrue; } 1003 1004 private: 1005 1006 char buf[131]; 1007 char *bufPtr; 1008 char *bufEnd; 1009 char *nextEnd; 1010 GBool eof; 1011 1012 GBool fillBuf(); 1013 }; 1014 1015 //------------------------------------------------------------------------ 1016 // LZWEncoder 1017 //------------------------------------------------------------------------ 1018 1019 struct LZWEncoderNode { 1020 int byte; 1021 LZWEncoderNode *next; // next sibling 1022 LZWEncoderNode *children; // first child 1023 }; 1024 1025 class LZWEncoder: public FilterStream { 1026 public: 1027 1028 LZWEncoder(Stream *strA); 1029 virtual ~LZWEncoder(); 1030 virtual Stream *copy(); getKind()1031 virtual StreamKind getKind() { return strWeird; } 1032 virtual void reset(); 1033 virtual int getChar(); 1034 virtual int lookChar(); getPSFilter(int psLevel,const char * indent,GBool okToReadStream)1035 virtual GString *getPSFilter(int psLevel, const char *indent, 1036 GBool okToReadStream) 1037 { return NULL; } 1038 virtual GBool isBinary(GBool last = gTrue) { return gTrue; } isEncoder()1039 virtual GBool isEncoder() { return gTrue; } 1040 1041 private: 1042 1043 LZWEncoderNode table[4096]; 1044 int nextSeq; 1045 int codeLen; 1046 Guchar inBuf[8192]; 1047 int inBufStart; 1048 int inBufLen; 1049 int outBuf; 1050 int outBufLen; 1051 GBool needEOD; 1052 1053 void fillBuf(); 1054 }; 1055 1056 #endif 1057