//========================================================================
//
// Stream.h
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2005 Jeff Muizelaar <jeff@infidigm.net>
// Copyright (C) 2008 Julien Rebetez <julien@fhtagn.net>
// Copyright (C) 2008, 2010, 2011, 2016-2022 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
// Copyright (C) 2011, 2012, 2016, 2020 William Bader <williambader@hotmail.com>
// Copyright (C) 2012, 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2012, 2013 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2013, 2017 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2013 Peter Breitenlohner <peb@mppmu.mpg.de>
// Copyright (C) 2013, 2018 Adam Reichold <adamreichold@myopera.com>
// Copyright (C) 2013 Pino Toscano <pino@kde.org>
// Copyright (C) 2019 Volker Krause <vkrause@kde.org>
// Copyright (C) 2019 Alexander Volkov <a.volkov@rusbitech.ru>
// Copyright (C) 2020-2022 Oliver Sander <oliver.sander@tu-dresden.de>
// Copyright (C) 2020 Philipp Knechtges <philipp-dev@knechtges.com>
// Copyright (C) 2021 Hubert Figuiere <hub@figuiere.net>
// Copyright (C) 2021 Christian Persch <chpe@src.gnome.org>
// Copyright (C) 2021 Georgiy Sgibnev <georgiy@sgibnev.com>. Work sponsored by lab50.net.
// Copyright (C) 2024 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#ifndef STREAM_H
#define STREAM_H

#include <atomic>
#include <cstdio>
#include <vector>
#include <span>

#include "poppler-config.h"
#include "poppler_private_export.h"
#include "Object.h"

class GooFile;
class BaseStream;
class CachedFile;
class SplashBitmap;

//------------------------------------------------------------------------

enum StreamKind
{
    strFile,
    strCachedFile,
    strASCIIHex,
    strASCII85,
    strLZW,
    strRunLength,
    strCCITTFax,
    strDCT,
    strFlate,
    strJBIG2,
    strJPX,
    strWeird, // internal-use stream types
    strCrypt // internal-use to detect decode streams
};

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,
    cryptNone
};

//------------------------------------------------------------------------

typedef struct _ByteRange
{
    size_t offset;
    unsigned int length;
} ByteRange;

//------------------------------------------------------------------------
// Stream (base class)
//------------------------------------------------------------------------

class POPPLER_PRIVATE_EXPORT Stream
{
public:
    // Constructor.
    Stream();

    // Destructor.
    virtual ~Stream();

    Stream(const Stream &) = delete;
    Stream &operator=(const Stream &other) = delete;

    // Get kind of stream.
    virtual StreamKind getKind() const = 0;

    // Reset stream to beginning.
    virtual void reset() = 0;

    // Close down the stream.
    virtual void close();

    inline int doGetChars(int nChars, unsigned char *buffer)
    {
        if (hasGetChars()) {
            return getChars(nChars, buffer);
        } else {
            for (int i = 0; i < nChars; ++i) {
                const int c = getChar();
                if (likely(c != EOF)) {
                    buffer[i] = c;
                } else {
                    return i;
                }
            }
            return nChars;
        }
    }

    inline void fillString(std::string &s)
    {
        unsigned char readBuf[4096];
        int readChars;
        reset();
        while ((readChars = doGetChars(4096, readBuf)) != 0) {
            s.append((const char *)readBuf, readChars);
        }
    }

    inline void fillGooString(GooString *s) { fillString(s->toNonConstStr()); }

    inline std::vector<unsigned char> toUnsignedChars(int initialSize = 4096, int sizeIncrement = 4096)
    {
        std::vector<unsigned char> buf(initialSize);

        int readChars;
        int size = initialSize;
        int length = 0;
        int charsToRead = initialSize;
        bool continueReading = true;
        reset();
        while (continueReading && (readChars = doGetChars(charsToRead, buf.data() + length)) != 0) {
            length += readChars;
            if (readChars == charsToRead) {
                if (lookChar() != EOF) {
                    size += sizeIncrement;
                    charsToRead = sizeIncrement;
                    buf.resize(size);
                } else {
                    continueReading = false;
                }
            } else {
                continueReading = false;
            }
        }

        buf.resize(length);
        return buf;
    }

    // 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();
    virtual void getRawChars(int nChars, int *buffer);

    // Get next char directly from stream source, without filtering it
    virtual int getUnfilteredChar() = 0;

    // Resets the stream without reading anything (even not the headers)
    // WARNING: Reading the stream with something else than getUnfilteredChar
    // may lead to unexcepted behaviour until you call reset ()
    virtual void unfilteredReset() = 0;

