cppcheck/test/bug-hunting/cve/CVE-2019-10025/Stream.h

1190 lines
32 KiB
C++

//========================================================================
//
// Stream.h
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================
#ifndef STREAM_H
#define STREAM_H
#include <aconf.h>
#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif
#include <stdio.h>
#if HAVE_JPEGLIB
#include <jpeglib.h>
#include <setjmp.h>
#endif
#include "gtypes.h"
#include "gfile.h"
#include "Object.h"
class BaseStream;
class SharedFile;
//------------------------------------------------------------------------
enum StreamKind {
strFile,
strASCIIHex,
strASCII85,
strLZW,
strRunLength,
strCCITTFax,
strDCT,
strFlate,
strJBIG2,
strJPX,
strWeird // internal-use stream types
};
enum StreamColorSpaceMode {
streamCSNone,
streamCSDeviceGray,
streamCSDeviceRGB,
streamCSDeviceCMYK
};
//------------------------------------------------------------------------
// This is in Stream.h instead of Decrypt.h to avoid really annoying
// include file dependency loops.
enum CryptAlgorithm {
cryptRC4,
cryptAES,
cryptAES256
};
//------------------------------------------------------------------------
// Stream (base class)
//------------------------------------------------------------------------
class Stream {
public:
// Constructor.
Stream();
// Destructor.
virtual ~Stream();
virtual Stream *copy() = 0;
// Get kind of stream.
virtual StreamKind getKind() = 0;
virtual GBool isEmbedStream() {
return gFalse;
}
// 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 exactly <size> bytes from stream. Returns the number of
// bytes read -- the returned count will be less than <size> at EOF.
virtual int getBlock(char *blk, int size);
// Get next line from stream.
virtual char *getLine(char *buf, int size);
// Discard the next <n> bytes from stream. Returns the number of
// bytes discarded, which will be less than <n> only if EOF is
// reached.
virtual Guint discardChars(Guint n);
// Get current position in file.
virtual GFileOffset getPos() = 0;
// Go to a position in the stream. If <dir> is negative, the
// position is from the end of the file; otherwise the position is
// from the start of the file.
virtual void setPos(GFileOffset pos, int dir = 0) = 0;
// Get PostScript command for the filter(s).
virtual GString *getPSFilter(int psLevel, const 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 stream after the last decoder (this may be a BaseStream
// or a DecryptStream).
virtual Stream *getUndecodedStream() = 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) {}
// Return the next stream in the "stack".
virtual Stream *getNextStream() {
return NULL;
}
// Add filters to this stream according to the parameters in <dict>.
// Returns the new stream.
Stream *addFilters(Object *dict, int recursion = 0);
private:
Stream *makeFilter(char *name, Stream *str, Object *params, int recursion);
};
//------------------------------------------------------------------------
// 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(GFileOffset start, GBool limited,
GFileOffset length, Object *dict) = 0;
virtual void setPos(GFileOffset pos, int dir = 0) = 0;
virtual GBool isBinary(GBool last = gTrue) {
return last;
}
virtual BaseStream *getBaseStream() {
return this;
}
virtual Stream *getUndecodedStream() {
return this;
}
virtual Dict *getDict() {
return dict.getDict();
}
virtual GString *getFileName() {
return NULL;
}
// Get/set position of first byte of stream within the file.
virtual GFileOffset getStart() = 0;
virtual void moveStart(int delta) = 0;
protected:
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 GFileOffset getPos() {
return str->getPos();
}
virtual void setPos(GFileOffset pos, int dir = 0);
virtual BaseStream *getBaseStream() {
return str->getBaseStream();
}
virtual Stream *getUndecodedStream() {
return str->getUndecodedStream();
}
virtual Dict *getDict() {
return str->getDict();
}
virtual Stream *getNextStream() {
return str;
}
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();
// Close down the stream.
void close();
// Gets the next pixel from the stream. <pix> 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
int inputLineSize; // input line buffer size
char *inputLine; // input line buffer
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;
}
void reset();
int lookChar();
int getChar();
int getBlock(char *blk, int size);
int getPredictor() {
return predictor;
}
int getWidth() {
return width;
}
int getNComps() {
return nComps;
}
int getNBits() {
return nBits;
}
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, GFileOffset startA, GBool limitedA,
GFileOffset lengthA, Object *dictA);
virtual ~FileStream();
virtual Stream *copy();
virtual Stream *makeSubStream(GFileOffset startA, GBool limitedA,
GFileOffset lengthA, Object *dictA);
virtual StreamKind getKind() {
return strFile;
}
virtual void reset();
virtual int getChar()
{
return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
}
virtual int lookChar()
{
return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff);
}
virtual int getBlock(char *blk, int size);
virtual GFileOffset getPos() {
return bufPos + (int)(bufPtr - buf);
}
virtual void setPos(GFileOffset pos, int dir = 0);
virtual GFileOffset getStart() {
return start;
}
virtual void moveStart(int delta);
private:
FileStream(SharedFile *fA, GFileOffset startA, GBool limitedA,
GFileOffset lengthA, Object *dictA);
GBool fillBuf();
SharedFile *f;
GFileOffset start;
GBool limited;
GFileOffset length;
char buf[fileStreamBufSize];
char *bufPtr;
char *bufEnd;
GFileOffset bufPos;
};
//------------------------------------------------------------------------
// MemStream
//------------------------------------------------------------------------
class MemStream : public BaseStream {
public:
MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA);
virtual ~MemStream();
virtual Stream *copy();
virtual Stream *makeSubStream(GFileOffset start, GBool limited,
GFileOffset 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 getBlock(char *blk, int size);
virtual GFileOffset getPos() {
return (GFileOffset)(bufPtr - buf);
}
virtual void setPos(GFileOffset pos, int dir = 0);
virtual GFileOffset getStart() {
return start;
}
virtual void moveStart(int delta);
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, GFileOffset lengthA);
virtual ~EmbedStream();
virtual Stream *copy();
virtual Stream *makeSubStream(GFileOffset start, GBool limitedA,
GFileOffset lengthA, Object *dictA);
virtual StreamKind getKind() {
return str->getKind();
}
virtual GBool isEmbedStream() {
return gTrue;
}
virtual void reset() {}
virtual int getChar();
virtual int lookChar();
virtual int getBlock(char *blk, int size);
virtual GFileOffset getPos() {
return str->getPos();
}
virtual void setPos(GFileOffset pos, int dir = 0);
virtual GFileOffset getStart();
virtual void moveStart(int delta);
private:
Stream *str;
GBool limited;
GFileOffset length;
};
//------------------------------------------------------------------------
// ASCIIHexStream
//------------------------------------------------------------------------
class ASCIIHexStream : public FilterStream {
public:
ASCIIHexStream(Stream *strA);
virtual ~ASCIIHexStream();
virtual Stream *copy();
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, const 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 Stream *copy();
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, const 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 Stream *copy();
virtual StreamKind getKind() {
return strLZW;
}
virtual void reset();
virtual int getChar();
virtual int lookChar();
virtual int getRawChar();
virtual int getBlock(char *blk, int size);
virtual GString *getPSFilter(int psLevel, const 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 Stream *copy();
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 int getBlock(char *blk, int size);
virtual GString *getPSFilter(int psLevel, const 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 Stream *copy();
virtual StreamKind getKind() {
return strCCITTFax;
}
virtual void reset();
virtual int getChar();
virtual int lookChar();
virtual int getBlock(char *blk, int size);
virtual GString *getPSFilter(int psLevel, const 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
int blackXOR;
GBool eof; // true if at eof
GBool nextLine2D; // true if next line uses 2D encoding
int row; // current row
Guint inputBuf; // input buffer
int inputBits; // number of bits in input buffer
int *codingLine; // coding line changing elements
int *refLine; // reference line changing elements
int nextCol; // next column to read
int a0i; // index into codingLine
GBool err; // error on current line
int nErrors; // number of errors so far in this stream
void addPixels(int a1, int blackPixels);
void addPixelsNeg(int a1, int blackPixels);
GBool readRow();
short getTwoDimCode();
short getWhiteCode();
short getBlackCode();
short lookBits(int n);
void eatBits(int n) {
if ((inputBits -= n) < 0) inputBits = 0;
}
};
//------------------------------------------------------------------------
// DCTStream
//------------------------------------------------------------------------
#if HAVE_JPEGLIB
class DCTStream;
#define dctStreamBufSize 4096
struct DCTSourceMgr {
jpeg_source_mgr src;
DCTStream *str;
char buf[dctStreamBufSize];
};
struct DCTErrorMgr {
struct jpeg_error_mgr err;
jmp_buf setjmpBuf;
};
#else // HAVE_JPEGLIB
// 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
};
#endif // HAVE_JPEGLIB
class DCTStream : public FilterStream {
public:
DCTStream(Stream *strA, int colorXformA);
virtual ~DCTStream();
virtual Stream *copy();
virtual StreamKind getKind() {
return strDCT;
}
virtual void reset();
virtual void close();
virtual int getChar();
virtual int lookChar();
virtual int getBlock(char *blk, int size);
virtual GString *getPSFilter(int psLevel, const char *indent);
virtual GBool isBinary(GBool last = gTrue);
Stream *getRawStream() {
return str;
}
private:
#if HAVE_JPEGLIB
int colorXform; // color transform: -1 = unspecified
// 0 = none
// 1 = YUV/YUVK -> RGB/CMYK
jpeg_decompress_struct decomp;
DCTErrorMgr errorMgr;
DCTSourceMgr sourceMgr;
GBool error;
char *lineBuf;
int lineBufHeight;
char *lineBufRows[4];
char *bufPtr;
char *bufEnd;
GBool inlineImage;
GBool fillBuf();
static void errorExit(j_common_ptr d);
static void errorMessage(j_common_ptr d);
static void initSourceCbk(j_decompress_ptr d);
static boolean fillInputBufferCbk(j_decompress_ptr d);
static void skipInputDataCbk(j_decompress_ptr d, long numBytes);
static void termSourceCbk(j_decompress_ptr d);
#else // HAVE_JPEGLIB
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; // color transform: -1 = unspecified
// 0 = none
// 1 = YUV/YUVK -> RGB/CMYK
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;
Guchar *rowBufPtr; // current position within rowBuf
Guchar *rowBufEnd; // end of valid data in rowBuf
int *frameBuf[4]; // buffer for frame (progressive mode)
int comp, x, y; // 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 frame);
GBool readBaselineSOF();
GBool readProgressiveSOF();
GBool readScanInfo();
GBool readQuantTables();
GBool readHuffmanTables();
GBool readRestartInterval();
GBool readJFIFMarker();
GBool readAdobeMarker();
GBool readTrailer();
int readMarker();
int read16();
#endif // HAVE_JPEGLIB
};
//------------------------------------------------------------------------
// 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 Stream *copy();
virtual StreamKind getKind() {
return strFlate;
}
virtual void reset();
virtual int getChar();
virtual int lookChar();
virtual int getRawChar();
virtual int getBlock(char *blk, int size);
virtual GString *getPSFilter(int psLevel, const 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 Stream *copy();
virtual StreamKind getKind() {
return strWeird;
}
virtual void reset() {}
virtual int getChar() {
return EOF;
}
virtual int lookChar() {
return EOF;
}
virtual int getBlock(char *blk, int size) {
return 0;
}
virtual GString *getPSFilter(int psLevel, const char *indent)
{
return NULL;
}
virtual GBool isBinary(GBool last = gTrue) {
return gFalse;
}
};
//------------------------------------------------------------------------
// BufStream
//------------------------------------------------------------------------
class BufStream : public FilterStream {
public:
BufStream(Stream *strA, int bufSizeA);
virtual ~BufStream();
virtual Stream *copy();
virtual StreamKind getKind() {
return strWeird;
}
virtual void reset();
virtual int getChar();
virtual int lookChar();
virtual GString *getPSFilter(int psLevel, const char *indent)
{
return NULL;
}
virtual GBool isBinary(GBool last = gTrue);
int lookChar(int idx);
private:
int *buf;
int bufSize;
};
//------------------------------------------------------------------------
// FixedLengthEncoder
//------------------------------------------------------------------------
class FixedLengthEncoder : public FilterStream {
public:
FixedLengthEncoder(Stream *strA, int lengthA);
~FixedLengthEncoder();
virtual Stream *copy();
virtual StreamKind getKind() {
return strWeird;
}
virtual void reset();
virtual int getChar();
virtual int lookChar();
virtual GString *getPSFilter(int psLevel, const 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 Stream *copy();
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, const 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 Stream *copy();
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, const 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 Stream *copy();
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, const 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();
};
//------------------------------------------------------------------------
// LZWEncoder
//------------------------------------------------------------------------
struct LZWEncoderNode {
int byte;
LZWEncoderNode *next; // next sibling
LZWEncoderNode *children; // first child
};
class LZWEncoder : public FilterStream {
public:
LZWEncoder(Stream *strA);
virtual ~LZWEncoder();
virtual Stream *copy();
virtual StreamKind getKind() {
return strWeird;
}
virtual void reset();
virtual int getChar();
virtual int lookChar();
virtual GString *getPSFilter(int psLevel, const char *indent)
{
return NULL;
}
virtual GBool isBinary(GBool last = gTrue) {
return gTrue;
}
virtual GBool isEncoder() {
return gTrue;
}
private:
LZWEncoderNode table[4096];
int nextSeq;
int codeLen;
Guchar inBuf[8192];
int inBufStart;
int inBufLen;
int outBuf;
int outBufLen;
GBool needEOD;
void fillBuf();
};
#endif