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