    // 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 unsigned int discardChars(unsigned int n);

    // Get current position in file.
    virtual Goffset 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(Goffset pos, int dir = 0) = 0;

    // Get PostScript command for the filter(s).
    virtual GooString *getPSFilter(int psLevel, const char *indent);

    // Does this stream type potentially contain non-printable chars?
    virtual bool isBinary(bool last = true) const = 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;
    virtual Object *getDictObject() = 0;

    // Is this an encoding filter?
    virtual bool isEncoder() const { return false; }

    // 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() const { return nullptr; }

    // Add filters to this stream according to the parameters in <dict>.
    // Returns the new stream.
    Stream *addFilters(Dict *dict, int recursion = 0);

    // Returns true if this stream includes a crypt filter.
    bool isEncrypted() const;

private:
    friend class Object; // for incRef/decRef

    // Reference counting.
    int incRef() { return ++ref; }
    int decRef() { return --ref; }

    virtual bool hasGetChars() { return false; }
    virtual int getChars(int nChars, unsigned char *buffer);

    Stream *makeFilter(const char *name, Stream *str, Object *params, int recursion = 0, Dict *dict = nullptr);

    std::atomic_int ref; // reference count
};

//------------------------------------------------------------------------
// OutStream
//
// This is the base class for all streams that output to a file
//------------------------------------------------------------------------
class POPPLER_PRIVATE_EXPORT OutStream
{
public:
    // Constructor.
    OutStream();

    // Desctructor.
    virtual ~OutStream();

    OutStream(const OutStream &) = delete;
    OutStream &operator=(const OutStream &other) = delete;

    // Close the stream
    virtual void close() = 0;

    // Return position in stream
    virtual Goffset getPos() = 0;

    // Put a char in the stream
    virtual void put(char c) = 0;

    virtual size_t write(std::span<unsigned char> data) = 0;

    virtual void printf(const char *format, ...) GCC_PRINTF_FORMAT(2, 3) = 0;
};

//------------------------------------------------------------------------
// FileOutStream
//------------------------------------------------------------------------
class POPPLER_PRIVATE_EXPORT FileOutStream : public OutStream
{
public:
    FileOutStream(FILE *fa, Goffset startA);

    ~FileOutStream() override;

    void close() override;

    Goffset getPos() override;

    void put(char c) override;

    size_t write(std::span<unsigned char> data) override;

    void printf(const char *format, ...) override GCC_PRINTF_FORMAT(2, 3);

private:
    FILE *f;
    Goffset start;
};

//------------------------------------------------------------------------
// BaseStream
//
// This is the base class for all streams that read directly from a file.
//------------------------------------------------------------------------

class POPPLER_PRIVATE_EXPORT BaseStream : public Stream
{
public:
    BaseStream(Object &&dictA, Goffset lengthA);
    ~BaseStream() override;
    virtual BaseStream *copy() = 0;
    virtual Stream *makeSubStream(Goffset start, bool limited, Goffset length, Object &&dict) = 0;
    void setPos(Goffset pos, int dir = 0) override = 0;
    bool isBinary(bool last = true) const override { return last; }
    BaseStream *getBaseStream() override { return this; }
    Stream *getUndecodedStream() override { return this; }
    Dict *getDict() override { return dict.getDict(); }
    Object *getDictObject() override { return &dict; }
    virtual GooString *getFileName() { return nullptr; }
    virtual Goffset getLength() { return length; }

    // Get/set position of first byte of stream within the file.
    virtual Goffset getStart() = 0;
    virtual void moveStart(Goffset delta) = 0;

protected:
    Goffset length;
    Object dict;
};

//------------------------------------------------------------------------
// BaseInputStream
//------------------------------------------------------------------------

class POPPLER_PRIVATE_EXPORT BaseSeekInputStream : public BaseStream
{
public:
    // This enum is used to tell the seek() method how it must reposition
    // the stream offset.
    enum SeekType
    {
        SeekSet, // the offset is set to offset bytes
        SeekCur, // the offset is set to its current location plus offset bytes
        SeekEnd // the offset is set to the size of the stream plus offset bytes
    };

    BaseSeekInputStream(Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA);
    ~BaseSeekInputStream() override;
    StreamKind getKind() const override { return strWeird; }
    void reset() override;
    void close() override;
    int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
    int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
    Goffset getPos() override { return bufPos + (bufPtr - buf); }
    void setPos(Goffset pos, int dir = 0) override;
    Goffset getStart() override { return start; }
    void moveStart(Goffset delta) override;

