Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-10 10:23:51

0001 //========================================================================
0002 //
0003 // Stream.h
0004 //
0005 // Copyright 1996-2003 Glyph & Cog, LLC
0006 //
0007 //========================================================================
0008 
0009 //========================================================================
0010 //
0011 // Modified under the Poppler project - http://poppler.freedesktop.org
0012 //
0013 // All changes made under the Poppler project to this file are licensed
0014 // under GPL version 2 or later
0015 //
0016 // Copyright (C) 2005 Jeff Muizelaar <jeff@infidigm.net>
0017 // Copyright (C) 2008 Julien Rebetez <julien@fhtagn.net>
0018 // Copyright (C) 2008, 2010, 2011, 2016-2022 Albert Astals Cid <aacid@kde.org>
0019 // Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
0020 // Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
0021 // Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
0022 // Copyright (C) 2011, 2012, 2016, 2020 William Bader <williambader@hotmail.com>
0023 // Copyright (C) 2012, 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
0024 // Copyright (C) 2012, 2013 Fabio D'Urso <fabiodurso@hotmail.it>
0025 // Copyright (C) 2013, 2017 Adrian Johnson <ajohnson@redneon.com>
0026 // Copyright (C) 2013 Peter Breitenlohner <peb@mppmu.mpg.de>
0027 // Copyright (C) 2013, 2018 Adam Reichold <adamreichold@myopera.com>
0028 // Copyright (C) 2013 Pino Toscano <pino@kde.org>
0029 // Copyright (C) 2019 Volker Krause <vkrause@kde.org>
0030 // Copyright (C) 2019 Alexander Volkov <a.volkov@rusbitech.ru>
0031 // Copyright (C) 2020-2022 Oliver Sander <oliver.sander@tu-dresden.de>
0032 // Copyright (C) 2020 Philipp Knechtges <philipp-dev@knechtges.com>
0033 // Copyright (C) 2021 Hubert Figuiere <hub@figuiere.net>
0034 // Copyright (C) 2021 Christian Persch <chpe@src.gnome.org>
0035 // Copyright (C) 2021 Georgiy Sgibnev <georgiy@sgibnev.com>. Work sponsored by lab50.net.
0036 //
0037 // To see a description of the changes please see the Changelog file that
0038 // came with your tarball or type make ChangeLog if you are building from git
0039 //
0040 //========================================================================
0041 
0042 #ifndef STREAM_H
0043 #define STREAM_H
0044 
0045 #include <atomic>
0046 #include <cstdio>
0047 #include <vector>
0048 
0049 #include "poppler-config.h"
0050 #include "poppler_private_export.h"
0051 #include "Object.h"
0052 
0053 class GooFile;
0054 class BaseStream;
0055 class CachedFile;
0056 class SplashBitmap;
0057 
0058 //------------------------------------------------------------------------
0059 
0060 enum StreamKind
0061 {
0062     strFile,
0063     strCachedFile,
0064     strASCIIHex,
0065     strASCII85,
0066     strLZW,
0067     strRunLength,
0068     strCCITTFax,
0069     strDCT,
0070     strFlate,
0071     strJBIG2,
0072     strJPX,
0073     strWeird, // internal-use stream types
0074     strCrypt // internal-use to detect decode streams
0075 };
0076 
0077 enum StreamColorSpaceMode
0078 {
0079     streamCSNone,
0080     streamCSDeviceGray,
0081     streamCSDeviceRGB,
0082     streamCSDeviceCMYK
0083 };
0084 
0085 //------------------------------------------------------------------------
0086 
0087 // This is in Stream.h instead of Decrypt.h to avoid really annoying
0088 // include file dependency loops.
0089 enum CryptAlgorithm
0090 {
0091     cryptRC4,
0092     cryptAES,
0093     cryptAES256,
0094     cryptNone
0095 };
0096 
0097 //------------------------------------------------------------------------
0098 
0099 typedef struct _ByteRange
0100 {
0101     size_t offset;
0102     unsigned int length;
0103 } ByteRange;
0104 
0105 //------------------------------------------------------------------------
0106 // Stream (base class)
0107 //------------------------------------------------------------------------
0108 
0109 class POPPLER_PRIVATE_EXPORT Stream
0110 {
0111 public:
0112     // Constructor.
0113     Stream();
0114 
0115     // Destructor.
0116     virtual ~Stream();
0117 
0118     Stream(const Stream &) = delete;
0119     Stream &operator=(const Stream &other) = delete;
0120 
0121     // Get kind of stream.
0122     virtual StreamKind getKind() const = 0;
0123 
0124     // Reset stream to beginning.
0125     virtual void reset() = 0;
0126 
0127     // Close down the stream.
0128     virtual void close();
0129 
0130     inline int doGetChars(int nChars, unsigned char *buffer)
0131     {
0132         if (hasGetChars()) {
0133             return getChars(nChars, buffer);
0134         } else {
0135             for (int i = 0; i < nChars; ++i) {
0136                 const int c = getChar();
0137                 if (likely(c != EOF)) {
0138                     buffer[i] = c;
0139                 } else {
0140                     return i;
0141                 }
0142             }
0143             return nChars;
0144         }
0145     }
0146 
0147     inline void fillString(std::string &s)
0148     {
0149         unsigned char readBuf[4096];
0150         int readChars;
0151         reset();
0152         while ((readChars = doGetChars(4096, readBuf)) != 0) {
0153             s.append((const char *)readBuf, readChars);
0154         }
0155     }
0156 
0157     inline void fillGooString(GooString *s) { fillString(s->toNonConstStr()); }
0158 
0159     inline std::vector<unsigned char> toUnsignedChars(int initialSize = 4096, int sizeIncrement = 4096)
0160     {
0161         std::vector<unsigned char> buf(initialSize);
0162 
0163         int readChars;
0164         int size = initialSize;
0165         int length = 0;
0166         int charsToRead = initialSize;
0167         bool continueReading = true;
0168         reset();
0169         while (continueReading && (readChars = doGetChars(charsToRead, buf.data() + length)) != 0) {
0170             length += readChars;
0171             if (readChars == charsToRead) {
0172                 if (lookChar() != EOF) {
0173                     size += sizeIncrement;
0174                     charsToRead = sizeIncrement;
0175                     buf.resize(size);
0176                 } else {
0177                     continueReading = false;
0178                 }
0179             } else {
0180                 continueReading = false;
0181             }
0182         }
0183 
0184         buf.resize(length);
0185         return buf;
0186     }
0187 
0188     // Get next char from stream.
0189     virtual int getChar() = 0;
0190 
0191     // Peek at next char in stream.
0192     virtual int lookChar() = 0;
0193 
0194     // Get next char from stream without using the predictor.
0195     // This is only used by StreamPredictor.
0196     virtual int getRawChar();
0197     virtual void getRawChars(int nChars, int *buffer);
0198 
0199     // Get next char directly from stream source, without filtering it
0200     virtual int getUnfilteredChar() = 0;
0201 
0202     // Resets the stream without reading anything (even not the headers)
0203     // WARNING: Reading the stream with something else than getUnfilteredChar
0204     // may lead to unexcepted behaviour until you call reset ()
0205     virtual void unfilteredReset() = 0;
0206 
0207     // Get next line from stream.
0208     virtual char *getLine(char *buf, int size);
0209 
0210     // Discard the next <n> bytes from stream.  Returns the number of
0211     // bytes discarded, which will be less than <n> only if EOF is
0212     // reached.
0213     virtual unsigned int discardChars(unsigned int n);
0214 
0215     // Get current position in file.
0216     virtual Goffset getPos() = 0;
0217 
0218     // Go to a position in the stream.  If <dir> is negative, the
0219     // position is from the end of the file; otherwise the position is
0220     // from the start of the file.
0221     virtual void setPos(Goffset pos, int dir = 0) = 0;
0222 
0223     // Get PostScript command for the filter(s).
0224     virtual GooString *getPSFilter(int psLevel, const char *indent);
0225 
0226     // Does this stream type potentially contain non-printable chars?
0227     virtual bool isBinary(bool last = true) const = 0;
0228 
0229     // Get the BaseStream of this stream.
0230     virtual BaseStream *getBaseStream() = 0;
0231 
0232     // Get the stream after the last decoder (this may be a BaseStream
0233     // or a DecryptStream).
0234     virtual Stream *getUndecodedStream() = 0;
0235 
0236     // Get the dictionary associated with this stream.
0237     virtual Dict *getDict() = 0;
0238     virtual Object *getDictObject() = 0;
0239 
0240     // Is this an encoding filter?
0241     virtual bool isEncoder() const { return false; }
0242 
0243     // Get image parameters which are defined by the stream contents.
0244     virtual void getImageParams(int * /*bitsPerComponent*/, StreamColorSpaceMode * /*csMode*/) { }
0245 
0246     // Return the next stream in the "stack".
0247     virtual Stream *getNextStream() const { return nullptr; }
0248 
0249     // Add filters to this stream according to the parameters in <dict>.
0250     // Returns the new stream.
0251     Stream *addFilters(Dict *dict, int recursion = 0);
0252 
0253     // Returns true if this stream includes a crypt filter.
0254     bool isEncrypted() const;
0255 
0256 private:
0257     friend class Object; // for incRef/decRef
0258 
0259     // Reference counting.
0260     int incRef() { return ++ref; }
0261     int decRef() { return --ref; }
0262 
0263     virtual bool hasGetChars() { return false; }
0264     virtual int getChars(int nChars, unsigned char *buffer);
0265 
0266     Stream *makeFilter(const char *name, Stream *str, Object *params, int recursion = 0, Dict *dict = nullptr);
0267 
0268     std::atomic_int ref; // reference count
0269 };
0270 
0271 //------------------------------------------------------------------------
0272 // OutStream
0273 //
0274 // This is the base class for all streams that output to a file
0275 //------------------------------------------------------------------------
0276 class POPPLER_PRIVATE_EXPORT OutStream
0277 {
0278 public:
0279     // Constructor.
0280     OutStream();
0281 
0282     // Desctructor.
0283     virtual ~OutStream();
0284 
0285     OutStream(const OutStream &) = delete;
0286     OutStream &operator=(const OutStream &other) = delete;
0287 
0288     // Close the stream
0289     virtual void close() = 0;
0290 
0291     // Return position in stream
0292     virtual Goffset getPos() = 0;
0293 
0294     // Put a char in the stream
0295     virtual void put(char c) = 0;
0296 
0297     virtual void printf(const char *format, ...) GCC_PRINTF_FORMAT(2, 3) = 0;
0298 };
0299 
0300 //------------------------------------------------------------------------
0301 // FileOutStream
0302 //------------------------------------------------------------------------
0303 class POPPLER_PRIVATE_EXPORT FileOutStream : public OutStream
0304 {
0305 public:
0306     FileOutStream(FILE *fa, Goffset startA);
0307 
0308     ~FileOutStream() override;
0309 
0310     void close() override;
0311 
0312     Goffset getPos() override;
0313 
0314     void put(char c) override;
0315 
0316     void printf(const char *format, ...) override GCC_PRINTF_FORMAT(2, 3);
0317 
0318 private:
0319     FILE *f;
0320     Goffset start;
0321 };
0322 
0323 //------------------------------------------------------------------------
0324 // BaseStream
0325 //
0326 // This is the base class for all streams that read directly from a file.
0327 //------------------------------------------------------------------------
0328 
0329 class POPPLER_PRIVATE_EXPORT BaseStream : public Stream
0330 {
0331 public:
0332     // TODO Mirar si puedo hacer que dictA sea un puntero
0333     BaseStream(Object &&dictA, Goffset lengthA);
0334     ~BaseStream() override;
0335     virtual BaseStream *copy() = 0;
0336     virtual Stream *makeSubStream(Goffset start, bool limited, Goffset length, Object &&dict) = 0;
0337     void setPos(Goffset pos, int dir = 0) override = 0;
0338     bool isBinary(bool last = true) const override { return last; }
0339     BaseStream *getBaseStream() override { return this; }
0340     Stream *getUndecodedStream() override { return this; }
0341     Dict *getDict() override { return dict.getDict(); }
0342     Object *getDictObject() override { return &dict; }
0343     virtual GooString *getFileName() { return nullptr; }
0344     virtual Goffset getLength() { return length; }
0345 
0346     // Get/set position of first byte of stream within the file.
0347     virtual Goffset getStart() = 0;
0348     virtual void moveStart(Goffset delta) = 0;
0349 
0350 protected:
0351     Goffset length;
0352     Object dict;
0353 };
0354 
0355 //------------------------------------------------------------------------
0356 // BaseInputStream
0357 //------------------------------------------------------------------------
0358 
0359 class POPPLER_PRIVATE_EXPORT BaseSeekInputStream : public BaseStream
0360 {
0361 public:
0362     // This enum is used to tell the seek() method how it must reposition
0363     // the stream offset.
0364     enum SeekType
0365     {
0366         SeekSet, // the offset is set to offset bytes
0367         SeekCur, // the offset is set to its current location plus offset bytes
0368         SeekEnd // the offset is set to the size of the stream plus offset bytes
0369     };
0370 
0371     BaseSeekInputStream(Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA);
0372     ~BaseSeekInputStream() override;
0373     StreamKind getKind() const override { return strWeird; }
0374     void reset() override;
0375     void close() override;
0376     int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
0377     int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
0378     Goffset getPos() override { return bufPos + (bufPtr - buf); }
0379     void setPos(Goffset pos, int dir = 0) override;
0380     Goffset getStart() override { return start; }
0381     void moveStart(Goffset delta) override;
0382 
0383     int getUnfilteredChar() override { return getChar(); }
0384     void unfilteredReset() override { reset(); }
0385 
0386 protected:
0387     Goffset start;
0388     bool limited;
0389 
0390 private:
0391     bool fillBuf();
0392 
0393     bool hasGetChars() override { return true; }
0394     int getChars(int nChars, unsigned char *buffer) override;
0395 
0396     virtual Goffset currentPos() const = 0;
0397     virtual void setCurrentPos(Goffset offset) = 0;
0398     virtual Goffset read(char *buf, Goffset size) = 0;
0399 
0400     static constexpr int seekInputStreamBufSize = 1024;
0401     char buf[seekInputStreamBufSize];
0402     char *bufPtr;
0403     char *bufEnd;
0404     Goffset bufPos;
0405     Goffset savePos;
0406     bool saved;
0407 };
0408 
0409 //------------------------------------------------------------------------
0410 // FilterStream
0411 //
0412 // This is the base class for all streams that filter another stream.
0413 //------------------------------------------------------------------------
0414 
0415 class FilterStream : public Stream
0416 {
0417 public:
0418     explicit FilterStream(Stream *strA);
0419     ~FilterStream() override;
0420     void close() override;
0421     Goffset getPos() override { return str->getPos(); }
0422     void setPos(Goffset pos, int dir = 0) override;
0423     BaseStream *getBaseStream() override { return str->getBaseStream(); }
0424     Stream *getUndecodedStream() override { return str->getUndecodedStream(); }
0425     Dict *getDict() override { return str->getDict(); }
0426     Object *getDictObject() override { return str->getDictObject(); }
0427     Stream *getNextStream() const override { return str; }
0428 
0429     int getUnfilteredChar() override { return str->getUnfilteredChar(); }
0430     void unfilteredReset() override { str->unfilteredReset(); }
0431 
0432 protected:
0433     Stream *str;
0434 };
0435 
0436 //------------------------------------------------------------------------
0437 // ImageStream
0438 //------------------------------------------------------------------------
0439 
0440 class POPPLER_PRIVATE_EXPORT ImageStream
0441 {
0442 public:
0443     // Create an image stream object for an image with the specified
0444     // parameters.  Note that these are the actual image parameters,
0445     // which may be different from the predictor parameters.
0446     ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA);
0447 
0448     ~ImageStream();
0449 
0450     ImageStream(const ImageStream &) = delete;
0451     ImageStream &operator=(const ImageStream &other) = delete;
0452 
0453     // Reset the stream.
0454     void reset();
0455 
0456     // Close the stream previously reset
0457     void close();
0458 
0459     // Gets the next pixel from the stream.  <pix> should be able to hold
0460     // at least nComps elements.  Returns false at end of file.
0461     bool getPixel(unsigned char *pix);
0462 
0463     // Returns a pointer to the next line of pixels.  Returns NULL at
0464     // end of file.
0465     unsigned char *getLine();
0466 
0467     // Skip an entire line from the image.
0468     void skipLine();
0469 
0470 private:
0471     Stream *str; // base stream
0472     int width; // pixels per line
0473     int nComps; // components per pixel
0474     int nBits; // bits per component
0475     int nVals; // components per line
0476     int inputLineSize; // input line buffer size
0477     unsigned char *inputLine; // input line buffer
0478     unsigned char *imgLine; // line buffer
0479     int imgIdx; // current index in imgLine
0480 };
0481 
0482 //------------------------------------------------------------------------
0483 // StreamPredictor
0484 //------------------------------------------------------------------------
0485 
0486 class StreamPredictor
0487 {
0488 public:
0489     // Create a predictor object.  Note that the parameters are for the
0490     // predictor, and may not match the actual image parameters.
0491     StreamPredictor(Stream *strA, int predictorA, int widthA, int nCompsA, int nBitsA);
0492 
0493     ~StreamPredictor();
0494 
0495     StreamPredictor(const StreamPredictor &) = delete;
0496     StreamPredictor &operator=(const StreamPredictor &) = delete;
0497 
0498     bool isOk() { return ok; }
0499 
0500     int lookChar();
0501     int getChar();
0502     int getChars(int nChars, unsigned char *buffer);
0503 
0504 private:
0505     bool getNextLine();
0506 
0507     Stream *str; // base stream
0508     int predictor; // predictor
0509     int width; // pixels per line
0510     int nComps; // components per pixel
0511     int nBits; // bits per component
0512     int nVals; // components per line
0513     int pixBytes; // bytes per pixel
0514     int rowBytes; // bytes per line
0515     unsigned char *predLine; // line buffer
0516     int predIdx; // current index in predLine
0517     bool ok;
0518 };
0519 
0520 //------------------------------------------------------------------------
0521 // FileStream
0522 //------------------------------------------------------------------------
0523 
0524 #define fileStreamBufSize 256
0525 
0526 class POPPLER_PRIVATE_EXPORT FileStream : public BaseStream
0527 {
0528 public:
0529     FileStream(GooFile *fileA, Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA);
0530     ~FileStream() override;
0531     BaseStream *copy() override;
0532     Stream *makeSubStream(Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA) override;
0533     StreamKind getKind() const override { return strFile; }
0534     void reset() override;
0535     void close() override;
0536     int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
0537     int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
0538     Goffset getPos() override { return bufPos + (bufPtr - buf); }
0539     void setPos(Goffset pos, int dir = 0) override;
0540     Goffset getStart() override { return start; }
0541     void moveStart(Goffset delta) override;
0542 
0543     int getUnfilteredChar() override { return getChar(); }
0544     void unfilteredReset() override { reset(); }
0545 
0546     bool getNeedsEncryptionOnSave() const { return needsEncryptionOnSave; }
0547     void setNeedsEncryptionOnSave(bool needsEncryptionOnSaveA) { needsEncryptionOnSave = needsEncryptionOnSaveA; }
0548 
0549 private:
0550     bool fillBuf();
0551 
0552     bool hasGetChars() override { return true; }
0553     int getChars(int nChars, unsigned char *buffer) override
0554     {
0555         int n, m;
0556 
0557         n = 0;
0558         while (n < nChars) {
0559             if (bufPtr >= bufEnd) {
0560                 if (!fillBuf()) {
0561                     break;
0562                 }
0563             }
0564             m = (int)(bufEnd - bufPtr);
0565             if (m > nChars - n) {
0566                 m = nChars - n;
0567             }
0568             memcpy(buffer + n, bufPtr, m);
0569             bufPtr += m;
0570             n += m;
0571         }
0572         return n;
0573     }
0574 
0575 private:
0576     GooFile *file;
0577     Goffset offset;
0578     Goffset start;
0579     bool limited;
0580     char buf[fileStreamBufSize];
0581     char *bufPtr;
0582     char *bufEnd;
0583     Goffset bufPos;
0584     Goffset savePos;
0585     bool saved;
0586     bool needsEncryptionOnSave; // Needed for FileStreams that point to "external" files
0587                                 // and thus when saving we can't do a raw copy
0588 };
0589 
0590 //------------------------------------------------------------------------
0591 // CachedFileStream
0592 //------------------------------------------------------------------------
0593 
0594 #define cachedStreamBufSize 1024
0595 
0596 class POPPLER_PRIVATE_EXPORT CachedFileStream : public BaseStream
0597 {
0598 public:
0599     CachedFileStream(CachedFile *ccA, Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA);
0600     ~CachedFileStream() override;
0601     BaseStream *copy() override;
0602     Stream *makeSubStream(Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA) override;
0603     StreamKind getKind() const override { return strCachedFile; }
0604     void reset() override;
0605     void close() override;
0606     int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
0607     int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
0608     Goffset getPos() override { return bufPos + (bufPtr - buf); }
0609     void setPos(Goffset pos, int dir = 0) override;
0610     Goffset getStart() override { return start; }
0611     void moveStart(Goffset delta) override;
0612 
0613     int getUnfilteredChar() override { return getChar(); }
0614     void unfilteredReset() override { reset(); }
0615 
0616 private:
0617     bool fillBuf();
0618 
0619     CachedFile *cc;
0620     Goffset start;
0621     bool limited;
0622     char buf[cachedStreamBufSize];
0623     char *bufPtr;
0624     char *bufEnd;
0625     unsigned int bufPos;
0626     int savePos;
0627     bool saved;
0628 };
0629 
0630 //------------------------------------------------------------------------
0631 // MemStream
0632 //------------------------------------------------------------------------
0633 
0634 template<typename T>
0635 class BaseMemStream : public BaseStream
0636 {
0637 public:
0638     BaseMemStream(T *bufA, Goffset startA, Goffset lengthA, Object &&dictA) : BaseStream(std::move(dictA), lengthA)
0639     {
0640         buf = bufA;
0641         start = startA;
0642         length = lengthA;
0643         bufEnd = buf + start + length;
0644         bufPtr = buf + start;
0645     }
0646 
0647     BaseStream *copy() override { return new BaseMemStream(buf, start, length, dict.copy()); }
0648 
0649     Stream *makeSubStream(Goffset startA, bool limited, Goffset lengthA, Object &&dictA) override
0650     {
0651         Goffset newLength;
0652 
0653         if (!limited || startA + lengthA > start + length) {
0654             newLength = start + length - startA;
0655         } else {
0656             newLength = lengthA;
0657         }
0658         return new BaseMemStream(buf, startA, newLength, std::move(dictA));
0659     }
0660 
0661     StreamKind getKind() const override { return strWeird; }
0662 
0663     void reset() override { bufPtr = buf + start; }
0664 
0665     void close() override { }
0666 
0667     int getChar() override { return (bufPtr < bufEnd) ? (*bufPtr++ & 0xff) : EOF; }
0668 
0669     int lookChar() override { return (bufPtr < bufEnd) ? (*bufPtr & 0xff) : EOF; }
0670 
0671     Goffset getPos() override { return (int)(bufPtr - buf); }
0672 
0673     void setPos(Goffset pos, int dir = 0) override
0674     {
0675         Goffset i;
0676 
0677         if (dir >= 0) {
0678             i = pos;
0679         } else {
0680             i = start + length - pos;
0681         }
0682         if (i < start) {
0683             i = start;
0684         } else if (i > start + length) {
0685             i = start + length;
0686         }
0687         bufPtr = buf + i;
0688     }
0689 
0690     Goffset getStart() override { return start; }
0691 
0692     void moveStart(Goffset delta) override
0693     {
0694         start += delta;
0695         length -= delta;
0696         bufPtr = buf + start;
0697     }
0698 
0699     int getUnfilteredChar() override { return getChar(); }
0700 
0701     void unfilteredReset() override { reset(); }
0702 
0703 protected:
0704     T *buf;
0705 
0706 private:
0707     bool hasGetChars() override { return true; }
0708 
0709     int getChars(int nChars, unsigned char *buffer) override
0710     {
0711         int n;
0712 
0713         if (unlikely(nChars <= 0)) {
0714             return 0;
0715         }
0716         if (unlikely(bufPtr >= bufEnd)) {
0717             return 0;
0718         }
0719         if (bufEnd - bufPtr < nChars) {
0720             n = (int)(bufEnd - bufPtr);
0721         } else {
0722             n = nChars;
0723         }
0724         memcpy(buffer, bufPtr, n);
0725         bufPtr += n;
0726         return n;
0727     }
0728 
0729     Goffset start;
0730     T *bufEnd;
0731     T *bufPtr;
0732 };
0733 
0734 class POPPLER_PRIVATE_EXPORT MemStream : public BaseMemStream<const char>
0735 {
0736 public:
0737     MemStream(const char *bufA, Goffset startA, Goffset lengthA, Object &&dictA) : BaseMemStream(bufA, startA, lengthA, std::move(dictA)) { }
0738     ~MemStream() override;
0739 };
0740 
0741 class AutoFreeMemStream : public BaseMemStream<char>
0742 {
0743     bool filterRemovalForbidden = false;
0744 
0745 public:
0746     // AutoFreeMemStream takes ownership over the buffer.
0747     // The buffer should be created using gmalloc().
0748     AutoFreeMemStream(char *bufA, Goffset startA, Goffset lengthA, Object &&dictA) : BaseMemStream(bufA, startA, lengthA, std::move(dictA)) { }
0749     ~AutoFreeMemStream() override;
0750 
0751     // A hack to deal with the strange behaviour of PDFDoc::writeObject().
0752     bool isFilterRemovalForbidden() const;
0753     void setFilterRemovalForbidden(bool forbidden);
0754 };
0755 
0756 //------------------------------------------------------------------------
0757 // EmbedStream
0758 //
0759 // This is a special stream type used for embedded streams (inline
0760 // images).  It reads directly from the base stream -- after the
0761 // EmbedStream is deleted, reads from the base stream will proceed where
0762 // the BaseStream left off.  Note that this is very different behavior
0763 // that creating a new FileStream (using makeSubStream).
0764 //------------------------------------------------------------------------
0765 
0766 class POPPLER_PRIVATE_EXPORT EmbedStream : public BaseStream
0767 {
0768 public:
0769     EmbedStream(Stream *strA, Object &&dictA, bool limitedA, Goffset lengthA, bool reusableA = false);
0770     ~EmbedStream() override;
0771     BaseStream *copy() override;
0772     Stream *makeSubStream(Goffset start, bool limitedA, Goffset lengthA, Object &&dictA) override;
0773     StreamKind getKind() const override { return str->getKind(); }
0774     void reset() override;
0775     int getChar() override;
0776     int lookChar() override;
0777     Goffset getPos() override;
0778     void setPos(Goffset pos, int dir = 0) override;
0779     Goffset getStart() override;
0780     void moveStart(Goffset delta) override;
0781 
0782     int getUnfilteredChar() override { return str->getUnfilteredChar(); }
0783     void unfilteredReset() override { str->unfilteredReset(); }
0784 
0785     void rewind();
0786     void restore();
0787 
0788 private:
0789     bool hasGetChars() override { return true; }
0790     int getChars(int nChars, unsigned char *buffer) override;
0791 
0792     Stream *str;
0793     bool limited;
0794     bool reusable;
0795     bool record;
0796     bool replay;
0797     unsigned char *bufData;
0798     long bufMax;
0799     long bufLen;
0800     long bufPos;
0801     Goffset start;
0802 };
0803 
0804 //------------------------------------------------------------------------
0805 // ASCIIHexStream
0806 //------------------------------------------------------------------------
0807 
0808 class ASCIIHexStream : public FilterStream
0809 {
0810 public:
0811     explicit ASCIIHexStream(Stream *strA);
0812     ~ASCIIHexStream() override;
0813     StreamKind getKind() const override { return strASCIIHex; }
0814     void reset() override;
0815     int getChar() override
0816     {
0817         int c = lookChar();
0818         buf = EOF;
0819         return c;
0820     }
0821     int lookChar() override;
0822     GooString *getPSFilter(int psLevel, const char *indent) override;
0823     bool isBinary(bool last = true) const override;
0824 
0825 private:
0826     int buf;
0827     bool eof;
0828 };
0829 
0830 //------------------------------------------------------------------------
0831 // ASCII85Stream
0832 //------------------------------------------------------------------------
0833 
0834 class ASCII85Stream : public FilterStream
0835 {
0836 public:
0837     explicit ASCII85Stream(Stream *strA);
0838     ~ASCII85Stream() override;
0839     StreamKind getKind() const override { return strASCII85; }
0840     void reset() override;
0841     int getChar() override
0842     {
0843         int ch = lookChar();
0844         ++index;
0845         return ch;
0846     }
0847     int lookChar() override;
0848     GooString *getPSFilter(int psLevel, const char *indent) override;
0849     bool isBinary(bool last = true) const override;
0850 
0851 private:
0852     int c[5];
0853     int b[4];
0854     int index, n;
0855     bool eof;
0856 };
0857 
0858 //------------------------------------------------------------------------
0859 // LZWStream
0860 //------------------------------------------------------------------------
0861 
0862 class LZWStream : public FilterStream
0863 {
0864 public:
0865     LZWStream(Stream *strA, int predictor, int columns, int colors, int bits, int earlyA);
0866     ~LZWStream() override;
0867     StreamKind getKind() const override { return strLZW; }
0868     void reset() override;
0869     int getChar() override;
0870     int lookChar() override;
0871     int getRawChar() override;
0872     void getRawChars(int nChars, int *buffer) override;
0873     GooString *getPSFilter(int psLevel, const char *indent) override;
0874     bool isBinary(bool last = true) const override;
0875 
0876 private:
0877     bool hasGetChars() override { return true; }
0878     int getChars(int nChars, unsigned char *buffer) override;
0879 
0880     inline int doGetRawChar()
0881     {
0882         if (eof) {
0883             return EOF;
0884         }
0885         if (seqIndex >= seqLength) {
0886             if (!processNextCode()) {
0887                 return EOF;
0888             }
0889         }
0890         return seqBuf[seqIndex++];
0891     }
0892 
0893     StreamPredictor *pred; // predictor
0894     int early; // early parameter
0895     bool eof; // true if at eof
0896     unsigned int inputBuf; // input buffer
0897     int inputBits; // number of bits in input buffer
0898     struct
0899     { // decoding table
0900         int length;
0901         int head;
0902         unsigned char tail;
0903     } table[4097];
0904     int nextCode; // next code to be used
0905     int nextBits; // number of bits in next code word
0906     int prevCode; // previous code used in stream
0907     int newChar; // next char to be added to table
0908     unsigned char seqBuf[4097]; // buffer for current sequence
0909     int seqLength; // length of current sequence
0910     int seqIndex; // index into current sequence
0911     bool first; // first code after a table clear
0912 
0913     bool processNextCode();
0914     void clearTable();
0915     int getCode();
0916 };
0917 
0918 //------------------------------------------------------------------------
0919 // RunLengthStream
0920 //------------------------------------------------------------------------
0921 
0922 class RunLengthStream : public FilterStream
0923 {
0924 public:
0925     explicit RunLengthStream(Stream *strA);
0926     ~RunLengthStream() override;
0927     StreamKind getKind() const override { return strRunLength; }
0928     void reset() override;
0929     int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
0930     int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
0931     GooString *getPSFilter(int psLevel, const char *indent) override;
0932     bool isBinary(bool last = true) const override;
0933 
0934 private:
0935     bool hasGetChars() override { return true; }
0936     int getChars(int nChars, unsigned char *buffer) override;
0937 
0938     char buf[128]; // buffer
0939     char *bufPtr; // next char to read
0940     char *bufEnd; // end of buffer
0941     bool eof;
0942 
0943     bool fillBuf();
0944 };
0945 
0946 //------------------------------------------------------------------------
0947 // CCITTFaxStream
0948 //------------------------------------------------------------------------
0949 
0950 struct CCITTCodeTable;
0951 
0952 class CCITTFaxStream : public FilterStream
0953 {
0954 public:
0955     CCITTFaxStream(Stream *strA, int encodingA, bool endOfLineA, bool byteAlignA, int columnsA, int rowsA, bool endOfBlockA, bool blackA, int damagedRowsBeforeErrorA);
0956     ~CCITTFaxStream() override;
0957     StreamKind getKind() const override { return strCCITTFax; }
0958     void reset() override;
0959     int getChar() override
0960     {
0961         int c = lookChar();
0962         buf = EOF;
0963         return c;
0964     }
0965     int lookChar() override;
0966     GooString *getPSFilter(int psLevel, const char *indent) override;
0967     bool isBinary(bool last = true) const override;
0968 
0969     void unfilteredReset() override;
0970 
0971     int getEncoding() { return encoding; }
0972     bool getEndOfLine() { return endOfLine; }
0973     bool getEncodedByteAlign() { return byteAlign; }
0974     bool getEndOfBlock() { return endOfBlock; }
0975     int getColumns() { return columns; }
0976     bool getBlackIs1() { return black; }
0977     int getDamagedRowsBeforeError() { return damagedRowsBeforeError; }
0978 
0979 private:
0980     void ccittReset(bool unfiltered);
0981     int encoding; // 'K' parameter
0982     bool endOfLine; // 'EndOfLine' parameter
0983     bool byteAlign; // 'EncodedByteAlign' parameter
0984     int columns; // 'Columns' parameter
0985     int rows; // 'Rows' parameter
0986     bool endOfBlock; // 'EndOfBlock' parameter
0987     bool black; // 'BlackIs1' parameter
0988     int damagedRowsBeforeError; // 'DamagedRowsBeforeError' parameter
0989     bool eof; // true if at eof
0990     bool nextLine2D; // true if next line uses 2D encoding
0991     int row; // current row
0992     unsigned int inputBuf; // input buffer
0993     int inputBits; // number of bits in input buffer
0994     int *codingLine; // coding line changing elements
0995     int *refLine; // reference line changing elements
0996     int a0i; // index into codingLine
0997     bool err; // error on current line
0998     int outputBits; // remaining ouput bits
0999     int buf; // character buffer
1000 
1001     void addPixels(int a1, int blackPixels);
1002     void addPixelsNeg(int a1, int blackPixels);
1003     short getTwoDimCode();
1004     short getWhiteCode();
1005     short getBlackCode();
1006     short lookBits(int n);
1007     void eatBits(int n)
1008     {
1009         if ((inputBits -= n) < 0) {
1010             inputBits = 0;
1011         }
1012     }
1013 };
1014 
1015 #ifndef ENABLE_LIBJPEG
1016 //------------------------------------------------------------------------
1017 // DCTStream
1018 //------------------------------------------------------------------------
1019 
1020 // DCT component info
1021 struct DCTCompInfo
1022 {
1023     int id; // component ID
1024     int hSample, vSample; // horiz/vert sampling resolutions
1025     int quantTable; // quantization table number
1026     int prevDC; // DC coefficient accumulator
1027 };
1028 
1029 struct DCTScanInfo
1030 {
1031     bool comp[4]; // comp[i] is set if component i is
1032                   //   included in this scan
1033     int numComps; // number of components in the scan
1034     int dcHuffTable[4]; // DC Huffman table numbers
1035     int acHuffTable[4]; // AC Huffman table numbers
1036     int firstCoeff, lastCoeff; // first and last DCT coefficient
1037     int ah, al; // successive approximation parameters
1038 };
1039 
1040 // DCT Huffman decoding table
1041 struct DCTHuffTable
1042 {
1043     unsigned char firstSym[17]; // first symbol for this bit length
1044     unsigned short firstCode[17]; // first code for this bit length
1045     unsigned short numCodes[17]; // number of codes of this bit length
1046     unsigned char sym[256]; // symbols
1047 };
1048 
1049 class DCTStream : public FilterStream
1050 {
1051 public:
1052     DCTStream(Stream *strA, int colorXformA, Dict *dict, int recursion);
1053     ~DCTStream() override;
1054     StreamKind getKind() const override { return strDCT; }
1055     void reset() override;
1056     void close() override;
1057     int getChar() override;
1058     int lookChar() override;
1059     GooString *getPSFilter(int psLevel, const char *indent) override;
1060     bool isBinary(bool last = true) const override;
1061 
1062     void unfilteredReset() override;
1063 
1064 private:
1065     void dctReset(bool unfiltered);
1066     bool progressive; // set if in progressive mode
1067     bool interleaved; // set if in interleaved mode
1068     int width, height; // image size
1069     int mcuWidth, mcuHeight; // size of min coding unit, in data units
1070     int bufWidth, bufHeight; // frameBuf size
1071     DCTCompInfo compInfo[4]; // info for each component
1072     DCTScanInfo scanInfo; // info for the current scan
1073     int numComps; // number of components in image
1074     int colorXform; // color transform: -1 = unspecified
1075                     //                   0 = none
1076                     //                   1 = YUV/YUVK -> RGB/CMYK
1077     bool gotJFIFMarker; // set if APP0 JFIF marker was present
1078     bool gotAdobeMarker; // set if APP14 Adobe marker was present
1079     int restartInterval; // restart interval, in MCUs
1080     unsigned short quantTables[4][64]; // quantization tables
1081     int numQuantTables; // number of quantization tables
1082     DCTHuffTable dcHuffTables[4]; // DC Huffman tables
1083     DCTHuffTable acHuffTables[4]; // AC Huffman tables
1084     int numDCHuffTables; // number of DC Huffman tables
1085     int numACHuffTables; // number of AC Huffman tables
1086     unsigned char *rowBuf[4][32]; // buffer for one MCU (non-progressive mode)
1087     int *frameBuf[4]; // buffer for frame (progressive mode)
1088     int comp, x, y, dy; // current position within image/MCU
1089     int restartCtr; // MCUs left until restart
1090     int restartMarker; // next restart marker
1091     int eobRun; // number of EOBs left in the current run
1092     int inputBuf; // input buffer for variable length codes
1093     int inputBits; // number of valid bits in input buffer
1094 
1095     void restart();
1096     bool readMCURow();
1097     void readScan();
1098     bool readDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable, int *prevDC, int data[64]);
1099     bool readProgressiveDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable, int *prevDC, int data[64]);
1100     void decodeImage();
1101     void transformDataUnit(unsigned short *quantTable, int dataIn[64], unsigned char dataOut[64]);
1102     int readHuffSym(DCTHuffTable *table);
1103     int readAmp(int size);
1104     int readBit();
1105     bool readHeader();
1106     bool readBaselineSOF();
1107     bool readProgressiveSOF();
1108     bool readScanInfo();
1109     bool readQuantTables();
1110     bool readHuffmanTables();
1111     bool readRestartInterval();
1112     bool readJFIFMarker();
1113     bool readAdobeMarker();
1114     bool readTrailer();
1115     int readMarker();
1116     int read16();
1117 };
1118 
1119 #endif
1120 
1121 #ifndef ENABLE_ZLIB_UNCOMPRESS
1122 //------------------------------------------------------------------------
1123 // FlateStream
1124 //------------------------------------------------------------------------
1125 
1126 #    define flateWindow 32768 // buffer size
1127 #    define flateMask (flateWindow - 1)
1128 #    define flateMaxHuffman 15 // max Huffman code length
1129 #    define flateMaxCodeLenCodes 19 // max # code length codes
1130 #    define flateMaxLitCodes 288 // max # literal codes
1131 #    define flateMaxDistCodes 30 // max # distance codes
1132 
1133 // Huffman code table entry
1134 struct FlateCode
1135 {
1136     unsigned short len; // code length, in bits
1137     unsigned short val; // value represented by this code
1138 };
1139 
1140 struct FlateHuffmanTab
1141 {
1142     const FlateCode *codes;
1143     int maxLen;
1144 };
1145 
1146 // Decoding info for length and distance code words
1147 struct FlateDecode
1148 {
1149     int bits; // # extra bits
1150     int first; // first length/distance
1151 };
1152 
1153 class FlateStream : public FilterStream
1154 {
1155 public:
1156     FlateStream(Stream *strA, int predictor, int columns, int colors, int bits);
1157     ~FlateStream() override;
1158     StreamKind getKind() const override { return strFlate; }
1159     void reset() override;
1160     int getChar() override;
1161     int lookChar() override;
1162     int getRawChar() override;
1163     void getRawChars(int nChars, int *buffer) override;
1164     GooString *getPSFilter(int psLevel, const char *indent) override;
1165     bool isBinary(bool last = true) const override;
1166     void unfilteredReset() override;
1167 
1168 private:
1169     void flateReset(bool unfiltered);
1170     inline int doGetRawChar()
1171     {
1172         int c;
1173 
1174         while (remain == 0) {
1175             if (endOfBlock && eof) {
1176                 return EOF;
1177             }
1178             readSome();
1179         }
1180         c = buf[index];
1181         index = (index + 1) & flateMask;
1182         --remain;
1183         return c;
1184     }
1185 
1186     bool hasGetChars() override { return true; }
1187     int getChars(int nChars, unsigned char *buffer) override;
1188 
1189     StreamPredictor *pred; // predictor
1190     unsigned char buf[flateWindow]; // output data buffer
1191     int index; // current index into output buffer
1192     int remain; // number valid bytes in output buffer
1193     int codeBuf; // input buffer
1194     int codeSize; // number of bits in input buffer
1195     int // literal and distance code lengths
1196             codeLengths[flateMaxLitCodes + flateMaxDistCodes];
1197     FlateHuffmanTab litCodeTab; // literal code table
1198     FlateHuffmanTab distCodeTab; // distance code table
1199     bool compressedBlock; // set if reading a compressed block
1200     int blockLen; // remaining length of uncompressed block
1201     bool endOfBlock; // set when end of block is reached
1202     bool eof; // set when end of stream is reached
1203 
1204     static const int // code length code reordering
1205             codeLenCodeMap[flateMaxCodeLenCodes];
1206     static const FlateDecode // length decoding info
1207             lengthDecode[flateMaxLitCodes - 257];
1208     static const FlateDecode // distance decoding info
1209             distDecode[flateMaxDistCodes];
1210     static FlateHuffmanTab // fixed literal code table
1211             fixedLitCodeTab;
1212     static FlateHuffmanTab // fixed distance code table
1213             fixedDistCodeTab;
1214 
1215     void readSome();
1216     bool startBlock();
1217     void loadFixedCodes();
1218     bool readDynamicCodes();
1219     FlateCode *compHuffmanCodes(const int *lengths, int n, int *maxLen);
1220     int getHuffmanCodeWord(FlateHuffmanTab *tab);
1221     int getCodeWord(int bits);
1222 };
1223 #endif
1224 
1225 //------------------------------------------------------------------------
1226 // EOFStream
1227 //------------------------------------------------------------------------
1228 
1229 class EOFStream : public FilterStream
1230 {
1231 public:
1232     explicit EOFStream(Stream *strA);
1233     ~EOFStream() override;
1234     StreamKind getKind() const override { return strWeird; }
1235     void reset() override { }
1236     int getChar() override { return EOF; }
1237     int lookChar() override { return EOF; }
1238     GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
1239     bool isBinary(bool /*last = true*/) const override { return false; }
1240 };
1241 
1242 //------------------------------------------------------------------------
1243 // BufStream
1244 //------------------------------------------------------------------------
1245 
1246 class BufStream : public FilterStream
1247 {
1248 public:
1249     BufStream(Stream *strA, int bufSizeA);
1250     ~BufStream() override;
1251     StreamKind getKind() const override { return strWeird; }
1252     void reset() override;
1253     int getChar() override;
1254     int lookChar() override;
1255     GooString *getPSFilter(int psLevel, const char *indent) override { return nullptr; }
1256     bool isBinary(bool last = true) const override;
1257 
1258     int lookChar(int idx);
1259 
1260 private:
1261     int *buf;
1262     int bufSize;
1263 };
1264 
1265 //------------------------------------------------------------------------
1266 // FixedLengthEncoder
1267 //------------------------------------------------------------------------
1268 
1269 class FixedLengthEncoder : public FilterStream
1270 {
1271 public:
1272     FixedLengthEncoder(Stream *strA, int lengthA);
1273     ~FixedLengthEncoder() override;
1274     StreamKind getKind() const override { return strWeird; }
1275     void reset() override;
1276     int getChar() override;
1277     int lookChar() override;
1278     GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
1279     bool isBinary(bool /*last = true*/) const override;
1280     bool isEncoder() const override { return true; }
1281 
1282 private:
1283     int length;
1284     int count;
1285 };
1286 
1287 //------------------------------------------------------------------------
1288 // ASCIIHexEncoder
1289 //------------------------------------------------------------------------
1290 
1291 class ASCIIHexEncoder : public FilterStream
1292 {
1293 public:
1294     explicit ASCIIHexEncoder(Stream *strA);
1295     ~ASCIIHexEncoder() override;
1296     StreamKind getKind() const override { return strWeird; }
1297     void reset() override;
1298     int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
1299     int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
1300     GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
1301     bool isBinary(bool /*last = true*/) const override { return false; }
1302     bool isEncoder() const override { return true; }
1303 
1304 private:
1305     char buf[4];
1306     char *bufPtr;
1307     char *bufEnd;
1308     int lineLen;
1309     bool eof;
1310 
1311     bool fillBuf();
1312 };
1313 
1314 //------------------------------------------------------------------------
1315 // ASCII85Encoder
1316 //------------------------------------------------------------------------
1317 
1318 class ASCII85Encoder : public FilterStream
1319 {
1320 public:
1321     explicit ASCII85Encoder(Stream *strA);
1322     ~ASCII85Encoder() override;
1323     StreamKind getKind() const override { return strWeird; }
1324     void reset() override;
1325     int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
1326     int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
1327     GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
1328     bool isBinary(bool /*last = true*/) const override { return false; }
1329     bool isEncoder() const override { return true; }
1330 
1331 private:
1332     char buf[8];
1333     char *bufPtr;
1334     char *bufEnd;
1335     int lineLen;
1336     bool eof;
1337 
1338     bool fillBuf();
1339 };
1340 
1341 //------------------------------------------------------------------------
1342 // RunLengthEncoder
1343 //------------------------------------------------------------------------
1344 
1345 class RunLengthEncoder : public FilterStream
1346 {
1347 public:
1348     explicit RunLengthEncoder(Stream *strA);
1349     ~RunLengthEncoder() override;
1350     StreamKind getKind() const override { return strWeird; }
1351     void reset() override;
1352     int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
1353     int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
1354     GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
1355     bool isBinary(bool /*last = true*/) const override { return true; }
1356     bool isEncoder() const override { return true; }
1357 
1358 private:
1359     char buf[131];
1360     char *bufPtr;
1361     char *bufEnd;
1362     char *nextEnd;
1363     bool eof;
1364 
1365     bool fillBuf();
1366 };
1367 
1368 //------------------------------------------------------------------------
1369 // LZWEncoder
1370 //------------------------------------------------------------------------
1371 
1372 struct LZWEncoderNode
1373 {
1374     int byte;
1375     LZWEncoderNode *next; // next sibling
1376     LZWEncoderNode *children; // first child
1377 };
1378 
1379 class LZWEncoder : public FilterStream
1380 {
1381 public:
1382     explicit LZWEncoder(Stream *strA);
1383     ~LZWEncoder() override;
1384     StreamKind getKind() const override { return strWeird; }
1385     void reset() override;
1386     int getChar() override;
1387     int lookChar() override;
1388     GooString *getPSFilter(int psLevel, const char *indent) override { return nullptr; }
1389     bool isBinary(bool last = true) const override { return true; }
1390     bool isEncoder() const override { return true; }
1391 
1392 private:
1393     LZWEncoderNode table[4096];
1394     int nextSeq;
1395     int codeLen;
1396     unsigned char inBuf[4096];
1397     int inBufLen;
1398     int outBuf;
1399     int outBufLen;
1400     bool needEOD;
1401 
1402     void fillBuf();
1403 };
1404 
1405 //------------------------------------------------------------------------
1406 // CMYKGrayEncoder
1407 //------------------------------------------------------------------------
1408 
1409 class CMYKGrayEncoder : public FilterStream
1410 {
1411 public:
1412     explicit CMYKGrayEncoder(Stream *strA);
1413     ~CMYKGrayEncoder() override;
1414     StreamKind getKind() const override { return strWeird; }
1415     void reset() override;
1416     int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
1417     int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
1418     GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
1419     bool isBinary(bool /*last = true*/) const override { return false; }
1420     bool isEncoder() const override { return true; }
1421 
1422 private:
1423     char buf[2];
1424     char *bufPtr;
1425     char *bufEnd;
1426     bool eof;
1427 
1428     bool fillBuf();
1429 };
1430 
1431 //------------------------------------------------------------------------
1432 // RGBGrayEncoder
1433 //------------------------------------------------------------------------
1434 
1435 class RGBGrayEncoder : public FilterStream
1436 {
1437 public:
1438     explicit RGBGrayEncoder(Stream *strA);
1439     ~RGBGrayEncoder() override;
1440     StreamKind getKind() const override { return strWeird; }
1441     void reset() override;
1442     int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
1443     int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
1444     GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
1445     bool isBinary(bool /*last = true*/) const override { return false; }
1446     bool isEncoder() const override { return true; }
1447 
1448 private:
1449     char buf[2];
1450     char *bufPtr;
1451     char *bufEnd;
1452     bool eof;
1453 
1454     bool fillBuf();
1455 };
1456 
1457 //------------------------------------------------------------------------
1458 // SplashBitmapCMYKEncoder
1459 //
1460 // This stream helps to condense SplashBitmaps (mostly of DeviceN8 type) into
1461 // pure CMYK colors. In particular for a DeviceN8 bitmap it redacts the spot colorants.
1462 //------------------------------------------------------------------------
1463 
1464 class SplashBitmapCMYKEncoder : public Stream
1465 {
1466 public:
1467     explicit SplashBitmapCMYKEncoder(SplashBitmap *bitmapA);
1468     ~SplashBitmapCMYKEncoder() override;
1469     StreamKind getKind() const override { return strWeird; }
1470     void reset() override;
1471     int getChar() override;
1472     int lookChar() override;
1473     GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
1474     bool isBinary(bool /*last = true*/) const override { return true; }
1475 
1476     // Although we are an encoder, we return false here, since we do not want do be auto-deleted by
1477     // successive streams.
1478     bool isEncoder() const override { return false; }
1479 
1480     int getUnfilteredChar() override { return getChar(); }
1481     void unfilteredReset() override { reset(); }
1482 
1483     BaseStream *getBaseStream() override { return nullptr; }
1484     Stream *getUndecodedStream() override { return this; }
1485 
1486     Dict *getDict() override { return nullptr; }
1487     Object *getDictObject() override { return nullptr; }
1488 
1489     Goffset getPos() override;
1490     void setPos(Goffset pos, int dir = 0) override;
1491 
1492 private:
1493     SplashBitmap *bitmap;
1494     size_t width;
1495     int height;
1496 
1497     std::vector<unsigned char> buf;
1498     size_t bufPtr;
1499     int curLine;
1500 
1501     bool fillBuf();
1502 };
1503 
1504 #endif