1//========================================================================
2//
3// Stream.h
4//
5// Copyright 1996-2003 Glyph & Cog, LLC
6//
7//========================================================================
8
9//========================================================================
10//
11// Modified under the Poppler project - http://poppler.freedesktop.org
12//
13// All changes made under the Poppler project to this file are licensed
14// under GPL version 2 or later
15//
16// Copyright (C) 2005 Jeff Muizelaar <jeff@infidigm.net>
17// Copyright (C) 2008 Julien Rebetez <julien@fhtagn.net>
18// Copyright (C) 2008, 2010, 2011, 2016-2022 Albert Astals Cid <aacid@kde.org>
19// Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
20// Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
21// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
22// Copyright (C) 2011, 2012, 2016, 2020 William Bader <williambader@hotmail.com>
23// Copyright (C) 2012, 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
24// Copyright (C) 2012, 2013 Fabio D'Urso <fabiodurso@hotmail.it>
25// Copyright (C) 2013, 2017 Adrian Johnson <ajohnson@redneon.com>
26// Copyright (C) 2013 Peter Breitenlohner <peb@mppmu.mpg.de>
27// Copyright (C) 2013, 2018 Adam Reichold <adamreichold@myopera.com>
28// Copyright (C) 2013 Pino Toscano <pino@kde.org>
29// Copyright (C) 2019 Volker Krause <vkrause@kde.org>
30// Copyright (C) 2019 Alexander Volkov <a.volkov@rusbitech.ru>
31// Copyright (C) 2020-2022 Oliver Sander <oliver.sander@tu-dresden.de>
32// Copyright (C) 2020 Philipp Knechtges <philipp-dev@knechtges.com>
33// Copyright (C) 2021 Hubert Figuiere <hub@figuiere.net>
34// Copyright (C) 2021 Christian Persch <chpe@src.gnome.org>
35// Copyright (C) 2021 Georgiy Sgibnev <georgiy@sgibnev.com>. Work sponsored by lab50.net.
36//
37// To see a description of the changes please see the Changelog file that
38// came with your tarball or type make ChangeLog if you are building from git
39//
40//========================================================================
41
42#ifndef STREAM_H
43#define STREAM_H
44
45#include <atomic>
46#include <cstdio>
47#include <vector>
48
49#include "poppler-config.h"
50#include "poppler_private_export.h"
51#include "Object.h"
52
53class GooFile;
54class BaseStream;
55class CachedFile;
56class SplashBitmap;
57
58//------------------------------------------------------------------------
59
60enum StreamKind
61{
62 strFile,
63 strCachedFile,
64 strASCIIHex,
65 strASCII85,
66 strLZW,
67 strRunLength,
68 strCCITTFax,
69 strDCT,
70 strFlate,
71 strJBIG2,
72 strJPX,
73 strWeird, // internal-use stream types
74 strCrypt // internal-use to detect decode streams
75};
76
77enum StreamColorSpaceMode
78{
79 streamCSNone,
80 streamCSDeviceGray,
81 streamCSDeviceRGB,
82 streamCSDeviceCMYK
83};
84
85//------------------------------------------------------------------------
86
87// This is in Stream.h instead of Decrypt.h to avoid really annoying
88// include file dependency loops.
89enum CryptAlgorithm
90{
91 cryptRC4,
92 cryptAES,
93 cryptAES256,
94 cryptNone
95};
96
97//------------------------------------------------------------------------
98
99typedef struct _ByteRange
100{
101 size_t offset;
102 unsigned int length;
103} ByteRange;
104
105//------------------------------------------------------------------------
106// Stream (base class)
107//------------------------------------------------------------------------
108
109class POPPLER_PRIVATE_EXPORT Stream
110{
111public:
112 // Constructor.
113 Stream();
114
115 // Destructor.
116 virtual ~Stream();
117
118 Stream(const Stream &) = delete;
119 Stream &operator=(const Stream &other) = delete;
120
121 // Get kind of stream.
122 virtual StreamKind getKind() const = 0;
123
124 // Reset stream to beginning.
125 virtual void reset() = 0;
126
127 // Close down the stream.
128 virtual void close();
129
130 inline int doGetChars(int nChars, unsigned char *buffer)
131 {
132 if (hasGetChars()) {
133 return getChars(nChars, buffer);
134 } else {
135 for (int i = 0; i < nChars; ++i) {
136 const int c = getChar();
137 if (likely(c != EOF)) {
138 buffer[i] = c;
139 } else {
140 return i;
141 }
142 }
143 return nChars;
144 }
145 }
146
147 inline void fillString(std::string &s)
148 {
149 unsigned char readBuf[4096];
150 int readChars;
151 reset();
152 while ((readChars = doGetChars(nChars: 4096, buffer: readBuf)) != 0) {
153 s.append(s: (const char *)readBuf, n: readChars);
154 }
155 }
156
157 inline void fillGooString(GooString *s) { fillString(s&: s->toNonConstStr()); }
158
159 inline std::vector<unsigned char> toUnsignedChars(int initialSize = 4096, int sizeIncrement = 4096)
160 {
161 std::vector<unsigned char> buf(initialSize);
162
163 int readChars;
164 int size = initialSize;
165 int length = 0;
166 int charsToRead = initialSize;
167 bool continueReading = true;
168 reset();
169 while (continueReading && (readChars = doGetChars(nChars: charsToRead, buffer: buf.data() + length)) != 0) {
170 length += readChars;
171 if (readChars == charsToRead) {
172 if (lookChar() != EOF) {
173 size += sizeIncrement;
174 charsToRead = sizeIncrement;
175 buf.resize(new_size: size);
176 } else {
177 continueReading = false;
178 }
179 } else {
180 continueReading = false;
181 }
182 }
183
184 buf.resize(new_size: length);
185 return buf;
186 }
187
188 // Get next char from stream.
189 virtual int getChar() = 0;
190
191 // Peek at next char in stream.
192 virtual int lookChar() = 0;
193
194 // Get next char from stream without using the predictor.
195 // This is only used by StreamPredictor.
196 virtual int getRawChar();
197 virtual void getRawChars(int nChars, int *buffer);
198
199 // Get next char directly from stream source, without filtering it
200 virtual int getUnfilteredChar() = 0;
201
202 // Resets the stream without reading anything (even not the headers)
203 // WARNING: Reading the stream with something else than getUnfilteredChar
204 // may lead to unexcepted behaviour until you call reset ()
205 virtual void unfilteredReset() = 0;
206
207 // Get next line from stream.
208 virtual char *getLine(char *buf, int size);
209
210 // Discard the next <n> bytes from stream. Returns the number of
211 // bytes discarded, which will be less than <n> only if EOF is
212 // reached.
213 virtual unsigned int discardChars(unsigned int n);
214
215 // Get current position in file.
216 virtual Goffset getPos() = 0;
217
218 // Go to a position in the stream. If <dir> is negative, the
219 // position is from the end of the file; otherwise the position is
220 // from the start of the file.
221 virtual void setPos(Goffset pos, int dir = 0) = 0;
222
223 // Get PostScript command for the filter(s).
224 virtual GooString *getPSFilter(int psLevel, const char *indent);
225
226 // Does this stream type potentially contain non-printable chars?
227 virtual bool isBinary(bool last = true) const = 0;
228
229 // Get the BaseStream of this stream.
230 virtual BaseStream *getBaseStream() = 0;
231
232 // Get the stream after the last decoder (this may be a BaseStream
233 // or a DecryptStream).
234 virtual Stream *getUndecodedStream() = 0;
235
236 // Get the dictionary associated with this stream.
237 virtual Dict *getDict() = 0;
238 virtual Object *getDictObject() = 0;
239
240 // Is this an encoding filter?
241 virtual bool isEncoder() const { return false; }
242
243 // Get image parameters which are defined by the stream contents.
244 virtual void getImageParams(int * /*bitsPerComponent*/, StreamColorSpaceMode * /*csMode*/) { }
245
246 // Return the next stream in the "stack".
247 virtual Stream *getNextStream() const { return nullptr; }
248
249 // Add filters to this stream according to the parameters in <dict>.
250 // Returns the new stream.
251 Stream *addFilters(Dict *dict, int recursion = 0);
252
253 // Returns true if this stream includes a crypt filter.
254 bool isEncrypted() const;
255
256private:
257 friend class Object; // for incRef/decRef
258
259 // Reference counting.
260 int incRef() { return ++ref; }
261 int decRef() { return --ref; }
262
263 virtual bool hasGetChars() { return false; }
264 virtual int getChars(int nChars, unsigned char *buffer);
265
266 Stream *makeFilter(const char *name, Stream *str, Object *params, int recursion = 0, Dict *dict = nullptr);
267
268 std::atomic_int ref; // reference count
269};
270
271//------------------------------------------------------------------------
272// OutStream
273//
274// This is the base class for all streams that output to a file
275//------------------------------------------------------------------------
276class POPPLER_PRIVATE_EXPORT OutStream
277{
278public:
279 // Constructor.
280 OutStream();
281
282 // Desctructor.
283 virtual ~OutStream();
284
285 OutStream(const OutStream &) = delete;
286 OutStream &operator=(const OutStream &other) = delete;
287
288 // Close the stream
289 virtual void close() = 0;
290
291 // Return position in stream
292 virtual Goffset getPos() = 0;
293
294 // Put a char in the stream
295 virtual void put(char c) = 0;
296
297 virtual void printf(const char *format, ...) GCC_PRINTF_FORMAT(2, 3) = 0;
298};
299
300//------------------------------------------------------------------------
301// FileOutStream
302//------------------------------------------------------------------------
303class POPPLER_PRIVATE_EXPORT FileOutStream : public OutStream
304{
305public:
306 FileOutStream(FILE *fa, Goffset startA);
307
308 ~FileOutStream() override;
309
310 void close() override;
311
312 Goffset getPos() override;
313
314 void put(char c) override;
315
316 void printf(const char *format, ...) override GCC_PRINTF_FORMAT(2, 3);
317
318private:
319 FILE *f;
320 Goffset start;
321};
322
323//------------------------------------------------------------------------
324// BaseStream
325//
326// This is the base class for all streams that read directly from a file.
327//------------------------------------------------------------------------
328
329class POPPLER_PRIVATE_EXPORT BaseStream : public Stream
330{
331public:
332 BaseStream(Object &&dictA, Goffset lengthA);
333 ~BaseStream() override;
334 virtual BaseStream *copy() = 0;
335 virtual Stream *makeSubStream(Goffset start, bool limited, Goffset length, Object &&dict) = 0;
336 void setPos(Goffset pos, int dir = 0) override = 0;
337 bool isBinary(bool last = true) const override { return last; }
338 BaseStream *getBaseStream() override { return this; }
339 Stream *getUndecodedStream() override { return this; }
340 Dict *getDict() override { return dict.getDict(); }
341 Object *getDictObject() override { return &dict; }
342 virtual GooString *getFileName() { return nullptr; }
343 virtual Goffset getLength() { return length; }
344
345 // Get/set position of first byte of stream within the file.
346 virtual Goffset getStart() = 0;
347 virtual void moveStart(Goffset delta) = 0;
348
349protected:
350 Goffset length;
351 Object dict;
352};
353
354//------------------------------------------------------------------------
355// BaseInputStream
356//------------------------------------------------------------------------
357
358class POPPLER_PRIVATE_EXPORT BaseSeekInputStream : public BaseStream
359{
360public:
361 // This enum is used to tell the seek() method how it must reposition
362 // the stream offset.
363 enum SeekType
364 {
365 SeekSet, // the offset is set to offset bytes
366 SeekCur, // the offset is set to its current location plus offset bytes
367 SeekEnd // the offset is set to the size of the stream plus offset bytes
368 };
369
370 BaseSeekInputStream(Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA);
371 ~BaseSeekInputStream() override;
372 StreamKind getKind() const override { return strWeird; }
373 void reset() override;
374 void close() override;
375 int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
376 int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
377 Goffset getPos() override { return bufPos + (bufPtr - buf); }
378 void setPos(Goffset pos, int dir = 0) override;
379 Goffset getStart() override { return start; }
380 void moveStart(Goffset delta) override;
381
382 int getUnfilteredChar() override { return getChar(); }
383 void unfilteredReset() override { reset(); }
384
385protected:
386 Goffset start;
387 bool limited;
388
389private:
390 bool fillBuf();
391
392 bool hasGetChars() override { return true; }
393 int getChars(int nChars, unsigned char *buffer) override;
394
395 virtual Goffset currentPos() const = 0;
396 virtual void setCurrentPos(Goffset offset) = 0;
397 virtual Goffset read(char *buf, Goffset size) = 0;
398
399 static constexpr int seekInputStreamBufSize = 1024;
400 char buf[seekInputStreamBufSize];
401 char *bufPtr;
402 char *bufEnd;
403 Goffset bufPos;
404 Goffset savePos;
405 bool saved;
406};
407
408//------------------------------------------------------------------------
409// FilterStream
410//
411// This is the base class for all streams that filter another stream.
412//------------------------------------------------------------------------
413
414class FilterStream : public Stream
415{
416public:
417 explicit FilterStream(Stream *strA);
418 ~FilterStream() override;
419 void close() override;
420 Goffset getPos() override { return str->getPos(); }
421 void setPos(Goffset pos, int dir = 0) override;
422 BaseStream *getBaseStream() override { return str->getBaseStream(); }
423 Stream *getUndecodedStream() override { return str->getUndecodedStream(); }
424 Dict *getDict() override { return str->getDict(); }
425 Object *getDictObject() override { return str->getDictObject(); }
426 Stream *getNextStream() const override { return str; }
427
428 int getUnfilteredChar() override { return str->getUnfilteredChar(); }
429 void unfilteredReset() override { str->unfilteredReset(); }
430
431protected:
432 Stream *str;
433};
434
435//------------------------------------------------------------------------
436// ImageStream
437//------------------------------------------------------------------------
438
439class POPPLER_PRIVATE_EXPORT ImageStream
440{
441public:
442 // Create an image stream object for an image with the specified
443 // parameters. Note that these are the actual image parameters,
444 // which may be different from the predictor parameters.
445 ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA);
446
447 ~ImageStream();
448
449 ImageStream(const ImageStream &) = delete;
450 ImageStream &operator=(const ImageStream &other) = delete;
451
452 // Reset the stream.
453 void reset();
454
455 // Close the stream previously reset
456 void close();
457
458 // Gets the next pixel from the stream. <pix> should be able to hold
459 // at least nComps elements. Returns false at end of file.
460 bool getPixel(unsigned char *pix);
461
462 // Returns a pointer to the next line of pixels. Returns NULL at
463 // end of file.
464 unsigned char *getLine();
465
466 // Skip an entire line from the image.
467 void skipLine();
468
469private:
470 Stream *str; // base stream
471 int width; // pixels per line
472 int nComps; // components per pixel
473 int nBits; // bits per component
474 int nVals; // components per line
475 int inputLineSize; // input line buffer size
476 unsigned char *inputLine; // input line buffer
477 unsigned char *imgLine; // line buffer
478 int imgIdx; // current index in imgLine
479};
480
481//------------------------------------------------------------------------
482// StreamPredictor
483//------------------------------------------------------------------------
484
485class StreamPredictor
486{
487public:
488 // Create a predictor object. Note that the parameters are for the
489 // predictor, and may not match the actual image parameters.
490 StreamPredictor(Stream *strA, int predictorA, int widthA, int nCompsA, int nBitsA);
491
492 ~StreamPredictor();
493
494 StreamPredictor(const StreamPredictor &) = delete;
495 StreamPredictor &operator=(const StreamPredictor &) = delete;
496
497 bool isOk() { return ok; }
498
499 int lookChar();
500 int getChar();
501 int getChars(int nChars, unsigned char *buffer);
502
503private:
504 bool getNextLine();
505
506 Stream *str; // base stream
507 int predictor; // predictor
508 int width; // pixels per line
509 int nComps; // components per pixel
510 int nBits; // bits per component
511 int nVals; // components per line
512 int pixBytes; // bytes per pixel
513 int rowBytes; // bytes per line
514 unsigned char *predLine; // line buffer
515 int predIdx; // current index in predLine
516 bool ok;
517};
518
519//------------------------------------------------------------------------
520// FileStream
521//------------------------------------------------------------------------
522
523#define fileStreamBufSize 256
524
525class POPPLER_PRIVATE_EXPORT FileStream : public BaseStream
526{
527public:
528 FileStream(GooFile *fileA, Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA);
529 ~FileStream() override;
530 BaseStream *copy() override;
531 Stream *makeSubStream(Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA) override;
532 StreamKind getKind() const override { return strFile; }
533 void reset() override;
534 void close() override;
535 int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
536 int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
537 Goffset getPos() override { return bufPos + (bufPtr - buf); }
538 void setPos(Goffset pos, int dir = 0) override;
539 Goffset getStart() override { return start; }
540 void moveStart(Goffset delta) override;
541
542 int getUnfilteredChar() override { return getChar(); }
543 void unfilteredReset() override { reset(); }
544
545 bool getNeedsEncryptionOnSave() const { return needsEncryptionOnSave; }
546 void setNeedsEncryptionOnSave(bool needsEncryptionOnSaveA) { needsEncryptionOnSave = needsEncryptionOnSaveA; }
547
548private:
549 bool fillBuf();
550
551 bool hasGetChars() override { return true; }
552 int getChars(int nChars, unsigned char *buffer) override
553 {
554 int n, m;
555
556 n = 0;
557 while (n < nChars) {
558 if (bufPtr >= bufEnd) {
559 if (!fillBuf()) {
560 break;
561 }
562 }
563 m = (int)(bufEnd - bufPtr);
564 if (m > nChars - n) {
565 m = nChars - n;
566 }
567 memcpy(dest: buffer + n, src: bufPtr, n: m);
568 bufPtr += m;
569 n += m;
570 }
571 return n;
572 }
573
574private:
575 GooFile *file;
576 Goffset offset;
577 Goffset start;
578 bool limited;
579 char buf[fileStreamBufSize];
580 char *bufPtr;
581 char *bufEnd;
582 Goffset bufPos;
583 Goffset savePos;
584 bool saved;
585 bool needsEncryptionOnSave; // Needed for FileStreams that point to "external" files
586 // and thus when saving we can't do a raw copy
587};
588
589//------------------------------------------------------------------------
590// CachedFileStream
591//------------------------------------------------------------------------
592
593#define cachedStreamBufSize 1024
594
595class POPPLER_PRIVATE_EXPORT CachedFileStream : public BaseStream
596{
597public:
598 CachedFileStream(CachedFile *ccA, Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA);
599 ~CachedFileStream() override;
600 BaseStream *copy() override;
601 Stream *makeSubStream(Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA) override;
602 StreamKind getKind() const override { return strCachedFile; }
603 void reset() override;
604 void close() override;
605 int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
606 int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
607 Goffset getPos() override { return bufPos + (bufPtr - buf); }
608 void setPos(Goffset pos, int dir = 0) override;
609 Goffset getStart() override { return start; }
610 void moveStart(Goffset delta) override;
611
612 int getUnfilteredChar() override { return getChar(); }
613 void unfilteredReset() override { reset(); }
614
615private:
616 bool fillBuf();
617
618 CachedFile *cc;
619 Goffset start;
620 bool limited;
621 char buf[cachedStreamBufSize];
622 char *bufPtr;
623 char *bufEnd;
624 unsigned int bufPos;
625 int savePos;
626 bool saved;
627};
628
629//------------------------------------------------------------------------
630// MemStream
631//------------------------------------------------------------------------
632
633template<typename T>
634class BaseMemStream : public BaseStream
635{
636public:
637 BaseMemStream(T *bufA, Goffset startA, Goffset lengthA, Object &&dictA) : BaseStream(std::move(dictA), lengthA)
638 {
639 buf = bufA;
640 start = startA;
641 length = lengthA;
642 bufEnd = buf + start + length;
643 bufPtr = buf + start;
644 }
645
646 BaseStream *copy() override { return new BaseMemStream(buf, start, length, dict.copy()); }
647
648 Stream *makeSubStream(Goffset startA, bool limited, Goffset lengthA, Object &&dictA) override
649 {
650 Goffset newLength;
651
652 if (!limited || startA + lengthA > start + length) {
653 newLength = start + length - startA;
654 } else {
655 newLength = lengthA;
656 }
657 return new BaseMemStream(buf, startA, newLength, std::move(dictA));
658 }
659
660 StreamKind getKind() const override { return strWeird; }
661
662 void reset() override { bufPtr = buf + start; }
663
664 void close() override { }
665
666 int getChar() override { return (bufPtr < bufEnd) ? (*bufPtr++ & 0xff) : EOF; }
667
668 int lookChar() override { return (bufPtr < bufEnd) ? (*bufPtr & 0xff) : EOF; }
669
670 Goffset getPos() override { return (int)(bufPtr - buf); }
671
672 void setPos(Goffset pos, int dir = 0) override
673 {
674 Goffset i;
675
676 if (dir >= 0) {
677 i = pos;
678 } else {
679 i = start + length - pos;
680 }
681 if (i < start) {
682 i = start;
683 } else if (i > start + length) {
684 i = start + length;
685 }
686 bufPtr = buf + i;
687 }
688
689 Goffset getStart() override { return start; }
690
691 void moveStart(Goffset delta) override
692 {
693 start += delta;
694 length -= delta;
695 bufPtr = buf + start;
696 }
697
698 int getUnfilteredChar() override { return getChar(); }
699
700 void unfilteredReset() override { reset(); }
701
702protected:
703 T *buf;
704
705private:
706 bool hasGetChars() override { return true; }
707
708 int getChars(int nChars, unsigned char *buffer) override
709 {
710 int n;
711
712 if (unlikely(nChars <= 0)) {
713 return 0;
714 }
715 if (unlikely(bufPtr >= bufEnd)) {
716 return 0;
717 }
718 if (bufEnd - bufPtr < nChars) {
719 n = (int)(bufEnd - bufPtr);
720 } else {
721 n = nChars;
722 }
723 memcpy(buffer, bufPtr, n);
724 bufPtr += n;
725 return n;
726 }
727
728 Goffset start;
729 T *bufEnd;
730 T *bufPtr;
731};
732
733class POPPLER_PRIVATE_EXPORT MemStream : public BaseMemStream<const char>
734{
735public:
736 MemStream(const char *bufA, Goffset startA, Goffset lengthA, Object &&dictA) : BaseMemStream(bufA, startA, lengthA, std::move(dictA)) { }
737 ~MemStream() override;
738};
739
740class AutoFreeMemStream : public BaseMemStream<char>
741{
742 bool filterRemovalForbidden = false;
743
744public:
745 // AutoFreeMemStream takes ownership over the buffer.
746 // The buffer should be created using gmalloc().
747 AutoFreeMemStream(char *bufA, Goffset startA, Goffset lengthA, Object &&dictA) : BaseMemStream(bufA, startA, lengthA, std::move(dictA)) { }
748 ~AutoFreeMemStream() override;
749
750 // A hack to deal with the strange behaviour of PDFDoc::writeObject().
751 bool isFilterRemovalForbidden() const;
752 void setFilterRemovalForbidden(bool forbidden);
753};
754
755//------------------------------------------------------------------------
756// EmbedStream
757//
758// This is a special stream type used for embedded streams (inline
759// images). It reads directly from the base stream -- after the
760// EmbedStream is deleted, reads from the base stream will proceed where
761// the BaseStream left off. Note that this is very different behavior
762// that creating a new FileStream (using makeSubStream).
763//------------------------------------------------------------------------
764
765class POPPLER_PRIVATE_EXPORT EmbedStream : public BaseStream
766{
767public:
768 EmbedStream(Stream *strA, Object &&dictA, bool limitedA, Goffset lengthA, bool reusableA = false);
769 ~EmbedStream() override;
770 BaseStream *copy() override;
771 Stream *makeSubStream(Goffset start, bool limitedA, Goffset lengthA, Object &&dictA) override;
772 StreamKind getKind() const override { return str->getKind(); }
773 void reset() override;
774 int getChar() override;
775 int lookChar() override;
776 Goffset getPos() override;
777 void setPos(Goffset pos, int dir = 0) override;
778 Goffset getStart() override;
779 void moveStart(Goffset delta) override;
780
781 int getUnfilteredChar() override { return str->getUnfilteredChar(); }
782 void unfilteredReset() override { str->unfilteredReset(); }
783
784 void rewind();
785 void restore();
786
787private:
788 bool hasGetChars() override { return true; }
789 int getChars(int nChars, unsigned char *buffer) override;
790
791 Stream *str;
792 bool limited;
793 bool reusable;
794 bool record;
795 bool replay;
796 unsigned char *bufData;
797 long bufMax;
798 long bufLen;
799 long bufPos;
800 Goffset start;
801};
802
803//------------------------------------------------------------------------
804// ASCIIHexStream
805//------------------------------------------------------------------------
806
807class ASCIIHexStream : public FilterStream
808{
809public:
810 explicit ASCIIHexStream(Stream *strA);
811 ~ASCIIHexStream() override;
812 StreamKind getKind() const override { return strASCIIHex; }
813 void reset() override;
814 int getChar() override
815 {
816 int c = lookChar();
817 buf = EOF;
818 return c;
819 }
820 int lookChar() override;
821 GooString *getPSFilter(int psLevel, const char *indent) override;
822 bool isBinary(bool last = true) const override;
823
824private:
825 int buf;
826 bool eof;
827};
828
829//------------------------------------------------------------------------
830// ASCII85Stream
831//------------------------------------------------------------------------
832
833class ASCII85Stream : public FilterStream
834{
835public:
836 explicit ASCII85Stream(Stream *strA);
837 ~ASCII85Stream() override;
838 StreamKind getKind() const override { return strASCII85; }
839 void reset() override;
840 int getChar() override
841 {
842 int ch = lookChar();
843 ++index;
844 return ch;
845 }
846 int lookChar() override;
847 GooString *getPSFilter(int psLevel, const char *indent) override;
848 bool isBinary(bool last = true) const override;
849
850private:
851 int c[5];
852 int b[4];
853 int index, n;
854 bool eof;
855};
856
857//------------------------------------------------------------------------
858// LZWStream
859//------------------------------------------------------------------------
860
861class LZWStream : public FilterStream
862{
863public:
864 LZWStream(Stream *strA, int predictor, int columns, int colors, int bits, int earlyA);
865 ~LZWStream() override;
866 StreamKind getKind() const override { return strLZW; }
867 void reset() override;
868 int getChar() override;
869 int lookChar() override;
870 int getRawChar() override;
871 void getRawChars(int nChars, int *buffer) override;
872 GooString *getPSFilter(int psLevel, const char *indent) override;
873 bool isBinary(bool last = true) const override;
874
875private:
876 bool hasGetChars() override { return true; }
877 int getChars(int nChars, unsigned char *buffer) override;
878
879 inline int doGetRawChar()
880 {
881 if (eof) {
882 return EOF;
883 }
884 if (seqIndex >= seqLength) {
885 if (!processNextCode()) {
886 return EOF;
887 }
888 }
889 return seqBuf[seqIndex++];
890 }
891
892 StreamPredictor *pred; // predictor
893 int early; // early parameter
894 bool eof; // true if at eof
895 unsigned int inputBuf; // input buffer
896 int inputBits; // number of bits in input buffer
897 struct
898 { // decoding table
899 int length;
900 int head;
901 unsigned char tail;
902 } table[4097];
903 int nextCode; // next code to be used
904 int nextBits; // number of bits in next code word
905 int prevCode; // previous code used in stream
906 int newChar; // next char to be added to table
907 unsigned char seqBuf[4097]; // buffer for current sequence
908 int seqLength; // length of current sequence
909 int seqIndex; // index into current sequence
910 bool first; // first code after a table clear
911
912 bool processNextCode();
913 void clearTable();
914 int getCode();
915};
916
917//------------------------------------------------------------------------
918// RunLengthStream
919//------------------------------------------------------------------------
920
921class RunLengthStream : public FilterStream
922{
923public:
924 explicit RunLengthStream(Stream *strA);
925 ~RunLengthStream() override;
926 StreamKind getKind() const override { return strRunLength; }
927 void reset() override;
928 int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
929 int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
930 GooString *getPSFilter(int psLevel, const char *indent) override;
931 bool isBinary(bool last = true) const override;
932
933private:
934 bool hasGetChars() override { return true; }
935 int getChars(int nChars, unsigned char *buffer) override;
936
937 char buf[128]; // buffer
938 char *bufPtr; // next char to read
939 char *bufEnd; // end of buffer
940 bool eof;
941
942 bool fillBuf();
943};
944
945//------------------------------------------------------------------------
946// CCITTFaxStream
947//------------------------------------------------------------------------
948
949struct CCITTCodeTable;
950
951class CCITTFaxStream : public FilterStream
952{
953public:
954 CCITTFaxStream(Stream *strA, int encodingA, bool endOfLineA, bool byteAlignA, int columnsA, int rowsA, bool endOfBlockA, bool blackA, int damagedRowsBeforeErrorA);
955 ~CCITTFaxStream() override;
956 StreamKind getKind() const override { return strCCITTFax; }
957 void reset() override;
958 int getChar() override
959 {
960 int c = lookChar();
961 buf = EOF;
962 return c;
963 }
964 int lookChar() override;
965 GooString *getPSFilter(int psLevel, const char *indent) override;
966 bool isBinary(bool last = true) const override;
967
968 void unfilteredReset() override;
969
970 int getEncoding() { return encoding; }
971 bool getEndOfLine() { return endOfLine; }
972 bool getEncodedByteAlign() { return byteAlign; }
973 bool getEndOfBlock() { return endOfBlock; }
974 int getColumns() { return columns; }
975 bool getBlackIs1() { return black; }
976 int getDamagedRowsBeforeError() { return damagedRowsBeforeError; }
977
978private:
979 void ccittReset(bool unfiltered);
980 int encoding; // 'K' parameter
981 bool endOfLine; // 'EndOfLine' parameter
982 bool byteAlign; // 'EncodedByteAlign' parameter
983 int columns; // 'Columns' parameter
984 int rows; // 'Rows' parameter
985 bool endOfBlock; // 'EndOfBlock' parameter
986 bool black; // 'BlackIs1' parameter
987 int damagedRowsBeforeError; // 'DamagedRowsBeforeError' parameter
988 bool eof; // true if at eof
989 bool nextLine2D; // true if next line uses 2D encoding
990 int row; // current row
991 unsigned int inputBuf; // input buffer
992 int inputBits; // number of bits in input buffer
993 int *codingLine; // coding line changing elements
994 int *refLine; // reference line changing elements
995 int a0i; // index into codingLine
996 bool err; // error on current line
997 int outputBits; // remaining ouput bits
998 int buf; // character buffer
999
1000 void addPixels(int a1, int blackPixels);
1001 void addPixelsNeg(int a1, int blackPixels);
1002 short getTwoDimCode();
1003 short getWhiteCode();
1004 short getBlackCode();
1005 short lookBits(int n);
1006 void eatBits(int n)
1007 {
1008 if ((inputBits -= n) < 0) {
1009 inputBits = 0;
1010 }
1011 }
1012};
1013
1014#ifndef ENABLE_LIBJPEG
1015//------------------------------------------------------------------------
1016// DCTStream
1017//------------------------------------------------------------------------
1018
1019// DCT component info
1020struct DCTCompInfo
1021{
1022 int id; // component ID
1023 int hSample, vSample; // horiz/vert sampling resolutions
1024 int quantTable; // quantization table number
1025 int prevDC; // DC coefficient accumulator
1026};
1027
1028struct DCTScanInfo
1029{
1030 bool comp[4]; // comp[i] is set if component i is
1031 // included in this scan
1032 int numComps; // number of components in the scan
1033 int dcHuffTable[4]; // DC Huffman table numbers
1034 int acHuffTable[4]; // AC Huffman table numbers
1035 int firstCoeff, lastCoeff; // first and last DCT coefficient
1036 int ah, al; // successive approximation parameters
1037};
1038
1039// DCT Huffman decoding table
1040struct DCTHuffTable
1041{
1042 unsigned char firstSym[17]; // first symbol for this bit length
1043 unsigned short firstCode[17]; // first code for this bit length
1044 unsigned short numCodes[17]; // number of codes of this bit length
1045 unsigned char sym[256]; // symbols
1046};
1047
1048class DCTStream : public FilterStream
1049{
1050public:
1051 DCTStream(Stream *strA, int colorXformA, Dict *dict, int recursion);
1052 ~DCTStream() override;
1053 StreamKind getKind() const override { return strDCT; }
1054 void reset() override;
1055 void close() override;
1056 int getChar() override;
1057 int lookChar() override;
1058 GooString *getPSFilter(int psLevel, const char *indent) override;
1059 bool isBinary(bool last = true) const override;
1060
1061 void unfilteredReset() override;
1062
1063private:
1064 void dctReset(bool unfiltered);
1065 bool progressive; // set if in progressive mode
1066 bool interleaved; // set if in interleaved mode
1067 int width, height; // image size
1068 int mcuWidth, mcuHeight; // size of min coding unit, in data units
1069 int bufWidth, bufHeight; // frameBuf size
1070 DCTCompInfo compInfo[4]; // info for each component
1071 DCTScanInfo scanInfo; // info for the current scan
1072 int numComps; // number of components in image
1073 int colorXform; // color transform: -1 = unspecified
1074 // 0 = none
1075 // 1 = YUV/YUVK -> RGB/CMYK
1076 bool gotJFIFMarker; // set if APP0 JFIF marker was present
1077 bool gotAdobeMarker; // set if APP14 Adobe marker was present
1078 int restartInterval; // restart interval, in MCUs
1079 unsigned short quantTables[4][64]; // quantization tables
1080 int numQuantTables; // number of quantization tables
1081 DCTHuffTable dcHuffTables[4]; // DC Huffman tables
1082 DCTHuffTable acHuffTables[4]; // AC Huffman tables
1083 int numDCHuffTables; // number of DC Huffman tables
1084 int numACHuffTables; // number of AC Huffman tables
1085 unsigned char *rowBuf[4][32]; // buffer for one MCU (non-progressive mode)
1086 int *frameBuf[4]; // buffer for frame (progressive mode)
1087 int comp, x, y, dy; // current position within image/MCU
1088 int restartCtr; // MCUs left until restart
1089 int restartMarker; // next restart marker
1090 int eobRun; // number of EOBs left in the current run
1091 int inputBuf; // input buffer for variable length codes
1092 int inputBits; // number of valid bits in input buffer
1093
1094 void restart();
1095 bool readMCURow();
1096 void readScan();
1097 bool readDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable, int *prevDC, int data[64]);
1098 bool readProgressiveDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable, int *prevDC, int data[64]);
1099 void decodeImage();
1100 void transformDataUnit(unsigned short *quantTable, int dataIn[64], unsigned char dataOut[64]);
1101 int readHuffSym(DCTHuffTable *table);
1102 int readAmp(int size);
1103 int readBit();
1104 bool readHeader();
1105 bool readBaselineSOF();
1106 bool readProgressiveSOF();
1107 bool readScanInfo();
1108 bool readQuantTables();
1109 bool readHuffmanTables();
1110 bool readRestartInterval();
1111 bool readJFIFMarker();
1112 bool readAdobeMarker();
1113 bool readTrailer();
1114 int readMarker();
1115 int read16();
1116};
1117
1118#endif
1119
1120#ifndef ENABLE_ZLIB_UNCOMPRESS
1121//------------------------------------------------------------------------
1122// FlateStream
1123//------------------------------------------------------------------------
1124
1125# define flateWindow 32768 // buffer size
1126# define flateMask (flateWindow - 1)
1127# define flateMaxHuffman 15 // max Huffman code length
1128# define flateMaxCodeLenCodes 19 // max # code length codes
1129# define flateMaxLitCodes 288 // max # literal codes
1130# define flateMaxDistCodes 30 // max # distance codes
1131
1132// Huffman code table entry
1133struct FlateCode
1134{
1135 unsigned short len; // code length, in bits
1136 unsigned short val; // value represented by this code
1137};
1138
1139struct FlateHuffmanTab
1140{
1141 const FlateCode *codes;
1142 int maxLen;
1143};
1144
1145// Decoding info for length and distance code words
1146struct FlateDecode
1147{
1148 int bits; // # extra bits
1149 int first; // first length/distance
1150};
1151
1152class FlateStream : public FilterStream
1153{
1154public:
1155 FlateStream(Stream *strA, int predictor, int columns, int colors, int bits);
1156 ~FlateStream() override;
1157 StreamKind getKind() const override { return strFlate; }
1158 void reset() override;
1159 int getChar() override;
1160 int lookChar() override;
1161 int getRawChar() override;
1162 void getRawChars(int nChars, int *buffer) override;
1163 GooString *getPSFilter(int psLevel, const char *indent) override;
1164 bool isBinary(bool last = true) const override;
1165 void unfilteredReset() override;
1166
1167private:
1168 void flateReset(bool unfiltered);
1169 inline int doGetRawChar()
1170 {
1171 int c;
1172
1173 while (remain == 0) {
1174 if (endOfBlock && eof) {
1175 return EOF;
1176 }
1177 readSome();
1178 }
1179 c = buf[index];
1180 index = (index + 1) & flateMask;
1181 --remain;
1182 return c;
1183 }
1184
1185 bool hasGetChars() override { return true; }
1186 int getChars(int nChars, unsigned char *buffer) override;
1187
1188 StreamPredictor *pred; // predictor
1189 unsigned char buf[flateWindow]; // output data buffer
1190 int index; // current index into output buffer
1191 int remain; // number valid bytes in output buffer
1192 int codeBuf; // input buffer
1193 int codeSize; // number of bits in input buffer
1194 int // literal and distance code lengths
1195 codeLengths[flateMaxLitCodes + flateMaxDistCodes];
1196 FlateHuffmanTab litCodeTab; // literal code table
1197 FlateHuffmanTab distCodeTab; // distance code table
1198 bool compressedBlock; // set if reading a compressed block
1199 int blockLen; // remaining length of uncompressed block
1200 bool endOfBlock; // set when end of block is reached
1201 bool eof; // set when end of stream is reached
1202
1203 static const int // code length code reordering
1204 codeLenCodeMap[flateMaxCodeLenCodes];
1205 static const FlateDecode // length decoding info
1206 lengthDecode[flateMaxLitCodes - 257];
1207 static const FlateDecode // distance decoding info
1208 distDecode[flateMaxDistCodes];
1209 static FlateHuffmanTab // fixed literal code table
1210 fixedLitCodeTab;
1211 static FlateHuffmanTab // fixed distance code table
1212 fixedDistCodeTab;
1213
1214 void readSome();
1215 bool startBlock();
1216 void loadFixedCodes();
1217 bool readDynamicCodes();
1218 FlateCode *compHuffmanCodes(const int *lengths, int n, int *maxLen);
1219 int getHuffmanCodeWord(FlateHuffmanTab *tab);
1220 int getCodeWord(int bits);
1221};
1222#endif
1223
1224//------------------------------------------------------------------------
1225// EOFStream
1226//------------------------------------------------------------------------
1227
1228class EOFStream : public FilterStream
1229{
1230public:
1231 explicit EOFStream(Stream *strA);
1232 ~EOFStream() override;
1233 StreamKind getKind() const override { return strWeird; }
1234 void reset() override { }
1235 int getChar() override { return EOF; }
1236 int lookChar() override { return EOF; }
1237 GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
1238 bool isBinary(bool /*last = true*/) const override { return false; }
1239};
1240
1241//------------------------------------------------------------------------
1242// BufStream
1243//------------------------------------------------------------------------
1244
1245class BufStream : public FilterStream
1246{
1247public:
1248 BufStream(Stream *strA, int bufSizeA);
1249 ~BufStream() override;
1250 StreamKind getKind() const override { return strWeird; }
1251 void reset() override;
1252 int getChar() override;
1253 int lookChar() override;
1254 GooString *getPSFilter(int psLevel, const char *indent) override { return nullptr; }
1255 bool isBinary(bool last = true) const override;
1256
1257 int lookChar(int idx);
1258
1259private:
1260 int *buf;
1261 int bufSize;
1262};
1263
1264//------------------------------------------------------------------------
1265// FixedLengthEncoder
1266//------------------------------------------------------------------------
1267
1268class FixedLengthEncoder : public FilterStream
1269{
1270public:
1271 FixedLengthEncoder(Stream *strA, int lengthA);
1272 ~FixedLengthEncoder() override;
1273 StreamKind getKind() const override { return strWeird; }
1274 void reset() override;
1275 int getChar() override;
1276 int lookChar() override;
1277 GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
1278 bool isBinary(bool /*last = true*/) const override;
1279 bool isEncoder() const override { return true; }
1280
1281private:
1282 int length;
1283 int count;
1284};
1285
1286//------------------------------------------------------------------------
1287// ASCIIHexEncoder
1288//------------------------------------------------------------------------
1289
1290class ASCIIHexEncoder : public FilterStream
1291{
1292public:
1293 explicit ASCIIHexEncoder(Stream *strA);
1294 ~ASCIIHexEncoder() override;
1295 StreamKind getKind() const override { return strWeird; }
1296 void reset() override;
1297 int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
1298 int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
1299 GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
1300 bool isBinary(bool /*last = true*/) const override { return false; }
1301 bool isEncoder() const override { return true; }
1302
1303private:
1304 char buf[4];
1305 char *bufPtr;
1306 char *bufEnd;
1307 int lineLen;
1308 bool eof;
1309
1310 bool fillBuf();
1311};
1312
1313//------------------------------------------------------------------------
1314// ASCII85Encoder
1315//------------------------------------------------------------------------
1316
1317class ASCII85Encoder : public FilterStream
1318{
1319public:
1320 explicit ASCII85Encoder(Stream *strA);
1321 ~ASCII85Encoder() override;
1322 StreamKind getKind() const override { return strWeird; }
1323 void reset() override;
1324 int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
1325 int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
1326 GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
1327 bool isBinary(bool /*last = true*/) const override { return false; }
1328 bool isEncoder() const override { return true; }
1329
1330private:
1331 char buf[8];
1332 char *bufPtr;
1333 char *bufEnd;
1334 int lineLen;
1335 bool eof;
1336
1337 bool fillBuf();
1338};
1339
1340//------------------------------------------------------------------------
1341// RunLengthEncoder
1342//------------------------------------------------------------------------
1343
1344class RunLengthEncoder : public FilterStream
1345{
1346public:
1347 explicit RunLengthEncoder(Stream *strA);
1348 ~RunLengthEncoder() override;
1349 StreamKind getKind() const override { return strWeird; }
1350 void reset() override;
1351 int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
1352 int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
1353 GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
1354 bool isBinary(bool /*last = true*/) const override { return true; }
1355 bool isEncoder() const override { return true; }
1356
1357private:
1358 char buf[131];
1359 char *bufPtr;
1360 char *bufEnd;
1361 char *nextEnd;
1362 bool eof;
1363
1364 bool fillBuf();
1365};
1366
1367//------------------------------------------------------------------------
1368// LZWEncoder
1369//------------------------------------------------------------------------
1370
1371struct LZWEncoderNode
1372{
1373 int byte;
1374 LZWEncoderNode *next; // next sibling
1375 LZWEncoderNode *children; // first child
1376};
1377
1378class LZWEncoder : public FilterStream
1379{
1380public:
1381 explicit LZWEncoder(Stream *strA);
1382 ~LZWEncoder() override;
1383 StreamKind getKind() const override { return strWeird; }
1384 void reset() override;
1385 int getChar() override;
1386 int lookChar() override;
1387 GooString *getPSFilter(int psLevel, const char *indent) override { return nullptr; }
1388 bool isBinary(bool last = true) const override { return true; }
1389 bool isEncoder() const override { return true; }
1390
1391private:
1392 LZWEncoderNode table[4096];
1393 int nextSeq;
1394 int codeLen;
1395 unsigned char inBuf[4096];
1396 int inBufLen;
1397 int outBuf;
1398 int outBufLen;
1399 bool needEOD;
1400
1401 void fillBuf();
1402};
1403
1404//------------------------------------------------------------------------
1405// CMYKGrayEncoder
1406//------------------------------------------------------------------------
1407
1408class CMYKGrayEncoder : public FilterStream
1409{
1410public:
1411 explicit CMYKGrayEncoder(Stream *strA);
1412 ~CMYKGrayEncoder() override;
1413 StreamKind getKind() const override { return strWeird; }
1414 void reset() override;
1415 int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
1416 int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
1417 GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
1418 bool isBinary(bool /*last = true*/) const override { return false; }
1419 bool isEncoder() const override { return true; }
1420
1421private:
1422 char buf[2];
1423 char *bufPtr;
1424 char *bufEnd;
1425 bool eof;
1426
1427 bool fillBuf();
1428};
1429
1430//------------------------------------------------------------------------
1431// RGBGrayEncoder
1432//------------------------------------------------------------------------
1433
1434class RGBGrayEncoder : public FilterStream
1435{
1436public:
1437 explicit RGBGrayEncoder(Stream *strA);
1438 ~RGBGrayEncoder() override;
1439 StreamKind getKind() const override { return strWeird; }
1440 void reset() override;
1441 int getChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
1442 int lookChar() override { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
1443 GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
1444 bool isBinary(bool /*last = true*/) const override { return false; }
1445 bool isEncoder() const override { return true; }
1446
1447private:
1448 char buf[2];
1449 char *bufPtr;
1450 char *bufEnd;
1451 bool eof;
1452
1453 bool fillBuf();
1454};
1455
1456//------------------------------------------------------------------------
1457// SplashBitmapCMYKEncoder
1458//
1459// This stream helps to condense SplashBitmaps (mostly of DeviceN8 type) into
1460// pure CMYK colors. In particular for a DeviceN8 bitmap it redacts the spot colorants.
1461//------------------------------------------------------------------------
1462
1463class SplashBitmapCMYKEncoder : public Stream
1464{
1465public:
1466 explicit SplashBitmapCMYKEncoder(SplashBitmap *bitmapA);
1467 ~SplashBitmapCMYKEncoder() override;
1468 StreamKind getKind() const override { return strWeird; }
1469 void reset() override;
1470 int getChar() override;
1471 int lookChar() override;
1472 GooString *getPSFilter(int /*psLevel*/, const char * /*indent*/) override { return nullptr; }
1473 bool isBinary(bool /*last = true*/) const override { return true; }
1474
1475 // Although we are an encoder, we return false here, since we do not want do be auto-deleted by
1476 // successive streams.
1477 bool isEncoder() const override { return false; }
1478
1479 int getUnfilteredChar() override { return getChar(); }
1480 void unfilteredReset() override { reset(); }
1481
1482 BaseStream *getBaseStream() override { return nullptr; }
1483 Stream *getUndecodedStream() override { return this; }
1484
1485 Dict *getDict() override { return nullptr; }
1486 Object *getDictObject() override { return nullptr; }
1487
1488 Goffset getPos() override;
1489 void setPos(Goffset pos, int dir = 0) override;
1490
1491private:
1492 SplashBitmap *bitmap;
1493 size_t width;
1494 int height;
1495
1496 std::vector<unsigned char> buf;
1497 size_t bufPtr;
1498 int curLine;
1499
1500 bool fillBuf();
1501};
1502
1503#endif
1504

source code of poppler/poppler/Stream.h