    int getUnfilteredChar() override { return getChar(); }
    void unfilteredReset() override { reset(); }

protected:
    Goffset start;
    bool limited;

private:
    bool fillBuf();

    bool hasGetChars() override { return true; }
    int getChars(int nChars, unsigned char *buffer) override;

    virtual Goffset currentPos() const = 0;
    virtual void setCurrentPos(Goffset offset) = 0;
    virtual Goffset read(char *buf, Goffset size) = 0;

    static constexpr int seekInputStreamBufSize = 1024;
    char buf[seekInputStreamBufSize];
    char *bufPtr;
    char *bufEnd;
    Goffset bufPos;
    Goffset savePos;
    bool saved;
};

//------------------------------------------------------------------------
// FilterStream
//
// This is the base class for all streams that filter another stream.
//------------------------------------------------------------------------

class FilterStream : public Stream
{
public:
    explicit FilterStream(Stream *strA);
    ~FilterStream() override;
    void close() override;
    Goffset getPos() override { return str->getPos(); }
    void setPos(Goffset pos, int dir = 0) override;
    BaseStream *getBaseStream() override { return str->getBaseStream(); }
    Stream *getUndecodedStream() override { return str->getUndecodedStream(); }
    Dict *getDict() override { return str->getDict(); }
    Object *getDictObject() override { return str->getDictObject(); }
    Stream *getNextStream() const override { return str; }

    int getUnfilteredChar() override { return str->getUnfilteredChar(); }
    void unfilteredReset() override { str->unfilteredReset(); }

protected:
    Stream *str;
};

//------------------------------------------------------------------------
// ImageStream
//------------------------------------------------------------------------

class POPPLER_PRIVATE_EXPORT 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();

    ImageStream(const ImageStream &) = delete;
    ImageStream &operator=(const ImageStream &other) = delete;

    // Reset the stream.
    void reset();

    // Close the stream previously reset
    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.
    bool getPixel(unsigned char *pix);

    // Returns a pointer to the next line of pixels.  Returns NULL at
    // end of file.
    unsigned char *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
    unsigned char *inputLine; // input line buffer
    unsigned char *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();

    StreamPredictor(const StreamPredictor &) = delete;
    StreamPredictor &operator=(const StreamPredictor &) = delete;

    bool isOk() { return ok; }

    int lookChar();
    int getChar();
    int getChars(int nChars, unsigned char *buffer);

private:
    bool 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
    unsigned char *predLine; // line buffer
    int predIdx; // current index in predLine
    bool ok;
};

//------------------------------------------------------------------------
// FileStream
//------------------------------------------------------------------------

#define fileStreamBufSize 256

class POPPLER_PRIVATE_EXPORT FileStream : public BaseStream
{
public:
    FileStream(GooFile *fileA, Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA);
    ~FileStream() override;
    BaseStream *copy() override;
    Stream *makeSubStream(Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA) override;
    StreamKind getKind() const override { return strFile; }
    void reset() override;
    void close() override;
    int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
    int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
    Goffset getPos() override { return bufPos + (bufPtr - buf); }
    void setPos(Goffset pos, int dir = 0) override;
    Goffset getStart() override { return start; }
    void moveStart(Goffset delta) override;

    int getUnfilteredChar() override { return getChar(); }
    void unfilteredReset() override { reset(); }

    bool getNeedsEncryptionOnSave() const { return needsEncryptionOnSave; }
    void setNeedsEncryptionOnSave(bool needsEncryptionOnSaveA) { needsEncryptionOnSave = needsEncryptionOnSaveA; }

private:
    bool fillBuf();

    bool hasGetChars() override { return true; }
    int getChars(int nChars, unsigned char *buffer) override
    {
        int n, m;

        n = 0;
        while (n < nChars) {
            if (bufPtr >= bufEnd) {
                if (!fillBuf()) {
                    break;
                }
            }
            m = (int)(bufEnd - bufPtr);
            if (m > nChars - n) {
                m = nChars - n;
            }
            memcpy(buffer + n, bufPtr, m);
            bufPtr += m;
            n += m;
        }
        return n;
    }

private:
    GooFile *file;
    Goffset offset;
    Goffset start;
    bool limited;
    char buf[fileStreamBufSize];
    char *bufPtr;
    char *bufEnd;
    Goffset bufPos;
    Goffset savePos;
    bool saved;
    bool needsEncryptionOnSave; // Needed for FileStreams that point to "external" files
                                // and thus when saving we can't do a raw copy
};

