X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fxpdf%2FStream.h;fp=lib%2Fxpdf%2FStream.h;h=e1e7bae4282e591acd1594002e07667639a650c0;hb=1279e7201aaf80eca58ad982ec11de68c85631af;hp=0000000000000000000000000000000000000000;hpb=e40d573cbf6659328121d0383d6d5ac8acd58c34;p=swftools.git diff --git a/lib/xpdf/Stream.h b/lib/xpdf/Stream.h new file mode 100644 index 0000000..e1e7bae --- /dev/null +++ b/lib/xpdf/Stream.h @@ -0,0 +1,846 @@ +//======================================================================== +// +// Stream.h +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#ifndef STREAM_H +#define STREAM_H + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma interface +#endif + +#include +#include "gtypes.h" +#include "Object.h" + +class Decrypt; +class BaseStream; + +//------------------------------------------------------------------------ + +enum StreamKind { + strFile, + strASCIIHex, + strASCII85, + strLZW, + strRunLength, + strCCITTFax, + strDCT, + strFlate, + strJBIG2, + strJPX, + strWeird // internal-use stream types +}; + +enum StreamColorSpaceMode { + streamCSNone, + streamCSDeviceGray, + streamCSDeviceRGB, + streamCSDeviceCMYK +}; + +//------------------------------------------------------------------------ +// Stream (base class) +//------------------------------------------------------------------------ + +class Stream { +public: + + // Constructor. + Stream(); + + // Destructor. + virtual ~Stream(); + + // Reference counting. + int incRef() { return ++ref; } + int decRef() { return --ref; } + + // Get kind of stream. + virtual StreamKind getKind() = 0; + + // Reset stream to beginning. + virtual void reset() = 0; + + // Close down the stream. + virtual void close(); + + // Get next char from stream. + virtual int getChar() = 0; + + // Peek at next char in stream. + virtual int lookChar() = 0; + + // Get next char from stream without using the predictor. + // This is only used by StreamPredictor. + virtual int getRawChar(); + + // Get next line from stream. + virtual char *getLine(char *buf, int size); + + // Get current position in file. + virtual int getPos() = 0; + + // Go to a position in the stream. If is negative, the + // position is from the end of the file; otherwise the position is + // from the start of the file. + virtual void setPos(Guint pos, int dir = 0) = 0; + + // Get PostScript command for the filter(s). + virtual GString *getPSFilter(int psLevel, char *indent); + + // Does this stream type potentially contain non-printable chars? + virtual GBool isBinary(GBool last = gTrue) = 0; + + // Get the BaseStream of this stream. + virtual BaseStream *getBaseStream() = 0; + + // Get the dictionary associated with this stream. + virtual Dict *getDict() = 0; + + // Is this an encoding filter? + virtual GBool isEncoder() { return gFalse; } + + // Get image parameters which are defined by the stream contents. + virtual void getImageParams(int *bitsPerComponent, + StreamColorSpaceMode *csMode) {} + + // Add filters to this stream according to the parameters in . + // Returns the new stream. + Stream *addFilters(Object *dict); + +private: + + Stream *makeFilter(char *name, Stream *str, Object *params); + + int ref; // reference count +}; + +//------------------------------------------------------------------------ +// BaseStream +// +// This is the base class for all streams that read directly from a file. +//------------------------------------------------------------------------ + +class BaseStream: public Stream { +public: + + BaseStream(Object *dictA); + virtual ~BaseStream(); + virtual Stream *makeSubStream(Guint start, GBool limited, + Guint length, Object *dict) = 0; + virtual void setPos(Guint pos, int dir = 0) = 0; + virtual GBool isBinary(GBool last = gTrue) { return last; } + virtual BaseStream *getBaseStream() { return this; } + virtual Dict *getDict() { return dict.getDict(); } + + // Get/set position of first byte of stream within the file. + virtual Guint getStart() = 0; + virtual void moveStart(int delta) = 0; + + // Set decryption for this stream. + virtual void doDecryption(Guchar *fileKey, int keyLength, + int objNum, int objGen); + +protected: + + Decrypt *decrypt; + +private: + + Object dict; +}; + +//------------------------------------------------------------------------ +// FilterStream +// +// This is the base class for all streams that filter another stream. +//------------------------------------------------------------------------ + +class FilterStream: public Stream { +public: + + FilterStream(Stream *strA); + virtual ~FilterStream(); + virtual void close(); + virtual int getPos() { return str->getPos(); } + virtual void setPos(Guint pos, int dir = 0); + virtual BaseStream *getBaseStream() { return str->getBaseStream(); } + virtual Dict *getDict() { return str->getDict(); } + +protected: + + Stream *str; +}; + +//------------------------------------------------------------------------ +// ImageStream +//------------------------------------------------------------------------ + +class ImageStream { +public: + + // Create an image stream object for an image with the specified + // parameters. Note that these are the actual image parameters, + // which may be different from the predictor parameters. + ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA); + + ~ImageStream(); + + // Reset the stream. + void reset(); + + // Gets the next pixel from the stream. should be able to hold + // at least nComps elements. Returns false at end of file. + GBool getPixel(Guchar *pix); + + // Returns a pointer to the next line of pixels. Returns NULL at + // end of file. + Guchar *getLine(); + + // Skip an entire line from the image. + void skipLine(); + +private: + + Stream *str; // base stream + int width; // pixels per line + int nComps; // components per pixel + int nBits; // bits per component + int nVals; // components per line + Guchar *imgLine; // line buffer + int imgIdx; // current index in imgLine +}; + +//------------------------------------------------------------------------ +// StreamPredictor +//------------------------------------------------------------------------ + +class StreamPredictor { +public: + + // Create a predictor object. Note that the parameters are for the + // predictor, and may not match the actual image parameters. + StreamPredictor(Stream *strA, int predictorA, + int widthA, int nCompsA, int nBitsA); + + ~StreamPredictor(); + + GBool isOk() { return ok; } + + int lookChar(); + int getChar(); + +private: + + GBool getNextLine(); + + Stream *str; // base stream + int predictor; // predictor + int width; // pixels per line + int nComps; // components per pixel + int nBits; // bits per component + int nVals; // components per line + int pixBytes; // bytes per pixel + int rowBytes; // bytes per line + Guchar *predLine; // line buffer + int predIdx; // current index in predLine + GBool ok; +}; + +//------------------------------------------------------------------------ +// FileStream +//------------------------------------------------------------------------ + +#define fileStreamBufSize 256 + +class FileStream: public BaseStream { +public: + + FileStream(FILE *fA, Guint startA, GBool limitedA, + Guint lengthA, Object *dictA); + virtual ~FileStream(); + virtual Stream *makeSubStream(Guint startA, GBool limitedA, + Guint lengthA, Object *dictA); + virtual StreamKind getKind() { return strFile; } + virtual void reset(); + virtual void close(); + virtual int getChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } + virtual int lookChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } + virtual int getPos() { return bufPos + (bufPtr - buf); } + virtual void setPos(Guint pos, int dir = 0); + virtual Guint getStart() { return start; } + virtual void moveStart(int delta); + +private: + + GBool fillBuf(); + + FILE *f; + Guint start; + GBool limited; + Guint length; + char buf[fileStreamBufSize]; + char *bufPtr; + char *bufEnd; + Guint bufPos; + int savePos; + GBool saved; +}; + +//------------------------------------------------------------------------ +// MemStream +//------------------------------------------------------------------------ + +class MemStream: public BaseStream { +public: + + MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA); + virtual ~MemStream(); + virtual Stream *makeSubStream(Guint start, GBool limited, + Guint lengthA, Object *dictA); + virtual StreamKind getKind() { return strWeird; } + virtual void reset(); + virtual void close(); + virtual int getChar() + { return (bufPtr < bufEnd) ? (*bufPtr++ & 0xff) : EOF; } + virtual int lookChar() + { return (bufPtr < bufEnd) ? (*bufPtr & 0xff) : EOF; } + virtual int getPos() { return (int)(bufPtr - buf); } + virtual void setPos(Guint pos, int dir = 0); + virtual Guint getStart() { return start; } + virtual void moveStart(int delta); + virtual void doDecryption(Guchar *fileKey, int keyLength, + int objNum, int objGen); + +private: + + char *buf; + Guint start; + Guint length; + char *bufEnd; + char *bufPtr; + GBool needFree; +}; + +//------------------------------------------------------------------------ +// EmbedStream +// +// This is a special stream type used for embedded streams (inline +// images). It reads directly from the base stream -- after the +// EmbedStream is deleted, reads from the base stream will proceed where +// the BaseStream left off. Note that this is very different behavior +// that creating a new FileStream (using makeSubStream). +//------------------------------------------------------------------------ + +class EmbedStream: public BaseStream { +public: + + EmbedStream(Stream *strA, Object *dictA, GBool limitedA, Guint lengthA); + virtual ~EmbedStream(); + virtual Stream *makeSubStream(Guint start, GBool limitedA, + Guint lengthA, Object *dictA); + virtual StreamKind getKind() { return str->getKind(); } + virtual void reset() {} + virtual int getChar(); + virtual int lookChar(); + virtual int getPos() { return str->getPos(); } + virtual void setPos(Guint pos, int dir = 0); + virtual Guint getStart(); + virtual void moveStart(int delta); + +private: + + Stream *str; + GBool limited; + Guint length; +}; + +//------------------------------------------------------------------------ +// ASCIIHexStream +//------------------------------------------------------------------------ + +class ASCIIHexStream: public FilterStream { +public: + + ASCIIHexStream(Stream *strA); + virtual ~ASCIIHexStream(); + virtual StreamKind getKind() { return strASCIIHex; } + virtual void reset(); + virtual int getChar() + { int c = lookChar(); buf = EOF; return c; } + virtual int lookChar(); + virtual GString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + +private: + + int buf; + GBool eof; +}; + +//------------------------------------------------------------------------ +// ASCII85Stream +//------------------------------------------------------------------------ + +class ASCII85Stream: public FilterStream { +public: + + ASCII85Stream(Stream *strA); + virtual ~ASCII85Stream(); + virtual StreamKind getKind() { return strASCII85; } + virtual void reset(); + virtual int getChar() + { int ch = lookChar(); ++index; return ch; } + virtual int lookChar(); + virtual GString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + +private: + + int c[5]; + int b[4]; + int index, n; + GBool eof; +}; + +//------------------------------------------------------------------------ +// LZWStream +//------------------------------------------------------------------------ + +class LZWStream: public FilterStream { +public: + + LZWStream(Stream *strA, int predictor, int columns, int colors, + int bits, int earlyA); + virtual ~LZWStream(); + virtual StreamKind getKind() { return strLZW; } + virtual void reset(); + virtual int getChar(); + virtual int lookChar(); + virtual int getRawChar(); + virtual GString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + +private: + + StreamPredictor *pred; // predictor + int early; // early parameter + GBool eof; // true if at eof + int inputBuf; // input buffer + int inputBits; // number of bits in input buffer + struct { // decoding table + int length; + int head; + Guchar tail; + } table[4097]; + int nextCode; // next code to be used + int nextBits; // number of bits in next code word + int prevCode; // previous code used in stream + int newChar; // next char to be added to table + Guchar seqBuf[4097]; // buffer for current sequence + int seqLength; // length of current sequence + int seqIndex; // index into current sequence + GBool first; // first code after a table clear + + GBool processNextCode(); + void clearTable(); + int getCode(); +}; + +//------------------------------------------------------------------------ +// RunLengthStream +//------------------------------------------------------------------------ + +class RunLengthStream: public FilterStream { +public: + + RunLengthStream(Stream *strA); + virtual ~RunLengthStream(); + virtual StreamKind getKind() { return strRunLength; } + virtual void reset(); + virtual int getChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } + virtual int lookChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } + virtual GString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + +private: + + char buf[128]; // buffer + char *bufPtr; // next char to read + char *bufEnd; // end of buffer + GBool eof; + + GBool fillBuf(); +}; + +//------------------------------------------------------------------------ +// CCITTFaxStream +//------------------------------------------------------------------------ + +struct CCITTCodeTable; + +class CCITTFaxStream: public FilterStream { +public: + + CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA, + GBool byteAlignA, int columnsA, int rowsA, + GBool endOfBlockA, GBool blackA); + virtual ~CCITTFaxStream(); + virtual StreamKind getKind() { return strCCITTFax; } + virtual void reset(); + virtual int getChar() + { int c = lookChar(); buf = EOF; return c; } + virtual int lookChar(); + virtual GString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + +private: + + int encoding; // 'K' parameter + GBool endOfLine; // 'EndOfLine' parameter + GBool byteAlign; // 'EncodedByteAlign' parameter + int columns; // 'Columns' parameter + int rows; // 'Rows' parameter + GBool endOfBlock; // 'EndOfBlock' parameter + GBool black; // 'BlackIs1' parameter + GBool eof; // true if at eof + GBool nextLine2D; // true if next line uses 2D encoding + int row; // current row + int inputBuf; // input buffer + int inputBits; // number of bits in input buffer + short *refLine; // reference line changing elements + int b1; // index into refLine + short *codingLine; // coding line changing elements + int a0; // index into codingLine + int outputBits; // remaining ouput bits + int buf; // character buffer + + short getTwoDimCode(); + short getWhiteCode(); + short getBlackCode(); + short lookBits(int n); + void eatBits(int n) { inputBits -= n; } +}; + +//------------------------------------------------------------------------ +// DCTStream +//------------------------------------------------------------------------ + +// DCT component info +struct DCTCompInfo { + int id; // component ID + int hSample, vSample; // horiz/vert sampling resolutions + int quantTable; // quantization table number + int prevDC; // DC coefficient accumulator +}; + +struct DCTScanInfo { + GBool comp[4]; // comp[i] is set if component i is + // included in this scan + int numComps; // number of components in the scan + int dcHuffTable[4]; // DC Huffman table numbers + int acHuffTable[4]; // AC Huffman table numbers + int firstCoeff, lastCoeff; // first and last DCT coefficient + int ah, al; // successive approximation parameters +}; + +// DCT Huffman decoding table +struct DCTHuffTable { + Guchar firstSym[17]; // first symbol for this bit length + Gushort firstCode[17]; // first code for this bit length + Gushort numCodes[17]; // number of codes of this bit length + Guchar sym[256]; // symbols +}; + +class DCTStream: public FilterStream { +public: + + DCTStream(Stream *strA); + virtual ~DCTStream(); + virtual StreamKind getKind() { return strDCT; } + virtual void reset(); + virtual int getChar(); + virtual int lookChar(); + virtual GString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + Stream *getRawStream() { return str; } + +private: + + GBool progressive; // set if in progressive mode + GBool interleaved; // set if in interleaved mode + int width, height; // image size + int mcuWidth, mcuHeight; // size of min coding unit, in data units + int bufWidth, bufHeight; // frameBuf size + DCTCompInfo compInfo[4]; // info for each component + DCTScanInfo scanInfo; // info for the current scan + int numComps; // number of components in image + int colorXform; // need YCbCr-to-RGB transform? + GBool gotJFIFMarker; // set if APP0 JFIF marker was present + GBool gotAdobeMarker; // set if APP14 Adobe marker was present + int restartInterval; // restart interval, in MCUs + Gushort quantTables[4][64]; // quantization tables + int numQuantTables; // number of quantization tables + DCTHuffTable dcHuffTables[4]; // DC Huffman tables + DCTHuffTable acHuffTables[4]; // AC Huffman tables + int numDCHuffTables; // number of DC Huffman tables + int numACHuffTables; // number of AC Huffman tables + Guchar *rowBuf[4][32]; // buffer for one MCU (non-progressive mode) + int *frameBuf[4]; // buffer for frame (progressive mode) + int comp, x, y, dy; // current position within image/MCU + int restartCtr; // MCUs left until restart + int restartMarker; // next restart marker + int eobRun; // number of EOBs left in the current run + int inputBuf; // input buffer for variable length codes + int inputBits; // number of valid bits in input buffer + + void restart(); + GBool readMCURow(); + void readScan(); + GBool readDataUnit(DCTHuffTable *dcHuffTable, + DCTHuffTable *acHuffTable, + int *prevDC, int data[64]); + GBool readProgressiveDataUnit(DCTHuffTable *dcHuffTable, + DCTHuffTable *acHuffTable, + int *prevDC, int data[64]); + void decodeImage(); + void transformDataUnit(Gushort *quantTable, + int dataIn[64], Guchar dataOut[64]); + int readHuffSym(DCTHuffTable *table); + int readAmp(int size); + int readBit(); + GBool readHeader(); + GBool readBaselineSOF(); + GBool readProgressiveSOF(); + GBool readScanInfo(); + GBool readQuantTables(); + GBool readHuffmanTables(); + GBool readRestartInterval(); + GBool readJFIFMarker(); + GBool readAdobeMarker(); + GBool readTrailer(); + int readMarker(); + int read16(); +}; + +//------------------------------------------------------------------------ +// FlateStream +//------------------------------------------------------------------------ + +#define flateWindow 32768 // buffer size +#define flateMask (flateWindow-1) +#define flateMaxHuffman 15 // max Huffman code length +#define flateMaxCodeLenCodes 19 // max # code length codes +#define flateMaxLitCodes 288 // max # literal codes +#define flateMaxDistCodes 30 // max # distance codes + +// Huffman code table entry +struct FlateCode { + Gushort len; // code length, in bits + Gushort val; // value represented by this code +}; + +struct FlateHuffmanTab { + FlateCode *codes; + int maxLen; +}; + +// Decoding info for length and distance code words +struct FlateDecode { + int bits; // # extra bits + int first; // first length/distance +}; + +class FlateStream: public FilterStream { +public: + + FlateStream(Stream *strA, int predictor, int columns, + int colors, int bits); + virtual ~FlateStream(); + virtual StreamKind getKind() { return strFlate; } + virtual void reset(); + virtual int getChar(); + virtual int lookChar(); + virtual int getRawChar(); + virtual GString *getPSFilter(int psLevel, char *indent); + virtual GBool isBinary(GBool last = gTrue); + +private: + + StreamPredictor *pred; // predictor + Guchar buf[flateWindow]; // output data buffer + int index; // current index into output buffer + int remain; // number valid bytes in output buffer + int codeBuf; // input buffer + int codeSize; // number of bits in input buffer + int // literal and distance code lengths + codeLengths[flateMaxLitCodes + flateMaxDistCodes]; + FlateHuffmanTab litCodeTab; // literal code table + FlateHuffmanTab distCodeTab; // distance code table + GBool compressedBlock; // set if reading a compressed block + int blockLen; // remaining length of uncompressed block + GBool endOfBlock; // set when end of block is reached + GBool eof; // set when end of stream is reached + + static int // code length code reordering + codeLenCodeMap[flateMaxCodeLenCodes]; + static FlateDecode // length decoding info + lengthDecode[flateMaxLitCodes-257]; + static FlateDecode // distance decoding info + distDecode[flateMaxDistCodes]; + static FlateHuffmanTab // fixed literal code table + fixedLitCodeTab; + static FlateHuffmanTab // fixed distance code table + fixedDistCodeTab; + + void readSome(); + GBool startBlock(); + void loadFixedCodes(); + GBool readDynamicCodes(); + void compHuffmanCodes(int *lengths, int n, FlateHuffmanTab *tab); + int getHuffmanCodeWord(FlateHuffmanTab *tab); + int getCodeWord(int bits); +}; + +//------------------------------------------------------------------------ +// EOFStream +//------------------------------------------------------------------------ + +class EOFStream: public FilterStream { +public: + + EOFStream(Stream *strA); + virtual ~EOFStream(); + virtual StreamKind getKind() { return strWeird; } + virtual void reset() {} + virtual int getChar() { return EOF; } + virtual int lookChar() { return EOF; } + virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; } + virtual GBool isBinary(GBool last = gTrue) { return gFalse; } +}; + +//------------------------------------------------------------------------ +// FixedLengthEncoder +//------------------------------------------------------------------------ + +class FixedLengthEncoder: public FilterStream { +public: + + FixedLengthEncoder(Stream *strA, int lengthA); + ~FixedLengthEncoder(); + virtual StreamKind getKind() { return strWeird; } + virtual void reset(); + virtual int getChar(); + virtual int lookChar(); + virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; } + virtual GBool isBinary(GBool last = gTrue); + virtual GBool isEncoder() { return gTrue; } + +private: + + int length; + int count; +}; + +//------------------------------------------------------------------------ +// ASCIIHexEncoder +//------------------------------------------------------------------------ + +class ASCIIHexEncoder: public FilterStream { +public: + + ASCIIHexEncoder(Stream *strA); + virtual ~ASCIIHexEncoder(); + virtual StreamKind getKind() { return strWeird; } + virtual void reset(); + virtual int getChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } + virtual int lookChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } + virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; } + virtual GBool isBinary(GBool last = gTrue) { return gFalse; } + virtual GBool isEncoder() { return gTrue; } + +private: + + char buf[4]; + char *bufPtr; + char *bufEnd; + int lineLen; + GBool eof; + + GBool fillBuf(); +}; + +//------------------------------------------------------------------------ +// ASCII85Encoder +//------------------------------------------------------------------------ + +class ASCII85Encoder: public FilterStream { +public: + + ASCII85Encoder(Stream *strA); + virtual ~ASCII85Encoder(); + virtual StreamKind getKind() { return strWeird; } + virtual void reset(); + virtual int getChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } + virtual int lookChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } + virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; } + virtual GBool isBinary(GBool last = gTrue) { return gFalse; } + virtual GBool isEncoder() { return gTrue; } + +private: + + char buf[8]; + char *bufPtr; + char *bufEnd; + int lineLen; + GBool eof; + + GBool fillBuf(); +}; + +//------------------------------------------------------------------------ +// RunLengthEncoder +//------------------------------------------------------------------------ + +class RunLengthEncoder: public FilterStream { +public: + + RunLengthEncoder(Stream *strA); + virtual ~RunLengthEncoder(); + virtual StreamKind getKind() { return strWeird; } + virtual void reset(); + virtual int getChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } + virtual int lookChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } + virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; } + virtual GBool isBinary(GBool last = gTrue) { return gTrue; } + virtual GBool isEncoder() { return gTrue; } + +private: + + char buf[131]; + char *bufPtr; + char *bufEnd; + char *nextEnd; + GBool eof; + + GBool fillBuf(); +}; + +#endif