1 //========================================================================
2 //
3 // Stream.cc
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) 2006-2010, 2012-2014, 2016-2021 Albert Astals Cid <aacid@kde.org>
18 // Copyright (C) 2007 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
19 // Copyright (C) 2008 Julien Rebetez <julien@fhtagn.net>
20 // Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
21 // Copyright (C) 2009 Glenn Ganz <glenn.ganz@uptime.ch>
22 // Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
23 // Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
24 // Copyright (C) 2010 Tomas Hoger <thoger@redhat.com>
25 // Copyright (C) 2011, 2012, 2016, 2020 William Bader <williambader@hotmail.com>
26 // Copyright (C) 2012, 2013, 2020 Thomas Freitag <Thomas.Freitag@alfa.de>
27 // Copyright (C) 2012, 2021 Oliver Sander <oliver.sander@tu-dresden.de>
28 // Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
29 // Copyright (C) 2012 Even Rouault <even.rouault@mines-paris.org>
30 // Copyright (C) 2013, 2017, 2018 Adrian Johnson <ajohnson@redneon.com>
31 // Copyright (C) 2013, 2018 Adam Reichold <adamreichold@myopera.com>
32 // Copyright (C) 2013 Pino Toscano <pino@kde.org>
33 // Copyright (C) 2015 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
34 // Copyright (C) 2015 Jason Crain <jason@aquaticape.us>
35 // Copyright (C) 2017 Jose Aliste <jaliste@src.gnome.org>
36 // Copyright (C) 2017 Kay Dohmann <k.dohmann@gmx.net>
37 // Copyright (C) 2019 Christian Persch <chpe@src.gnome.org>
38 // Copyright (C) 2019 LE GARREC Vincent <legarrec.vincent@gmail.com>
39 // Copyright (C) 2019 Volker Krause <vkrause@kde.org>
40 // Copyright (C) 2019 Alexander Volkov <a.volkov@rusbitech.ru>
41 // Copyright (C) 2020 Philipp Knechtges <philipp-dev@knechtges.com>
42 // Copyright (C) 2021 Hubert Figuiere <hub@figuiere.net>
43 // Copyright (C) 2021 Georgiy Sgibnev <georgiy@sgibnev.com>. Work sponsored by lab50.net.
44 //
45 // To see a description of the changes please see the Changelog file that
46 // came with your tarball or type make ChangeLog if you are building from git
47 //
48 //========================================================================
49 
50 #include <config.h>
51 
52 #include <cstdio>
53 #include <cstdlib>
54 #include <cstddef>
55 #include <climits>
56 #ifdef HAVE_UNISTD_H
57 #    include <unistd.h>
58 #endif
59 #include <cstring>
60 #include <cctype>
61 #include "goo/gmem.h"
62 #include "goo/gfile.h"
63 #include "poppler-config.h"
64 #include "Error.h"
65 #include "Object.h"
66 #include "Lexer.h"
67 #include "GfxState.h"
68 #include "Stream.h"
69 #include "XRef.h"
70 #include "JBIG2Stream.h"
71 #include "Stream-CCITT.h"
72 #include "CachedFile.h"
73 
74 #include "splash/SplashBitmap.h"
75 
76 #ifdef ENABLE_LIBJPEG
77 #    include "DCTStream.h"
78 #endif
79 
80 #ifdef ENABLE_ZLIB_UNCOMPRESS
81 #    include "FlateStream.h"
82 #endif
83 
84 #ifdef ENABLE_LIBOPENJPEG
85 #    include "JPEG2000Stream.h"
86 #else
87 #    include "JPXStream.h"
88 #endif
89 
90 #ifdef __DJGPP__
91 static bool setDJSYSFLAGS = false;
92 #endif
93 
94 //------------------------------------------------------------------------
95 // Stream (base class)
96 //------------------------------------------------------------------------
97 
Stream()98 Stream::Stream()
99 {
100     ref = 1;
101 }
102 
103 Stream::~Stream() = default;
104 
close()105 void Stream::close() { }
106 
getRawChar()107 int Stream::getRawChar()
108 {
109     error(errInternal, -1, "Internal: called getRawChar() on non-predictor stream");
110     return EOF;
111 }
112 
getChars(int nChars,unsigned char * buffer)113 int Stream::getChars(int nChars, unsigned char *buffer)
114 {
115     error(errInternal, -1, "Internal: called getChars() on non-predictor stream");
116     return 0;
117 }
118 
getRawChars(int nChars,int * buffer)119 void Stream::getRawChars(int nChars, int *buffer)
120 {
121     error(errInternal, -1, "Internal: called getRawChars() on non-predictor stream");
122 }
123 
getLine(char * buf,int size)124 char *Stream::getLine(char *buf, int size)
125 {
126     int i;
127     int c;
128 
129     if (lookChar() == EOF || size < 0)
130         return nullptr;
131     for (i = 0; i < size - 1; ++i) {
132         c = getChar();
133         if (c == EOF || c == '\n')
134             break;
135         if (c == '\r') {
136             if ((c = lookChar()) == '\n')
137                 getChar();
138             break;
139         }
140         buf[i] = c;
141     }
142     buf[i] = '\0';
143     return buf;
144 }
145 
discardChars(unsigned int n)146 unsigned int Stream::discardChars(unsigned int n)
147 {
148     unsigned char buf[4096];
149     unsigned int count, i, j;
150 
151     count = 0;
152     while (count < n) {
153         if ((i = n - count) > sizeof(buf)) {
154             i = (unsigned int)sizeof(buf);
155         }
156         j = (unsigned int)doGetChars((int)i, buf);
157         count += j;
158         if (j != i) {
159             break;
160         }
161     }
162     return count;
163 }
164 
getPSFilter(int psLevel,const char * indent)165 GooString *Stream::getPSFilter(int psLevel, const char *indent)
166 {
167     return new GooString();
168 }
169 
wrapEOFStream(Stream * str)170 static Stream *wrapEOFStream(Stream *str)
171 {
172     if (dynamic_cast<EOFStream *>(str)) {
173         // str is already a EOFStream, no need to wrap it in another EOFStream
174         return str;
175     } else {
176         return new EOFStream(str);
177     }
178 }
179 
addFilters(Dict * dict,int recursion)180 Stream *Stream::addFilters(Dict *dict, int recursion)
181 {
182     Object obj, obj2;
183     Object params, params2;
184     Stream *str;
185     int i;
186 
187     str = this;
188     obj = dict->lookup("Filter", recursion);
189     if (obj.isNull()) {
190         obj = dict->lookup("F", recursion);
191     }
192     params = dict->lookup("DecodeParms", recursion);
193     if (params.isNull()) {
194         params = dict->lookup("DP", recursion);
195     }
196     if (obj.isName()) {
197         str = makeFilter(obj.getName(), str, &params, recursion, dict);
198     } else if (obj.isArray()) {
199         for (i = 0; i < obj.arrayGetLength(); ++i) {
200             obj2 = obj.arrayGet(i, recursion);
201             if (params.isArray())
202                 params2 = params.arrayGet(i, recursion);
203             else
204                 params2.setToNull();
205             if (obj2.isName()) {
206                 str = makeFilter(obj2.getName(), str, &params2, recursion);
207             } else {
208                 error(errSyntaxError, getPos(), "Bad filter name");
209                 str = wrapEOFStream(str);
210             }
211         }
212     } else if (!obj.isNull()) {
213         error(errSyntaxError, getPos(), "Bad 'Filter' attribute in stream");
214     }
215 
216     return str;
217 }
218 
isEncrypted() const219 bool Stream::isEncrypted() const
220 {
221     for (const Stream *str = this; str != nullptr; str = str->getNextStream()) {
222         if (str->getKind() == strCrypt)
223             return true;
224     }
225     return false;
226 }
227 
228 class BaseStreamStream : public Stream
229 {
230 public:
BaseStreamStream(Stream * strA)231     explicit BaseStreamStream(Stream *strA) : str(strA) { }
232     ~BaseStreamStream() override;
233 
getKind() const234     StreamKind getKind() const override { return str->getBaseStream()->getKind(); }
reset()235     void reset() override { str->getBaseStream()->reset(); }
getChar()236     int getChar() override { return str->getBaseStream()->getChar(); }
lookChar()237     int lookChar() override { return str->getBaseStream()->lookChar(); }
isBinary(bool last=true) const238     bool isBinary(bool last = true) const override { return str->getBaseStream()->isBinary(); }
getUnfilteredChar()239     int getUnfilteredChar() override { return str->getBaseStream()->getUnfilteredChar(); }
unfilteredReset()240     void unfilteredReset() override { str->getBaseStream()->unfilteredReset(); }
getPos()241     Goffset getPos() override { return str->getBaseStream()->getPos(); }
setPos(Goffset pos,int dir)242     void setPos(Goffset pos, int dir) override { str->getBaseStream()->setPos(pos, dir); }
getBaseStream()243     BaseStream *getBaseStream() override { return str->getBaseStream()->getBaseStream(); }
getUndecodedStream()244     Stream *getUndecodedStream() override { return str->getBaseStream()->getUndecodedStream(); }
getDict()245     Dict *getDict() override { return str->getBaseStream()->getDict(); }
getDictObject()246     Object *getDictObject() override { return str->getBaseStream()->getDictObject(); }
247 
248 private:
249     std::unique_ptr<Stream> str;
250 };
251 
252 BaseStreamStream::~BaseStreamStream() = default;
253 
makeFilter(const char * name,Stream * str,Object * params,int recursion,Dict * dict)254 Stream *Stream::makeFilter(const char *name, Stream *str, Object *params, int recursion, Dict *dict)
255 {
256     int pred; // parameters
257     int colors;
258     int bits;
259     int early;
260     int encoding;
261     bool endOfLine, byteAlign, endOfBlock, black, damagedRowsBeforeError;
262     int columns, rows;
263     Object obj;
264 
265     if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) {
266         str = new ASCIIHexStream(str);
267     } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) {
268         str = new ASCII85Stream(str);
269     } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) {
270         pred = 1;
271         columns = 1;
272         colors = 1;
273         bits = 8;
274         early = 1;
275         if (params->isDict()) {
276             obj = params->dictLookup("Predictor", recursion);
277             if (obj.isInt())
278                 pred = obj.getInt();
279             obj = params->dictLookup("Columns", recursion);
280             if (obj.isInt())
281                 columns = obj.getInt();
282             obj = params->dictLookup("Colors", recursion);
283             if (obj.isInt())
284                 colors = obj.getInt();
285             obj = params->dictLookup("BitsPerComponent", recursion);
286             if (obj.isInt())
287                 bits = obj.getInt();
288             obj = params->dictLookup("EarlyChange", recursion);
289             if (obj.isInt())
290                 early = obj.getInt();
291         }
292         str = new LZWStream(str, pred, columns, colors, bits, early);
293     } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) {
294         str = new RunLengthStream(str);
295     } else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) {
296         encoding = 0;
297         endOfLine = false;
298         byteAlign = false;
299         columns = 1728;
300         rows = 0;
301         endOfBlock = true;
302         black = false;
303         damagedRowsBeforeError = false;
304         if (params->isDict()) {
305             obj = params->dictLookup("K", recursion);
306             if (obj.isInt()) {
307                 encoding = obj.getInt();
308             }
309             obj = params->dictLookup("EndOfLine", recursion);
310             if (obj.isBool()) {
311                 endOfLine = obj.getBool();
312             }
313             obj = params->dictLookup("EncodedByteAlign", recursion);
314             if (obj.isBool()) {
315                 byteAlign = obj.getBool();
316             }
317             obj = params->dictLookup("Columns", recursion);
318             if (obj.isInt()) {
319                 columns = obj.getInt();
320             }
321             obj = params->dictLookup("Rows", recursion);
322             if (obj.isInt()) {
323                 rows = obj.getInt();
324             }
325             obj = params->dictLookup("EndOfBlock", recursion);
326             if (obj.isBool()) {
327                 endOfBlock = obj.getBool();
328             }
329             obj = params->dictLookup("BlackIs1", recursion);
330             if (obj.isBool()) {
331                 black = obj.getBool();
332             }
333             obj = params->dictLookup("DamagedRowsBeforeError", recursion);
334             if (obj.isInt()) {
335                 damagedRowsBeforeError = obj.getInt();
336             }
337         }
338         str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign, columns, rows, endOfBlock, black, damagedRowsBeforeError);
339     } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) {
340 #ifdef HAVE_DCT_DECODER
341         int colorXform = -1;
342         if (params->isDict()) {
343             obj = params->dictLookup("ColorTransform", recursion);
344             if (obj.isInt()) {
345                 colorXform = obj.getInt();
346             }
347         }
348         str = new DCTStream(str, colorXform, dict, recursion);
349 #else
350         error(errSyntaxError, getPos(), "Unknown filter '{0:s}'", name);
351         str = wrapEOFStream(str);
352 #endif
353     } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) {
354         pred = 1;
355         columns = 1;
356         colors = 1;
357         bits = 8;
358         if (params->isDict()) {
359             obj = params->dictLookup("Predictor", recursion);
360             if (obj.isInt())
361                 pred = obj.getInt();
362             obj = params->dictLookup("Columns", recursion);
363             if (obj.isInt())
364                 columns = obj.getInt();
365             obj = params->dictLookup("Colors", recursion);
366             if (obj.isInt())
367                 colors = obj.getInt();
368             obj = params->dictLookup("BitsPerComponent", recursion);
369             if (obj.isInt())
370                 bits = obj.getInt();
371         }
372         str = new FlateStream(str, pred, columns, colors, bits);
373     } else if (!strcmp(name, "JBIG2Decode")) {
374         Object globals;
375         if (params->isDict()) {
376             XRef *xref = params->getDict()->getXRef();
377             obj = params->dictLookupNF("JBIG2Globals").copy();
378             globals = obj.fetch(xref, recursion);
379         }
380         str = new JBIG2Stream(str, std::move(globals), &obj);
381     } else if (!strcmp(name, "JPXDecode")) {
382 #ifdef HAVE_JPX_DECODER
383         str = new JPXStream(str);
384 #else
385         error(errSyntaxError, getPos(), "Unknown filter '{0:s}'", name);
386         str = wrapEOFStream(str);
387 #endif
388     } else if (!strcmp(name, "Crypt")) {
389         if (str->getKind() == strCrypt) {
390             str = new BaseStreamStream(str);
391         } else {
392             error(errSyntaxError, getPos(), "Can't revert non decrypt streams");
393         }
394     } else {
395         error(errSyntaxError, getPos(), "Unknown filter '{0:s}'", name);
396         str = wrapEOFStream(str);
397     }
398     return str;
399 }
400 
401 //------------------------------------------------------------------------
402 // OutStream
403 //------------------------------------------------------------------------
OutStream()404 OutStream::OutStream() { }
405 
~OutStream()406 OutStream::~OutStream() { }
407 
408 //------------------------------------------------------------------------
409 // FileOutStream
410 //------------------------------------------------------------------------
FileOutStream(FILE * fa,Goffset startA)411 FileOutStream::FileOutStream(FILE *fa, Goffset startA)
412 {
413     f = fa;
414     start = startA;
415 }
416 
~FileOutStream()417 FileOutStream::~FileOutStream()
418 {
419     close();
420 }
421 
close()422 void FileOutStream::close() { }
423 
getPos()424 Goffset FileOutStream::getPos()
425 {
426     return Gftell(f);
427 }
428 
put(char c)429 void FileOutStream::put(char c)
430 {
431     fputc(c, f);
432 }
433 
printf(const char * format,...)434 void FileOutStream::printf(const char *format, ...)
435 {
436     va_list argptr;
437     va_start(argptr, format);
438     vfprintf(f, format, argptr);
439     va_end(argptr);
440 }
441 
442 //------------------------------------------------------------------------
443 // BaseStream
444 //------------------------------------------------------------------------
445 
BaseStream(Object && dictA,Goffset lengthA)446 BaseStream::BaseStream(Object &&dictA, Goffset lengthA)
447 {
448     dict = std::move(dictA);
449     length = lengthA;
450 }
451 
~BaseStream()452 BaseStream::~BaseStream() { }
453 
454 //------------------------------------------------------------------------
455 // BaseStream
456 //------------------------------------------------------------------------
457 
BaseSeekInputStream(Goffset startA,bool limitedA,Goffset lengthA,Object && dictA)458 BaseSeekInputStream::BaseSeekInputStream(Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA)
459     : BaseStream(std::move(dictA), lengthA), start(startA), limited(limitedA), bufPtr(buf), bufEnd(buf), bufPos(start), savePos(0), saved(false)
460 {
461 }
462 
~BaseSeekInputStream()463 BaseSeekInputStream::~BaseSeekInputStream() { }
464 
reset()465 void BaseSeekInputStream::reset()
466 {
467     savePos = currentPos();
468     setCurrentPos(start);
469     saved = true;
470     bufPtr = bufEnd = buf;
471     bufPos = start;
472 }
473 
close()474 void BaseSeekInputStream::close()
475 {
476     if (!saved)
477         return;
478     setCurrentPos(savePos);
479     saved = false;
480 }
481 
setPos(Goffset pos,int dir)482 void BaseSeekInputStream::setPos(Goffset pos, int dir)
483 {
484     if (dir >= 0) {
485         setCurrentPos(pos);
486         bufPos = pos;
487     } else {
488         if (pos > length)
489             pos = length;
490 
491         bufPos = length - pos;
492         setCurrentPos(bufPos);
493     }
494     bufPtr = bufEnd = buf;
495 }
496 
moveStart(Goffset delta)497 void BaseSeekInputStream::moveStart(Goffset delta)
498 {
499     start += delta;
500     bufPtr = bufEnd = buf;
501     bufPos = start;
502 }
503 
fillBuf()504 bool BaseSeekInputStream::fillBuf()
505 {
506     Goffset n;
507 
508     bufPos += bufEnd - buf;
509     bufPtr = bufEnd = buf;
510     if (limited && bufPos >= start + length) {
511         return false;
512     }
513 
514     if (limited && bufPos + seekInputStreamBufSize > start + length) {
515         n = start + length - bufPos;
516     } else {
517         n = seekInputStreamBufSize - (bufPos % seekInputStreamBufSize);
518     }
519 
520     n = read(buf, n);
521     bufEnd = buf + n;
522     if (bufPtr >= bufEnd) {
523         return false;
524     }
525 
526     return true;
527 }
528 
getChars(int nChars,unsigned char * buffer)529 int BaseSeekInputStream::getChars(int nChars, unsigned char *buffer)
530 {
531     int n, m;
532 
533     n = 0;
534     while (n < nChars) {
535         if (bufPtr >= bufEnd) {
536             if (!fillBuf()) {
537                 break;
538             }
539         }
540         m = (int)(bufEnd - bufPtr);
541         if (m > nChars - n) {
542             m = nChars - n;
543         }
544         memcpy(buffer + n, bufPtr, m);
545         bufPtr += m;
546         n += m;
547     }
548     return n;
549 }
550 
551 //------------------------------------------------------------------------
552 // FilterStream
553 //------------------------------------------------------------------------
554 
FilterStream(Stream * strA)555 FilterStream::FilterStream(Stream *strA)
556 {
557     str = strA;
558 }
559 
~FilterStream()560 FilterStream::~FilterStream() { }
561 
close()562 void FilterStream::close()
563 {
564     str->close();
565 }
566 
setPos(Goffset pos,int dir)567 void FilterStream::setPos(Goffset pos, int dir)
568 {
569     error(errInternal, -1, "Internal: called setPos() on FilterStream");
570 }
571 
572 //------------------------------------------------------------------------
573 // ImageStream
574 //------------------------------------------------------------------------
575 
ImageStream(Stream * strA,int widthA,int nCompsA,int nBitsA)576 ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA)
577 {
578     int imgLineSize;
579 
580     str = strA;
581     width = widthA;
582     nComps = nCompsA;
583     nBits = nBitsA;
584 
585     nVals = width * nComps;
586     inputLineSize = (nVals * nBits + 7) >> 3;
587     if (nComps <= 0 || nBits <= 0 || nVals > INT_MAX / nBits - 7 || width > INT_MAX / nComps) {
588         inputLineSize = -1;
589     }
590     inputLine = (unsigned char *)gmallocn_checkoverflow(inputLineSize, sizeof(char));
591     if (nBits == 8) {
592         imgLine = (unsigned char *)inputLine;
593     } else {
594         if (nBits == 1) {
595             imgLineSize = (nVals + 7) & ~7;
596         } else {
597             imgLineSize = nVals;
598         }
599         if (nComps <= 0 || width > INT_MAX / nComps) {
600             imgLineSize = -1;
601         }
602         imgLine = (unsigned char *)gmallocn_checkoverflow(imgLineSize, sizeof(unsigned char));
603     }
604     imgIdx = nVals;
605 }
606 
~ImageStream()607 ImageStream::~ImageStream()
608 {
609     if (imgLine != (unsigned char *)inputLine) {
610         gfree(imgLine);
611     }
612     gfree(inputLine);
613 }
614 
reset()615 void ImageStream::reset()
616 {
617     str->reset();
618 }
619 
close()620 void ImageStream::close()
621 {
622     str->close();
623 }
624 
getPixel(unsigned char * pix)625 bool ImageStream::getPixel(unsigned char *pix)
626 {
627     int i;
628 
629     if (imgIdx >= nVals) {
630         if (!getLine()) {
631             return false;
632         }
633         imgIdx = 0;
634     }
635     for (i = 0; i < nComps; ++i) {
636         pix[i] = imgLine[imgIdx++];
637     }
638     return true;
639 }
640 
getLine()641 unsigned char *ImageStream::getLine()
642 {
643     if (unlikely(inputLine == nullptr)) {
644         return nullptr;
645     }
646 
647     int readChars = str->doGetChars(inputLineSize, inputLine);
648     if (unlikely(readChars == -1)) {
649         readChars = 0;
650     }
651     for (; readChars < inputLineSize; readChars++)
652         inputLine[readChars] = EOF;
653     if (nBits == 1) {
654         unsigned char *p = inputLine;
655         for (int i = 0; i < nVals; i += 8) {
656             const int c = *p++;
657             imgLine[i + 0] = (unsigned char)((c >> 7) & 1);
658             imgLine[i + 1] = (unsigned char)((c >> 6) & 1);
659             imgLine[i + 2] = (unsigned char)((c >> 5) & 1);
660             imgLine[i + 3] = (unsigned char)((c >> 4) & 1);
661             imgLine[i + 4] = (unsigned char)((c >> 3) & 1);
662             imgLine[i + 5] = (unsigned char)((c >> 2) & 1);
663             imgLine[i + 6] = (unsigned char)((c >> 1) & 1);
664             imgLine[i + 7] = (unsigned char)(c & 1);
665         }
666     } else if (nBits == 8) {
667         // special case: imgLine == inputLine
668     } else if (nBits == 16) {
669         // this is a hack to support 16 bits images, everywhere
670         // we assume a component fits in 8 bits, with this hack
671         // we treat 16 bit images as 8 bit ones until it's fixed correctly.
672         // The hack has another part on GfxImageColorMap::GfxImageColorMap
673         unsigned char *p = inputLine;
674         for (int i = 0; i < nVals; ++i) {
675             imgLine[i] = *p++;
676             p++;
677         }
678     } else {
679         const unsigned long bitMask = (1 << nBits) - 1;
680         unsigned long buf = 0;
681         int bits = 0;
682         unsigned char *p = inputLine;
683         for (int i = 0; i < nVals; ++i) {
684             while (bits < nBits) {
685                 buf = (buf << 8) | (*p++ & 0xff);
686                 bits += 8;
687             }
688             imgLine[i] = (unsigned char)((buf >> (bits - nBits)) & bitMask);
689             bits -= nBits;
690         }
691     }
692     return imgLine;
693 }
694 
skipLine()695 void ImageStream::skipLine()
696 {
697     str->doGetChars(inputLineSize, inputLine);
698 }
699 
700 //------------------------------------------------------------------------
701 // StreamPredictor
702 //------------------------------------------------------------------------
703 
StreamPredictor(Stream * strA,int predictorA,int widthA,int nCompsA,int nBitsA)704 StreamPredictor::StreamPredictor(Stream *strA, int predictorA, int widthA, int nCompsA, int nBitsA)
705 {
706     str = strA;
707     predictor = predictorA;
708     width = widthA;
709     nComps = nCompsA;
710     nBits = nBitsA;
711     predLine = nullptr;
712     ok = false;
713 
714     nVals = width * nComps;
715     if (width <= 0 || nComps <= 0 || nBits <= 0 || nComps > gfxColorMaxComps || nBits > 16 || width >= INT_MAX / nComps || // check for overflow in nVals
716         nVals >= (INT_MAX - 7) / nBits) { // check for overflow in rowBytes
717         return;
718     }
719     pixBytes = (nComps * nBits + 7) >> 3;
720     rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes;
721     predLine = (unsigned char *)gmalloc(rowBytes);
722     memset(predLine, 0, rowBytes);
723     predIdx = rowBytes;
724 
725     ok = true;
726 }
727 
~StreamPredictor()728 StreamPredictor::~StreamPredictor()
729 {
730     gfree(predLine);
731 }
732 
lookChar()733 int StreamPredictor::lookChar()
734 {
735     if (predIdx >= rowBytes) {
736         if (!getNextLine()) {
737             return EOF;
738         }
739     }
740     return predLine[predIdx];
741 }
742 
getChar()743 int StreamPredictor::getChar()
744 {
745     if (predIdx >= rowBytes) {
746         if (!getNextLine()) {
747             return EOF;
748         }
749     }
750     return predLine[predIdx++];
751 }
752 
getChars(int nChars,unsigned char * buffer)753 int StreamPredictor::getChars(int nChars, unsigned char *buffer)
754 {
755     int n, m;
756 
757     n = 0;
758     while (n < nChars) {
759         if (predIdx >= rowBytes) {
760             if (!getNextLine()) {
761                 break;
762             }
763         }
764         m = rowBytes - predIdx;
765         if (m > nChars - n) {
766             m = nChars - n;
767         }
768         memcpy(buffer + n, predLine + predIdx, m);
769         predIdx += m;
770         n += m;
771     }
772     return n;
773 }
774 
getNextLine()775 bool StreamPredictor::getNextLine()
776 {
777     int curPred;
778     unsigned char upLeftBuf[gfxColorMaxComps * 2 + 1];
779     int left, up, upLeft, p, pa, pb, pc;
780     int c;
781     unsigned long inBuf, outBuf;
782     int inBits, outBits;
783     int i, j, k, kk;
784 
785     // get PNG optimum predictor number
786     if (predictor >= 10) {
787         if ((curPred = str->getRawChar()) == EOF) {
788             return false;
789         }
790         curPred += 10;
791     } else {
792         curPred = predictor;
793     }
794 
795     // read the raw line, apply PNG (byte) predictor
796     int *rawCharLine = new int[rowBytes - pixBytes];
797     str->getRawChars(rowBytes - pixBytes, rawCharLine);
798     memset(upLeftBuf, 0, pixBytes + 1);
799     for (i = pixBytes; i < rowBytes; ++i) {
800         for (j = pixBytes; j > 0; --j) {
801             upLeftBuf[j] = upLeftBuf[j - 1];
802         }
803         upLeftBuf[0] = predLine[i];
804         if ((c = rawCharLine[i - pixBytes]) == EOF) {
805             if (i > pixBytes) {
806                 // this ought to return false, but some (broken) PDF files
807                 // contain truncated image data, and Adobe apparently reads the
808                 // last partial line
809                 break;
810             }
811             delete[] rawCharLine;
812             return false;
813         }
814         switch (curPred) {
815         case 11: // PNG sub
816             predLine[i] = predLine[i - pixBytes] + (unsigned char)c;
817             break;
818         case 12: // PNG up
819             predLine[i] = predLine[i] + (unsigned char)c;
820             break;
821         case 13: // PNG average
822             predLine[i] = ((predLine[i - pixBytes] + predLine[i]) >> 1) + (unsigned char)c;
823             break;
824         case 14: // PNG Paeth
825             left = predLine[i - pixBytes];
826             up = predLine[i];
827             upLeft = upLeftBuf[pixBytes];
828             p = left + up - upLeft;
829             if ((pa = p - left) < 0)
830                 pa = -pa;
831             if ((pb = p - up) < 0)
832                 pb = -pb;
833             if ((pc = p - upLeft) < 0)
834                 pc = -pc;
835             if (pa <= pb && pa <= pc)
836                 predLine[i] = left + (unsigned char)c;
837             else if (pb <= pc)
838                 predLine[i] = up + (unsigned char)c;
839             else
840                 predLine[i] = upLeft + (unsigned char)c;
841             break;
842         case 10: // PNG none
843         default: // no predictor or TIFF predictor
844             predLine[i] = (unsigned char)c;
845             break;
846         }
847     }
848     delete[] rawCharLine;
849 
850     // apply TIFF (component) predictor
851     if (predictor == 2) {
852         if (nBits == 1 && nComps == 1) {
853             inBuf = predLine[pixBytes - 1];
854             for (i = pixBytes; i < rowBytes; ++i) {
855                 c = predLine[i] ^ inBuf;
856                 c ^= c >> 1;
857                 c ^= c >> 2;
858                 c ^= c >> 4;
859                 inBuf = (c & 1) << 7;
860                 predLine[i] = c;
861             }
862         } else if (nBits == 8) {
863             for (i = pixBytes; i < rowBytes; ++i) {
864                 predLine[i] += predLine[i - nComps];
865             }
866         } else {
867             memset(upLeftBuf, 0, nComps + 1);
868             const unsigned long bitMask = (1 << nBits) - 1;
869             inBuf = outBuf = 0;
870             inBits = outBits = 0;
871             j = k = pixBytes;
872             for (i = 0; i < width; ++i) {
873                 for (kk = 0; kk < nComps; ++kk) {
874                     while (inBits < nBits) {
875                         inBuf = (inBuf << 8) | (predLine[j++] & 0xff);
876                         inBits += 8;
877                     }
878                     upLeftBuf[kk] = (unsigned char)((upLeftBuf[kk] + (inBuf >> (inBits - nBits))) & bitMask);
879                     inBits -= nBits;
880                     outBuf = (outBuf << nBits) | upLeftBuf[kk];
881                     outBits += nBits;
882                     if (outBits >= 8) {
883                         predLine[k++] = (unsigned char)(outBuf >> (outBits - 8));
884                         outBits -= 8;
885                     }
886                 }
887             }
888             if (outBits > 0) {
889                 predLine[k++] = (unsigned char)((outBuf << (8 - outBits)) + (inBuf & ((1 << (8 - outBits)) - 1)));
890             }
891         }
892     }
893 
894     // reset to start of line
895     predIdx = pixBytes;
896 
897     return true;
898 }
899 
900 //------------------------------------------------------------------------
901 // FileStream
902 //------------------------------------------------------------------------
903 
FileStream(GooFile * fileA,Goffset startA,bool limitedA,Goffset lengthA,Object && dictA)904 FileStream::FileStream(GooFile *fileA, Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA) : BaseStream(std::move(dictA), lengthA)
905 {
906     file = fileA;
907     offset = start = startA;
908     limited = limitedA;
909     length = lengthA;
910     bufPtr = bufEnd = buf;
911     bufPos = start;
912     savePos = 0;
913     saved = false;
914     needsEncryptionOnSave = false;
915 }
916 
~FileStream()917 FileStream::~FileStream()
918 {
919     close();
920 }
921 
copy()922 BaseStream *FileStream::copy()
923 {
924     return new FileStream(file, start, limited, length, dict.copy());
925 }
926 
makeSubStream(Goffset startA,bool limitedA,Goffset lengthA,Object && dictA)927 Stream *FileStream::makeSubStream(Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA)
928 {
929     return new FileStream(file, startA, limitedA, lengthA, std::move(dictA));
930 }
931 
reset()932 void FileStream::reset()
933 {
934     savePos = offset;
935     offset = start;
936     saved = true;
937     bufPtr = bufEnd = buf;
938     bufPos = start;
939 }
940 
close()941 void FileStream::close()
942 {
943     if (saved) {
944         offset = savePos;
945         saved = false;
946     }
947 }
948 
fillBuf()949 bool FileStream::fillBuf()
950 {
951     int n;
952 
953     bufPos += bufEnd - buf;
954     bufPtr = bufEnd = buf;
955     if (limited && bufPos >= start + length) {
956         return false;
957     }
958     if (limited && bufPos + fileStreamBufSize > start + length) {
959         n = start + length - bufPos;
960     } else {
961         n = fileStreamBufSize;
962     }
963     n = file->read(buf, n, offset);
964     if (n == -1) {
965         return false;
966     }
967     offset += n;
968     bufEnd = buf + n;
969     if (bufPtr >= bufEnd) {
970         return false;
971     }
972     return true;
973 }
974 
setPos(Goffset pos,int dir)975 void FileStream::setPos(Goffset pos, int dir)
976 {
977     Goffset size;
978 
979     if (dir >= 0) {
980         offset = bufPos = pos;
981     } else {
982         size = file->size();
983         if (pos > size)
984             pos = size;
985         offset = size - pos;
986         bufPos = offset;
987     }
988     bufPtr = bufEnd = buf;
989 }
990 
moveStart(Goffset delta)991 void FileStream::moveStart(Goffset delta)
992 {
993     start += delta;
994     bufPtr = bufEnd = buf;
995     bufPos = start;
996 }
997 
998 //------------------------------------------------------------------------
999 // CachedFileStream
1000 //------------------------------------------------------------------------
1001 
CachedFileStream(CachedFile * ccA,Goffset startA,bool limitedA,Goffset lengthA,Object && dictA)1002 CachedFileStream::CachedFileStream(CachedFile *ccA, Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA) : BaseStream(std::move(dictA), lengthA)
1003 {
1004     cc = ccA;
1005     start = startA;
1006     limited = limitedA;
1007     length = lengthA;
1008     bufPtr = bufEnd = buf;
1009     bufPos = start;
1010     savePos = 0;
1011     saved = false;
1012 }
1013 
~CachedFileStream()1014 CachedFileStream::~CachedFileStream()
1015 {
1016     close();
1017     cc->decRefCnt();
1018 }
1019 
copy()1020 BaseStream *CachedFileStream::copy()
1021 {
1022     cc->incRefCnt();
1023     return new CachedFileStream(cc, start, limited, length, dict.copy());
1024 }
1025 
makeSubStream(Goffset startA,bool limitedA,Goffset lengthA,Object && dictA)1026 Stream *CachedFileStream::makeSubStream(Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA)
1027 {
1028     cc->incRefCnt();
1029     return new CachedFileStream(cc, startA, limitedA, lengthA, std::move(dictA));
1030 }
1031 
reset()1032 void CachedFileStream::reset()
1033 {
1034     savePos = (unsigned int)cc->tell();
1035     cc->seek(start, SEEK_SET);
1036 
1037     saved = true;
1038     bufPtr = bufEnd = buf;
1039     bufPos = start;
1040 }
1041 
close()1042 void CachedFileStream::close()
1043 {
1044     if (saved) {
1045         cc->seek(savePos, SEEK_SET);
1046         saved = false;
1047     }
1048 }
1049 
fillBuf()1050 bool CachedFileStream::fillBuf()
1051 {
1052     int n;
1053 
1054     bufPos += bufEnd - buf;
1055     bufPtr = bufEnd = buf;
1056     if (limited && bufPos >= start + length) {
1057         return false;
1058     }
1059     if (limited && bufPos + cachedStreamBufSize > start + length) {
1060         n = start + length - bufPos;
1061     } else {
1062         n = cachedStreamBufSize - (bufPos % cachedStreamBufSize);
1063     }
1064     n = cc->read(buf, 1, n);
1065     bufEnd = buf + n;
1066     if (bufPtr >= bufEnd) {
1067         return false;
1068     }
1069     return true;
1070 }
1071 
setPos(Goffset pos,int dir)1072 void CachedFileStream::setPos(Goffset pos, int dir)
1073 {
1074     unsigned int size;
1075 
1076     if (dir >= 0) {
1077         cc->seek(pos, SEEK_SET);
1078         bufPos = pos;
1079     } else {
1080         cc->seek(0, SEEK_END);
1081         size = (unsigned int)cc->tell();
1082 
1083         if (pos > size)
1084             pos = (unsigned int)size;
1085 
1086         cc->seek(-(int)pos, SEEK_END);
1087         bufPos = (unsigned int)cc->tell();
1088     }
1089 
1090     bufPtr = bufEnd = buf;
1091 }
1092 
moveStart(Goffset delta)1093 void CachedFileStream::moveStart(Goffset delta)
1094 {
1095     start += delta;
1096     bufPtr = bufEnd = buf;
1097     bufPos = start;
1098 }
1099 
1100 MemStream::~MemStream() = default;
1101 
~AutoFreeMemStream()1102 AutoFreeMemStream::~AutoFreeMemStream()
1103 {
1104     gfree(buf);
1105 }
1106 
isFilterRemovalForbidden() const1107 bool AutoFreeMemStream::isFilterRemovalForbidden() const
1108 {
1109     return filterRemovalForbidden;
1110 }
1111 
setFilterRemovalForbidden(bool forbidden)1112 void AutoFreeMemStream::setFilterRemovalForbidden(bool forbidden)
1113 {
1114     filterRemovalForbidden = forbidden;
1115 }
1116 
1117 //------------------------------------------------------------------------
1118 // EmbedStream
1119 //------------------------------------------------------------------------
1120 
EmbedStream(Stream * strA,Object && dictA,bool limitedA,Goffset lengthA,bool reusableA)1121 EmbedStream::EmbedStream(Stream *strA, Object &&dictA, bool limitedA, Goffset lengthA, bool reusableA) : BaseStream(std::move(dictA), lengthA)
1122 {
1123     str = strA;
1124     limited = limitedA;
1125     length = lengthA;
1126     reusable = reusableA;
1127     record = false;
1128     replay = false;
1129     start = str->getPos();
1130     if (reusable) {
1131         bufData = (unsigned char *)gmalloc(16384);
1132         bufMax = 16384;
1133         bufLen = 0;
1134         record = true;
1135     }
1136 }
1137 
~EmbedStream()1138 EmbedStream::~EmbedStream()
1139 {
1140     if (reusable)
1141         gfree(bufData);
1142 }
1143 
reset()1144 void EmbedStream::reset()
1145 {
1146     if (str->getPos() != start) {
1147         str->reset();
1148         // Might be a FilterStream that does not support str->setPos(start)
1149         while (str->getPos() < start) {
1150             if (str->getChar() == EOF) {
1151                 break;
1152             }
1153         }
1154         if (str->getPos() != start) {
1155             error(errInternal, -1, "Failed to reset EmbedStream");
1156         }
1157     }
1158     record = false;
1159     replay = false;
1160     bufPos = 0;
1161 }
1162 
copy()1163 BaseStream *EmbedStream::copy()
1164 {
1165     error(errInternal, -1, "Called copy() on EmbedStream");
1166     return nullptr;
1167 }
1168 
makeSubStream(Goffset startA,bool limitedA,Goffset lengthA,Object && dictA)1169 Stream *EmbedStream::makeSubStream(Goffset startA, bool limitedA, Goffset lengthA, Object &&dictA)
1170 {
1171     error(errInternal, -1, "Called makeSubStream() on EmbedStream");
1172     return nullptr;
1173 }
1174 
rewind()1175 void EmbedStream::rewind()
1176 {
1177     record = false;
1178     replay = true;
1179     bufPos = 0;
1180 }
1181 
restore()1182 void EmbedStream::restore()
1183 {
1184     replay = false;
1185 }
1186 
getPos()1187 Goffset EmbedStream::getPos()
1188 {
1189     if (replay)
1190         return bufPos;
1191     else
1192         return str->getPos();
1193 }
1194 
getChar()1195 int EmbedStream::getChar()
1196 {
1197     if (replay) {
1198         if (bufPos < bufLen)
1199             return bufData[bufPos++];
1200         else
1201             return EOF;
1202     } else {
1203         if (limited && !length) {
1204             return EOF;
1205         }
1206         int c = str->getChar();
1207         --length;
1208         if (record) {
1209             bufData[bufLen] = c;
1210             bufLen++;
1211             if (bufLen >= bufMax) {
1212                 bufMax *= 2;
1213                 bufData = (unsigned char *)grealloc(bufData, bufMax);
1214             }
1215         }
1216         return c;
1217     }
1218 }
1219 
lookChar()1220 int EmbedStream::lookChar()
1221 {
1222     if (replay) {
1223         if (bufPos < bufLen)
1224             return bufData[bufPos];
1225         else
1226             return EOF;
1227     } else {
1228         if (limited && !length) {
1229             return EOF;
1230         }
1231         return str->lookChar();
1232     }
1233 }
1234 
getChars(int nChars,unsigned char * buffer)1235 int EmbedStream::getChars(int nChars, unsigned char *buffer)
1236 {
1237     int len;
1238 
1239     if (nChars <= 0) {
1240         return 0;
1241     }
1242     if (replay) {
1243         if (bufPos >= bufLen)
1244             return EOF;
1245         len = bufLen - bufPos;
1246         if (nChars > len)
1247             nChars = len;
1248         memcpy(buffer, bufData, nChars);
1249         return len;
1250     } else {
1251         if (limited && length < nChars) {
1252             nChars = length;
1253         }
1254         len = str->doGetChars(nChars, buffer);
1255         if (record) {
1256             if (bufLen + len >= bufMax) {
1257                 while (bufLen + len >= bufMax)
1258                     bufMax *= 2;
1259                 bufData = (unsigned char *)grealloc(bufData, bufMax);
1260             }
1261             memcpy(bufData + bufLen, buffer, len);
1262             bufLen += len;
1263         }
1264     }
1265     return len;
1266 }
1267 
setPos(Goffset pos,int dir)1268 void EmbedStream::setPos(Goffset pos, int dir)
1269 {
1270     error(errInternal, -1, "Internal: called setPos() on EmbedStream");
1271 }
1272 
getStart()1273 Goffset EmbedStream::getStart()
1274 {
1275     error(errInternal, -1, "Internal: called getStart() on EmbedStream");
1276     return 0;
1277 }
1278 
moveStart(Goffset delta)1279 void EmbedStream::moveStart(Goffset delta)
1280 {
1281     error(errInternal, -1, "Internal: called moveStart() on EmbedStream");
1282 }
1283 
1284 //------------------------------------------------------------------------
1285 // ASCIIHexStream
1286 //------------------------------------------------------------------------
1287 
ASCIIHexStream(Stream * strA)1288 ASCIIHexStream::ASCIIHexStream(Stream *strA) : FilterStream(strA)
1289 {
1290     buf = EOF;
1291     eof = false;
1292 }
1293 
~ASCIIHexStream()1294 ASCIIHexStream::~ASCIIHexStream()
1295 {
1296     delete str;
1297 }
1298 
reset()1299 void ASCIIHexStream::reset()
1300 {
1301     str->reset();
1302     buf = EOF;
1303     eof = false;
1304 }
1305 
lookChar()1306 int ASCIIHexStream::lookChar()
1307 {
1308     int c1, c2, x;
1309 
1310     if (buf != EOF)
1311         return buf;
1312     if (eof) {
1313         buf = EOF;
1314         return EOF;
1315     }
1316     do {
1317         c1 = str->getChar();
1318     } while (isspace(c1));
1319     if (c1 == '>') {
1320         eof = true;
1321         buf = EOF;
1322         return buf;
1323     }
1324     do {
1325         c2 = str->getChar();
1326     } while (isspace(c2));
1327     if (c2 == '>') {
1328         eof = true;
1329         c2 = '0';
1330     }
1331     if (c1 >= '0' && c1 <= '9') {
1332         x = (c1 - '0') << 4;
1333     } else if (c1 >= 'A' && c1 <= 'F') {
1334         x = (c1 - 'A' + 10) << 4;
1335     } else if (c1 >= 'a' && c1 <= 'f') {
1336         x = (c1 - 'a' + 10) << 4;
1337     } else if (c1 == EOF) {
1338         eof = true;
1339         x = 0;
1340     } else {
1341         error(errSyntaxError, getPos(), "Illegal character <{0:02x}> in ASCIIHex stream", c1);
1342         x = 0;
1343     }
1344     if (c2 >= '0' && c2 <= '9') {
1345         x += c2 - '0';
1346     } else if (c2 >= 'A' && c2 <= 'F') {
1347         x += c2 - 'A' + 10;
1348     } else if (c2 >= 'a' && c2 <= 'f') {
1349         x += c2 - 'a' + 10;
1350     } else if (c2 == EOF) {
1351         eof = true;
1352         x = 0;
1353     } else {
1354         error(errSyntaxError, getPos(), "Illegal character <{0:02x}> in ASCIIHex stream", c2);
1355     }
1356     buf = x & 0xff;
1357     return buf;
1358 }
1359 
getPSFilter(int psLevel,const char * indent)1360 GooString *ASCIIHexStream::getPSFilter(int psLevel, const char *indent)
1361 {
1362     GooString *s;
1363 
1364     if (psLevel < 2) {
1365         return nullptr;
1366     }
1367     if (!(s = str->getPSFilter(psLevel, indent))) {
1368         return nullptr;
1369     }
1370     s->append(indent)->append("/ASCIIHexDecode filter\n");
1371     return s;
1372 }
1373 
isBinary(bool last) const1374 bool ASCIIHexStream::isBinary(bool last) const
1375 {
1376     return str->isBinary(false);
1377 }
1378 
1379 //------------------------------------------------------------------------
1380 // ASCII85Stream
1381 //------------------------------------------------------------------------
1382 
ASCII85Stream(Stream * strA)1383 ASCII85Stream::ASCII85Stream(Stream *strA) : FilterStream(strA)
1384 {
1385     index = n = 0;
1386     eof = false;
1387 }
1388 
~ASCII85Stream()1389 ASCII85Stream::~ASCII85Stream()
1390 {
1391     delete str;
1392 }
1393 
reset()1394 void ASCII85Stream::reset()
1395 {
1396     str->reset();
1397     index = n = 0;
1398     eof = false;
1399 }
1400 
lookChar()1401 int ASCII85Stream::lookChar()
1402 {
1403     int k;
1404     unsigned long t;
1405 
1406     if (index >= n) {
1407         if (eof)
1408             return EOF;
1409         index = 0;
1410         do {
1411             c[0] = str->getChar();
1412         } while (Lexer::isSpace(c[0]));
1413         if (c[0] == '~' || c[0] == EOF) {
1414             eof = true;
1415             n = 0;
1416             return EOF;
1417         } else if (c[0] == 'z') {
1418             b[0] = b[1] = b[2] = b[3] = 0;
1419             n = 4;
1420         } else {
1421             for (k = 1; k < 5; ++k) {
1422                 do {
1423                     c[k] = str->getChar();
1424                 } while (Lexer::isSpace(c[k]));
1425                 if (c[k] == '~' || c[k] == EOF)
1426                     break;
1427             }
1428             n = k - 1;
1429             if (k < 5 && (c[k] == '~' || c[k] == EOF)) {
1430                 for (++k; k < 5; ++k)
1431                     c[k] = 0x21 + 84;
1432                 eof = true;
1433             }
1434             t = 0;
1435             for (k = 0; k < 5; ++k)
1436                 t = t * 85 + (c[k] - 0x21);
1437             for (k = 3; k >= 0; --k) {
1438                 b[k] = (int)(t & 0xff);
1439                 t >>= 8;
1440             }
1441         }
1442     }
1443     return b[index];
1444 }
1445 
getPSFilter(int psLevel,const char * indent)1446 GooString *ASCII85Stream::getPSFilter(int psLevel, const char *indent)
1447 {
1448     GooString *s;
1449 
1450     if (psLevel < 2) {
1451         return nullptr;
1452     }
1453     if (!(s = str->getPSFilter(psLevel, indent))) {
1454         return nullptr;
1455     }
1456     s->append(indent)->append("/ASCII85Decode filter\n");
1457     return s;
1458 }
1459 
isBinary(bool last) const1460 bool ASCII85Stream::isBinary(bool last) const
1461 {
1462     return str->isBinary(false);
1463 }
1464 
1465 //------------------------------------------------------------------------
1466 // LZWStream
1467 //------------------------------------------------------------------------
1468 
LZWStream(Stream * strA,int predictor,int columns,int colors,int bits,int earlyA)1469 LZWStream::LZWStream(Stream *strA, int predictor, int columns, int colors, int bits, int earlyA) : FilterStream(strA)
1470 {
1471     if (predictor != 1) {
1472         pred = new StreamPredictor(this, predictor, columns, colors, bits);
1473         if (!pred->isOk()) {
1474             delete pred;
1475             pred = nullptr;
1476         }
1477     } else {
1478         pred = nullptr;
1479     }
1480     early = earlyA;
1481     eof = false;
1482     inputBits = 0;
1483     clearTable();
1484 }
1485 
~LZWStream()1486 LZWStream::~LZWStream()
1487 {
1488     if (pred) {
1489         delete pred;
1490     }
1491     delete str;
1492 }
1493 
getChar()1494 int LZWStream::getChar()
1495 {
1496     if (pred) {
1497         return pred->getChar();
1498     }
1499     if (eof) {
1500         return EOF;
1501     }
1502     if (seqIndex >= seqLength) {
1503         if (!processNextCode()) {
1504             return EOF;
1505         }
1506     }
1507     return seqBuf[seqIndex++];
1508 }
1509 
lookChar()1510 int LZWStream::lookChar()
1511 {
1512     if (pred) {
1513         return pred->lookChar();
1514     }
1515     if (eof) {
1516         return EOF;
1517     }
1518     if (seqIndex >= seqLength) {
1519         if (!processNextCode()) {
1520             return EOF;
1521         }
1522     }
1523     return seqBuf[seqIndex];
1524 }
1525 
getRawChars(int nChars,int * buffer)1526 void LZWStream::getRawChars(int nChars, int *buffer)
1527 {
1528     for (int i = 0; i < nChars; ++i)
1529         buffer[i] = doGetRawChar();
1530 }
1531 
getRawChar()1532 int LZWStream::getRawChar()
1533 {
1534     return doGetRawChar();
1535 }
1536 
getChars(int nChars,unsigned char * buffer)1537 int LZWStream::getChars(int nChars, unsigned char *buffer)
1538 {
1539     int n, m;
1540 
1541     if (pred) {
1542         return pred->getChars(nChars, buffer);
1543     }
1544     if (eof) {
1545         return 0;
1546     }
1547     n = 0;
1548     while (n < nChars) {
1549         if (seqIndex >= seqLength) {
1550             if (!processNextCode()) {
1551                 break;
1552             }
1553         }
1554         m = seqLength - seqIndex;
1555         if (m > nChars - n) {
1556             m = nChars - n;
1557         }
1558         memcpy(buffer + n, seqBuf + seqIndex, m);
1559         seqIndex += m;
1560         n += m;
1561     }
1562     return n;
1563 }
1564 
reset()1565 void LZWStream::reset()
1566 {
1567     str->reset();
1568     eof = false;
1569     inputBits = 0;
1570     clearTable();
1571 }
1572 
processNextCode()1573 bool LZWStream::processNextCode()
1574 {
1575     int code;
1576     int nextLength;
1577     int i, j;
1578 
1579     // check for EOF
1580     if (eof) {
1581         return false;
1582     }
1583 
1584     // check for eod and clear-table codes
1585 start:
1586     code = getCode();
1587     if (code == EOF || code == 257) {
1588         eof = true;
1589         return false;
1590     }
1591     if (code == 256) {
1592         clearTable();
1593         goto start;
1594     }
1595 
1596     // process the next code
1597     nextLength = seqLength + 1;
1598     if (code < 256) {
1599         seqBuf[0] = code;
1600         seqLength = 1;
1601     } else if (code < nextCode) {
1602         seqLength = table[code].length;
1603         for (i = seqLength - 1, j = code; i > 0; --i) {
1604             seqBuf[i] = table[j].tail;
1605             j = table[j].head;
1606         }
1607         seqBuf[0] = j;
1608     } else if (code == nextCode) {
1609         seqBuf[seqLength] = newChar;
1610         ++seqLength;
1611     } else {
1612         error(errSyntaxError, getPos(), "Bad LZW stream - unexpected code");
1613         eof = true;
1614         return false;
1615     }
1616     newChar = seqBuf[0];
1617     if (first) {
1618         first = false;
1619     } else {
1620         if (nextCode < 4097) {
1621             table[nextCode].length = nextLength;
1622             table[nextCode].head = prevCode;
1623             table[nextCode].tail = newChar;
1624             ++nextCode;
1625         }
1626         if (nextCode + early == 512)
1627             nextBits = 10;
1628         else if (nextCode + early == 1024)
1629             nextBits = 11;
1630         else if (nextCode + early == 2048)
1631             nextBits = 12;
1632     }
1633     prevCode = code;
1634 
1635     // reset buffer
1636     seqIndex = 0;
1637 
1638     return true;
1639 }
1640 
clearTable()1641 void LZWStream::clearTable()
1642 {
1643     nextCode = 258;
1644     nextBits = 9;
1645     seqIndex = seqLength = 0;
1646     first = true;
1647     newChar = 0;
1648 }
1649 
getCode()1650 int LZWStream::getCode()
1651 {
1652     int c;
1653     int code;
1654 
1655     while (inputBits < nextBits) {
1656         if ((c = str->getChar()) == EOF)
1657             return EOF;
1658         inputBuf = (inputBuf << 8) | static_cast<unsigned>(c & 0xff);
1659         inputBits += 8;
1660     }
1661     code = static_cast<signed>((inputBuf >> (inputBits - nextBits)) & ((1 << nextBits) - 1));
1662     inputBits -= nextBits;
1663     return code;
1664 }
1665 
getPSFilter(int psLevel,const char * indent)1666 GooString *LZWStream::getPSFilter(int psLevel, const char *indent)
1667 {
1668     GooString *s;
1669 
1670     if (psLevel < 2 || pred) {
1671         return nullptr;
1672     }
1673     if (!(s = str->getPSFilter(psLevel, indent))) {
1674         return nullptr;
1675     }
1676     s->append(indent)->append("<< ");
1677     if (!early) {
1678         s->append("/EarlyChange 0 ");
1679     }
1680     s->append(">> /LZWDecode filter\n");
1681     return s;
1682 }
1683 
isBinary(bool last) const1684 bool LZWStream::isBinary(bool last) const
1685 {
1686     return str->isBinary(true);
1687 }
1688 
1689 //------------------------------------------------------------------------
1690 // RunLengthStream
1691 //------------------------------------------------------------------------
1692 
RunLengthStream(Stream * strA)1693 RunLengthStream::RunLengthStream(Stream *strA) : FilterStream(strA)
1694 {
1695     bufPtr = bufEnd = buf;
1696     eof = false;
1697 }
1698 
~RunLengthStream()1699 RunLengthStream::~RunLengthStream()
1700 {
1701     delete str;
1702 }
1703 
reset()1704 void RunLengthStream::reset()
1705 {
1706     str->reset();
1707     bufPtr = bufEnd = buf;
1708     eof = false;
1709 }
1710 
getChars(int nChars,unsigned char * buffer)1711 int RunLengthStream::getChars(int nChars, unsigned char *buffer)
1712 {
1713     int n, m;
1714 
1715     n = 0;
1716     while (n < nChars) {
1717         if (bufPtr >= bufEnd) {
1718             if (!fillBuf()) {
1719                 break;
1720             }
1721         }
1722         m = (int)(bufEnd - bufPtr);
1723         if (m > nChars - n) {
1724             m = nChars - n;
1725         }
1726         memcpy(buffer + n, bufPtr, m);
1727         bufPtr += m;
1728         n += m;
1729     }
1730     return n;
1731 }
1732 
getPSFilter(int psLevel,const char * indent)1733 GooString *RunLengthStream::getPSFilter(int psLevel, const char *indent)
1734 {
1735     GooString *s;
1736 
1737     if (psLevel < 2) {
1738         return nullptr;
1739     }
1740     if (!(s = str->getPSFilter(psLevel, indent))) {
1741         return nullptr;
1742     }
1743     s->append(indent)->append("/RunLengthDecode filter\n");
1744     return s;
1745 }
1746 
isBinary(bool last) const1747 bool RunLengthStream::isBinary(bool last) const
1748 {
1749     return str->isBinary(true);
1750 }
1751 
fillBuf()1752 bool RunLengthStream::fillBuf()
1753 {
1754     int c;
1755     int n, i;
1756 
1757     if (eof)
1758         return false;
1759     c = str->getChar();
1760     if (c == 0x80 || c == EOF) {
1761         eof = true;
1762         return false;
1763     }
1764     if (c < 0x80) {
1765         n = c + 1;
1766         for (i = 0; i < n; ++i)
1767             buf[i] = (char)str->getChar();
1768     } else {
1769         n = 0x101 - c;
1770         c = str->getChar();
1771         for (i = 0; i < n; ++i)
1772             buf[i] = (char)c;
1773     }
1774     bufPtr = buf;
1775     bufEnd = buf + n;
1776     return true;
1777 }
1778 
1779 //------------------------------------------------------------------------
1780 // CCITTFaxStream
1781 //------------------------------------------------------------------------
1782 
CCITTFaxStream(Stream * strA,int encodingA,bool endOfLineA,bool byteAlignA,int columnsA,int rowsA,bool endOfBlockA,bool blackA,int damagedRowsBeforeErrorA)1783 CCITTFaxStream::CCITTFaxStream(Stream *strA, int encodingA, bool endOfLineA, bool byteAlignA, int columnsA, int rowsA, bool endOfBlockA, bool blackA, int damagedRowsBeforeErrorA) : FilterStream(strA)
1784 {
1785     encoding = encodingA;
1786     endOfLine = endOfLineA;
1787     byteAlign = byteAlignA;
1788     columns = columnsA;
1789     damagedRowsBeforeError = damagedRowsBeforeErrorA;
1790     if (columns < 1) {
1791         columns = 1;
1792     } else if (columns > INT_MAX - 2) {
1793         columns = INT_MAX - 2;
1794     }
1795     rows = rowsA;
1796     endOfBlock = endOfBlockA;
1797     black = blackA;
1798     // 0 <= codingLine[0] < codingLine[1] < ... < codingLine[n] = columns
1799     // ---> max codingLine size = columns + 1
1800     // refLine has one extra guard entry at the end
1801     // ---> max refLine size = columns + 2
1802     codingLine = (int *)gmallocn_checkoverflow(columns + 1, sizeof(int));
1803     refLine = (int *)gmallocn_checkoverflow(columns + 2, sizeof(int));
1804 
1805     if (codingLine != nullptr && refLine != nullptr) {
1806         eof = false;
1807         codingLine[0] = columns;
1808     } else {
1809         eof = true;
1810     }
1811     row = 0;
1812     nextLine2D = encoding < 0;
1813     inputBits = 0;
1814     a0i = 0;
1815     outputBits = 0;
1816 
1817     buf = EOF;
1818 }
1819 
~CCITTFaxStream()1820 CCITTFaxStream::~CCITTFaxStream()
1821 {
1822     delete str;
1823     gfree(refLine);
1824     gfree(codingLine);
1825 }
1826 
ccittReset(bool unfiltered)1827 void CCITTFaxStream::ccittReset(bool unfiltered)
1828 {
1829     if (unfiltered)
1830         str->unfilteredReset();
1831     else
1832         str->reset();
1833 
1834     row = 0;
1835     nextLine2D = encoding < 0;
1836     inputBits = 0;
1837     a0i = 0;
1838     outputBits = 0;
1839     buf = EOF;
1840 }
1841 
unfilteredReset()1842 void CCITTFaxStream::unfilteredReset()
1843 {
1844     ccittReset(true);
1845 }
1846 
reset()1847 void CCITTFaxStream::reset()
1848 {
1849     int code1;
1850 
1851     ccittReset(false);
1852 
1853     if (codingLine != nullptr && refLine != nullptr) {
1854         eof = false;
1855         codingLine[0] = columns;
1856     } else {
1857         eof = true;
1858     }
1859 
1860     // skip any initial zero bits and end-of-line marker, and get the 2D
1861     // encoding tag
1862     while ((code1 = lookBits(12)) == 0) {
1863         eatBits(1);
1864     }
1865     if (code1 == 0x001) {
1866         eatBits(12);
1867         endOfLine = true;
1868     }
1869     if (encoding > 0) {
1870         nextLine2D = !lookBits(1);
1871         eatBits(1);
1872     }
1873 }
1874 
addPixels(int a1,int blackPixels)1875 inline void CCITTFaxStream::addPixels(int a1, int blackPixels)
1876 {
1877     if (a1 > codingLine[a0i]) {
1878         if (a1 > columns) {
1879             error(errSyntaxError, getPos(), "CCITTFax row is wrong length ({0:d})", a1);
1880             err = true;
1881             a1 = columns;
1882         }
1883         if ((a0i & 1) ^ blackPixels) {
1884             ++a0i;
1885         }
1886         codingLine[a0i] = a1;
1887     }
1888 }
1889 
addPixelsNeg(int a1,int blackPixels)1890 inline void CCITTFaxStream::addPixelsNeg(int a1, int blackPixels)
1891 {
1892     if (a1 > codingLine[a0i]) {
1893         if (a1 > columns) {
1894             error(errSyntaxError, getPos(), "CCITTFax row is wrong length ({0:d})", a1);
1895             err = true;
1896             a1 = columns;
1897         }
1898         if ((a0i & 1) ^ blackPixels) {
1899             ++a0i;
1900         }
1901         codingLine[a0i] = a1;
1902     } else if (a1 < codingLine[a0i]) {
1903         if (a1 < 0) {
1904             error(errSyntaxError, getPos(), "Invalid CCITTFax code");
1905             err = true;
1906             a1 = columns;
1907         }
1908         while (a0i > 0 && a1 <= codingLine[a0i - 1]) {
1909             --a0i;
1910         }
1911         codingLine[a0i] = a1;
1912     }
1913 }
1914 
lookChar()1915 int CCITTFaxStream::lookChar()
1916 {
1917     int code1, code2, code3;
1918     int b1i, blackPixels, i, bits;
1919     bool gotEOL;
1920 
1921     if (buf != EOF) {
1922         return buf;
1923     }
1924 
1925     // read the next row
1926     if (outputBits == 0) {
1927 
1928         // if at eof just return EOF
1929         if (eof) {
1930             return EOF;
1931         }
1932 
1933         err = false;
1934 
1935         // 2-D encoding
1936         if (nextLine2D) {
1937             for (i = 0; i < columns && codingLine[i] < columns; ++i) {
1938                 refLine[i] = codingLine[i];
1939             }
1940             for (; i < columns + 2; ++i) {
1941                 refLine[i] = columns;
1942             }
1943             codingLine[0] = 0;
1944             a0i = 0;
1945             b1i = 0;
1946             blackPixels = 0;
1947             // invariant:
1948             // refLine[b1i-1] <= codingLine[a0i] < refLine[b1i] < refLine[b1i+1]
1949             //                                                             <= columns
1950             // exception at left edge:
1951             //   codingLine[a0i = 0] = refLine[b1i = 0] = 0 is possible
1952             // exception at right edge:
1953             //   refLine[b1i] = refLine[b1i+1] = columns is possible
1954             while (codingLine[a0i] < columns && !err) {
1955                 code1 = getTwoDimCode();
1956                 switch (code1) {
1957                 case twoDimPass:
1958                     if (likely(b1i + 1 < columns + 2)) {
1959                         addPixels(refLine[b1i + 1], blackPixels);
1960                         if (refLine[b1i + 1] < columns) {
1961                             b1i += 2;
1962                         }
1963                     }
1964                     break;
1965                 case twoDimHoriz:
1966                     code1 = code2 = 0;
1967                     if (blackPixels) {
1968                         do {
1969                             code1 += code3 = getBlackCode();
1970                         } while (code3 >= 64);
1971                         do {
1972                             code2 += code3 = getWhiteCode();
1973                         } while (code3 >= 64);
1974                     } else {
1975                         do {
1976                             code1 += code3 = getWhiteCode();
1977                         } while (code3 >= 64);
1978                         do {
1979                             code2 += code3 = getBlackCode();
1980                         } while (code3 >= 64);
1981                     }
1982                     addPixels(codingLine[a0i] + code1, blackPixels);
1983                     if (codingLine[a0i] < columns) {
1984                         addPixels(codingLine[a0i] + code2, blackPixels ^ 1);
1985                     }
1986                     while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1987                         b1i += 2;
1988                         if (unlikely(b1i > columns + 1)) {
1989                             error(errSyntaxError, getPos(), "Bad 2D code {0:04x} in CCITTFax stream", code1);
1990                             err = true;
1991                             break;
1992                         }
1993                     }
1994                     break;
1995                 case twoDimVertR3:
1996                     if (unlikely(b1i > columns + 1)) {
1997                         error(errSyntaxError, getPos(), "Bad 2D code {0:04x} in CCITTFax stream", code1);
1998                         err = true;
1999                         break;
2000                     }
2001                     addPixels(refLine[b1i] + 3, blackPixels);
2002                     blackPixels ^= 1;
2003                     if (codingLine[a0i] < columns) {
2004                         ++b1i;
2005                         while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
2006                             b1i += 2;
2007                             if (unlikely(b1i > columns + 1)) {
2008                                 error(errSyntaxError, getPos(), "Bad 2D code {0:04x} in CCITTFax stream", code1);
2009                                 err = true;
2010                                 break;
2011                             }
2012                         }
2013                     }
2014                     break;
2015                 case twoDimVertR2:
2016                     if (unlikely(b1i > columns + 1)) {
2017                         error(errSyntaxError, getPos(), "Bad 2D code {0:04x} in CCITTFax stream", code1);
2018                         err = true;
2019                         break;
2020                     }
2021                     addPixels(refLine[b1i] + 2, blackPixels);
2022                     blackPixels ^= 1;
2023                     if (codingLine[a0i] < columns) {
2024                         ++b1i;
2025                         while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
2026                             b1i += 2;
2027                             if (unlikely(b1i > columns + 1)) {
2028                                 error(errSyntaxError, getPos(), "Bad 2D code {0:04x} in CCITTFax stream", code1);
2029                                 err = true;
2030                                 break;
2031                             }
2032                         }
2033                     }
2034                     break;
2035                 case twoDimVertR1:
2036                     if (unlikely(b1i > columns + 1)) {
2037                         error(errSyntaxError, getPos(), "Bad 2D code {0:04x} in CCITTFax stream", code1);
2038                         err = true;
2039                         break;
2040                     }
2041                     addPixels(refLine[b1i] + 1, blackPixels);
2042                     blackPixels ^= 1;
2043                     if (codingLine[a0i] < columns) {
2044                         ++b1i;
2045                         while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
2046                             b1i += 2;
2047                             if (unlikely(b1i > columns + 1)) {
2048                                 error(errSyntaxError, getPos(), "Bad 2D code {0:04x} in CCITTFax stream", code1);
2049                                 err = true;
2050                                 break;
2051                             }
2052                         }
2053                     }
2054                     break;
2055                 case twoDimVert0:
2056                     if (unlikely(b1i > columns + 1)) {
2057                         error(errSyntaxError, getPos(), "Bad 2D code {0:04x} in CCITTFax stream", code1);
2058                         err = true;
2059                         break;
2060                     }
2061                     addPixels(refLine[b1i], blackPixels);
2062                     blackPixels ^= 1;
2063                     if (codingLine[a0i] < columns) {
2064                         ++b1i;
2065                         while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
2066                             b1i += 2;
2067                             if (unlikely(b1i > columns + 1)) {
2068                                 error(errSyntaxError, getPos(), "Bad 2D code {0:04x} in CCITTFax stream", code1);
2069                                 err = true;
2070                                 break;
2071                             }
2072                         }
2073                     }
2074                     break;
2075                 case twoDimVertL3:
2076                     if (unlikely(b1i > columns + 1)) {
2077                         error(errSyntaxError, getPos(), "Bad 2D code {0:04x} in CCITTFax stream", code1);
2078                         err = true;
2079                         break;
2080                     }
2081                     addPixelsNeg(refLine[b1i] - 3, blackPixels);
2082                     blackPixels ^= 1;
2083                     if (codingLine[a0i] < columns) {
2084                         if (b1i > 0) {
2085                             --b1i;
2086                         } else {
2087                             ++b1i;
2088                         }
2089                         while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
2090                             b1i += 2;
2091                             if (unlikely(b1i > columns + 1)) {
2092                                 error(errSyntaxError, getPos(), "Bad 2D code {0:04x} in CCITTFax stream", code1);
2093                                 err = true;
2094                                 break;
2095                             }
2096                         }
2097                     }
2098                     break;
2099                 case twoDimVertL2:
2100                     if (unlikely(b1i > columns + 1)) {
2101                         error(errSyntaxError, getPos(), "Bad 2D code {0:04x} in CCITTFax stream", code1);
2102                         err = true;
2103                         break;
2104                     }
2105                     addPixelsNeg(refLine[b1i] - 2, blackPixels);
2106                     blackPixels ^= 1;
2107                     if (codingLine[a0i] < columns) {
2108                         if (b1i > 0) {
2109                             --b1i;
2110                         } else {
2111                             ++b1i;
2112                         }
2113                         while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
2114                             b1i += 2;
2115                             if (unlikely(b1i > columns + 1)) {
2116                                 error(errSyntaxError, getPos(), "Bad 2D code {0:04x} in CCITTFax stream", code1);
2117                                 err = true;
2118                                 break;
2119                             }
2120                         }
2121                     }
2122                     break;
2123                 case twoDimVertL1:
2124                     if (unlikely(b1i > columns + 1)) {
2125                         error(errSyntaxError, getPos(), "Bad 2D code {0:04x} in CCITTFax stream", code1);
2126                         err = true;
2127                         break;
2128                     }
2129                     addPixelsNeg(refLine[b1i] - 1, blackPixels);
2130                     blackPixels ^= 1;
2131                     if (codingLine[a0i] < columns) {
2132                         if (b1i > 0) {
2133                             --b1i;
2134                         } else {
2135                             ++b1i;
2136                         }
2137                         while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
2138                             b1i += 2;
2139                             if (unlikely(b1i > columns + 1)) {
2140                                 error(errSyntaxError, getPos(), "Bad 2D code {0:04x} in CCITTFax stream", code1);
2141                                 err = true;
2142                                 break;
2143                             }
2144                         }
2145                     }
2146                     break;
2147                 case EOF:
2148                     addPixels(columns, 0);
2149                     eof = true;
2150                     break;
2151                 default:
2152                     error(errSyntaxError, getPos(), "Bad 2D code {0:04x} in CCITTFax stream", code1);
2153                     addPixels(columns, 0);
2154                     err = true;
2155                     break;
2156                 }
2157             }
2158 
2159             // 1-D encoding
2160         } else {
2161             codingLine[0] = 0;
2162             a0i = 0;
2163             blackPixels = 0;
2164             while (codingLine[a0i] < columns) {
2165                 code1 = 0;
2166                 if (blackPixels) {
2167                     do {
2168                         code1 += code3 = getBlackCode();
2169                     } while (code3 >= 64);
2170                 } else {
2171                     do {
2172                         code1 += code3 = getWhiteCode();
2173                     } while (code3 >= 64);
2174                 }
2175                 addPixels(codingLine[a0i] + code1, blackPixels);
2176                 blackPixels ^= 1;
2177             }
2178         }
2179 
2180         // check for end-of-line marker, skipping over any extra zero bits
2181         // (if EncodedByteAlign is true and EndOfLine is false, there can
2182         // be "false" EOL markers -- i.e., if the last n unused bits in
2183         // row i are set to zero, and the first 11-n bits in row i+1
2184         // happen to be zero -- so we don't look for EOL markers in this
2185         // case)
2186         gotEOL = false;
2187         if (!endOfBlock && row == rows - 1) {
2188             eof = true;
2189         } else if (endOfLine || !byteAlign) {
2190             code1 = lookBits(12);
2191             if (endOfLine) {
2192                 while (code1 != EOF && code1 != 0x001) {
2193                     eatBits(1);
2194                     code1 = lookBits(12);
2195                 }
2196             } else {
2197                 while (code1 == 0) {
2198                     eatBits(1);
2199                     code1 = lookBits(12);
2200                 }
2201             }
2202             if (code1 == 0x001) {
2203                 eatBits(12);
2204                 gotEOL = true;
2205             }
2206         }
2207 
2208         // byte-align the row
2209         // (Adobe apparently doesn't do byte alignment after EOL markers
2210         // -- I've seen CCITT image data streams in two different formats,
2211         // both with the byteAlign flag set:
2212         //   1. xx:x0:01:yy:yy
2213         //   2. xx:00:1y:yy:yy
2214         // where xx is the previous line, yy is the next line, and colons
2215         // separate bytes.)
2216         if (byteAlign && !gotEOL) {
2217             inputBits &= ~7;
2218         }
2219 
2220         // check for end of stream
2221         if (lookBits(1) == EOF) {
2222             eof = true;
2223         }
2224 
2225         // get 2D encoding tag
2226         if (!eof && encoding > 0) {
2227             nextLine2D = !lookBits(1);
2228             eatBits(1);
2229         }
2230 
2231         // check for end-of-block marker
2232         if (endOfBlock && !endOfLine && byteAlign) {
2233             // in this case, we didn't check for an EOL code above, so we
2234             // need to check here
2235             code1 = lookBits(24);
2236             if (code1 == 0x001001) {
2237                 eatBits(12);
2238                 gotEOL = true;
2239             }
2240         }
2241         if (endOfBlock && gotEOL) {
2242             code1 = lookBits(12);
2243             if (code1 == 0x001) {
2244                 eatBits(12);
2245                 if (encoding > 0) {
2246                     lookBits(1);
2247                     eatBits(1);
2248                 }
2249                 if (encoding >= 0) {
2250                     for (i = 0; i < 4; ++i) {
2251                         code1 = lookBits(12);
2252                         if (code1 != 0x001) {
2253                             error(errSyntaxError, getPos(), "Bad RTC code in CCITTFax stream");
2254                         }
2255                         eatBits(12);
2256                         if (encoding > 0) {
2257                             lookBits(1);
2258                             eatBits(1);
2259                         }
2260                     }
2261                 }
2262                 eof = true;
2263             }
2264 
2265             // look for an end-of-line marker after an error -- we only do
2266             // this if we know the stream contains end-of-line markers because
2267             // the "just plow on" technique tends to work better otherwise
2268         } else if (err && endOfLine) {
2269             while (true) {
2270                 code1 = lookBits(13);
2271                 if (code1 == EOF) {
2272                     eof = true;
2273                     return EOF;
2274                 }
2275                 if ((code1 >> 1) == 0x001) {
2276                     break;
2277                 }
2278                 eatBits(1);
2279             }
2280             eatBits(12);
2281             if (encoding > 0) {
2282                 eatBits(1);
2283                 nextLine2D = !(code1 & 1);
2284             }
2285         }
2286 
2287         // set up for output
2288         if (codingLine[0] > 0) {
2289             outputBits = codingLine[a0i = 0];
2290         } else {
2291             outputBits = codingLine[a0i = 1];
2292         }
2293 
2294         ++row;
2295     }
2296 
2297     // get a byte
2298     if (outputBits >= 8) {
2299         buf = (a0i & 1) ? 0x00 : 0xff;
2300         outputBits -= 8;
2301         if (outputBits == 0 && codingLine[a0i] < columns) {
2302             ++a0i;
2303             outputBits = codingLine[a0i] - codingLine[a0i - 1];
2304         }
2305     } else {
2306         bits = 8;
2307         buf = 0;
2308         do {
2309             if (outputBits > bits) {
2310                 buf <<= bits;
2311                 if (!(a0i & 1)) {
2312                     buf |= 0xff >> (8 - bits);
2313                 }
2314                 outputBits -= bits;
2315                 bits = 0;
2316             } else {
2317                 buf <<= outputBits;
2318                 if (!(a0i & 1)) {
2319                     buf |= 0xff >> (8 - outputBits);
2320                 }
2321                 bits -= outputBits;
2322                 outputBits = 0;
2323                 if (codingLine[a0i] < columns) {
2324                     ++a0i;
2325                     if (unlikely(a0i > columns)) {
2326                         error(errSyntaxError, getPos(), "Bad bits {0:04x} in CCITTFax stream", bits);
2327                         err = true;
2328                         break;
2329                     }
2330                     outputBits = codingLine[a0i] - codingLine[a0i - 1];
2331                 } else if (bits > 0) {
2332                     buf <<= bits;
2333                     bits = 0;
2334                 }
2335             }
2336         } while (bits);
2337     }
2338     if (black) {
2339         buf ^= 0xff;
2340     }
2341     return buf;
2342 }
2343 
getTwoDimCode()2344 short CCITTFaxStream::getTwoDimCode()
2345 {
2346     int code;
2347     const CCITTCode *p;
2348     int n;
2349 
2350     code = 0; // make gcc happy
2351     if (endOfBlock) {
2352         if ((code = lookBits(7)) != EOF) {
2353             p = &twoDimTab1[code];
2354             if (p->bits > 0) {
2355                 eatBits(p->bits);
2356                 return p->n;
2357             }
2358         }
2359     } else {
2360         for (n = 1; n <= 7; ++n) {
2361             if ((code = lookBits(n)) == EOF) {
2362                 break;
2363             }
2364             if (n < 7) {
2365                 code <<= 7 - n;
2366             }
2367             p = &twoDimTab1[code];
2368             if (p->bits == n) {
2369                 eatBits(n);
2370                 return p->n;
2371             }
2372         }
2373     }
2374     error(errSyntaxError, getPos(), "Bad two dim code ({0:04x}) in CCITTFax stream", code);
2375     return EOF;
2376 }
2377 
getWhiteCode()2378 short CCITTFaxStream::getWhiteCode()
2379 {
2380     short code;
2381     const CCITTCode *p;
2382     int n;
2383 
2384     code = 0; // make gcc happy
2385     if (endOfBlock) {
2386         code = lookBits(12);
2387         if (code == EOF) {
2388             return 1;
2389         }
2390         if ((code >> 5) == 0) {
2391             p = &whiteTab1[code];
2392         } else {
2393             p = &whiteTab2[code >> 3];
2394         }
2395         if (p->bits > 0) {
2396             eatBits(p->bits);
2397             return p->n;
2398         }
2399     } else {
2400         for (n = 1; n <= 9; ++n) {
2401             code = lookBits(n);
2402             if (code == EOF) {
2403                 return 1;
2404             }
2405             if (n < 9) {
2406                 code <<= 9 - n;
2407             }
2408             p = &whiteTab2[code];
2409             if (p->bits == n) {
2410                 eatBits(n);
2411                 return p->n;
2412             }
2413         }
2414         for (n = 11; n <= 12; ++n) {
2415             code = lookBits(n);
2416             if (code == EOF) {
2417                 return 1;
2418             }
2419             if (n < 12) {
2420                 code <<= 12 - n;
2421             }
2422             p = &whiteTab1[code];
2423             if (p->bits == n) {
2424                 eatBits(n);
2425                 return p->n;
2426             }
2427         }
2428     }
2429     error(errSyntaxError, getPos(), "Bad white code ({0:04x}) in CCITTFax stream", code);
2430     // eat a bit and return a positive number so that the caller doesn't
2431     // go into an infinite loop
2432     eatBits(1);
2433     return 1;
2434 }
2435 
getBlackCode()2436 short CCITTFaxStream::getBlackCode()
2437 {
2438     short code;
2439     const CCITTCode *p;
2440     int n;
2441 
2442     code = 0; // make gcc happy
2443     if (endOfBlock) {
2444         code = lookBits(13);
2445         if (code == EOF) {
2446             return 1;
2447         }
2448         if ((code >> 7) == 0) {
2449             p = &blackTab1[code];
2450         } else if ((code >> 9) == 0 && (code >> 7) != 0) {
2451             p = &blackTab2[(code >> 1) - 64];
2452         } else {
2453             p = &blackTab3[code >> 7];
2454         }
2455         if (p->bits > 0) {
2456             eatBits(p->bits);
2457             return p->n;
2458         }
2459     } else {
2460         for (n = 2; n <= 6; ++n) {
2461             code = lookBits(n);
2462             if (code == EOF) {
2463                 return 1;
2464             }
2465             if (n < 6) {
2466                 code <<= 6 - n;
2467             }
2468             p = &blackTab3[code];
2469             if (p->bits == n) {
2470                 eatBits(n);
2471                 return p->n;
2472             }
2473         }
2474         for (n = 7; n <= 12; ++n) {
2475             code = lookBits(n);
2476             if (code == EOF) {
2477                 return 1;
2478             }
2479             if (n < 12) {
2480                 code <<= 12 - n;
2481             }
2482             if (code >= 64) {
2483                 p = &blackTab2[code - 64];
2484                 if (p->bits == n) {
2485                     eatBits(n);
2486                     return p->n;
2487                 }
2488             }
2489         }
2490         for (n = 10; n <= 13; ++n) {
2491             code = lookBits(n);
2492             if (code == EOF) {
2493                 return 1;
2494             }
2495             if (n < 13) {
2496                 code <<= 13 - n;
2497             }
2498             p = &blackTab1[code];
2499             if (p->bits == n) {
2500                 eatBits(n);
2501                 return p->n;
2502             }
2503         }
2504     }
2505     error(errSyntaxError, getPos(), "Bad black code ({0:04x}) in CCITTFax stream", code);
2506     // eat a bit and return a positive number so that the caller doesn't
2507     // go into an infinite loop
2508     eatBits(1);
2509     return 1;
2510 }
2511 
lookBits(int n)2512 short CCITTFaxStream::lookBits(int n)
2513 {
2514     int c;
2515 
2516     while (inputBits < n) {
2517         if ((c = str->getChar()) == EOF) {
2518             if (inputBits == 0) {
2519                 return EOF;
2520             }
2521             // near the end of the stream, the caller may ask for more bits
2522             // than are available, but there may still be a valid code in
2523             // however many bits are available -- we need to return correct
2524             // data in this case
2525             return (inputBuf << (n - inputBits)) & (0xffffffff >> (32 - n));
2526         }
2527         inputBuf = (inputBuf << 8) + c;
2528         inputBits += 8;
2529     }
2530     return (inputBuf >> (inputBits - n)) & (0xffffffff >> (32 - n));
2531 }
2532 
getPSFilter(int psLevel,const char * indent)2533 GooString *CCITTFaxStream::getPSFilter(int psLevel, const char *indent)
2534 {
2535     GooString *s;
2536     char s1[50];
2537 
2538     if (psLevel < 2) {
2539         return nullptr;
2540     }
2541     if (!(s = str->getPSFilter(psLevel, indent))) {
2542         return nullptr;
2543     }
2544     s->append(indent)->append("<< ");
2545     if (encoding != 0) {
2546         sprintf(s1, "/K %d ", encoding);
2547         s->append(s1);
2548     }
2549     if (endOfLine) {
2550         s->append("/EndOfLine true ");
2551     }
2552     if (byteAlign) {
2553         s->append("/EncodedByteAlign true ");
2554     }
2555     sprintf(s1, "/Columns %d ", columns);
2556     s->append(s1);
2557     if (rows != 0) {
2558         sprintf(s1, "/Rows %d ", rows);
2559         s->append(s1);
2560     }
2561     if (!endOfBlock) {
2562         s->append("/EndOfBlock false ");
2563     }
2564     if (black) {
2565         s->append("/BlackIs1 true ");
2566     }
2567     s->append(">> /CCITTFaxDecode filter\n");
2568     return s;
2569 }
2570 
isBinary(bool last) const2571 bool CCITTFaxStream::isBinary(bool last) const
2572 {
2573     return str->isBinary(true);
2574 }
2575 
2576 #ifndef ENABLE_LIBJPEG
2577 
2578 //------------------------------------------------------------------------
2579 // DCTStream
2580 //------------------------------------------------------------------------
2581 
2582 // IDCT constants (20.12 fixed point format)
2583 #    define dctCos1 4017 // cos(pi/16)
2584 #    define dctSin1 799 // sin(pi/16)
2585 #    define dctCos3 3406 // cos(3*pi/16)
2586 #    define dctSin3 2276 // sin(3*pi/16)
2587 #    define dctCos6 1567 // cos(6*pi/16)
2588 #    define dctSin6 3784 // sin(6*pi/16)
2589 #    define dctSqrt2 5793 // sqrt(2)
2590 #    define dctSqrt1d2 2896 // sqrt(2) / 2
2591 
2592 // color conversion parameters (16.16 fixed point format)
2593 #    define dctCrToR 91881 //  1.4020
2594 #    define dctCbToG -22553 // -0.3441363
2595 #    define dctCrToG -46802 // -0.71413636
2596 #    define dctCbToB 116130 //  1.772
2597 
2598 // clip [-256,511] --> [0,255]
2599 #    define dctClipOffset 256
2600 #    define dctClipLength 768
2601 static unsigned char dctClip[dctClipLength];
2602 static int dctClipInit = 0;
2603 
2604 // zig zag decode map
2605 static const int dctZigZag[64] = { 0,  1,  8,  16, 9,  2,  3,  10, 17, 24, 32, 25, 18, 11, 4,  5,  12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6,  7,  14, 21, 28,
2606                                    35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 };
2607 
DCTStream(Stream * strA,int colorXformA,Dict * dict,int recursion)2608 DCTStream::DCTStream(Stream *strA, int colorXformA, Dict *dict, int recursion) : FilterStream(strA)
2609 {
2610     int i, j;
2611 
2612     colorXform = colorXformA;
2613     progressive = interleaved = false;
2614     width = height = 0;
2615     mcuWidth = mcuHeight = 0;
2616     numComps = 0;
2617     comp = 0;
2618     x = y = dy = 0;
2619     for (i = 0; i < 4; ++i) {
2620         for (j = 0; j < 32; ++j) {
2621             rowBuf[i][j] = nullptr;
2622         }
2623         frameBuf[i] = nullptr;
2624     }
2625 
2626     if (!dctClipInit) {
2627         for (i = -256; i < 0; ++i)
2628             dctClip[dctClipOffset + i] = 0;
2629         for (i = 0; i < 256; ++i)
2630             dctClip[dctClipOffset + i] = i;
2631         for (i = 256; i < 512; ++i)
2632             dctClip[dctClipOffset + i] = 255;
2633         dctClipInit = 1;
2634     }
2635 }
2636 
~DCTStream()2637 DCTStream::~DCTStream()
2638 {
2639     close();
2640     delete str;
2641 }
2642 
dctReset(bool unfiltered)2643 void DCTStream::dctReset(bool unfiltered)
2644 {
2645     if (unfiltered)
2646         str->unfilteredReset();
2647     else
2648         str->reset();
2649 
2650     progressive = interleaved = false;
2651     width = height = 0;
2652     numComps = 0;
2653     numQuantTables = 0;
2654     numDCHuffTables = 0;
2655     numACHuffTables = 0;
2656     gotJFIFMarker = false;
2657     gotAdobeMarker = false;
2658     restartInterval = 0;
2659 }
2660 
unfilteredReset()2661 void DCTStream::unfilteredReset()
2662 {
2663     dctReset(true);
2664 }
2665 
reset()2666 void DCTStream::reset()
2667 {
2668     int i, j;
2669 
2670     dctReset(false);
2671 
2672     if (!readHeader()) {
2673         y = height;
2674         return;
2675     }
2676 
2677     // compute MCU size
2678     if (numComps == 1) {
2679         compInfo[0].hSample = compInfo[0].vSample = 1;
2680     }
2681     mcuWidth = compInfo[0].hSample;
2682     mcuHeight = compInfo[0].vSample;
2683     for (i = 1; i < numComps; ++i) {
2684         if (compInfo[i].hSample > mcuWidth) {
2685             mcuWidth = compInfo[i].hSample;
2686         }
2687         if (compInfo[i].vSample > mcuHeight) {
2688             mcuHeight = compInfo[i].vSample;
2689         }
2690     }
2691     mcuWidth *= 8;
2692     mcuHeight *= 8;
2693 
2694     // figure out color transform
2695     if (colorXform == -1) {
2696         if (numComps == 3) {
2697             if (gotJFIFMarker) {
2698                 colorXform = 1;
2699             } else if (compInfo[0].id == 82 && compInfo[1].id == 71 && compInfo[2].id == 66) { // ASCII "RGB"
2700                 colorXform = 0;
2701             } else {
2702                 colorXform = 1;
2703             }
2704         } else {
2705             colorXform = 0;
2706         }
2707     }
2708 
2709     if (progressive || !interleaved) {
2710 
2711         // allocate a buffer for the whole image
2712         bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
2713         bufHeight = ((height + mcuHeight - 1) / mcuHeight) * mcuHeight;
2714         if (bufWidth <= 0 || bufHeight <= 0 || bufWidth > INT_MAX / bufWidth / (int)sizeof(int)) {
2715             error(errSyntaxError, getPos(), "Invalid image size in DCT stream");
2716             y = height;
2717             return;
2718         }
2719         for (i = 0; i < numComps; ++i) {
2720             frameBuf[i] = (int *)gmallocn(bufWidth * bufHeight, sizeof(int));
2721             memset(frameBuf[i], 0, bufWidth * bufHeight * sizeof(int));
2722         }
2723 
2724         // read the image data
2725         do {
2726             restartMarker = 0xd0;
2727             restart();
2728             readScan();
2729         } while (readHeader());
2730 
2731         // decode
2732         decodeImage();
2733 
2734         // initialize counters
2735         comp = 0;
2736         x = 0;
2737         y = 0;
2738 
2739     } else {
2740 
2741         // allocate a buffer for one row of MCUs
2742         bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
2743         for (i = 0; i < numComps; ++i) {
2744             for (j = 0; j < mcuHeight; ++j) {
2745                 rowBuf[i][j] = (unsigned char *)gmallocn(bufWidth, sizeof(unsigned char));
2746             }
2747         }
2748 
2749         // initialize counters
2750         comp = 0;
2751         x = 0;
2752         y = 0;
2753         dy = mcuHeight;
2754 
2755         restartMarker = 0xd0;
2756         restart();
2757     }
2758 }
2759 
close()2760 void DCTStream::close()
2761 {
2762     int i, j;
2763 
2764     for (i = 0; i < 4; ++i) {
2765         for (j = 0; j < 32; ++j) {
2766             gfree(rowBuf[i][j]);
2767             rowBuf[i][j] = nullptr;
2768         }
2769         gfree(frameBuf[i]);
2770         frameBuf[i] = nullptr;
2771     }
2772     FilterStream::close();
2773 }
2774 
getChar()2775 int DCTStream::getChar()
2776 {
2777     int c;
2778 
2779     if (y >= height) {
2780         return EOF;
2781     }
2782     if (progressive || !interleaved) {
2783         c = frameBuf[comp][y * bufWidth + x];
2784         if (++comp == numComps) {
2785             comp = 0;
2786             if (++x == width) {
2787                 x = 0;
2788                 ++y;
2789             }
2790         }
2791     } else {
2792         if (dy >= mcuHeight) {
2793             if (!readMCURow()) {
2794                 y = height;
2795                 return EOF;
2796             }
2797             comp = 0;
2798             x = 0;
2799             dy = 0;
2800         }
2801         c = rowBuf[comp][dy][x];
2802         if (++comp == numComps) {
2803             comp = 0;
2804             if (++x == width) {
2805                 x = 0;
2806                 ++y;
2807                 ++dy;
2808                 if (y == height) {
2809                     readTrailer();
2810                 }
2811             }
2812         }
2813     }
2814     return c;
2815 }
2816 
lookChar()2817 int DCTStream::lookChar()
2818 {
2819     if (y >= height) {
2820         return EOF;
2821     }
2822     if (progressive || !interleaved) {
2823         return frameBuf[comp][y * bufWidth + x];
2824     } else {
2825         if (dy >= mcuHeight) {
2826             if (!readMCURow()) {
2827                 y = height;
2828                 return EOF;
2829             }
2830             comp = 0;
2831             x = 0;
2832             dy = 0;
2833         }
2834         return rowBuf[comp][dy][x];
2835     }
2836 }
2837 
restart()2838 void DCTStream::restart()
2839 {
2840     int i;
2841 
2842     inputBits = 0;
2843     restartCtr = restartInterval;
2844     for (i = 0; i < numComps; ++i) {
2845         compInfo[i].prevDC = 0;
2846     }
2847     eobRun = 0;
2848 }
2849 
2850 // Read one row of MCUs from a sequential JPEG stream.
readMCURow()2851 bool DCTStream::readMCURow()
2852 {
2853     int data1[64];
2854     unsigned char data2[64];
2855     unsigned char *p1, *p2;
2856     int pY, pCb, pCr, pR, pG, pB;
2857     int h, v, horiz, vert, hSub, vSub;
2858     int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
2859     int c;
2860 
2861     for (x1 = 0; x1 < width; x1 += mcuWidth) {
2862 
2863         // deal with restart marker
2864         if (restartInterval > 0 && restartCtr == 0) {
2865             c = readMarker();
2866             if (c != restartMarker) {
2867                 error(errSyntaxError, getPos(), "Bad DCT data: incorrect restart marker");
2868                 return false;
2869             }
2870             if (++restartMarker == 0xd8)
2871                 restartMarker = 0xd0;
2872             restart();
2873         }
2874 
2875         // read one MCU
2876         for (cc = 0; cc < numComps; ++cc) {
2877             h = compInfo[cc].hSample;
2878             v = compInfo[cc].vSample;
2879             horiz = mcuWidth / h;
2880             vert = mcuHeight / v;
2881             hSub = horiz / 8;
2882             vSub = vert / 8;
2883             for (y2 = 0; y2 < mcuHeight; y2 += vert) {
2884                 for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
2885                     if (unlikely(scanInfo.dcHuffTable[cc] >= 4) || unlikely(scanInfo.acHuffTable[cc] >= 4)) {
2886                         return false;
2887                     }
2888                     if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]], &acHuffTables[scanInfo.acHuffTable[cc]], &compInfo[cc].prevDC, data1)) {
2889                         return false;
2890                     }
2891                     transformDataUnit(quantTables[compInfo[cc].quantTable], data1, data2);
2892                     if (hSub == 1 && vSub == 1) {
2893                         for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2894                             p1 = &rowBuf[cc][y2 + y3][x1 + x2];
2895                             p1[0] = data2[i];
2896                             p1[1] = data2[i + 1];
2897                             p1[2] = data2[i + 2];
2898                             p1[3] = data2[i + 3];
2899                             p1[4] = data2[i + 4];
2900                             p1[5] = data2[i + 5];
2901                             p1[6] = data2[i + 6];
2902                             p1[7] = data2[i + 7];
2903                         }
2904                     } else if (hSub == 2 && vSub == 2) {
2905                         for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
2906                             p1 = &rowBuf[cc][y2 + y3][x1 + x2];
2907                             p2 = &rowBuf[cc][y2 + y3 + 1][x1 + x2];
2908                             p1[0] = p1[1] = p2[0] = p2[1] = data2[i];
2909                             p1[2] = p1[3] = p2[2] = p2[3] = data2[i + 1];
2910                             p1[4] = p1[5] = p2[4] = p2[5] = data2[i + 2];
2911                             p1[6] = p1[7] = p2[6] = p2[7] = data2[i + 3];
2912                             p1[8] = p1[9] = p2[8] = p2[9] = data2[i + 4];
2913                             p1[10] = p1[11] = p2[10] = p2[11] = data2[i + 5];
2914                             p1[12] = p1[13] = p2[12] = p2[13] = data2[i + 6];
2915                             p1[14] = p1[15] = p2[14] = p2[15] = data2[i + 7];
2916                         }
2917                     } else {
2918                         i = 0;
2919                         for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
2920                             for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
2921                                 for (y5 = 0; y5 < vSub; ++y5)
2922                                     for (x5 = 0; x5 < hSub; ++x5)
2923                                         rowBuf[cc][y2 + y4 + y5][x1 + x2 + x4 + x5] = data2[i];
2924                                 ++i;
2925                             }
2926                         }
2927                     }
2928                 }
2929             }
2930         }
2931         --restartCtr;
2932 
2933         // color space conversion
2934         if (colorXform) {
2935             // convert YCbCr to RGB
2936             if (numComps == 3) {
2937                 for (y2 = 0; y2 < mcuHeight; ++y2) {
2938                     for (x2 = 0; x2 < mcuWidth; ++x2) {
2939                         pY = rowBuf[0][y2][x1 + x2];
2940                         pCb = rowBuf[1][y2][x1 + x2] - 128;
2941                         pCr = rowBuf[2][y2][x1 + x2] - 128;
2942                         pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2943                         rowBuf[0][y2][x1 + x2] = dctClip[dctClipOffset + pR];
2944                         pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
2945                         rowBuf[1][y2][x1 + x2] = dctClip[dctClipOffset + pG];
2946                         pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2947                         rowBuf[2][y2][x1 + x2] = dctClip[dctClipOffset + pB];
2948                     }
2949                 }
2950                 // convert YCbCrK to CMYK (K is passed through unchanged)
2951             } else if (numComps == 4) {
2952                 for (y2 = 0; y2 < mcuHeight; ++y2) {
2953                     for (x2 = 0; x2 < mcuWidth; ++x2) {
2954                         pY = rowBuf[0][y2][x1 + x2];
2955                         pCb = rowBuf[1][y2][x1 + x2] - 128;
2956                         pCr = rowBuf[2][y2][x1 + x2] - 128;
2957                         pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2958                         rowBuf[0][y2][x1 + x2] = 255 - dctClip[dctClipOffset + pR];
2959                         pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
2960                         rowBuf[1][y2][x1 + x2] = 255 - dctClip[dctClipOffset + pG];
2961                         pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2962                         rowBuf[2][y2][x1 + x2] = 255 - dctClip[dctClipOffset + pB];
2963                     }
2964                 }
2965             }
2966         }
2967     }
2968     return true;
2969 }
2970 
2971 // Read one scan from a progressive or non-interleaved JPEG stream.
readScan()2972 void DCTStream::readScan()
2973 {
2974     int data[64];
2975     int x1, y1, dx1, dy1, x2, y2, y3, cc, i;
2976     int h, v, horiz, vert, vSub;
2977     int *p1;
2978     int c;
2979 
2980     if (scanInfo.numComps == 1) {
2981         for (cc = 0; cc < numComps; ++cc) {
2982             if (scanInfo.comp[cc]) {
2983                 break;
2984             }
2985         }
2986         dx1 = mcuWidth / compInfo[cc].hSample;
2987         dy1 = mcuHeight / compInfo[cc].vSample;
2988     } else {
2989         dx1 = mcuWidth;
2990         dy1 = mcuHeight;
2991     }
2992 
2993     for (y1 = 0; y1 < height; y1 += dy1) {
2994         for (x1 = 0; x1 < width; x1 += dx1) {
2995 
2996             // deal with restart marker
2997             if (restartInterval > 0 && restartCtr == 0) {
2998                 c = readMarker();
2999                 if (c != restartMarker) {
3000                     error(errSyntaxError, getPos(), "Bad DCT data: incorrect restart marker");
3001                     return;
3002                 }
3003                 if (++restartMarker == 0xd8) {
3004                     restartMarker = 0xd0;
3005                 }
3006                 restart();
3007             }
3008 
3009             // read one MCU
3010             for (cc = 0; cc < numComps; ++cc) {
3011                 if (!scanInfo.comp[cc]) {
3012                     continue;
3013                 }
3014 
3015                 h = compInfo[cc].hSample;
3016                 v = compInfo[cc].vSample;
3017                 horiz = mcuWidth / h;
3018                 vert = mcuHeight / v;
3019                 vSub = vert / 8;
3020                 for (y2 = 0; y2 < dy1; y2 += vert) {
3021                     for (x2 = 0; x2 < dx1; x2 += horiz) {
3022 
3023                         // pull out the current values
3024                         p1 = &frameBuf[cc][(y1 + y2) * bufWidth + (x1 + x2)];
3025                         for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3026                             data[i] = p1[0];
3027                             data[i + 1] = p1[1];
3028                             data[i + 2] = p1[2];
3029                             data[i + 3] = p1[3];
3030                             data[i + 4] = p1[4];
3031                             data[i + 5] = p1[5];
3032                             data[i + 6] = p1[6];
3033                             data[i + 7] = p1[7];
3034                             p1 += bufWidth * vSub;
3035                         }
3036 
3037                         // read one data unit
3038                         if (progressive) {
3039                             if (!readProgressiveDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]], &acHuffTables[scanInfo.acHuffTable[cc]], &compInfo[cc].prevDC, data)) {
3040                                 return;
3041                             }
3042                         } else {
3043                             if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]], &acHuffTables[scanInfo.acHuffTable[cc]], &compInfo[cc].prevDC, data)) {
3044                                 return;
3045                             }
3046                         }
3047 
3048                         // add the data unit into frameBuf
3049                         p1 = &frameBuf[cc][(y1 + y2) * bufWidth + (x1 + x2)];
3050                         for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3051                             p1[0] = data[i];
3052                             p1[1] = data[i + 1];
3053                             p1[2] = data[i + 2];
3054                             p1[3] = data[i + 3];
3055                             p1[4] = data[i + 4];
3056                             p1[5] = data[i + 5];
3057                             p1[6] = data[i + 6];
3058                             p1[7] = data[i + 7];
3059                             p1 += bufWidth * vSub;
3060                         }
3061                     }
3062                 }
3063             }
3064             --restartCtr;
3065         }
3066     }
3067 }
3068 
3069 // Read one data unit from a sequential JPEG stream.
readDataUnit(DCTHuffTable * dcHuffTable,DCTHuffTable * acHuffTable,int * prevDC,int data[64])3070 bool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable, int *prevDC, int data[64])
3071 {
3072     int run, size, amp;
3073     int c;
3074     int i, j;
3075 
3076     if ((size = readHuffSym(dcHuffTable)) == 9999) {
3077         return false;
3078     }
3079     if (size > 0) {
3080         if ((amp = readAmp(size)) == 9999) {
3081             return false;
3082         }
3083     } else {
3084         amp = 0;
3085     }
3086     data[0] = *prevDC += amp;
3087     for (i = 1; i < 64; ++i) {
3088         data[i] = 0;
3089     }
3090     i = 1;
3091     while (i < 64) {
3092         run = 0;
3093         while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30) {
3094             run += 0x10;
3095         }
3096         if (c == 9999) {
3097             return false;
3098         }
3099         if (c == 0x00) {
3100             break;
3101         } else {
3102             run += (c >> 4) & 0x0f;
3103             size = c & 0x0f;
3104             amp = readAmp(size);
3105             if (amp == 9999) {
3106                 return false;
3107             }
3108             i += run;
3109             if (i < 64) {
3110                 j = dctZigZag[i++];
3111                 data[j] = amp;
3112             }
3113         }
3114     }
3115     return true;
3116 }
3117 
3118 // Read one data unit from a sequential JPEG stream.
readProgressiveDataUnit(DCTHuffTable * dcHuffTable,DCTHuffTable * acHuffTable,int * prevDC,int data[64])3119 bool DCTStream::readProgressiveDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable, int *prevDC, int data[64])
3120 {
3121     int run, size, amp, bit, c;
3122     int i, j, k;
3123 
3124     // get the DC coefficient
3125     i = scanInfo.firstCoeff;
3126     if (i == 0) {
3127         if (scanInfo.ah == 0) {
3128             if ((size = readHuffSym(dcHuffTable)) == 9999) {
3129                 return false;
3130             }
3131             if (size > 0) {
3132                 if ((amp = readAmp(size)) == 9999) {
3133                     return false;
3134                 }
3135             } else {
3136                 amp = 0;
3137             }
3138             data[0] += (*prevDC += amp) << scanInfo.al;
3139         } else {
3140             if ((bit = readBit()) == 9999) {
3141                 return false;
3142             }
3143             data[0] += bit << scanInfo.al;
3144         }
3145         ++i;
3146     }
3147     if (scanInfo.lastCoeff == 0) {
3148         return true;
3149     }
3150 
3151     // check for an EOB run
3152     if (eobRun > 0) {
3153         while (i <= scanInfo.lastCoeff) {
3154             j = dctZigZag[i++];
3155             if (data[j] != 0) {
3156                 if ((bit = readBit()) == EOF) {
3157                     return false;
3158                 }
3159                 if (bit) {
3160                     data[j] += 1 << scanInfo.al;
3161                 }
3162             }
3163         }
3164         --eobRun;
3165         return true;
3166     }
3167 
3168     // read the AC coefficients
3169     while (i <= scanInfo.lastCoeff) {
3170         if ((c = readHuffSym(acHuffTable)) == 9999) {
3171             return false;
3172         }
3173 
3174         // ZRL
3175         if (c == 0xf0) {
3176             k = 0;
3177             while (k < 16 && i <= scanInfo.lastCoeff) {
3178                 j = dctZigZag[i++];
3179                 if (data[j] == 0) {
3180                     ++k;
3181                 } else {
3182                     if ((bit = readBit()) == EOF) {
3183                         return false;
3184                     }
3185                     if (bit) {
3186                         data[j] += 1 << scanInfo.al;
3187                     }
3188                 }
3189             }
3190 
3191             // EOB run
3192         } else if ((c & 0x0f) == 0x00) {
3193             j = c >> 4;
3194             eobRun = 0;
3195             for (k = 0; k < j; ++k) {
3196                 if ((bit = readBit()) == EOF) {
3197                     return false;
3198                 }
3199                 eobRun = (eobRun << 1) | bit;
3200             }
3201             eobRun += 1 << j;
3202             while (i <= scanInfo.lastCoeff) {
3203                 j = dctZigZag[i++];
3204                 if (data[j] != 0) {
3205                     if ((bit = readBit()) == EOF) {
3206                         return false;
3207                     }
3208                     if (bit) {
3209                         data[j] += 1 << scanInfo.al;
3210                     }
3211                 }
3212             }
3213             --eobRun;
3214             break;
3215 
3216             // zero run and one AC coefficient
3217         } else {
3218             run = (c >> 4) & 0x0f;
3219             size = c & 0x0f;
3220             if ((amp = readAmp(size)) == 9999) {
3221                 return false;
3222             }
3223             j = 0; // make gcc happy
3224             for (k = 0; k <= run && i <= scanInfo.lastCoeff; ++k) {
3225                 j = dctZigZag[i++];
3226                 while (data[j] != 0 && i <= scanInfo.lastCoeff) {
3227                     if ((bit = readBit()) == EOF) {
3228                         return false;
3229                     }
3230                     if (bit) {
3231                         data[j] += 1 << scanInfo.al;
3232                     }
3233                     j = dctZigZag[i++];
3234                 }
3235             }
3236             data[j] = amp << scanInfo.al;
3237         }
3238     }
3239 
3240     return true;
3241 }
3242 
3243 // Decode a progressive JPEG image.
decodeImage()3244 void DCTStream::decodeImage()
3245 {
3246     int dataIn[64];
3247     unsigned char dataOut[64];
3248     unsigned short *quantTable;
3249     int pY, pCb, pCr, pR, pG, pB;
3250     int x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
3251     int h, v, horiz, vert, hSub, vSub;
3252     int *p0, *p1, *p2;
3253 
3254     for (y1 = 0; y1 < bufHeight; y1 += mcuHeight) {
3255         for (x1 = 0; x1 < bufWidth; x1 += mcuWidth) {
3256             for (cc = 0; cc < numComps; ++cc) {
3257                 quantTable = quantTables[compInfo[cc].quantTable];
3258                 h = compInfo[cc].hSample;
3259                 v = compInfo[cc].vSample;
3260                 horiz = mcuWidth / h;
3261                 vert = mcuHeight / v;
3262                 hSub = horiz / 8;
3263                 vSub = vert / 8;
3264                 for (y2 = 0; y2 < mcuHeight; y2 += vert) {
3265                     for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
3266 
3267                         // pull out the coded data unit
3268                         p1 = &frameBuf[cc][(y1 + y2) * bufWidth + (x1 + x2)];
3269                         for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3270                             dataIn[i] = p1[0];
3271                             dataIn[i + 1] = p1[1];
3272                             dataIn[i + 2] = p1[2];
3273                             dataIn[i + 3] = p1[3];
3274                             dataIn[i + 4] = p1[4];
3275                             dataIn[i + 5] = p1[5];
3276                             dataIn[i + 6] = p1[6];
3277                             dataIn[i + 7] = p1[7];
3278                             p1 += bufWidth * vSub;
3279                         }
3280 
3281                         // transform
3282                         transformDataUnit(quantTable, dataIn, dataOut);
3283 
3284                         // store back into frameBuf, doing replication for
3285                         // subsampled components
3286                         p1 = &frameBuf[cc][(y1 + y2) * bufWidth + (x1 + x2)];
3287                         if (hSub == 1 && vSub == 1) {
3288                             for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3289                                 p1[0] = dataOut[i] & 0xff;
3290                                 p1[1] = dataOut[i + 1] & 0xff;
3291                                 p1[2] = dataOut[i + 2] & 0xff;
3292                                 p1[3] = dataOut[i + 3] & 0xff;
3293                                 p1[4] = dataOut[i + 4] & 0xff;
3294                                 p1[5] = dataOut[i + 5] & 0xff;
3295                                 p1[6] = dataOut[i + 6] & 0xff;
3296                                 p1[7] = dataOut[i + 7] & 0xff;
3297                                 p1 += bufWidth;
3298                             }
3299                         } else if (hSub == 2 && vSub == 2) {
3300                             p2 = p1 + bufWidth;
3301                             for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
3302                                 p1[0] = p1[1] = p2[0] = p2[1] = dataOut[i] & 0xff;
3303                                 p1[2] = p1[3] = p2[2] = p2[3] = dataOut[i + 1] & 0xff;
3304                                 p1[4] = p1[5] = p2[4] = p2[5] = dataOut[i + 2] & 0xff;
3305                                 p1[6] = p1[7] = p2[6] = p2[7] = dataOut[i + 3] & 0xff;
3306                                 p1[8] = p1[9] = p2[8] = p2[9] = dataOut[i + 4] & 0xff;
3307                                 p1[10] = p1[11] = p2[10] = p2[11] = dataOut[i + 5] & 0xff;
3308                                 p1[12] = p1[13] = p2[12] = p2[13] = dataOut[i + 6] & 0xff;
3309                                 p1[14] = p1[15] = p2[14] = p2[15] = dataOut[i + 7] & 0xff;
3310                                 p1 += bufWidth * 2;
3311                                 p2 += bufWidth * 2;
3312                             }
3313                         } else {
3314                             i = 0;
3315                             for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
3316                                 for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
3317                                     p2 = p1 + x4;
3318                                     for (y5 = 0; y5 < vSub; ++y5) {
3319                                         for (x5 = 0; x5 < hSub; ++x5) {
3320                                             p2[x5] = dataOut[i] & 0xff;
3321                                         }
3322                                         p2 += bufWidth;
3323                                     }
3324                                     ++i;
3325                                 }
3326                                 p1 += bufWidth * vSub;
3327                             }
3328                         }
3329                     }
3330                 }
3331             }
3332 
3333             // color space conversion
3334             if (colorXform) {
3335                 // convert YCbCr to RGB
3336                 if (numComps == 3) {
3337                     for (y2 = 0; y2 < mcuHeight; ++y2) {
3338                         p0 = &frameBuf[0][(y1 + y2) * bufWidth + x1];
3339                         p1 = &frameBuf[1][(y1 + y2) * bufWidth + x1];
3340                         p2 = &frameBuf[2][(y1 + y2) * bufWidth + x1];
3341                         for (x2 = 0; x2 < mcuWidth; ++x2) {
3342                             pY = *p0;
3343                             pCb = *p1 - 128;
3344                             pCr = *p2 - 128;
3345                             pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
3346                             *p0++ = dctClip[dctClipOffset + pR];
3347                             pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
3348                             *p1++ = dctClip[dctClipOffset + pG];
3349                             pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
3350                             *p2++ = dctClip[dctClipOffset + pB];
3351                         }
3352                     }
3353                     // convert YCbCrK to CMYK (K is passed through unchanged)
3354                 } else if (numComps == 4) {
3355                     for (y2 = 0; y2 < mcuHeight; ++y2) {
3356                         p0 = &frameBuf[0][(y1 + y2) * bufWidth + x1];
3357                         p1 = &frameBuf[1][(y1 + y2) * bufWidth + x1];
3358                         p2 = &frameBuf[2][(y1 + y2) * bufWidth + x1];
3359                         for (x2 = 0; x2 < mcuWidth; ++x2) {
3360                             pY = *p0;
3361                             pCb = *p1 - 128;
3362                             pCr = *p2 - 128;
3363                             pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
3364                             *p0++ = 255 - dctClip[dctClipOffset + pR];
3365                             pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
3366                             *p1++ = 255 - dctClip[dctClipOffset + pG];
3367                             pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
3368                             *p2++ = 255 - dctClip[dctClipOffset + pB];
3369                         }
3370                     }
3371                 }
3372             }
3373         }
3374     }
3375 }
3376 
3377 // Transform one data unit -- this performs the dequantization and
3378 // IDCT steps.  This IDCT algorithm is taken from:
3379 //   Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,
3380 //   "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
3381 //   IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
3382 //   988-991.
3383 // The stage numbers mentioned in the comments refer to Figure 1 in this
3384 // paper.
transformDataUnit(unsigned short * quantTable,int dataIn[64],unsigned char dataOut[64])3385 void DCTStream::transformDataUnit(unsigned short *quantTable, int dataIn[64], unsigned char dataOut[64])
3386 {
3387     int v0, v1, v2, v3, v4, v5, v6, v7, t;
3388     int *p;
3389     int i;
3390 
3391     // dequant
3392     for (i = 0; i < 64; ++i) {
3393         dataIn[i] *= quantTable[i];
3394     }
3395 
3396     // inverse DCT on rows
3397     for (i = 0; i < 64; i += 8) {
3398         p = dataIn + i;
3399 
3400         // check for all-zero AC coefficients
3401         if (p[1] == 0 && p[2] == 0 && p[3] == 0 && p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] == 0) {
3402             t = (dctSqrt2 * p[0] + 512) >> 10;
3403             p[0] = t;
3404             p[1] = t;
3405             p[2] = t;
3406             p[3] = t;
3407             p[4] = t;
3408             p[5] = t;
3409             p[6] = t;
3410             p[7] = t;
3411             continue;
3412         }
3413 
3414         // stage 4
3415         v0 = (dctSqrt2 * p[0] + 128) >> 8;
3416         v1 = (dctSqrt2 * p[4] + 128) >> 8;
3417         v2 = p[2];
3418         v3 = p[6];
3419         v4 = (dctSqrt1d2 * (p[1] - p[7]) + 128) >> 8;
3420         v7 = (dctSqrt1d2 * (p[1] + p[7]) + 128) >> 8;
3421         v5 = p[3] << 4;
3422         v6 = p[5] << 4;
3423 
3424         // stage 3
3425         t = (v0 - v1 + 1) >> 1;
3426         v0 = (v0 + v1 + 1) >> 1;
3427         v1 = t;
3428         t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8;
3429         v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8;
3430         v3 = t;
3431         t = (v4 - v6 + 1) >> 1;
3432         v4 = (v4 + v6 + 1) >> 1;
3433         v6 = t;
3434         t = (v7 + v5 + 1) >> 1;
3435         v5 = (v7 - v5 + 1) >> 1;
3436         v7 = t;
3437 
3438         // stage 2
3439         t = (v0 - v3 + 1) >> 1;
3440         v0 = (v0 + v3 + 1) >> 1;
3441         v3 = t;
3442         t = (v1 - v2 + 1) >> 1;
3443         v1 = (v1 + v2 + 1) >> 1;
3444         v2 = t;
3445         t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
3446         v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
3447         v7 = t;
3448         t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
3449         v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
3450         v6 = t;
3451 
3452         // stage 1
3453         p[0] = v0 + v7;
3454         p[7] = v0 - v7;
3455         p[1] = v1 + v6;
3456         p[6] = v1 - v6;
3457         p[2] = v2 + v5;
3458         p[5] = v2 - v5;
3459         p[3] = v3 + v4;
3460         p[4] = v3 - v4;
3461     }
3462 
3463     // inverse DCT on columns
3464     for (i = 0; i < 8; ++i) {
3465         p = dataIn + i;
3466 
3467         // check for all-zero AC coefficients
3468         if (p[1 * 8] == 0 && p[2 * 8] == 0 && p[3 * 8] == 0 && p[4 * 8] == 0 && p[5 * 8] == 0 && p[6 * 8] == 0 && p[7 * 8] == 0) {
3469             t = (dctSqrt2 * dataIn[i + 0] + 8192) >> 14;
3470             p[0 * 8] = t;
3471             p[1 * 8] = t;
3472             p[2 * 8] = t;
3473             p[3 * 8] = t;
3474             p[4 * 8] = t;
3475             p[5 * 8] = t;
3476             p[6 * 8] = t;
3477             p[7 * 8] = t;
3478             continue;
3479         }
3480 
3481         // stage 4
3482         v0 = (dctSqrt2 * p[0 * 8] + 2048) >> 12;
3483         v1 = (dctSqrt2 * p[4 * 8] + 2048) >> 12;
3484         v2 = p[2 * 8];
3485         v3 = p[6 * 8];
3486         v4 = (dctSqrt1d2 * (p[1 * 8] - p[7 * 8]) + 2048) >> 12;
3487         v7 = (dctSqrt1d2 * (p[1 * 8] + p[7 * 8]) + 2048) >> 12;
3488         v5 = p[3 * 8];
3489         v6 = p[5 * 8];
3490 
3491         // stage 3
3492         t = (v0 - v1 + 1) >> 1;
3493         v0 = (v0 + v1 + 1) >> 1;
3494         v1 = t;
3495         t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12;
3496         v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12;
3497         v3 = t;
3498         t = (v4 - v6 + 1) >> 1;
3499         v4 = (v4 + v6 + 1) >> 1;
3500         v6 = t;
3501         t = (v7 + v5 + 1) >> 1;
3502         v5 = (v7 - v5 + 1) >> 1;
3503         v7 = t;
3504 
3505         // stage 2
3506         t = (v0 - v3 + 1) >> 1;
3507         v0 = (v0 + v3 + 1) >> 1;
3508         v3 = t;
3509         t = (v1 - v2 + 1) >> 1;
3510         v1 = (v1 + v2 + 1) >> 1;
3511         v2 = t;
3512         t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
3513         v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
3514         v7 = t;
3515         t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
3516         v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
3517         v6 = t;
3518 
3519         // stage 1
3520         p[0 * 8] = v0 + v7;
3521         p[7 * 8] = v0 - v7;
3522         p[1 * 8] = v1 + v6;
3523         p[6 * 8] = v1 - v6;
3524         p[2 * 8] = v2 + v5;
3525         p[5 * 8] = v2 - v5;
3526         p[3 * 8] = v3 + v4;
3527         p[4 * 8] = v3 - v4;
3528     }
3529 
3530     // convert to 8-bit integers
3531     for (i = 0; i < 64; ++i) {
3532         const int ix = dctClipOffset + 128 + ((dataIn[i] + 8) >> 4);
3533         if (unlikely(ix < 0 || ix >= dctClipLength)) {
3534             dataOut[i] = 0;
3535         } else {
3536             dataOut[i] = dctClip[ix];
3537         }
3538     }
3539 }
3540 
readHuffSym(DCTHuffTable * table)3541 int DCTStream::readHuffSym(DCTHuffTable *table)
3542 {
3543     unsigned short code;
3544     int bit;
3545     int codeBits;
3546 
3547     code = 0;
3548     codeBits = 0;
3549     do {
3550         // add a bit to the code
3551         if ((bit = readBit()) == EOF) {
3552             return 9999;
3553         }
3554         code = (code << 1) + bit;
3555         ++codeBits;
3556 
3557         // look up code
3558         if (code < table->firstCode[codeBits]) {
3559             break;
3560         }
3561         if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
3562             code -= table->firstCode[codeBits];
3563             return table->sym[table->firstSym[codeBits] + code];
3564         }
3565     } while (codeBits < 16);
3566 
3567     error(errSyntaxError, getPos(), "Bad Huffman code in DCT stream");
3568     return 9999;
3569 }
3570 
readAmp(int size)3571 int DCTStream::readAmp(int size)
3572 {
3573     int amp, bit;
3574     int bits;
3575 
3576     amp = 0;
3577     for (bits = 0; bits < size; ++bits) {
3578         if ((bit = readBit()) == EOF)
3579             return 9999;
3580         amp = (amp << 1) + bit;
3581     }
3582     if (amp < (1 << (size - 1)))
3583         amp -= (1 << size) - 1;
3584     return amp;
3585 }
3586 
readBit()3587 int DCTStream::readBit()
3588 {
3589     int bit;
3590     int c, c2;
3591 
3592     if (inputBits == 0) {
3593         if ((c = str->getChar()) == EOF)
3594             return EOF;
3595         if (c == 0xff) {
3596             do {
3597                 c2 = str->getChar();
3598             } while (c2 == 0xff);
3599             if (c2 != 0x00) {
3600                 error(errSyntaxError, getPos(), "Bad DCT data: missing 00 after ff");
3601                 return EOF;
3602             }
3603         }
3604         inputBuf = c;
3605         inputBits = 8;
3606     }
3607     bit = (inputBuf >> (inputBits - 1)) & 1;
3608     --inputBits;
3609     return bit;
3610 }
3611 
readHeader()3612 bool DCTStream::readHeader()
3613 {
3614     bool doScan;
3615     int n;
3616     int c = 0;
3617     int i;
3618 
3619     // read headers
3620     doScan = false;
3621     while (!doScan) {
3622         c = readMarker();
3623         switch (c) {
3624         case 0xc0: // SOF0 (sequential)
3625         case 0xc1: // SOF1 (extended sequential)
3626             if (!readBaselineSOF()) {
3627                 return false;
3628             }
3629             break;
3630         case 0xc2: // SOF2 (progressive)
3631             if (!readProgressiveSOF()) {
3632                 return false;
3633             }
3634             break;
3635         case 0xc4: // DHT
3636             if (!readHuffmanTables()) {
3637                 return false;
3638             }
3639             break;
3640         case 0xd8: // SOI
3641             break;
3642         case 0xd9: // EOI
3643             return false;
3644         case 0xda: // SOS
3645             if (!readScanInfo()) {
3646                 return false;
3647             }
3648             doScan = true;
3649             break;
3650         case 0xdb: // DQT
3651             if (!readQuantTables()) {
3652                 return false;
3653             }
3654             break;
3655         case 0xdd: // DRI
3656             if (!readRestartInterval()) {
3657                 return false;
3658             }
3659             break;
3660         case 0xe0: // APP0
3661             if (!readJFIFMarker()) {
3662                 return false;
3663             }
3664             break;
3665         case 0xee: // APP14
3666             if (!readAdobeMarker()) {
3667                 return false;
3668             }
3669             break;
3670         case EOF:
3671             error(errSyntaxError, getPos(), "Bad DCT header");
3672             return false;
3673         default:
3674             // skip APPn / COM / etc.
3675             if (c >= 0xe0) {
3676                 n = read16() - 2;
3677                 for (i = 0; i < n; ++i) {
3678                     str->getChar();
3679                 }
3680             } else {
3681                 error(errSyntaxError, getPos(), "Unknown DCT marker <{0:02x}>", c);
3682                 return false;
3683             }
3684             break;
3685         }
3686     }
3687 
3688     return true;
3689 }
3690 
readBaselineSOF()3691 bool DCTStream::readBaselineSOF()
3692 {
3693     int length;
3694     int prec;
3695     int i;
3696     int c;
3697 
3698     length = read16();
3699     prec = str->getChar();
3700     height = read16();
3701     width = read16();
3702     numComps = str->getChar();
3703     if (numComps <= 0 || numComps > 4) {
3704         error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
3705         numComps = 0;
3706         return false;
3707     }
3708     if (prec != 8) {
3709         error(errSyntaxError, getPos(), "Bad DCT precision {0:d}", prec);
3710         return false;
3711     }
3712     for (i = 0; i < numComps; ++i) {
3713         compInfo[i].id = str->getChar();
3714         c = str->getChar();
3715         compInfo[i].hSample = (c >> 4) & 0x0f;
3716         compInfo[i].vSample = c & 0x0f;
3717         compInfo[i].quantTable = str->getChar();
3718         if (compInfo[i].hSample < 1 || compInfo[i].hSample > 4 || compInfo[i].vSample < 1 || compInfo[i].vSample > 4) {
3719             error(errSyntaxError, getPos(), "Bad DCT sampling factor");
3720             return false;
3721         }
3722         if (compInfo[i].quantTable < 0 || compInfo[i].quantTable > 3) {
3723             error(errSyntaxError, getPos(), "Bad DCT quant table selector");
3724             return false;
3725         }
3726     }
3727     progressive = false;
3728     return true;
3729 }
3730 
readProgressiveSOF()3731 bool DCTStream::readProgressiveSOF()
3732 {
3733     int length;
3734     int prec;
3735     int i;
3736     int c;
3737 
3738     length = read16();
3739     prec = str->getChar();
3740     height = read16();
3741     width = read16();
3742     numComps = str->getChar();
3743 
3744     if (numComps <= 0 || numComps > 4) {
3745         error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
3746         numComps = 0;
3747         return false;
3748     }
3749     if (prec != 8) {
3750         error(errSyntaxError, getPos(), "Bad DCT precision {0:d}", prec);
3751         return false;
3752     }
3753     for (i = 0; i < numComps; ++i) {
3754         compInfo[i].id = str->getChar();
3755         c = str->getChar();
3756         compInfo[i].hSample = (c >> 4) & 0x0f;
3757         compInfo[i].vSample = c & 0x0f;
3758         compInfo[i].quantTable = str->getChar();
3759         if (compInfo[i].hSample < 1 || compInfo[i].hSample > 4 || compInfo[i].vSample < 1 || compInfo[i].vSample > 4) {
3760             error(errSyntaxError, getPos(), "Bad DCT sampling factor");
3761             return false;
3762         }
3763         if (compInfo[i].quantTable < 0 || compInfo[i].quantTable > 3) {
3764             error(errSyntaxError, getPos(), "Bad DCT quant table selector");
3765             return false;
3766         }
3767     }
3768     progressive = true;
3769     return true;
3770 }
3771 
readScanInfo()3772 bool DCTStream::readScanInfo()
3773 {
3774     int length;
3775     int id, c;
3776     int i, j;
3777 
3778     length = read16() - 2;
3779     scanInfo.numComps = str->getChar();
3780     if (scanInfo.numComps <= 0 || scanInfo.numComps > 4) {
3781         error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
3782         scanInfo.numComps = 0;
3783         return false;
3784     }
3785     --length;
3786     if (length != 2 * scanInfo.numComps + 3) {
3787         error(errSyntaxError, getPos(), "Bad DCT scan info block");
3788         return false;
3789     }
3790     interleaved = scanInfo.numComps == numComps;
3791     for (j = 0; j < numComps; ++j) {
3792         scanInfo.comp[j] = false;
3793         scanInfo.dcHuffTable[j] = 0;
3794         scanInfo.acHuffTable[j] = 0;
3795     }
3796     for (i = 0; i < scanInfo.numComps; ++i) {
3797         id = str->getChar();
3798         // some (broken) DCT streams reuse ID numbers, but at least they
3799         // keep the components in order, so we check compInfo[i] first to
3800         // work around the problem
3801         if (id == compInfo[i].id) {
3802             j = i;
3803         } else {
3804             for (j = 0; j < numComps; ++j) {
3805                 if (id == compInfo[j].id) {
3806                     break;
3807                 }
3808             }
3809             if (j == numComps) {
3810                 error(errSyntaxError, getPos(), "Bad DCT component ID in scan info block");
3811                 return false;
3812             }
3813         }
3814         scanInfo.comp[j] = true;
3815         c = str->getChar();
3816         scanInfo.dcHuffTable[j] = (c >> 4) & 0x0f;
3817         scanInfo.acHuffTable[j] = c & 0x0f;
3818     }
3819     scanInfo.firstCoeff = str->getChar();
3820     scanInfo.lastCoeff = str->getChar();
3821     if (scanInfo.firstCoeff < 0 || scanInfo.lastCoeff > 63 || scanInfo.firstCoeff > scanInfo.lastCoeff) {
3822         error(errSyntaxError, getPos(), "Bad DCT coefficient numbers in scan info block");
3823         return false;
3824     }
3825     c = str->getChar();
3826     scanInfo.ah = (c >> 4) & 0x0f;
3827     scanInfo.al = c & 0x0f;
3828     return true;
3829 }
3830 
readQuantTables()3831 bool DCTStream::readQuantTables()
3832 {
3833     int length, prec, i, index;
3834 
3835     length = read16() - 2;
3836     while (length > 0) {
3837         index = str->getChar();
3838         prec = (index >> 4) & 0x0f;
3839         index &= 0x0f;
3840         if (prec > 1 || index >= 4) {
3841             error(errSyntaxError, getPos(), "Bad DCT quantization table");
3842             return false;
3843         }
3844         if (index == numQuantTables) {
3845             numQuantTables = index + 1;
3846         }
3847         for (i = 0; i < 64; ++i) {
3848             if (prec) {
3849                 quantTables[index][dctZigZag[i]] = read16();
3850             } else {
3851                 quantTables[index][dctZigZag[i]] = str->getChar();
3852             }
3853         }
3854         if (prec) {
3855             length -= 129;
3856         } else {
3857             length -= 65;
3858         }
3859     }
3860     return true;
3861 }
3862 
readHuffmanTables()3863 bool DCTStream::readHuffmanTables()
3864 {
3865     DCTHuffTable *tbl;
3866     int length;
3867     int index;
3868     unsigned short code;
3869     unsigned char sym;
3870     int i;
3871     int c;
3872 
3873     length = read16() - 2;
3874     while (length > 0) {
3875         index = str->getChar();
3876         --length;
3877         if ((index & 0x0f) >= 4) {
3878             error(errSyntaxError, getPos(), "Bad DCT Huffman table");
3879             return false;
3880         }
3881         if (index & 0x10) {
3882             index &= 0x0f;
3883             if (index >= numACHuffTables)
3884                 numACHuffTables = index + 1;
3885             tbl = &acHuffTables[index];
3886         } else {
3887             index &= 0x0f;
3888             if (index >= numDCHuffTables)
3889                 numDCHuffTables = index + 1;
3890             tbl = &dcHuffTables[index];
3891         }
3892         sym = 0;
3893         code = 0;
3894         for (i = 1; i <= 16; ++i) {
3895             c = str->getChar();
3896             tbl->firstSym[i] = sym;
3897             tbl->firstCode[i] = code;
3898             tbl->numCodes[i] = c;
3899             sym += c;
3900             code = (code + c) << 1;
3901         }
3902         length -= 16;
3903         for (i = 0; i < sym; ++i)
3904             tbl->sym[i] = str->getChar();
3905         length -= sym;
3906     }
3907     return true;
3908 }
3909 
readRestartInterval()3910 bool DCTStream::readRestartInterval()
3911 {
3912     int length;
3913 
3914     length = read16();
3915     if (length != 4) {
3916         error(errSyntaxError, getPos(), "Bad DCT restart interval");
3917         return false;
3918     }
3919     restartInterval = read16();
3920     return true;
3921 }
3922 
readJFIFMarker()3923 bool DCTStream::readJFIFMarker()
3924 {
3925     int length, i;
3926     char buf[5];
3927     int c;
3928 
3929     length = read16();
3930     length -= 2;
3931     if (length >= 5) {
3932         for (i = 0; i < 5; ++i) {
3933             if ((c = str->getChar()) == EOF) {
3934                 error(errSyntaxError, getPos(), "Bad DCT APP0 marker");
3935                 return false;
3936             }
3937             buf[i] = c;
3938         }
3939         length -= 5;
3940         if (!memcmp(buf, "JFIF\0", 5)) {
3941             gotJFIFMarker = true;
3942         }
3943     }
3944     while (length > 0) {
3945         if (str->getChar() == EOF) {
3946             error(errSyntaxError, getPos(), "Bad DCT APP0 marker");
3947             return false;
3948         }
3949         --length;
3950     }
3951     return true;
3952 }
3953 
readAdobeMarker()3954 bool DCTStream::readAdobeMarker()
3955 {
3956     int length, i;
3957     char buf[12];
3958     int c;
3959 
3960     length = read16();
3961     if (length < 14) {
3962         goto err;
3963     }
3964     for (i = 0; i < 12; ++i) {
3965         if ((c = str->getChar()) == EOF) {
3966             goto err;
3967         }
3968         buf[i] = c;
3969     }
3970     if (strncmp(buf, "Adobe", 5)) {
3971         goto err;
3972     }
3973     colorXform = buf[11];
3974     gotAdobeMarker = true;
3975     for (i = 14; i < length; ++i) {
3976         if (str->getChar() == EOF) {
3977             goto err;
3978         }
3979     }
3980     return true;
3981 
3982 err:
3983     error(errSyntaxError, getPos(), "Bad DCT Adobe APP14 marker");
3984     return false;
3985 }
3986 
readTrailer()3987 bool DCTStream::readTrailer()
3988 {
3989     int c;
3990 
3991     c = readMarker();
3992     if (c != 0xd9) { // EOI
3993         error(errSyntaxError, getPos(), "Bad DCT trailer");
3994         return false;
3995     }
3996     return true;
3997 }
3998 
readMarker()3999 int DCTStream::readMarker()
4000 {
4001     int c;
4002 
4003     do {
4004         do {
4005             c = str->getChar();
4006         } while (c != 0xff && c != EOF);
4007         while (c == 0xff) {
4008             c = str->getChar();
4009         }
4010     } while (c == 0x00);
4011     return c;
4012 }
4013 
read16()4014 int DCTStream::read16()
4015 {
4016     int c1, c2;
4017 
4018     if ((c1 = str->getChar()) == EOF)
4019         return EOF;
4020     if ((c2 = str->getChar()) == EOF)
4021         return EOF;
4022     return (c1 << 8) + c2;
4023 }
4024 
getPSFilter(int psLevel,const char * indent)4025 GooString *DCTStream::getPSFilter(int psLevel, const char *indent)
4026 {
4027     GooString *s;
4028 
4029     if (psLevel < 2) {
4030         return nullptr;
4031     }
4032     if (!(s = str->getPSFilter(psLevel, indent))) {
4033         return nullptr;
4034     }
4035     s->append(indent)->append("<< >> /DCTDecode filter\n");
4036     return s;
4037 }
4038 
isBinary(bool last) const4039 bool DCTStream::isBinary(bool last) const
4040 {
4041     return str->isBinary(true);
4042 }
4043 
4044 #endif
4045 
4046 #ifndef ENABLE_ZLIB_UNCOMPRESS
4047 //------------------------------------------------------------------------
4048 // FlateStream
4049 //------------------------------------------------------------------------
4050 
4051 const int FlateStream::codeLenCodeMap[flateMaxCodeLenCodes] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
4052 
4053 const FlateDecode FlateStream::lengthDecode[flateMaxLitCodes - 257] = { { 0, 3 },  { 0, 4 },   { 0, 5 },   { 0, 6 },   { 0, 7 },   { 0, 8 },   { 0, 9 },   { 0, 10 },  { 1, 11 }, { 1, 13 }, { 1, 15 },
4054                                                                         { 1, 17 }, { 2, 19 },  { 2, 23 },  { 2, 27 },  { 2, 31 },  { 3, 35 },  { 3, 43 },  { 3, 51 },  { 3, 59 }, { 4, 67 }, { 4, 83 },
4055                                                                         { 4, 99 }, { 4, 115 }, { 5, 131 }, { 5, 163 }, { 5, 195 }, { 5, 227 }, { 0, 258 }, { 0, 258 }, { 0, 258 } };
4056 
4057 const FlateDecode FlateStream::distDecode[flateMaxDistCodes] = { { 0, 1 },    { 0, 2 },    { 0, 3 },     { 0, 4 },     { 1, 5 },     { 1, 7 },     { 2, 9 },     { 2, 13 },     { 3, 17 },     { 3, 25 },
4058                                                                  { 4, 33 },   { 4, 49 },   { 5, 65 },    { 5, 97 },    { 6, 129 },   { 6, 193 },   { 7, 257 },   { 7, 385 },    { 8, 513 },    { 8, 769 },
4059                                                                  { 9, 1025 }, { 9, 1537 }, { 10, 2049 }, { 10, 3073 }, { 11, 4097 }, { 11, 6145 }, { 12, 8193 }, { 12, 12289 }, { 13, 16385 }, { 13, 24577 } };
4060 
4061 static const FlateCode flateFixedLitCodeTabCodes[512] = {
4062     { 7, 0x0100 }, { 8, 0x0050 }, { 8, 0x0010 }, { 8, 0x0118 }, { 7, 0x0110 }, { 8, 0x0070 }, { 8, 0x0030 }, { 9, 0x00c0 }, { 7, 0x0108 }, { 8, 0x0060 }, { 8, 0x0020 }, { 9, 0x00a0 }, { 8, 0x0000 }, { 8, 0x0080 }, { 8, 0x0040 },
4063     { 9, 0x00e0 }, { 7, 0x0104 }, { 8, 0x0058 }, { 8, 0x0018 }, { 9, 0x0090 }, { 7, 0x0114 }, { 8, 0x0078 }, { 8, 0x0038 }, { 9, 0x00d0 }, { 7, 0x010c }, { 8, 0x0068 }, { 8, 0x0028 }, { 9, 0x00b0 }, { 8, 0x0008 }, { 8, 0x0088 },
4064     { 8, 0x0048 }, { 9, 0x00f0 }, { 7, 0x0102 }, { 8, 0x0054 }, { 8, 0x0014 }, { 8, 0x011c }, { 7, 0x0112 }, { 8, 0x0074 }, { 8, 0x0034 }, { 9, 0x00c8 }, { 7, 0x010a }, { 8, 0x0064 }, { 8, 0x0024 }, { 9, 0x00a8 }, { 8, 0x0004 },
4065     { 8, 0x0084 }, { 8, 0x0044 }, { 9, 0x00e8 }, { 7, 0x0106 }, { 8, 0x005c }, { 8, 0x001c }, { 9, 0x0098 }, { 7, 0x0116 }, { 8, 0x007c }, { 8, 0x003c }, { 9, 0x00d8 }, { 7, 0x010e }, { 8, 0x006c }, { 8, 0x002c }, { 9, 0x00b8 },
4066     { 8, 0x000c }, { 8, 0x008c }, { 8, 0x004c }, { 9, 0x00f8 }, { 7, 0x0101 }, { 8, 0x0052 }, { 8, 0x0012 }, { 8, 0x011a }, { 7, 0x0111 }, { 8, 0x0072 }, { 8, 0x0032 }, { 9, 0x00c4 }, { 7, 0x0109 }, { 8, 0x0062 }, { 8, 0x0022 },
4067     { 9, 0x00a4 }, { 8, 0x0002 }, { 8, 0x0082 }, { 8, 0x0042 }, { 9, 0x00e4 }, { 7, 0x0105 }, { 8, 0x005a }, { 8, 0x001a }, { 9, 0x0094 }, { 7, 0x0115 }, { 8, 0x007a }, { 8, 0x003a }, { 9, 0x00d4 }, { 7, 0x010d }, { 8, 0x006a },
4068     { 8, 0x002a }, { 9, 0x00b4 }, { 8, 0x000a }, { 8, 0x008a }, { 8, 0x004a }, { 9, 0x00f4 }, { 7, 0x0103 }, { 8, 0x0056 }, { 8, 0x0016 }, { 8, 0x011e }, { 7, 0x0113 }, { 8, 0x0076 }, { 8, 0x0036 }, { 9, 0x00cc }, { 7, 0x010b },
4069     { 8, 0x0066 }, { 8, 0x0026 }, { 9, 0x00ac }, { 8, 0x0006 }, { 8, 0x0086 }, { 8, 0x0046 }, { 9, 0x00ec }, { 7, 0x0107 }, { 8, 0x005e }, { 8, 0x001e }, { 9, 0x009c }, { 7, 0x0117 }, { 8, 0x007e }, { 8, 0x003e }, { 9, 0x00dc },
4070     { 7, 0x010f }, { 8, 0x006e }, { 8, 0x002e }, { 9, 0x00bc }, { 8, 0x000e }, { 8, 0x008e }, { 8, 0x004e }, { 9, 0x00fc }, { 7, 0x0100 }, { 8, 0x0051 }, { 8, 0x0011 }, { 8, 0x0119 }, { 7, 0x0110 }, { 8, 0x0071 }, { 8, 0x0031 },
4071     { 9, 0x00c2 }, { 7, 0x0108 }, { 8, 0x0061 }, { 8, 0x0021 }, { 9, 0x00a2 }, { 8, 0x0001 }, { 8, 0x0081 }, { 8, 0x0041 }, { 9, 0x00e2 }, { 7, 0x0104 }, { 8, 0x0059 }, { 8, 0x0019 }, { 9, 0x0092 }, { 7, 0x0114 }, { 8, 0x0079 },
4072     { 8, 0x0039 }, { 9, 0x00d2 }, { 7, 0x010c }, { 8, 0x0069 }, { 8, 0x0029 }, { 9, 0x00b2 }, { 8, 0x0009 }, { 8, 0x0089 }, { 8, 0x0049 }, { 9, 0x00f2 }, { 7, 0x0102 }, { 8, 0x0055 }, { 8, 0x0015 }, { 8, 0x011d }, { 7, 0x0112 },
4073     { 8, 0x0075 }, { 8, 0x0035 }, { 9, 0x00ca }, { 7, 0x010a }, { 8, 0x0065 }, { 8, 0x0025 }, { 9, 0x00aa }, { 8, 0x0005 }, { 8, 0x0085 }, { 8, 0x0045 }, { 9, 0x00ea }, { 7, 0x0106 }, { 8, 0x005d }, { 8, 0x001d }, { 9, 0x009a },
4074     { 7, 0x0116 }, { 8, 0x007d }, { 8, 0x003d }, { 9, 0x00da }, { 7, 0x010e }, { 8, 0x006d }, { 8, 0x002d }, { 9, 0x00ba }, { 8, 0x000d }, { 8, 0x008d }, { 8, 0x004d }, { 9, 0x00fa }, { 7, 0x0101 }, { 8, 0x0053 }, { 8, 0x0013 },
4075     { 8, 0x011b }, { 7, 0x0111 }, { 8, 0x0073 }, { 8, 0x0033 }, { 9, 0x00c6 }, { 7, 0x0109 }, { 8, 0x0063 }, { 8, 0x0023 }, { 9, 0x00a6 }, { 8, 0x0003 }, { 8, 0x0083 }, { 8, 0x0043 }, { 9, 0x00e6 }, { 7, 0x0105 }, { 8, 0x005b },
4076     { 8, 0x001b }, { 9, 0x0096 }, { 7, 0x0115 }, { 8, 0x007b }, { 8, 0x003b }, { 9, 0x00d6 }, { 7, 0x010d }, { 8, 0x006b }, { 8, 0x002b }, { 9, 0x00b6 }, { 8, 0x000b }, { 8, 0x008b }, { 8, 0x004b }, { 9, 0x00f6 }, { 7, 0x0103 },
4077     { 8, 0x0057 }, { 8, 0x0017 }, { 8, 0x011f }, { 7, 0x0113 }, { 8, 0x0077 }, { 8, 0x0037 }, { 9, 0x00ce }, { 7, 0x010b }, { 8, 0x0067 }, { 8, 0x0027 }, { 9, 0x00ae }, { 8, 0x0007 }, { 8, 0x0087 }, { 8, 0x0047 }, { 9, 0x00ee },
4078     { 7, 0x0107 }, { 8, 0x005f }, { 8, 0x001f }, { 9, 0x009e }, { 7, 0x0117 }, { 8, 0x007f }, { 8, 0x003f }, { 9, 0x00de }, { 7, 0x010f }, { 8, 0x006f }, { 8, 0x002f }, { 9, 0x00be }, { 8, 0x000f }, { 8, 0x008f }, { 8, 0x004f },
4079     { 9, 0x00fe }, { 7, 0x0100 }, { 8, 0x0050 }, { 8, 0x0010 }, { 8, 0x0118 }, { 7, 0x0110 }, { 8, 0x0070 }, { 8, 0x0030 }, { 9, 0x00c1 }, { 7, 0x0108 }, { 8, 0x0060 }, { 8, 0x0020 }, { 9, 0x00a1 }, { 8, 0x0000 }, { 8, 0x0080 },
4080     { 8, 0x0040 }, { 9, 0x00e1 }, { 7, 0x0104 }, { 8, 0x0058 }, { 8, 0x0018 }, { 9, 0x0091 }, { 7, 0x0114 }, { 8, 0x0078 }, { 8, 0x0038 }, { 9, 0x00d1 }, { 7, 0x010c }, { 8, 0x0068 }, { 8, 0x0028 }, { 9, 0x00b1 }, { 8, 0x0008 },
4081     { 8, 0x0088 }, { 8, 0x0048 }, { 9, 0x00f1 }, { 7, 0x0102 }, { 8, 0x0054 }, { 8, 0x0014 }, { 8, 0x011c }, { 7, 0x0112 }, { 8, 0x0074 }, { 8, 0x0034 }, { 9, 0x00c9 }, { 7, 0x010a }, { 8, 0x0064 }, { 8, 0x0024 }, { 9, 0x00a9 },
4082     { 8, 0x0004 }, { 8, 0x0084 }, { 8, 0x0044 }, { 9, 0x00e9 }, { 7, 0x0106 }, { 8, 0x005c }, { 8, 0x001c }, { 9, 0x0099 }, { 7, 0x0116 }, { 8, 0x007c }, { 8, 0x003c }, { 9, 0x00d9 }, { 7, 0x010e }, { 8, 0x006c }, { 8, 0x002c },
4083     { 9, 0x00b9 }, { 8, 0x000c }, { 8, 0x008c }, { 8, 0x004c }, { 9, 0x00f9 }, { 7, 0x0101 }, { 8, 0x0052 }, { 8, 0x0012 }, { 8, 0x011a }, { 7, 0x0111 }, { 8, 0x0072 }, { 8, 0x0032 }, { 9, 0x00c5 }, { 7, 0x0109 }, { 8, 0x0062 },
4084     { 8, 0x0022 }, { 9, 0x00a5 }, { 8, 0x0002 }, { 8, 0x0082 }, { 8, 0x0042 }, { 9, 0x00e5 }, { 7, 0x0105 }, { 8, 0x005a }, { 8, 0x001a }, { 9, 0x0095 }, { 7, 0x0115 }, { 8, 0x007a }, { 8, 0x003a }, { 9, 0x00d5 }, { 7, 0x010d },
4085     { 8, 0x006a }, { 8, 0x002a }, { 9, 0x00b5 }, { 8, 0x000a }, { 8, 0x008a }, { 8, 0x004a }, { 9, 0x00f5 }, { 7, 0x0103 }, { 8, 0x0056 }, { 8, 0x0016 }, { 8, 0x011e }, { 7, 0x0113 }, { 8, 0x0076 }, { 8, 0x0036 }, { 9, 0x00cd },
4086     { 7, 0x010b }, { 8, 0x0066 }, { 8, 0x0026 }, { 9, 0x00ad }, { 8, 0x0006 }, { 8, 0x0086 }, { 8, 0x0046 }, { 9, 0x00ed }, { 7, 0x0107 }, { 8, 0x005e }, { 8, 0x001e }, { 9, 0x009d }, { 7, 0x0117 }, { 8, 0x007e }, { 8, 0x003e },
4087     { 9, 0x00dd }, { 7, 0x010f }, { 8, 0x006e }, { 8, 0x002e }, { 9, 0x00bd }, { 8, 0x000e }, { 8, 0x008e }, { 8, 0x004e }, { 9, 0x00fd }, { 7, 0x0100 }, { 8, 0x0051 }, { 8, 0x0011 }, { 8, 0x0119 }, { 7, 0x0110 }, { 8, 0x0071 },
4088     { 8, 0x0031 }, { 9, 0x00c3 }, { 7, 0x0108 }, { 8, 0x0061 }, { 8, 0x0021 }, { 9, 0x00a3 }, { 8, 0x0001 }, { 8, 0x0081 }, { 8, 0x0041 }, { 9, 0x00e3 }, { 7, 0x0104 }, { 8, 0x0059 }, { 8, 0x0019 }, { 9, 0x0093 }, { 7, 0x0114 },
4089     { 8, 0x0079 }, { 8, 0x0039 }, { 9, 0x00d3 }, { 7, 0x010c }, { 8, 0x0069 }, { 8, 0x0029 }, { 9, 0x00b3 }, { 8, 0x0009 }, { 8, 0x0089 }, { 8, 0x0049 }, { 9, 0x00f3 }, { 7, 0x0102 }, { 8, 0x0055 }, { 8, 0x0015 }, { 8, 0x011d },
4090     { 7, 0x0112 }, { 8, 0x0075 }, { 8, 0x0035 }, { 9, 0x00cb }, { 7, 0x010a }, { 8, 0x0065 }, { 8, 0x0025 }, { 9, 0x00ab }, { 8, 0x0005 }, { 8, 0x0085 }, { 8, 0x0045 }, { 9, 0x00eb }, { 7, 0x0106 }, { 8, 0x005d }, { 8, 0x001d },
4091     { 9, 0x009b }, { 7, 0x0116 }, { 8, 0x007d }, { 8, 0x003d }, { 9, 0x00db }, { 7, 0x010e }, { 8, 0x006d }, { 8, 0x002d }, { 9, 0x00bb }, { 8, 0x000d }, { 8, 0x008d }, { 8, 0x004d }, { 9, 0x00fb }, { 7, 0x0101 }, { 8, 0x0053 },
4092     { 8, 0x0013 }, { 8, 0x011b }, { 7, 0x0111 }, { 8, 0x0073 }, { 8, 0x0033 }, { 9, 0x00c7 }, { 7, 0x0109 }, { 8, 0x0063 }, { 8, 0x0023 }, { 9, 0x00a7 }, { 8, 0x0003 }, { 8, 0x0083 }, { 8, 0x0043 }, { 9, 0x00e7 }, { 7, 0x0105 },
4093     { 8, 0x005b }, { 8, 0x001b }, { 9, 0x0097 }, { 7, 0x0115 }, { 8, 0x007b }, { 8, 0x003b }, { 9, 0x00d7 }, { 7, 0x010d }, { 8, 0x006b }, { 8, 0x002b }, { 9, 0x00b7 }, { 8, 0x000b }, { 8, 0x008b }, { 8, 0x004b }, { 9, 0x00f7 },
4094     { 7, 0x0103 }, { 8, 0x0057 }, { 8, 0x0017 }, { 8, 0x011f }, { 7, 0x0113 }, { 8, 0x0077 }, { 8, 0x0037 }, { 9, 0x00cf }, { 7, 0x010b }, { 8, 0x0067 }, { 8, 0x0027 }, { 9, 0x00af }, { 8, 0x0007 }, { 8, 0x0087 }, { 8, 0x0047 },
4095     { 9, 0x00ef }, { 7, 0x0107 }, { 8, 0x005f }, { 8, 0x001f }, { 9, 0x009f }, { 7, 0x0117 }, { 8, 0x007f }, { 8, 0x003f }, { 9, 0x00df }, { 7, 0x010f }, { 8, 0x006f }, { 8, 0x002f }, { 9, 0x00bf }, { 8, 0x000f }, { 8, 0x008f },
4096     { 8, 0x004f }, { 9, 0x00ff }
4097 };
4098 
4099 FlateHuffmanTab FlateStream::fixedLitCodeTab = { flateFixedLitCodeTabCodes, 9 };
4100 
4101 static const FlateCode flateFixedDistCodeTabCodes[32] = { { 5, 0x0000 }, { 5, 0x0010 }, { 5, 0x0008 }, { 5, 0x0018 }, { 5, 0x0004 }, { 5, 0x0014 }, { 5, 0x000c }, { 5, 0x001c }, { 5, 0x0002 }, { 5, 0x0012 }, { 5, 0x000a },
4102                                                           { 5, 0x001a }, { 5, 0x0006 }, { 5, 0x0016 }, { 5, 0x000e }, { 0, 0x0000 }, { 5, 0x0001 }, { 5, 0x0011 }, { 5, 0x0009 }, { 5, 0x0019 }, { 5, 0x0005 }, { 5, 0x0015 },
4103                                                           { 5, 0x000d }, { 5, 0x001d }, { 5, 0x0003 }, { 5, 0x0013 }, { 5, 0x000b }, { 5, 0x001b }, { 5, 0x0007 }, { 5, 0x0017 }, { 5, 0x000f }, { 0, 0x0000 } };
4104 
4105 FlateHuffmanTab FlateStream::fixedDistCodeTab = { flateFixedDistCodeTabCodes, 5 };
4106 
FlateStream(Stream * strA,int predictor,int columns,int colors,int bits)4107 FlateStream::FlateStream(Stream *strA, int predictor, int columns, int colors, int bits) : FilterStream(strA)
4108 {
4109     if (predictor != 1) {
4110         pred = new StreamPredictor(this, predictor, columns, colors, bits);
4111         if (!pred->isOk()) {
4112             delete pred;
4113             pred = nullptr;
4114         }
4115     } else {
4116         pred = nullptr;
4117     }
4118     litCodeTab.codes = nullptr;
4119     distCodeTab.codes = nullptr;
4120     memset(buf, 0, flateWindow);
4121 }
4122 
~FlateStream()4123 FlateStream::~FlateStream()
4124 {
4125     if (litCodeTab.codes != fixedLitCodeTab.codes) {
4126         gfree(const_cast<FlateCode *>(litCodeTab.codes));
4127     }
4128     if (distCodeTab.codes != fixedDistCodeTab.codes) {
4129         gfree(const_cast<FlateCode *>(distCodeTab.codes));
4130     }
4131     if (pred) {
4132         delete pred;
4133     }
4134     delete str;
4135 }
4136 
flateReset(bool unfiltered)4137 void FlateStream::flateReset(bool unfiltered)
4138 {
4139     if (unfiltered)
4140         str->unfilteredReset();
4141     else
4142         str->reset();
4143 
4144     index = 0;
4145     remain = 0;
4146     codeBuf = 0;
4147     codeSize = 0;
4148     compressedBlock = false;
4149     endOfBlock = true;
4150     eof = true;
4151 }
4152 
unfilteredReset()4153 void FlateStream::unfilteredReset()
4154 {
4155     flateReset(true);
4156 }
4157 
reset()4158 void FlateStream::reset()
4159 {
4160     int cmf, flg;
4161 
4162     flateReset(false);
4163 
4164     // read header
4165     //~ need to look at window size?
4166     endOfBlock = eof = true;
4167     cmf = str->getChar();
4168     flg = str->getChar();
4169     if (cmf == EOF || flg == EOF)
4170         return;
4171     if ((cmf & 0x0f) != 0x08) {
4172         error(errSyntaxError, getPos(), "Unknown compression method in flate stream");
4173         return;
4174     }
4175     if ((((cmf << 8) + flg) % 31) != 0) {
4176         error(errSyntaxError, getPos(), "Bad FCHECK in flate stream");
4177         return;
4178     }
4179     if (flg & 0x20) {
4180         error(errSyntaxError, getPos(), "FDICT bit set in flate stream");
4181         return;
4182     }
4183 
4184     eof = false;
4185 }
4186 
getChar()4187 int FlateStream::getChar()
4188 {
4189     if (pred) {
4190         return pred->getChar();
4191     }
4192     return doGetRawChar();
4193 }
4194 
getChars(int nChars,unsigned char * buffer)4195 int FlateStream::getChars(int nChars, unsigned char *buffer)
4196 {
4197     if (pred) {
4198         return pred->getChars(nChars, buffer);
4199     } else {
4200         for (int i = 0; i < nChars; ++i) {
4201             const int c = doGetRawChar();
4202             if (likely(c != EOF))
4203                 buffer[i] = c;
4204             else
4205                 return i;
4206         }
4207         return nChars;
4208     }
4209 }
4210 
lookChar()4211 int FlateStream::lookChar()
4212 {
4213     int c;
4214 
4215     if (pred) {
4216         return pred->lookChar();
4217     }
4218     while (remain == 0) {
4219         if (endOfBlock && eof)
4220             return EOF;
4221         readSome();
4222     }
4223     c = buf[index];
4224     return c;
4225 }
4226 
getRawChars(int nChars,int * buffer)4227 void FlateStream::getRawChars(int nChars, int *buffer)
4228 {
4229     for (int i = 0; i < nChars; ++i)
4230         buffer[i] = doGetRawChar();
4231 }
4232 
getRawChar()4233 int FlateStream::getRawChar()
4234 {
4235     return doGetRawChar();
4236 }
4237 
getPSFilter(int psLevel,const char * indent)4238 GooString *FlateStream::getPSFilter(int psLevel, const char *indent)
4239 {
4240     GooString *s;
4241 
4242     if (psLevel < 3 || pred) {
4243         return nullptr;
4244     }
4245     if (!(s = str->getPSFilter(psLevel, indent))) {
4246         return nullptr;
4247     }
4248     s->append(indent)->append("<< >> /FlateDecode filter\n");
4249     return s;
4250 }
4251 
isBinary(bool last) const4252 bool FlateStream::isBinary(bool last) const
4253 {
4254     return str->isBinary(true);
4255 }
4256 
readSome()4257 void FlateStream::readSome()
4258 {
4259     int code1, code2;
4260     int len, dist;
4261     int i, j, k;
4262     int c;
4263 
4264     if (endOfBlock) {
4265         if (!startBlock())
4266             return;
4267     }
4268 
4269     if (compressedBlock) {
4270         if ((code1 = getHuffmanCodeWord(&litCodeTab)) == EOF)
4271             goto err;
4272         if (code1 < 256) {
4273             buf[index] = code1;
4274             remain = 1;
4275         } else if (code1 == 256) {
4276             endOfBlock = true;
4277             remain = 0;
4278         } else {
4279             code1 -= 257;
4280             code2 = lengthDecode[code1].bits;
4281             if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
4282                 goto err;
4283             len = lengthDecode[code1].first + code2;
4284             if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF)
4285                 goto err;
4286             code2 = distDecode[code1].bits;
4287             if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
4288                 goto err;
4289             dist = distDecode[code1].first + code2;
4290             i = index;
4291             j = (index - dist) & flateMask;
4292             for (k = 0; k < len; ++k) {
4293                 buf[i] = buf[j];
4294                 i = (i + 1) & flateMask;
4295                 j = (j + 1) & flateMask;
4296             }
4297             remain = len;
4298         }
4299 
4300     } else {
4301         len = (blockLen < flateWindow) ? blockLen : flateWindow;
4302         for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) {
4303             if ((c = str->getChar()) == EOF) {
4304                 endOfBlock = eof = true;
4305                 break;
4306             }
4307             buf[j] = c & 0xff;
4308         }
4309         remain = i;
4310         blockLen -= len;
4311         if (blockLen == 0)
4312             endOfBlock = true;
4313     }
4314 
4315     return;
4316 
4317 err:
4318     error(errSyntaxError, getPos(), "Unexpected end of file in flate stream");
4319     endOfBlock = eof = true;
4320     remain = 0;
4321 }
4322 
startBlock()4323 bool FlateStream::startBlock()
4324 {
4325     int blockHdr;
4326     int c;
4327     int check;
4328 
4329     // free the code tables from the previous block
4330     if (litCodeTab.codes != fixedLitCodeTab.codes) {
4331         gfree(const_cast<FlateCode *>(litCodeTab.codes));
4332     }
4333     litCodeTab.codes = nullptr;
4334     if (distCodeTab.codes != fixedDistCodeTab.codes) {
4335         gfree(const_cast<FlateCode *>(distCodeTab.codes));
4336     }
4337     distCodeTab.codes = nullptr;
4338 
4339     // read block header
4340     blockHdr = getCodeWord(3);
4341     if (blockHdr & 1)
4342         eof = true;
4343     blockHdr >>= 1;
4344 
4345     // uncompressed block
4346     if (blockHdr == 0) {
4347         compressedBlock = false;
4348         if ((c = str->getChar()) == EOF)
4349             goto err;
4350         blockLen = c & 0xff;
4351         if ((c = str->getChar()) == EOF)
4352             goto err;
4353         blockLen |= (c & 0xff) << 8;
4354         if ((c = str->getChar()) == EOF)
4355             goto err;
4356         check = c & 0xff;
4357         if ((c = str->getChar()) == EOF)
4358             goto err;
4359         check |= (c & 0xff) << 8;
4360         if (check != (~blockLen & 0xffff))
4361             error(errSyntaxError, getPos(), "Bad uncompressed block length in flate stream");
4362         codeBuf = 0;
4363         codeSize = 0;
4364 
4365         // compressed block with fixed codes
4366     } else if (blockHdr == 1) {
4367         compressedBlock = true;
4368         loadFixedCodes();
4369 
4370         // compressed block with dynamic codes
4371     } else if (blockHdr == 2) {
4372         compressedBlock = true;
4373         if (!readDynamicCodes()) {
4374             goto err;
4375         }
4376 
4377         // unknown block type
4378     } else {
4379         goto err;
4380     }
4381 
4382     endOfBlock = false;
4383     return true;
4384 
4385 err:
4386     error(errSyntaxError, getPos(), "Bad block header in flate stream");
4387     endOfBlock = eof = true;
4388     return false;
4389 }
4390 
loadFixedCodes()4391 void FlateStream::loadFixedCodes()
4392 {
4393     litCodeTab.codes = fixedLitCodeTab.codes;
4394     litCodeTab.maxLen = fixedLitCodeTab.maxLen;
4395     distCodeTab.codes = fixedDistCodeTab.codes;
4396     distCodeTab.maxLen = fixedDistCodeTab.maxLen;
4397 }
4398 
readDynamicCodes()4399 bool FlateStream::readDynamicCodes()
4400 {
4401     int numCodeLenCodes;
4402     int numLitCodes;
4403     int numDistCodes;
4404     int codeLenCodeLengths[flateMaxCodeLenCodes];
4405     FlateHuffmanTab codeLenCodeTab;
4406     int len, repeat, code;
4407     int i;
4408 
4409     codeLenCodeTab.codes = nullptr;
4410 
4411     // read lengths
4412     if ((numLitCodes = getCodeWord(5)) == EOF) {
4413         goto err;
4414     }
4415     numLitCodes += 257;
4416     if ((numDistCodes = getCodeWord(5)) == EOF) {
4417         goto err;
4418     }
4419     numDistCodes += 1;
4420     if ((numCodeLenCodes = getCodeWord(4)) == EOF) {
4421         goto err;
4422     }
4423     numCodeLenCodes += 4;
4424     if (numLitCodes > flateMaxLitCodes || numDistCodes > flateMaxDistCodes || numCodeLenCodes > flateMaxCodeLenCodes) {
4425         goto err;
4426     }
4427 
4428     // build the code length code table
4429     for (i = 0; i < flateMaxCodeLenCodes; ++i) {
4430         codeLenCodeLengths[i] = 0;
4431     }
4432     for (i = 0; i < numCodeLenCodes; ++i) {
4433         if ((codeLenCodeLengths[codeLenCodeMap[i]] = getCodeWord(3)) == -1) {
4434             goto err;
4435         }
4436     }
4437     codeLenCodeTab.codes = compHuffmanCodes(codeLenCodeLengths, flateMaxCodeLenCodes, &codeLenCodeTab.maxLen);
4438 
4439     // build the literal and distance code tables
4440     len = 0;
4441     repeat = 0;
4442     i = 0;
4443     while (i < numLitCodes + numDistCodes) {
4444         if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF) {
4445             goto err;
4446         }
4447         if (code == 16) {
4448             if ((repeat = getCodeWord(2)) == EOF) {
4449                 goto err;
4450             }
4451             repeat += 3;
4452             if (i + repeat > numLitCodes + numDistCodes) {
4453                 goto err;
4454             }
4455             for (; repeat > 0; --repeat) {
4456                 codeLengths[i++] = len;
4457             }
4458         } else if (code == 17) {
4459             if ((repeat = getCodeWord(3)) == EOF) {
4460                 goto err;
4461             }
4462             repeat += 3;
4463             if (i + repeat > numLitCodes + numDistCodes) {
4464                 goto err;
4465             }
4466             len = 0;
4467             for (; repeat > 0; --repeat) {
4468                 codeLengths[i++] = 0;
4469             }
4470         } else if (code == 18) {
4471             if ((repeat = getCodeWord(7)) == EOF) {
4472                 goto err;
4473             }
4474             repeat += 11;
4475             if (i + repeat > numLitCodes + numDistCodes) {
4476                 goto err;
4477             }
4478             len = 0;
4479             for (; repeat > 0; --repeat) {
4480                 codeLengths[i++] = 0;
4481             }
4482         } else {
4483             codeLengths[i++] = len = code;
4484         }
4485     }
4486     litCodeTab.codes = compHuffmanCodes(codeLengths, numLitCodes, &litCodeTab.maxLen);
4487     distCodeTab.codes = compHuffmanCodes(codeLengths + numLitCodes, numDistCodes, &distCodeTab.maxLen);
4488 
4489     gfree(const_cast<FlateCode *>(codeLenCodeTab.codes));
4490     return true;
4491 
4492 err:
4493     error(errSyntaxError, getPos(), "Bad dynamic code table in flate stream");
4494     gfree(const_cast<FlateCode *>(codeLenCodeTab.codes));
4495     return false;
4496 }
4497 
4498 // Convert an array <lengths> of <n> lengths, in value order, into a
4499 // Huffman code lookup table.
compHuffmanCodes(const int * lengths,int n,int * maxLen)4500 FlateCode *FlateStream::compHuffmanCodes(const int *lengths, int n, int *maxLen)
4501 {
4502     int len, code, code2, skip, val, i, t;
4503 
4504     // find max code length
4505     *maxLen = 0;
4506     for (val = 0; val < n; ++val) {
4507         if (lengths[val] > *maxLen) {
4508             *maxLen = lengths[val];
4509         }
4510     }
4511 
4512     // allocate the table
4513     const int tabSize = 1 << *maxLen;
4514     FlateCode *codes = (FlateCode *)gmallocn(tabSize, sizeof(FlateCode));
4515 
4516     // clear the table
4517     for (i = 0; i < tabSize; ++i) {
4518         codes[i].len = 0;
4519         codes[i].val = 0;
4520     }
4521 
4522     // build the table
4523     for (len = 1, code = 0, skip = 2; len <= *maxLen; ++len, code <<= 1, skip <<= 1) {
4524         for (val = 0; val < n; ++val) {
4525             if (lengths[val] == len) {
4526 
4527                 // bit-reverse the code
4528                 code2 = 0;
4529                 t = code;
4530                 for (i = 0; i < len; ++i) {
4531                     code2 = (code2 << 1) | (t & 1);
4532                     t >>= 1;
4533                 }
4534 
4535                 // fill in the table entries
4536                 for (i = code2; i < tabSize; i += skip) {
4537                     codes[i].len = (unsigned short)len;
4538                     codes[i].val = (unsigned short)val;
4539                 }
4540 
4541                 ++code;
4542             }
4543         }
4544     }
4545 
4546     return codes;
4547 }
4548 
getHuffmanCodeWord(FlateHuffmanTab * tab)4549 int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab)
4550 {
4551     const FlateCode *code;
4552     int c;
4553 
4554     while (codeSize < tab->maxLen) {
4555         if ((c = str->getChar()) == EOF) {
4556             break;
4557         }
4558         codeBuf |= (c & 0xff) << codeSize;
4559         codeSize += 8;
4560     }
4561     code = &tab->codes[codeBuf & ((1 << tab->maxLen) - 1)];
4562     if (codeSize == 0 || codeSize < code->len || code->len == 0) {
4563         return EOF;
4564     }
4565     codeBuf >>= code->len;
4566     codeSize -= code->len;
4567     return (int)code->val;
4568 }
4569 
getCodeWord(int bits)4570 int FlateStream::getCodeWord(int bits)
4571 {
4572     int c;
4573 
4574     while (codeSize < bits) {
4575         if ((c = str->getChar()) == EOF)
4576             return EOF;
4577         codeBuf |= (c & 0xff) << codeSize;
4578         codeSize += 8;
4579     }
4580     c = codeBuf & ((1 << bits) - 1);
4581     codeBuf >>= bits;
4582     codeSize -= bits;
4583     return c;
4584 }
4585 #endif
4586 
4587 //------------------------------------------------------------------------
4588 // EOFStream
4589 //------------------------------------------------------------------------
4590 
EOFStream(Stream * strA)4591 EOFStream::EOFStream(Stream *strA) : FilterStream(strA) { }
4592 
~EOFStream()4593 EOFStream::~EOFStream()
4594 {
4595     delete str;
4596 }
4597 
4598 //------------------------------------------------------------------------
4599 // BufStream
4600 //------------------------------------------------------------------------
4601 
BufStream(Stream * strA,int bufSizeA)4602 BufStream::BufStream(Stream *strA, int bufSizeA) : FilterStream(strA)
4603 {
4604     bufSize = bufSizeA;
4605     buf = (int *)gmallocn(bufSize, sizeof(int));
4606 }
4607 
~BufStream()4608 BufStream::~BufStream()
4609 {
4610     gfree(buf);
4611     delete str;
4612 }
4613 
reset()4614 void BufStream::reset()
4615 {
4616     int i;
4617 
4618     str->reset();
4619     for (i = 0; i < bufSize; ++i) {
4620         buf[i] = str->getChar();
4621     }
4622 }
4623 
getChar()4624 int BufStream::getChar()
4625 {
4626     int c, i;
4627 
4628     c = buf[0];
4629     for (i = 1; i < bufSize; ++i) {
4630         buf[i - 1] = buf[i];
4631     }
4632     buf[bufSize - 1] = str->getChar();
4633     return c;
4634 }
4635 
lookChar()4636 int BufStream::lookChar()
4637 {
4638     return buf[0];
4639 }
4640 
lookChar(int idx)4641 int BufStream::lookChar(int idx)
4642 {
4643     return buf[idx];
4644 }
4645 
isBinary(bool last) const4646 bool BufStream::isBinary(bool last) const
4647 {
4648     return str->isBinary(true);
4649 }
4650 
4651 //------------------------------------------------------------------------
4652 // FixedLengthEncoder
4653 //------------------------------------------------------------------------
4654 
FixedLengthEncoder(Stream * strA,int lengthA)4655 FixedLengthEncoder::FixedLengthEncoder(Stream *strA, int lengthA) : FilterStream(strA)
4656 {
4657     length = lengthA;
4658     count = 0;
4659 }
4660 
~FixedLengthEncoder()4661 FixedLengthEncoder::~FixedLengthEncoder()
4662 {
4663     if (str->isEncoder())
4664         delete str;
4665 }
4666 
reset()4667 void FixedLengthEncoder::reset()
4668 {
4669     str->reset();
4670     count = 0;
4671 }
4672 
getChar()4673 int FixedLengthEncoder::getChar()
4674 {
4675     if (length >= 0 && count >= length)
4676         return EOF;
4677     ++count;
4678     return str->getChar();
4679 }
4680 
lookChar()4681 int FixedLengthEncoder::lookChar()
4682 {
4683     if (length >= 0 && count >= length)
4684         return EOF;
4685     return str->getChar();
4686 }
4687 
isBinary(bool last) const4688 bool FixedLengthEncoder::isBinary(bool last) const
4689 {
4690     return str->isBinary(true);
4691 }
4692 
4693 //------------------------------------------------------------------------
4694 // ASCIIHexEncoder
4695 //------------------------------------------------------------------------
4696 
ASCIIHexEncoder(Stream * strA)4697 ASCIIHexEncoder::ASCIIHexEncoder(Stream *strA) : FilterStream(strA)
4698 {
4699     bufPtr = bufEnd = buf;
4700     lineLen = 0;
4701     eof = false;
4702 }
4703 
~ASCIIHexEncoder()4704 ASCIIHexEncoder::~ASCIIHexEncoder()
4705 {
4706     if (str->isEncoder()) {
4707         delete str;
4708     }
4709 }
4710 
reset()4711 void ASCIIHexEncoder::reset()
4712 {
4713     str->reset();
4714     bufPtr = bufEnd = buf;
4715     lineLen = 0;
4716     eof = false;
4717 }
4718 
fillBuf()4719 bool ASCIIHexEncoder::fillBuf()
4720 {
4721     static const char *hex = "0123456789abcdef";
4722     int c;
4723 
4724     if (eof) {
4725         return false;
4726     }
4727     bufPtr = bufEnd = buf;
4728     if ((c = str->getChar()) == EOF) {
4729         *bufEnd++ = '>';
4730         eof = true;
4731     } else {
4732         if (lineLen >= 64) {
4733             *bufEnd++ = '\n';
4734             lineLen = 0;
4735         }
4736         *bufEnd++ = hex[(c >> 4) & 0x0f];
4737         *bufEnd++ = hex[c & 0x0f];
4738         lineLen += 2;
4739     }
4740     return true;
4741 }
4742 
4743 //------------------------------------------------------------------------
4744 // ASCII85Encoder
4745 //------------------------------------------------------------------------
4746 
ASCII85Encoder(Stream * strA)4747 ASCII85Encoder::ASCII85Encoder(Stream *strA) : FilterStream(strA)
4748 {
4749     bufPtr = bufEnd = buf;
4750     lineLen = 0;
4751     eof = false;
4752 }
4753 
~ASCII85Encoder()4754 ASCII85Encoder::~ASCII85Encoder()
4755 {
4756     if (str->isEncoder())
4757         delete str;
4758 }
4759 
reset()4760 void ASCII85Encoder::reset()
4761 {
4762     str->reset();
4763     bufPtr = bufEnd = buf;
4764     lineLen = 0;
4765     eof = false;
4766 }
4767 
fillBuf()4768 bool ASCII85Encoder::fillBuf()
4769 {
4770     unsigned int t;
4771     char buf1[5];
4772     int c0, c1, c2, c3;
4773     int n, i;
4774 
4775     if (eof) {
4776         return false;
4777     }
4778     c0 = str->getChar();
4779     c1 = str->getChar();
4780     c2 = str->getChar();
4781     c3 = str->getChar();
4782     bufPtr = bufEnd = buf;
4783     if (c3 == EOF) {
4784         if (c0 == EOF) {
4785             n = 0;
4786             t = 0;
4787         } else {
4788             if (c1 == EOF) {
4789                 n = 1;
4790                 t = c0 << 24;
4791             } else if (c2 == EOF) {
4792                 n = 2;
4793                 t = (c0 << 24) | (c1 << 16);
4794             } else {
4795                 n = 3;
4796                 t = (c0 << 24) | (c1 << 16) | (c2 << 8);
4797             }
4798             for (i = 4; i >= 0; --i) {
4799                 buf1[i] = (char)(t % 85 + 0x21);
4800                 t /= 85;
4801             }
4802             for (i = 0; i <= n; ++i) {
4803                 *bufEnd++ = buf1[i];
4804                 if (++lineLen == 65) {
4805                     *bufEnd++ = '\n';
4806                     lineLen = 0;
4807                 }
4808             }
4809         }
4810         *bufEnd++ = '~';
4811         *bufEnd++ = '>';
4812         eof = true;
4813     } else {
4814         t = (c0 << 24) | (c1 << 16) | (c2 << 8) | c3;
4815         if (t == 0) {
4816             *bufEnd++ = 'z';
4817             if (++lineLen == 65) {
4818                 *bufEnd++ = '\n';
4819                 lineLen = 0;
4820             }
4821         } else {
4822             for (i = 4; i >= 0; --i) {
4823                 buf1[i] = (char)(t % 85 + 0x21);
4824                 t /= 85;
4825             }
4826             for (i = 0; i <= 4; ++i) {
4827                 *bufEnd++ = buf1[i];
4828                 if (++lineLen == 65) {
4829                     *bufEnd++ = '\n';
4830                     lineLen = 0;
4831                 }
4832             }
4833         }
4834     }
4835     return true;
4836 }
4837 
4838 //------------------------------------------------------------------------
4839 // RunLengthEncoder
4840 //------------------------------------------------------------------------
4841 
RunLengthEncoder(Stream * strA)4842 RunLengthEncoder::RunLengthEncoder(Stream *strA) : FilterStream(strA)
4843 {
4844     bufPtr = bufEnd = nextEnd = buf;
4845     eof = false;
4846 }
4847 
~RunLengthEncoder()4848 RunLengthEncoder::~RunLengthEncoder()
4849 {
4850     if (str->isEncoder())
4851         delete str;
4852 }
4853 
reset()4854 void RunLengthEncoder::reset()
4855 {
4856     str->reset();
4857     bufPtr = bufEnd = nextEnd = buf;
4858     eof = false;
4859 }
4860 
4861 //
4862 // When fillBuf finishes, buf[] looks like this:
4863 //   +-----+--------------+-----------------+--
4864 //   + tag | ... data ... | next 0, 1, or 2 |
4865 //   +-----+--------------+-----------------+--
4866 //    ^                    ^                 ^
4867 //    bufPtr               bufEnd            nextEnd
4868 //
fillBuf()4869 bool RunLengthEncoder::fillBuf()
4870 {
4871     int c, c1, c2;
4872     int n;
4873 
4874     // already hit EOF?
4875     if (eof)
4876         return false;
4877 
4878     // grab two bytes
4879     if (nextEnd < bufEnd + 1) {
4880         if ((c1 = str->getChar()) == EOF) {
4881             eof = true;
4882             return false;
4883         }
4884     } else {
4885         c1 = bufEnd[0] & 0xff;
4886     }
4887     if (nextEnd < bufEnd + 2) {
4888         if ((c2 = str->getChar()) == EOF) {
4889             eof = true;
4890             buf[0] = 0;
4891             buf[1] = c1;
4892             bufPtr = buf;
4893             bufEnd = &buf[2];
4894             return true;
4895         }
4896     } else {
4897         c2 = bufEnd[1] & 0xff;
4898     }
4899 
4900     // check for repeat
4901     c = 0; // make gcc happy
4902     if (c1 == c2) {
4903         n = 2;
4904         while (n < 128 && (c = str->getChar()) == c1)
4905             ++n;
4906         buf[0] = (char)(257 - n);
4907         buf[1] = c1;
4908         bufEnd = &buf[2];
4909         if (c == EOF) {
4910             eof = true;
4911         } else if (n < 128) {
4912             buf[2] = c;
4913             nextEnd = &buf[3];
4914         } else {
4915             nextEnd = bufEnd;
4916         }
4917 
4918         // get up to 128 chars
4919     } else {
4920         buf[1] = c1;
4921         buf[2] = c2;
4922         n = 2;
4923         while (n < 128) {
4924             if ((c = str->getChar()) == EOF) {
4925                 eof = true;
4926                 break;
4927             }
4928             ++n;
4929             buf[n] = c;
4930             if (buf[n] == buf[n - 1])
4931                 break;
4932         }
4933         if (buf[n] == buf[n - 1]) {
4934             buf[0] = (char)(n - 2 - 1);
4935             bufEnd = &buf[n - 1];
4936             nextEnd = &buf[n + 1];
4937         } else {
4938             buf[0] = (char)(n - 1);
4939             bufEnd = nextEnd = &buf[n + 1];
4940         }
4941     }
4942     bufPtr = buf;
4943     return true;
4944 }
4945 
4946 //------------------------------------------------------------------------
4947 // LZWEncoder
4948 //------------------------------------------------------------------------
4949 
LZWEncoder(Stream * strA)4950 LZWEncoder::LZWEncoder(Stream *strA) : FilterStream(strA)
4951 {
4952     inBufLen = 0;
4953     outBufLen = 0;
4954 }
4955 
~LZWEncoder()4956 LZWEncoder::~LZWEncoder()
4957 {
4958     if (str->isEncoder()) {
4959         delete str;
4960     }
4961 }
4962 
reset()4963 void LZWEncoder::reset()
4964 {
4965     int i;
4966 
4967     str->reset();
4968 
4969     // initialize code table
4970     for (i = 0; i < 256; ++i) {
4971         table[i].byte = i;
4972         table[i].next = nullptr;
4973         table[i].children = nullptr;
4974     }
4975     nextSeq = 258;
4976     codeLen = 9;
4977 
4978     // initialize input buffer
4979     inBufLen = str->doGetChars(sizeof(inBuf), inBuf);
4980 
4981     // initialize output buffer with a clear-table code
4982     outBuf = 256;
4983     outBufLen = 9;
4984     needEOD = false;
4985 }
4986 
getChar()4987 int LZWEncoder::getChar()
4988 {
4989     int ret;
4990 
4991     if (inBufLen == 0 && !needEOD && outBufLen == 0) {
4992         return EOF;
4993     }
4994     if (outBufLen < 8 && (inBufLen > 0 || needEOD)) {
4995         fillBuf();
4996     }
4997     if (outBufLen >= 8) {
4998         ret = (outBuf >> (outBufLen - 8)) & 0xff;
4999         outBufLen -= 8;
5000     } else {
5001         ret = (outBuf << (8 - outBufLen)) & 0xff;
5002         outBufLen = 0;
5003     }
5004     return ret;
5005 }
5006 
lookChar()5007 int LZWEncoder::lookChar()
5008 {
5009     if (inBufLen == 0 && !needEOD && outBufLen == 0) {
5010         return EOF;
5011     }
5012     if (outBufLen < 8 && (inBufLen > 0 || needEOD)) {
5013         fillBuf();
5014     }
5015     if (outBufLen >= 8) {
5016         return (outBuf >> (outBufLen - 8)) & 0xff;
5017     } else {
5018         return (outBuf << (8 - outBufLen)) & 0xff;
5019     }
5020 }
5021 
5022 // On input, outBufLen < 8.
5023 // This function generates, at most, 2 12-bit codes
5024 //   --> outBufLen < 8 + 12 + 12 = 32
fillBuf()5025 void LZWEncoder::fillBuf()
5026 {
5027     LZWEncoderNode *p0, *p1;
5028     int seqLen, code, i;
5029 
5030     if (needEOD) {
5031         outBuf = (outBuf << codeLen) | 257;
5032         outBufLen += codeLen;
5033         needEOD = false;
5034         return;
5035     }
5036 
5037     // find longest matching sequence (if any)
5038     p0 = table + inBuf[0];
5039     seqLen = 1;
5040     while (inBufLen > seqLen) {
5041         for (p1 = p0->children; p1; p1 = p1->next) {
5042             if (p1->byte == inBuf[seqLen]) {
5043                 break;
5044             }
5045         }
5046         if (!p1) {
5047             break;
5048         }
5049         p0 = p1;
5050         ++seqLen;
5051     }
5052     code = (int)(p0 - table);
5053 
5054     // generate an output code
5055     outBuf = (outBuf << codeLen) | code;
5056     outBufLen += codeLen;
5057 
5058     // update the table
5059     table[nextSeq].byte = seqLen < inBufLen ? inBuf[seqLen] : 0;
5060     table[nextSeq].children = nullptr;
5061     if (table[code].children) {
5062         table[nextSeq].next = table[code].children;
5063     } else {
5064         table[nextSeq].next = nullptr;
5065     }
5066     table[code].children = table + nextSeq;
5067     ++nextSeq;
5068 
5069     // update the input buffer
5070     memmove(inBuf, inBuf + seqLen, inBufLen - seqLen);
5071     inBufLen -= seqLen;
5072     inBufLen += str->doGetChars(sizeof(inBuf) - inBufLen, inBuf + inBufLen);
5073 
5074     // increment codeLen; generate clear-table code
5075     if (nextSeq == (1 << codeLen)) {
5076         ++codeLen;
5077         if (codeLen == 13) {
5078             outBuf = (outBuf << 12) | 256;
5079             outBufLen += 12;
5080             for (i = 0; i < 256; ++i) {
5081                 table[i].next = nullptr;
5082                 table[i].children = nullptr;
5083             }
5084             nextSeq = 258;
5085             codeLen = 9;
5086         }
5087     }
5088 
5089     // generate EOD next time
5090     if (inBufLen == 0) {
5091         needEOD = true;
5092     }
5093 }
5094 
5095 //------------------------------------------------------------------------
5096 // CMYKGrayEncoder
5097 //------------------------------------------------------------------------
5098 
CMYKGrayEncoder(Stream * strA)5099 CMYKGrayEncoder::CMYKGrayEncoder(Stream *strA) : FilterStream(strA)
5100 {
5101     bufPtr = bufEnd = buf;
5102     eof = false;
5103 }
5104 
~CMYKGrayEncoder()5105 CMYKGrayEncoder::~CMYKGrayEncoder()
5106 {
5107     if (str->isEncoder())
5108         delete str;
5109 }
5110 
reset()5111 void CMYKGrayEncoder::reset()
5112 {
5113     str->reset();
5114     bufPtr = bufEnd = buf;
5115     eof = false;
5116 }
5117 
fillBuf()5118 bool CMYKGrayEncoder::fillBuf()
5119 {
5120     int c0, c1, c2, c3;
5121     int i;
5122 
5123     if (eof) {
5124         return false;
5125     }
5126     c0 = str->getChar();
5127     c1 = str->getChar();
5128     c2 = str->getChar();
5129     c3 = str->getChar();
5130     if (c3 == EOF) {
5131         eof = true;
5132         return false;
5133     }
5134     i = (3 * c0 + 6 * c1 + c2) / 10 + c3;
5135     if (i > 255)
5136         i = 255;
5137     bufPtr = bufEnd = buf;
5138     *bufEnd++ = (char)i;
5139     return true;
5140 }
5141 
5142 //------------------------------------------------------------------------
5143 // RGBGrayEncoder
5144 //------------------------------------------------------------------------
5145 
RGBGrayEncoder(Stream * strA)5146 RGBGrayEncoder::RGBGrayEncoder(Stream *strA) : FilterStream(strA)
5147 {
5148     bufPtr = bufEnd = buf;
5149     eof = false;
5150 }
5151 
~RGBGrayEncoder()5152 RGBGrayEncoder::~RGBGrayEncoder()
5153 {
5154     if (str->isEncoder())
5155         delete str;
5156 }
5157 
reset()5158 void RGBGrayEncoder::reset()
5159 {
5160     str->reset();
5161     bufPtr = bufEnd = buf;
5162     eof = false;
5163 }
5164 
fillBuf()5165 bool RGBGrayEncoder::fillBuf()
5166 {
5167     int c0, c1, c2;
5168     int i;
5169 
5170     if (eof) {
5171         return false;
5172     }
5173     c0 = str->getChar();
5174     c1 = str->getChar();
5175     c2 = str->getChar();
5176     if (c2 == EOF) {
5177         eof = true;
5178         return false;
5179     }
5180     i = 255 - (3 * c0 + 6 * c1 + c2) / 10;
5181     if (i < 0)
5182         i = 0;
5183     bufPtr = bufEnd = buf;
5184     *bufEnd++ = (char)i;
5185     return true;
5186 }
5187 
5188 //------------------------------------------------------------------------
5189 // SplashBitmapCMYKEncoder
5190 //------------------------------------------------------------------------
5191 
SplashBitmapCMYKEncoder(SplashBitmap * bitmapA)5192 SplashBitmapCMYKEncoder::SplashBitmapCMYKEncoder(SplashBitmap *bitmapA) : bitmap(bitmapA)
5193 {
5194     width = (size_t)4 * bitmap->getWidth();
5195     height = bitmap->getHeight();
5196     buf.resize(width);
5197     bufPtr = width;
5198     curLine = height - 1;
5199 }
5200 
~SplashBitmapCMYKEncoder()5201 SplashBitmapCMYKEncoder::~SplashBitmapCMYKEncoder() { }
5202 
reset()5203 void SplashBitmapCMYKEncoder::reset()
5204 {
5205     bufPtr = width;
5206     curLine = height - 1;
5207 }
5208 
lookChar()5209 int SplashBitmapCMYKEncoder::lookChar()
5210 {
5211     if (bufPtr >= width && !fillBuf()) {
5212         return EOF;
5213     }
5214     return buf[bufPtr];
5215 }
5216 
getChar()5217 int SplashBitmapCMYKEncoder::getChar()
5218 {
5219     int ret = lookChar();
5220     bufPtr++;
5221     return ret;
5222 }
5223 
fillBuf()5224 bool SplashBitmapCMYKEncoder::fillBuf()
5225 {
5226     if (curLine < 0) {
5227         return false;
5228     }
5229 
5230     if (bufPtr < width) {
5231         return true;
5232     }
5233 
5234     bitmap->getCMYKLine(curLine, &buf[0]);
5235     bufPtr = 0;
5236     curLine--;
5237     return true;
5238 }
5239 
getPos()5240 Goffset SplashBitmapCMYKEncoder::getPos()
5241 {
5242     return (height - 1 - curLine) * width + bufPtr;
5243 }
5244 
setPos(Goffset pos,int dir)5245 void SplashBitmapCMYKEncoder::setPos(Goffset pos, int dir)
5246 {
5247     // This code is mostly untested!
5248     if (dir < 0) {
5249         curLine = pos / width;
5250     } else {
5251         curLine = height - 1 - pos / width;
5252     }
5253 
5254     bufPtr = width;
5255     fillBuf();
5256 
5257     if (dir < 0) {
5258         bufPtr = width - 1 - pos % width;
5259     } else {
5260         bufPtr = pos % width;
5261     }
5262 }
5263