//------------------------------------------------------------------------
// CachedFileStream
//------------------------------------------------------------------------

#define cachedStreamBufSize 1024

class POPPLER_PRIVATE_EXPORT CachedFileStream : public BaseStream
{
public:
    CachedFileStream(CachedFile *ccA, Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA);
    ~CachedFileStream() override;
    BaseStream *copy() override;
    Stream *makeSubStream(Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA) override;
    StreamKind getKind() const override { return strCachedFile; }
    void reset() override;
    void close() override;
    int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
    int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
    Goffset getPos() override { return bufPos + (bufPtr - buf); }
    void setPos(Goffset pos, int dir = 0) override;
    Goffset getStart() override { return start; }
    void moveStart(Goffset delta) override;

    int getUnfilteredChar() override { return getChar(); }
    void unfilteredReset() override { reset(); }

private:
    bool fillBuf();

    CachedFile *cc;
    Goffset start;
    bool limited;
    char buf[cachedStreamBufSize];
    char *bufPtr;
    char *bufEnd;
    unsigned int bufPos;
    int savePos;
    bool saved;
};

//------------------------------------------------------------------------
// MemStream
//------------------------------------------------------------------------

template<typename T>
class BaseMemStream : public BaseStream
{
public:
    BaseMemStream(T *bufA, Goffset startA, Goffset lengthA, Object &&dictA) : BaseStream(std::move(dictA), lengthA)
    {
        buf = bufA;
        start = startA;
        length = lengthA;
        bufEnd = buf + start + length;
        bufPtr = buf + start;
    }

    BaseStream *copy() override { return new BaseMemStream(buf, start, length, dict.copy()); }

    Stream *makeSubStream(Goffset startA, bool limited, Goffset lengthA, Object &&dictA) override
    {
        Goffset newLength;

        if (!limited || startA + lengthA > start + length) {
            newLength = start + length - startA;
        } else {
            newLength = lengthA;
        }
        return new BaseMemStream(buf, startA, newLength, std::move(dictA));
    }

    StreamKind getKind() const override { return strWeird; }

    void reset() override { bufPtr = buf + start; }

    void close() override { }

    int getChar() override { return (bufPtr < bufEnd) ? (*bufPtr++ & 0xff) : EOF; }

    int lookChar() override { return (bufPtr < bufEnd) ? (*bufPtr & 0xff) : EOF; }

    Goffset getPos() override { return (int)(bufPtr - buf); }

    void setPos(Goffset pos, int dir = 0) override
    {
        Goffset i;

        if (dir >= 0) {
            i = pos;
        } else {
            i = start + length - pos;
        }
        if (i < start) {
            i = start;
        } else if (i > start + length) {
            i = start + length;
        }
        bufPtr = buf + i;
    }

    Goffset getStart() override { return start; }

    void moveStart(Goffset delta) override
    {
        start += delta;
        length -= delta;
        bufPtr = buf + start;
    }

    int getUnfilteredChar() override { return getChar(); }

    void unfilteredReset() override { reset(); }

protected:
    T *buf;

private:
    bool hasGetChars() override { return true; }

    int getChars(int nChars, unsigned char *buffer) override
    {
        int n;

        if (unlikely(nChars <= 0)) {
            return 0;
        }
        if (unlikely(bufPtr >= bufEnd)) {
            return 0;
        }
        if (bufEnd - bufPtr < nChars) {
            n = (int)(bufEnd - bufPtr);
        } else {
            n = nChars;
        }
        memcpy(buffer, bufPtr, n);
        bufPtr += n;
        return n;
    }

    Goffset start;
    T *bufEnd;
    T *bufPtr;
};

class POPPLER_PRIVATE_EXPORT MemStream : public BaseMemStream<const char>
{
public:
    MemStream(const char *bufA, Goffset startA, Goffset lengthA, Object &&dictA) : BaseMemStream(bufA, startA, lengthA, std::move(dictA)) { }
    ~MemStream() override;
};

class AutoFreeMemStream : public BaseMemStream<char>
{
    bool filterRemovalForbidden = false;

public:
    // AutoFreeMemStream takes ownership over the buffer.
    // The buffer should be created using gmalloc().
    AutoFreeMemStream(char *bufA, Goffset startA, Goffset lengthA, Object &&dictA) : BaseMemStream(bufA, startA, lengthA, std::move(dictA)) { }
    ~AutoFreeMemStream() override;

    // A hack to deal with the strange behaviour of PDFDoc::writeObject().
    bool isFilterRemovalForbidden() const;
    void setFilterRemovalForbidden(bool forbidden);
};

//------------------------------------------------------------------------
// 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 POPPLER_PRIVATE_EXPORT EmbedStream : public BaseStream
{
public:
    EmbedStream(Stream *strA, Object &&dictA, bool limitedA, Goffset lengthA, bool reusableA = false);
    ~EmbedStream() override;
    BaseStream *copy() override;
    Stream *makeSubStream(Goffset start, bool limitedA, Goffset lengthA, Object &&dictA) override;
    StreamKind getKind() const override { return str->getKind(); }
    void reset() override;
    int getChar() override;
    int lookChar() override;
    Goffset getPos() override;
    void setPos(Goffset pos, int dir = 0) override;
    Goffset getStart() override;
    void moveStart(Goffset delta) override;

    int getUnfilteredChar() override { return str->getUnfilteredChar(); }
    void unfilteredReset() override { str->unfilteredReset(); }

    void rewind();
    void restore();

private:
    bool hasGetChars() override { return true; }
    int getChars(int nChars, unsigned char *buffer) override;

    Stream *str;
    bool limited;
    bool reusable;
    bool record;
    bool replay;
    unsigned char *bufData;
    long bufMax;
    long bufLen;
    long bufPos;
    Goffset start;
};

//------------------------------------------------------------------------
// ASCIIHexStream
//------------------------------------------------------------------------

class ASCIIHexStream : public FilterStream
{
public:
    explicit ASCIIHexStream(Stream *strA);
    ~ASCIIHexStream() override;
    StreamKind getKind() const override { return strASCIIHex; }
    void reset() override;
    int getChar() override
    {
        int c = lookChar();
        buf = EOF;
        return c;
    }
    int lookChar() override;
    GooString *getPSFilter(int psLevel, const char *indent) override;
    bool isBinary(bool last = true) const override;

private:
    int buf;
    bool eof;
};

//------------------------------------------------------------------------
// ASCII85Stream
//------------------------------------------------------------------------

class ASCII85Stream : public FilterStream
{
public:
    explicit ASCII85Stream(Stream *strA);
    ~ASCII85Stream() override;
    StreamKind getKind() const override { return strASCII85; }
    void reset() override;
    int getChar() override
    {
        int ch = lookChar();
        ++index;
        return ch;
    }
    int lookChar() override;
    GooString *getPSFilter(int psLevel, const char *indent) override;
    bool isBinary(bool last = true) const override;

private:
    int c[5];
    int b[4];
    int index, n;
    bool eof;
};

//------------------------------------------------------------------------
// LZWStream
//------------------------------------------------------------------------

class LZWStream : public FilterStream
{
public:
    LZWStream(Stream *strA, int predictor, int columns, int colors, int bits, int earlyA);
    ~LZWStream() override;
    StreamKind getKind() const override { return strLZW; }
    void reset() override;
    int getChar() override;
    int lookChar() override;
    int getRawChar() override;
    void getRawChars(int nChars, int *buffer) override;
    GooString *getPSFilter(int psLevel, const char *indent) override;
    bool isBinary(bool last = true) const override;

private:
    bool hasGetChars() override { return true; }
    int getChars(int nChars, unsigned char *buffer) override;

    inline int doGetRawChar()
    {
        if (eof) {
            return EOF;
        }
        if (seqIndex >= seqLength) {
            if (!processNextCode()) {
                return EOF;
            }
        }
        return seqBuf[seqIndex++];
    }

    StreamPredictor *pred; // predictor
    int early; // early parameter
    bool eof; // true if at eof
    unsigned int inputBuf; // input buffer
    int inputBits; // number of bits in input buffer
    struct
    { // decoding table
        int length;
        int head;
        unsigned char 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
    unsigned char seqBuf[4097]; // buffer for current sequence
    int seqLength; // length of current sequence
    int seqIndex; // index into current sequence
    bool first; // first code after a table clear

    bool processNextCode();
    void clearTable();
    int getCode();
};

//------------------------------------------------------------------------
// RunLengthStream
//------------------------------------------------------------------------

class RunLengthStream : public FilterStream
{
public:
    explicit RunLengthStream(Stream *strA);
    ~RunLengthStream() override;
    StreamKind getKind() const override { return strRunLength; }
    void reset() override;
    int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
    int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
    GooString *getPSFilter(int psLevel, const char *indent) override;
    bool isBinary(bool last = true) const override;

private:
    bool hasGetChars() override { return true; }
    int getChars(int nChars, unsigned char *buffer) override;

    char buf[128]; // buffer
    char *bufPtr; // next char to read
    char *bufEnd; // end of buffer
    bool eof;

    bool fillBuf();
};

//------------------------------------------------------------------------
// CCITTFaxStream
//------------------------------------------------------------------------

struct CCITTCodeTable;

class CCITTFaxStream : public FilterStream
{
public:
    CCITTFaxStream(Stream *strA, int encodingA, bool endOfLineA, bool byteAlignA, int columnsA, int rowsA, bool endOfBlockA, bool blackA, int damagedRowsBeforeErrorA);
    ~CCITTFaxStream() override;
    StreamKind getKind() const override { return strCCITTFax; }
    void reset() override;
    int getChar() override
    {
        int c = lookChar();
        buf = EOF;
        return c;
    }
    int lookChar() override;
    GooString *getPSFilter(int psLevel, const char *indent) override;
    bool isBinary(bool last = true) const override;

    void unfilteredReset() override;

    int getEncoding() { return encoding; }
    bool getEndOfLine() { return endOfLine; }
    bool getEncodedByteAlign() { return byteAlign; }
    bool getEndOfBlock() { return endOfBlock; }
    int getColumns() { return columns; }
    bool getBlackIs1() { return black; }
    int getDamagedRowsBeforeError() { return damagedRowsBeforeError; }

private:
    void ccittReset(bool unfiltered);
    int encoding; // 'K' parameter
    bool endOfLine; // 'EndOfLine' parameter
    bool byteAlign; // 'EncodedByteAlign' parameter
    int columns; // 'Columns' parameter
    int rows; // 'Rows' parameter
    bool endOfBlock; // 'EndOfBlock' parameter
    bool black; // 'BlackIs1' parameter
    int damagedRowsBeforeError; // 'DamagedRowsBeforeError' parameter
    bool eof; // true if at eof
    bool nextLine2D; // true if next line uses 2D encoding
    int row; // current row
    unsigned int inputBuf; // input buffer
    int inputBits; // number of bits in input buffer
    int *codingLine; // coding line changing elements
    int *refLine; // reference line changing elements
    int a0i; // index into codingLine
    bool err; // error on current line
    int outputBits; // remaining ouput bits
    int buf; // character buffer

    void addPixels(int a1, int blackPixels);
    void addPixelsNeg(int a1, int blackPixels);
    short getTwoDimCode();
    short getWhiteCode();
    short getBlackCode();
    short lookBits(int n);
    void eatBits(int n)
    {
        if ((inputBits -= n) < 0) {
            inputBits = 0;
        }
    }
};

#ifndef ENABLE_LIBJPEG
//------------------------------------------------------------------------
// 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
{
    bool 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
{
    unsigned char firstSym[17]; // first symbol for this bit length
    unsigned short firstCode[17]; // first code for this bit length
    unsigned short numCodes[17]; // number of codes of this bit length
    unsigned char sym[256]; // symbols
};

class DCTStream : public FilterStream
{
public:
    DCTStream(Stream *strA, int colorXformA, Dict *dict, int recursion);
    ~DCTStream() override;
    StreamKind getKind() const override { return strDCT; }
    void reset() override;
    void close() override;
    int getChar() override;
    int lookChar() override;
    GooString *getPSFilter(int psLevel, const char *indent) override;
    bool isBinary(bool last = true) const override;

    void unfilteredReset() override;

private:
    void dctReset(bool unfiltered);
    bool progressive; // set if in progressive mode
    bool 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
    bool gotJFIFMarker; // set if APP0 JFIF marker was present
    bool gotAdobeMarker; // set if APP14 Adobe marker was present
    int restartInterval; // restart interval, in MCUs
    unsigned short 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
    unsigned char *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();
    bool readMCURow();
    void readScan();
    bool readDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable, int *prevDC, int data[64]);
    bool readProgressiveDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable, int *prevDC, int data[64]);
    void decodeImage();
    void transformDataUnit(unsigned short *quantTable, int dataIn[64], unsigned char dataOut[64]);
    int readHuffSym(DCTHuffTable *table);
    int readAmp(int size);
    int readBit();
    bool readHeader();
    bool readBaselineSOF();
    bool readProgressiveSOF();
    bool readScanInfo();
    bool readQuantTables();
    bool readHuffmanTables();
    bool readRestartInterval();
    bool readJFIFMarker();
    bool readAdobeMarker();
    bool readTrailer();
    int readMarker();
    int read16();
};

#endif

#ifndef ENABLE_ZLIB_UNCOMPRESS
//------------------------------------------------------------------------
// 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
{
    unsigned short len; // code length, in bits
    unsigned short val; // value represented by this code
};

struct FlateHuffmanTab
{
    const 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);
    ~FlateStream() override;
    StreamKind getKind() const override { return strFlate; }
    void reset() override;
    int getChar() override;
    int lookChar() override;
    int getRawChar() override;
    void getRawChars(int nChars, int *buffer) override;
    GooString *getPSFilter(int psLevel, const char *indent) override;
    bool isBinary(bool last = true) const override;
    void unfilteredReset() override;

private:
    void flateReset(bool unfiltered);
    inline int doGetRawChar()
    {
        int c;

        while (remain == 0) {
            if (endOfBlock && eof) {
                return EOF;
            }
            readSome();
        }
        c = buf[index];
        index = (index + 1) & flateMask;
        --remain;
        return c;
    }

    bool hasGetChars() override { return true; }
    int getChars(int nChars, unsigned char *buffer) override;

    StreamPredictor *pred; // predictor
    unsigned char 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
    bool compressedBlock; // set if reading a compressed block
    int blockLen; // remaining length of uncompressed block
    bool endOfBlock; // set when end of block is reached
    bool eof; // set when end of stream is reached

    static const int // code length code reordering
            codeLenCodeMap[flateMaxCodeLenCodes];
    static const FlateDecode // length decoding info
            lengthDecode[flateMaxLitCodes - 257];
    static const FlateDecode // distance decoding info
            distDecode[flateMaxDistCodes];
    static FlateHuffmanTab // fixed literal code table
            fixedLitCodeTab;
    static FlateHuffmanTab // fixed distance code table
            fixedDistCodeTab;

    void readSome();
    bool startBlock();
    void loadFixedCodes();
    bool readDynamicCodes();
    FlateCode *compHuffmanCodes(const int *lengths, int n, int *maxLen);
    int getHuffmanCodeWord(FlateHuffmanTab *tab);
    int getCodeWord(int bits);
};
#endif

//------------------------------------------------------------------------
// EOFStream
//------------------------------------------------------------------------

class EOFStream : public FilterStream
{
public:
    explicit EOFStream(Stream *strA);
    ~EOFStream() override;
    StreamKind getKind() const override { return strWeird; }
    void reset() override { }
    int getChar() override { return EOF; }
    int lookChar() override { return EOF; }
    GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
    bool isBinary(bool /*last = true*/) const override { return false; }
};

//------------------------------------------------------------------------
// BufStream
//------------------------------------------------------------------------

class BufStream : public FilterStream
{
public:
    BufStream(Stream *strA, int bufSizeA);
    ~BufStream() override;
    StreamKind getKind() const override { return strWeird; }
    void reset() override;
    int getChar() override;
    int lookChar() override;
    GooString *getPSFilter(int psLevel, const char *indent) override { return nullptr; }
    bool isBinary(bool last = true) const override;

    int lookChar(int idx);

private:
    int *buf;
    int bufSize;
};

//------------------------------------------------------------------------
// FixedLengthEncoder
//------------------------------------------------------------------------

class FixedLengthEncoder : public FilterStream
{
public:
    FixedLengthEncoder(Stream *strA, int lengthA);
    ~FixedLengthEncoder() override;
    StreamKind getKind() const override { return strWeird; }
    void reset() override;
    int getChar() override;
    int lookChar() override;
    GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
    bool isBinary(bool /*last = true*/) const override;
    bool isEncoder() const override { return true; }

private:
    int length;
    int count;
};

//------------------------------------------------------------------------
// ASCIIHexEncoder
//------------------------------------------------------------------------

class ASCIIHexEncoder : public FilterStream
{
public:
    explicit ASCIIHexEncoder(Stream *strA);
    ~ASCIIHexEncoder() override;
    StreamKind getKind() const override { return strWeird; }
    void reset() override;
    int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
    int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
    GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
    bool isBinary(bool /*last = true*/) const override { return false; }
    bool isEncoder() const override { return true; }

private:
    char buf[4];
    char *bufPtr;
    char *bufEnd;
    int lineLen;
    bool eof;

    bool fillBuf();
};

//------------------------------------------------------------------------
// ASCII85Encoder
//------------------------------------------------------------------------

class ASCII85Encoder : public FilterStream
{
public:
    explicit ASCII85Encoder(Stream *strA);
    ~ASCII85Encoder() override;
    StreamKind getKind() const override { return strWeird; }
    void reset() override;
    int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
    int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
    GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
    bool isBinary(bool /*last = true*/) const override { return false; }
    bool isEncoder() const override { return true; }

private:
    char buf[8];
    char *bufPtr;
    char *bufEnd;
    int lineLen;
    bool eof;

    bool fillBuf();
};

//------------------------------------------------------------------------
// RunLengthEncoder
//------------------------------------------------------------------------

class RunLengthEncoder : public FilterStream
{
public:
    explicit RunLengthEncoder(Stream *strA);
    ~RunLengthEncoder() override;
    StreamKind getKind() const override { return strWeird; }
    void reset() override;
    int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
    int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
    GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
    bool isBinary(bool /*last = true*/) const override { return true; }
    bool isEncoder() const override { return true; }

private:
    char buf[131];
    char *bufPtr;
    char *bufEnd;
    char *nextEnd;
    bool eof;

    bool fillBuf();
};

//------------------------------------------------------------------------
// LZWEncoder
//------------------------------------------------------------------------

struct LZWEncoderNode
{
    int byte;
    LZWEncoderNode *next; // next sibling
    LZWEncoderNode *children; // first child
};

class LZWEncoder : public FilterStream
{
public:
    explicit LZWEncoder(Stream *strA);
    ~LZWEncoder() override;
    StreamKind getKind() const override { return strWeird; }
    void reset() override;
    int getChar() override;
    int lookChar() override;
    GooString *getPSFilter(int psLevel, const char *indent) override { return nullptr; }
    bool isBinary(bool last = true) const override { return true; }
    bool isEncoder() const override { return true; }

private:
    LZWEncoderNode table[4096];
    int nextSeq;
    int codeLen;
    unsigned char inBuf[4096];
    int inBufLen;
    int outBuf;
    int outBufLen;
    bool needEOD;

    void fillBuf();
};

//------------------------------------------------------------------------
// CMYKGrayEncoder
//------------------------------------------------------------------------

class CMYKGrayEncoder : public FilterStream
{
public:
    explicit CMYKGrayEncoder(Stream *strA);
    ~CMYKGrayEncoder() override;
    StreamKind getKind() const override { return strWeird; }
    void reset() override;
    int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
    int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
    GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
    bool isBinary(bool /*last = true*/) const override { return false; }
    bool isEncoder() const override { return true; }

private:
    char buf[2];
    char *bufPtr;
    char *bufEnd;
    bool eof;

    bool fillBuf();
};

//------------------------------------------------------------------------
// RGBGrayEncoder
//------------------------------------------------------------------------

class RGBGrayEncoder : public FilterStream
{
public:
    explicit RGBGrayEncoder(Stream *strA);
    ~RGBGrayEncoder() override;
    StreamKind getKind() const override { return strWeird; }
    void reset() override;
    int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
    int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
    GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
    bool isBinary(bool /*last = true*/) const override { return false; }
    bool isEncoder() const override { return true; }

private:
    char buf[2];
    char *bufPtr;
    char *bufEnd;
    bool eof;

    bool fillBuf();
};

//------------------------------------------------------------------------
// SplashBitmapCMYKEncoder
//
// This stream helps to condense SplashBitmaps (mostly of DeviceN8 type) into
// pure CMYK colors. In particular for a DeviceN8 bitmap it redacts the spot colorants.
//------------------------------------------------------------------------

class SplashBitmapCMYKEncoder : public Stream
{
public:
    explicit SplashBitmapCMYKEncoder(SplashBitmap *bitmapA);
    ~SplashBitmapCMYKEncoder() override;
    StreamKind getKind() const override { return strWeird; }
    void reset() override;
    int getChar() override;
    int lookChar() override;
    GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
    bool isBinary(bool /*last = true*/) const override { return true; }

    // Although we are an encoder, we return false here, since we do not want do be auto-deleted by
    // successive streams.
    bool isEncoder() const override { return false; }

    int getUnfilteredChar() override { return getChar(); }
    void unfilteredReset() override { reset(); }

    BaseStream *getBaseStream() override { return nullptr; }
    Stream *getUndecodedStream() override { return this; }

    Dict *getDict() override { return nullptr; }
    Object *getDictObject() override { return nullptr; }

    Goffset getPos() override;
    void setPos(Goffset pos, int dir = 0) override;

private:
    SplashBitmap *bitmap;
    size_t width;
    int height;

    std::vector<unsigned char> buf;
    size_t bufPtr;
    int curLine;

    bool fillBuf();
};

#endif
