1 //========================================================================
5 // Copyright 1996-2003 Glyph & Cog, LLC
7 //========================================================================
9 //========================================================================
11 // Modified under the Poppler project - http://poppler.freedesktop.org
13 // All changes made under the Poppler project to this file are licensed
14 // under GPL version 2 or later
16 // Copyright (C) 2005 Jeff Muizelaar <jeff@infidigm.net>
17 // Copyright (C) 2008 Julien Rebetez <julien@fhtagn.net>
18 // Copyright (C) 2008, 2010, 2011, 2016 Albert Astals Cid <aacid@kde.org>
19 // Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
20 // Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
21 // Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
22 // Copyright (C) 2011, 2012, 2016 William Bader <williambader@hotmail.com>
23 // Copyright (C) 2012, 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
24 // Copyright (C) 2012, 2013 Fabio D'Urso <fabiodurso@hotmail.it>
25 // Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com>
26 // Copyright (C) 2013 Peter Breitenlohner <peb@mppmu.mpg.de>
27 // Copyright (C) 2013 Adam Reichold <adamreichold@myopera.com>
28 // Copyright (C) 2013 Pino Toscano <pino@kde.org>
30 // To see a description of the changes please see the Changelog file that
31 // came with your tarball or type make ChangeLog if you are building from git
33 //========================================================================
38 #ifdef USE_GCC_PRAGMAS
42 #include "poppler-config.h"
44 #include "goo/gtypes.h"
46 #include "goo/GooMutex.h"
52 //------------------------------------------------------------------------
66 strWeird
, // internal-use stream types
67 strCrypt
// internal-use to detect decode streams
70 enum StreamColorSpaceMode
{
77 //------------------------------------------------------------------------
79 // This is in Stream.h instead of Decrypt.h to avoid really annoying
80 // include file dependency loops.
88 //------------------------------------------------------------------------
90 typedef struct _ByteRange
{
95 //------------------------------------------------------------------------
96 // Stream (base class)
97 //------------------------------------------------------------------------
108 // Reference counting.
112 // Get kind of stream.
113 virtual StreamKind
getKind() = 0;
115 // Reset stream to beginning.
116 virtual void reset() = 0;
118 // Close down the stream.
119 virtual void close();
121 inline int doGetChars(int nChars
, Guchar
*buffer
)
124 return getChars(nChars
, buffer
);
126 for (int i
= 0; i
< nChars
; ++i
) {
127 const int c
= getChar();
128 if (likely(c
!= EOF
)) buffer
[i
] = c
;
135 inline void fillGooString(GooString
*s
)
137 Guchar readBuf
[4096];
140 while ((readChars
= doGetChars(4096, readBuf
)) != 0) {
141 s
->append((const char *)readBuf
, readChars
);
145 inline Guchar
*toUnsignedChars(int *length
, int initialSize
= 4096, int sizeIncrement
= 4096)
148 Guchar
*buf
= (Guchar
*)gmalloc(initialSize
);
149 int size
= initialSize
;
151 int charsToRead
= initialSize
;
152 bool continueReading
= true;
154 while (continueReading
&& (readChars
= doGetChars(charsToRead
, &buf
[*length
])) != 0) {
155 *length
+= readChars
;
156 if (readChars
== charsToRead
) {
157 if (lookChar() != EOF
) {
158 size
+= sizeIncrement
;
159 charsToRead
= sizeIncrement
;
160 buf
= (Guchar
*)grealloc(buf
, size
);
162 continueReading
= false;
165 continueReading
= false;
171 // Get next char from stream.
172 virtual int getChar() = 0;
174 // Peek at next char in stream.
175 virtual int lookChar() = 0;
177 // Get next char from stream without using the predictor.
178 // This is only used by StreamPredictor.
179 virtual int getRawChar();
180 virtual void getRawChars(int nChars
, int *buffer
);
182 // Get next char directly from stream source, without filtering it
183 virtual int getUnfilteredChar () = 0;
185 // Resets the stream without reading anything (even not the headers)
186 // WARNING: Reading the stream with something else than getUnfilteredChar
187 // may lead to unexcepted behaviour until you call reset ()
188 virtual void unfilteredReset () = 0;
190 // Get next line from stream.
191 virtual char *getLine(char *buf
, int size
);
193 // Get current position in file.
194 virtual Goffset
getPos() = 0;
196 // Go to a position in the stream. If <dir> is negative, the
197 // position is from the end of the file; otherwise the position is
198 // from the start of the file.
199 virtual void setPos(Goffset pos
, int dir
= 0) = 0;
201 // Get PostScript command for the filter(s).
202 virtual GooString
*getPSFilter(int psLevel
, const char *indent
);
204 // Does this stream type potentially contain non-printable chars?
205 virtual GBool
isBinary(GBool last
= gTrue
) = 0;
207 // Get the BaseStream of this stream.
208 virtual BaseStream
*getBaseStream() = 0;
210 // Get the stream after the last decoder (this may be a BaseStream
211 // or a DecryptStream).
212 virtual Stream
*getUndecodedStream() = 0;
214 // Get the dictionary associated with this stream.
215 virtual Dict
*getDict() = 0;
217 // Is this an encoding filter?
218 virtual GBool
isEncoder() { return gFalse
; }
220 // Get image parameters which are defined by the stream contents.
221 virtual void getImageParams(int * /*bitsPerComponent*/,
222 StreamColorSpaceMode
* /*csMode*/) {}
224 // Return the next stream in the "stack".
225 virtual Stream
*getNextStream() { return NULL
; }
227 // Add filters to this stream according to the parameters in <dict>.
228 // Returns the new stream.
229 Stream
*addFilters(Object
*dict
, int recursion
= 0);
232 virtual GBool
hasGetChars() { return false; }
233 virtual int getChars(int nChars
, Guchar
*buffer
);
235 Stream
*makeFilter(char *name
, Stream
*str
, Object
*params
, int recursion
= 0, Object
*dict
= NULL
);
237 int ref
; // reference count
244 //------------------------------------------------------------------------
247 // This is the base class for all streams that output to a file
248 //------------------------------------------------------------------------
255 virtual ~OutStream ();
257 // Reference counting.
258 int incRef() { return ++ref
; }
259 int decRef() { return --ref
; }
262 virtual void close() = 0;
264 // Return position in stream
265 virtual Goffset
getPos() = 0;
267 // Put a char in the stream
268 virtual void put (char c
) = 0;
270 virtual void printf (const char *format
, ...) GCC_PRINTF_FORMAT(2,3) = 0;
273 int ref
; // reference count
277 //------------------------------------------------------------------------
279 //------------------------------------------------------------------------
280 class FileOutStream
: public OutStream
{
282 FileOutStream (FILE* fa
, Goffset startA
);
284 virtual ~FileOutStream ();
286 virtual void close();
288 virtual Goffset
getPos();
290 virtual void put (char c
);
292 virtual void printf (const char *format
, ...);
300 //------------------------------------------------------------------------
303 // This is the base class for all streams that read directly from a file.
304 //------------------------------------------------------------------------
306 class BaseStream
: public Stream
{
309 BaseStream(Object
*dictA
, Goffset lengthA
);
310 virtual ~BaseStream();
311 virtual BaseStream
*copy() = 0;
312 virtual Stream
*makeSubStream(Goffset start
, GBool limited
,
313 Goffset length
, Object
*dict
) = 0;
314 virtual void setPos(Goffset pos
, int dir
= 0) = 0;
315 virtual GBool
isBinary(GBool last
= gTrue
) { return last
; }
316 virtual BaseStream
*getBaseStream() { return this; }
317 virtual Stream
*getUndecodedStream() { return this; }
318 virtual Dict
*getDict() { return dict
.getDict(); }
319 virtual GooString
*getFileName() { return NULL
; }
320 virtual Goffset
getLength() { return length
; }
322 // Get/set position of first byte of stream within the file.
323 virtual Goffset
getStart() = 0;
324 virtual void moveStart(Goffset delta
) = 0;
332 //------------------------------------------------------------------------
335 // This is the base class for all streams that filter another stream.
336 //------------------------------------------------------------------------
338 class FilterStream
: public Stream
{
341 FilterStream(Stream
*strA
);
342 virtual ~FilterStream();
343 virtual void close();
344 virtual Goffset
getPos() { return str
->getPos(); }
345 virtual void setPos(Goffset pos
, int dir
= 0);
346 virtual BaseStream
*getBaseStream() { return str
->getBaseStream(); }
347 virtual Stream
*getUndecodedStream() { return str
->getUndecodedStream(); }
348 virtual Dict
*getDict() { return str
->getDict(); }
349 virtual Stream
*getNextStream() { return str
; }
351 virtual int getUnfilteredChar () { return str
->getUnfilteredChar(); }
352 virtual void unfilteredReset () { str
->unfilteredReset(); }
359 //------------------------------------------------------------------------
361 //------------------------------------------------------------------------
366 // Create an image stream object for an image with the specified
367 // parameters. Note that these are the actual image parameters,
368 // which may be different from the predictor parameters.
369 ImageStream(Stream
*strA
, int widthA
, int nCompsA
, int nBitsA
);
376 // Close the stream previously reset
379 // Gets the next pixel from the stream. <pix> should be able to hold
380 // at least nComps elements. Returns false at end of file.
381 GBool
getPixel(Guchar
*pix
);
383 // Returns a pointer to the next line of pixels. Returns NULL at
387 // Skip an entire line from the image.
392 Stream
*str
; // base stream
393 int width
; // pixels per line
394 int nComps
; // components per pixel
395 int nBits
; // bits per component
396 int nVals
; // components per line
397 int inputLineSize
; // input line buffer size
398 Guchar
*inputLine
; // input line buffer
399 Guchar
*imgLine
; // line buffer
400 int imgIdx
; // current index in imgLine
403 //------------------------------------------------------------------------
405 //------------------------------------------------------------------------
407 class StreamPredictor
{
410 // Create a predictor object. Note that the parameters are for the
411 // predictor, and may not match the actual image parameters.
412 StreamPredictor(Stream
*strA
, int predictorA
,
413 int widthA
, int nCompsA
, int nBitsA
);
417 GBool
isOk() { return ok
; }
421 int getChars(int nChars
, Guchar
*buffer
);
427 Stream
*str
; // base stream
428 int predictor
; // predictor
429 int width
; // pixels per line
430 int nComps
; // components per pixel
431 int nBits
; // bits per component
432 int nVals
; // components per line
433 int pixBytes
; // bytes per pixel
434 int rowBytes
; // bytes per line
435 Guchar
*predLine
; // line buffer
436 int predIdx
; // current index in predLine
440 //------------------------------------------------------------------------
442 //------------------------------------------------------------------------
444 #define fileStreamBufSize 256
446 class FileStream
: public BaseStream
{
449 FileStream(GooFile
* fileA
, Goffset startA
, GBool limitedA
,
450 Goffset lengthA
, Object
*dictA
);
451 virtual ~FileStream();
452 virtual BaseStream
*copy();
453 virtual Stream
*makeSubStream(Goffset startA
, GBool limitedA
,
454 Goffset lengthA
, Object
*dictA
);
455 virtual StreamKind
getKind() { return strFile
; }
456 virtual void reset();
457 virtual void close();
458 virtual int getChar()
459 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
460 virtual int lookChar()
461 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
462 virtual Goffset
getPos() { return bufPos
+ (bufPtr
- buf
); }
463 virtual void setPos(Goffset pos
, int dir
= 0);
464 virtual Goffset
getStart() { return start
; }
465 virtual void moveStart(Goffset delta
);
467 virtual int getUnfilteredChar () { return getChar(); }
468 virtual void unfilteredReset () { reset(); }
474 virtual GBool
hasGetChars() { return true; }
475 virtual int getChars(int nChars
, Guchar
*buffer
)
481 if (bufPtr
>= bufEnd
) {
486 m
= (int)(bufEnd
- bufPtr
);
487 if (m
> nChars
- n
) {
490 memcpy(buffer
+ n
, bufPtr
, m
);
502 char buf
[fileStreamBufSize
];
510 //------------------------------------------------------------------------
512 //------------------------------------------------------------------------
514 #define cachedStreamBufSize 1024
516 class CachedFileStream
: public BaseStream
{
519 CachedFileStream(CachedFile
*ccA
, Goffset startA
, GBool limitedA
,
520 Goffset lengthA
, Object
*dictA
);
521 virtual ~CachedFileStream();
522 virtual BaseStream
*copy();
523 virtual Stream
*makeSubStream(Goffset startA
, GBool limitedA
,
524 Goffset lengthA
, Object
*dictA
);
525 virtual StreamKind
getKind() { return strCachedFile
; }
526 virtual void reset();
527 virtual void close();
528 virtual int getChar()
529 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
530 virtual int lookChar()
531 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
532 virtual Goffset
getPos() { return bufPos
+ (bufPtr
- buf
); }
533 virtual void setPos(Goffset pos
, int dir
= 0);
534 virtual Goffset
getStart() { return start
; }
535 virtual void moveStart(Goffset delta
);
537 virtual int getUnfilteredChar () { return getChar(); }
538 virtual void unfilteredReset () { reset(); }
547 char buf
[cachedStreamBufSize
];
556 //------------------------------------------------------------------------
558 //------------------------------------------------------------------------
560 class MemStream
: public BaseStream
{
563 MemStream(char *bufA
, Goffset startA
, Goffset lengthA
, Object
*dictA
);
564 virtual ~MemStream();
565 virtual BaseStream
*copy();
566 virtual Stream
*makeSubStream(Goffset start
, GBool limited
,
567 Goffset lengthA
, Object
*dictA
);
568 virtual StreamKind
getKind() { return strWeird
; }
569 virtual void reset();
570 virtual void close();
571 virtual int getChar()
572 { return (bufPtr
< bufEnd
) ? (*bufPtr
++ & 0xff) : EOF
; }
573 virtual int lookChar()
574 { return (bufPtr
< bufEnd
) ? (*bufPtr
& 0xff) : EOF
; }
575 virtual Goffset
getPos() { return (int)(bufPtr
- buf
); }
576 virtual void setPos(Goffset pos
, int dir
= 0);
577 virtual Goffset
getStart() { return start
; }
578 virtual void moveStart(Goffset delta
);
580 //if needFree = true, the stream will delete buf when it is destroyed
581 //otherwise it will not touch it. Default value is false
582 virtual void setNeedFree (GBool val
) { needFree
= val
; }
584 virtual int getUnfilteredChar () { return getChar(); }
585 virtual void unfilteredReset () { reset (); }
589 virtual GBool
hasGetChars() { return true; }
590 virtual int getChars(int nChars
, Guchar
*buffer
);
599 //------------------------------------------------------------------------
602 // This is a special stream type used for embedded streams (inline
603 // images). It reads directly from the base stream -- after the
604 // EmbedStream is deleted, reads from the base stream will proceed where
605 // the BaseStream left off. Note that this is very different behavior
606 // that creating a new FileStream (using makeSubStream).
607 //------------------------------------------------------------------------
609 class EmbedStream
: public BaseStream
{
612 EmbedStream(Stream
*strA
, Object
*dictA
, GBool limitedA
, Goffset lengthA
);
613 virtual ~EmbedStream();
614 virtual BaseStream
*copy();
615 virtual Stream
*makeSubStream(Goffset start
, GBool limitedA
,
616 Goffset lengthA
, Object
*dictA
);
617 virtual StreamKind
getKind() { return str
->getKind(); }
618 virtual void reset() {}
619 virtual int getChar();
620 virtual int lookChar();
621 virtual Goffset
getPos() { return str
->getPos(); }
622 virtual void setPos(Goffset pos
, int dir
= 0);
623 virtual Goffset
getStart();
624 virtual void moveStart(Goffset delta
);
626 virtual int getUnfilteredChar () { return str
->getUnfilteredChar(); }
627 virtual void unfilteredReset () { str
->unfilteredReset(); }
632 virtual GBool
hasGetChars() { return true; }
633 virtual int getChars(int nChars
, Guchar
*buffer
);
639 //------------------------------------------------------------------------
641 //------------------------------------------------------------------------
643 class ASCIIHexStream
: public FilterStream
{
646 ASCIIHexStream(Stream
*strA
);
647 virtual ~ASCIIHexStream();
648 virtual StreamKind
getKind() { return strASCIIHex
; }
649 virtual void reset();
650 virtual int getChar()
651 { int c
= lookChar(); buf
= EOF
; return c
; }
652 virtual int lookChar();
653 virtual GooString
*getPSFilter(int psLevel
, const char *indent
);
654 virtual GBool
isBinary(GBool last
= gTrue
);
662 //------------------------------------------------------------------------
664 //------------------------------------------------------------------------
666 class ASCII85Stream
: public FilterStream
{
669 ASCII85Stream(Stream
*strA
);
670 virtual ~ASCII85Stream();
671 virtual StreamKind
getKind() { return strASCII85
; }
672 virtual void reset();
673 virtual int getChar()
674 { int ch
= lookChar(); ++index
; return ch
; }
675 virtual int lookChar();
676 virtual GooString
*getPSFilter(int psLevel
, const char *indent
);
677 virtual GBool
isBinary(GBool last
= gTrue
);
687 //------------------------------------------------------------------------
689 //------------------------------------------------------------------------
691 class LZWStream
: public FilterStream
{
694 LZWStream(Stream
*strA
, int predictor
, int columns
, int colors
,
695 int bits
, int earlyA
);
696 virtual ~LZWStream();
697 virtual StreamKind
getKind() { return strLZW
; }
698 virtual void reset();
699 virtual int getChar();
700 virtual int lookChar();
701 virtual int getRawChar();
702 virtual void getRawChars(int nChars
, int *buffer
);
703 virtual GooString
*getPSFilter(int psLevel
, const char *indent
);
704 virtual GBool
isBinary(GBool last
= gTrue
);
708 virtual GBool
hasGetChars() { return true; }
709 virtual int getChars(int nChars
, Guchar
*buffer
);
711 inline int doGetRawChar() {
715 if (seqIndex
>= seqLength
) {
716 if (!processNextCode()) {
720 return seqBuf
[seqIndex
++];
723 StreamPredictor
*pred
; // predictor
724 int early
; // early parameter
725 GBool eof
; // true if at eof
726 int inputBuf
; // input buffer
727 int inputBits
; // number of bits in input buffer
728 struct { // decoding table
733 int nextCode
; // next code to be used
734 int nextBits
; // number of bits in next code word
735 int prevCode
; // previous code used in stream
736 int newChar
; // next char to be added to table
737 Guchar seqBuf
[4097]; // buffer for current sequence
738 int seqLength
; // length of current sequence
739 int seqIndex
; // index into current sequence
740 GBool first
; // first code after a table clear
742 GBool
processNextCode();
747 //------------------------------------------------------------------------
749 //------------------------------------------------------------------------
751 class RunLengthStream
: public FilterStream
{
754 RunLengthStream(Stream
*strA
);
755 virtual ~RunLengthStream();
756 virtual StreamKind
getKind() { return strRunLength
; }
757 virtual void reset();
758 virtual int getChar()
759 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
760 virtual int lookChar()
761 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
762 virtual GooString
*getPSFilter(int psLevel
, const char *indent
);
763 virtual GBool
isBinary(GBool last
= gTrue
);
767 virtual GBool
hasGetChars() { return true; }
768 virtual int getChars(int nChars
, Guchar
*buffer
);
770 char buf
[128]; // buffer
771 char *bufPtr
; // next char to read
772 char *bufEnd
; // end of buffer
778 //------------------------------------------------------------------------
780 //------------------------------------------------------------------------
782 struct CCITTCodeTable
;
784 class CCITTFaxStream
: public FilterStream
{
787 CCITTFaxStream(Stream
*strA
, int encodingA
, GBool endOfLineA
,
788 GBool byteAlignA
, int columnsA
, int rowsA
,
789 GBool endOfBlockA
, GBool blackA
);
790 virtual ~CCITTFaxStream();
791 virtual StreamKind
getKind() { return strCCITTFax
; }
792 virtual void reset();
793 virtual int getChar()
794 { int c
= lookChar(); buf
= EOF
; return c
; }
795 virtual int lookChar();
796 virtual GooString
*getPSFilter(int psLevel
, const char *indent
);
797 virtual GBool
isBinary(GBool last
= gTrue
);
799 virtual void unfilteredReset ();
801 int getEncoding() { return encoding
; }
802 GBool
getEndOfLine() { return endOfLine
; }
803 int getColumns() { return columns
; }
804 GBool
getBlackIs1() { return black
; }
808 void ccittReset(GBool unfiltered
);
809 int encoding
; // 'K' parameter
810 GBool endOfLine
; // 'EndOfLine' parameter
811 GBool byteAlign
; // 'EncodedByteAlign' parameter
812 int columns
; // 'Columns' parameter
813 int rows
; // 'Rows' parameter
814 GBool endOfBlock
; // 'EndOfBlock' parameter
815 GBool black
; // 'BlackIs1' parameter
816 GBool eof
; // true if at eof
817 GBool nextLine2D
; // true if next line uses 2D encoding
818 int row
; // current row
819 Guint inputBuf
; // input buffer
820 int inputBits
; // number of bits in input buffer
821 int *codingLine
; // coding line changing elements
822 int *refLine
; // reference line changing elements
823 int a0i
; // index into codingLine
824 GBool err
; // error on current line
825 int outputBits
; // remaining ouput bits
826 int buf
; // character buffer
828 void addPixels(int a1
, int blackPixels
);
829 void addPixelsNeg(int a1
, int blackPixels
);
830 short getTwoDimCode();
831 short getWhiteCode();
832 short getBlackCode();
833 short lookBits(int n
);
834 void eatBits(int n
) { if ((inputBits
-= n
) < 0) inputBits
= 0; }
837 #ifndef ENABLE_LIBJPEG
838 //------------------------------------------------------------------------
840 //------------------------------------------------------------------------
842 // DCT component info
844 int id
; // component ID
845 int hSample
, vSample
; // horiz/vert sampling resolutions
846 int quantTable
; // quantization table number
847 int prevDC
; // DC coefficient accumulator
851 GBool comp
[4]; // comp[i] is set if component i is
852 // included in this scan
853 int numComps
; // number of components in the scan
854 int dcHuffTable
[4]; // DC Huffman table numbers
855 int acHuffTable
[4]; // AC Huffman table numbers
856 int firstCoeff
, lastCoeff
; // first and last DCT coefficient
857 int ah
, al
; // successive approximation parameters
860 // DCT Huffman decoding table
861 struct DCTHuffTable
{
862 Guchar firstSym
[17]; // first symbol for this bit length
863 Gushort firstCode
[17]; // first code for this bit length
864 Gushort numCodes
[17]; // number of codes of this bit length
865 Guchar sym
[256]; // symbols
868 class DCTStream
: public FilterStream
{
871 DCTStream(Stream
*strA
, int colorXformA
, Object
*dict
, int recursion
);
872 virtual ~DCTStream();
873 virtual StreamKind
getKind() { return strDCT
; }
874 virtual void reset();
875 virtual void close();
876 virtual int getChar();
877 virtual int lookChar();
878 virtual GooString
*getPSFilter(int psLevel
, const char *indent
);
879 virtual GBool
isBinary(GBool last
= gTrue
);
881 virtual void unfilteredReset();
885 void dctReset(GBool unfiltered
);
886 GBool progressive
; // set if in progressive mode
887 GBool interleaved
; // set if in interleaved mode
888 int width
, height
; // image size
889 int mcuWidth
, mcuHeight
; // size of min coding unit, in data units
890 int bufWidth
, bufHeight
; // frameBuf size
891 DCTCompInfo compInfo
[4]; // info for each component
892 DCTScanInfo scanInfo
; // info for the current scan
893 int numComps
; // number of components in image
894 int colorXform
; // color transform: -1 = unspecified
896 // 1 = YUV/YUVK -> RGB/CMYK
897 GBool gotJFIFMarker
; // set if APP0 JFIF marker was present
898 GBool gotAdobeMarker
; // set if APP14 Adobe marker was present
899 int restartInterval
; // restart interval, in MCUs
900 Gushort quantTables
[4][64]; // quantization tables
901 int numQuantTables
; // number of quantization tables
902 DCTHuffTable dcHuffTables
[4]; // DC Huffman tables
903 DCTHuffTable acHuffTables
[4]; // AC Huffman tables
904 int numDCHuffTables
; // number of DC Huffman tables
905 int numACHuffTables
; // number of AC Huffman tables
906 Guchar
*rowBuf
[4][32]; // buffer for one MCU (non-progressive mode)
907 int *frameBuf
[4]; // buffer for frame (progressive mode)
908 int comp
, x
, y
, dy
; // current position within image/MCU
909 int restartCtr
; // MCUs left until restart
910 int restartMarker
; // next restart marker
911 int eobRun
; // number of EOBs left in the current run
912 int inputBuf
; // input buffer for variable length codes
913 int inputBits
; // number of valid bits in input buffer
918 GBool
readDataUnit(DCTHuffTable
*dcHuffTable
,
919 DCTHuffTable
*acHuffTable
,
920 int *prevDC
, int data
[64]);
921 GBool
readProgressiveDataUnit(DCTHuffTable
*dcHuffTable
,
922 DCTHuffTable
*acHuffTable
,
923 int *prevDC
, int data
[64]);
925 void transformDataUnit(Gushort
*quantTable
,
926 int dataIn
[64], Guchar dataOut
[64]);
927 int readHuffSym(DCTHuffTable
*table
);
928 int readAmp(int size
);
931 GBool
readBaselineSOF();
932 GBool
readProgressiveSOF();
933 GBool
readScanInfo();
934 GBool
readQuantTables();
935 GBool
readHuffmanTables();
936 GBool
readRestartInterval();
937 GBool
readJFIFMarker();
938 GBool
readAdobeMarker();
946 #ifndef ENABLE_ZLIB_UNCOMPRESS
947 //------------------------------------------------------------------------
949 //------------------------------------------------------------------------
951 #define flateWindow 32768 // buffer size
952 #define flateMask (flateWindow-1)
953 #define flateMaxHuffman 15 // max Huffman code length
954 #define flateMaxCodeLenCodes 19 // max # code length codes
955 #define flateMaxLitCodes 288 // max # literal codes
956 #define flateMaxDistCodes 30 // max # distance codes
958 // Huffman code table entry
960 Gushort len
; // code length, in bits
961 Gushort val
; // value represented by this code
964 struct FlateHuffmanTab
{
969 // Decoding info for length and distance code words
971 int bits
; // # extra bits
972 int first
; // first length/distance
975 class FlateStream
: public FilterStream
{
978 FlateStream(Stream
*strA
, int predictor
, int columns
,
979 int colors
, int bits
);
980 virtual ~FlateStream();
981 virtual StreamKind
getKind() { return strFlate
; }
982 virtual void reset();
983 virtual int getChar();
984 virtual int lookChar();
985 virtual int getRawChar();
986 virtual void getRawChars(int nChars
, int *buffer
);
987 virtual GooString
*getPSFilter(int psLevel
, const char *indent
);
988 virtual GBool
isBinary(GBool last
= gTrue
);
989 virtual void unfilteredReset ();
992 void flateReset(GBool unfiltered
);
993 inline int doGetRawChar() {
996 while (remain
== 0) {
997 if (endOfBlock
&& eof
)
1002 index
= (index
+ 1) & flateMask
;
1007 virtual GBool
hasGetChars() { return true; }
1008 virtual int getChars(int nChars
, Guchar
*buffer
);
1010 StreamPredictor
*pred
; // predictor
1011 Guchar buf
[flateWindow
]; // output data buffer
1012 int index
; // current index into output buffer
1013 int remain
; // number valid bytes in output buffer
1014 int codeBuf
; // input buffer
1015 int codeSize
; // number of bits in input buffer
1016 int // literal and distance code lengths
1017 codeLengths
[flateMaxLitCodes
+ flateMaxDistCodes
];
1018 FlateHuffmanTab litCodeTab
; // literal code table
1019 FlateHuffmanTab distCodeTab
; // distance code table
1020 GBool compressedBlock
; // set if reading a compressed block
1021 int blockLen
; // remaining length of uncompressed block
1022 GBool endOfBlock
; // set when end of block is reached
1023 GBool eof
; // set when end of stream is reached
1025 static int // code length code reordering
1026 codeLenCodeMap
[flateMaxCodeLenCodes
];
1027 static FlateDecode
// length decoding info
1028 lengthDecode
[flateMaxLitCodes
-257];
1029 static FlateDecode
// distance decoding info
1030 distDecode
[flateMaxDistCodes
];
1031 static FlateHuffmanTab
// fixed literal code table
1033 static FlateHuffmanTab
// fixed distance code table
1038 void loadFixedCodes();
1039 GBool
readDynamicCodes();
1040 void compHuffmanCodes(int *lengths
, int n
, FlateHuffmanTab
*tab
);
1041 int getHuffmanCodeWord(FlateHuffmanTab
*tab
);
1042 int getCodeWord(int bits
);
1046 //------------------------------------------------------------------------
1048 //------------------------------------------------------------------------
1050 class EOFStream
: public FilterStream
{
1053 EOFStream(Stream
*strA
);
1054 virtual ~EOFStream();
1055 virtual StreamKind
getKind() { return strWeird
; }
1056 virtual void reset() {}
1057 virtual int getChar() { return EOF
; }
1058 virtual int lookChar() { return EOF
; }
1059 virtual GooString
*getPSFilter(int /*psLevel*/, const char * /*indent*/) { return NULL
; }
1060 virtual GBool
isBinary(GBool
/*last = gTrue*/) { return gFalse
; }
1063 //------------------------------------------------------------------------
1065 //------------------------------------------------------------------------
1067 class BufStream
: public FilterStream
{
1070 BufStream(Stream
*strA
, int bufSizeA
);
1071 virtual ~BufStream();
1072 virtual StreamKind
getKind() { return strWeird
; }
1073 virtual void reset();
1074 virtual int getChar();
1075 virtual int lookChar();
1076 virtual GooString
*getPSFilter(int psLevel
, const char *indent
)
1078 virtual GBool
isBinary(GBool last
= gTrue
);
1080 int lookChar(int idx
);
1088 //------------------------------------------------------------------------
1089 // FixedLengthEncoder
1090 //------------------------------------------------------------------------
1092 class FixedLengthEncoder
: public FilterStream
{
1095 FixedLengthEncoder(Stream
*strA
, int lengthA
);
1096 ~FixedLengthEncoder();
1097 virtual StreamKind
getKind() { return strWeird
; }
1098 virtual void reset();
1099 virtual int getChar();
1100 virtual int lookChar();
1101 virtual GooString
*getPSFilter(int /*psLevel*/, const char * /*indent*/) { return NULL
; }
1102 virtual GBool
isBinary(GBool
/*last = gTrue*/);
1103 virtual GBool
isEncoder() { return gTrue
; }
1111 //------------------------------------------------------------------------
1113 //------------------------------------------------------------------------
1115 class ASCIIHexEncoder
: public FilterStream
{
1118 ASCIIHexEncoder(Stream
*strA
);
1119 virtual ~ASCIIHexEncoder();
1120 virtual StreamKind
getKind() { return strWeird
; }
1121 virtual void reset();
1122 virtual int getChar()
1123 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
1124 virtual int lookChar()
1125 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
1126 virtual GooString
*getPSFilter(int /*psLevel*/, const char * /*indent*/) { return NULL
; }
1127 virtual GBool
isBinary(GBool
/*last = gTrue*/) { return gFalse
; }
1128 virtual GBool
isEncoder() { return gTrue
; }
1141 //------------------------------------------------------------------------
1143 //------------------------------------------------------------------------
1145 class ASCII85Encoder
: public FilterStream
{
1148 ASCII85Encoder(Stream
*strA
);
1149 virtual ~ASCII85Encoder();
1150 virtual StreamKind
getKind() { return strWeird
; }
1151 virtual void reset();
1152 virtual int getChar()
1153 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
1154 virtual int lookChar()
1155 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
1156 virtual GooString
*getPSFilter(int /*psLevel*/, const char * /*indent*/) { return NULL
; }
1157 virtual GBool
isBinary(GBool
/*last = gTrue*/) { return gFalse
; }
1158 virtual GBool
isEncoder() { return gTrue
; }
1171 //------------------------------------------------------------------------
1173 //------------------------------------------------------------------------
1175 class RunLengthEncoder
: public FilterStream
{
1178 RunLengthEncoder(Stream
*strA
);
1179 virtual ~RunLengthEncoder();
1180 virtual StreamKind
getKind() { return strWeird
; }
1181 virtual void reset();
1182 virtual int getChar()
1183 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
1184 virtual int lookChar()
1185 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
1186 virtual GooString
*getPSFilter(int /*psLevel*/, const char * /*indent*/) { return NULL
; }
1187 virtual GBool
isBinary(GBool
/*last = gTrue*/) { return gTrue
; }
1188 virtual GBool
isEncoder() { return gTrue
; }
1201 //------------------------------------------------------------------------
1203 //------------------------------------------------------------------------
1205 struct LZWEncoderNode
{
1207 LZWEncoderNode
*next
; // next sibling
1208 LZWEncoderNode
*children
; // first child
1211 class LZWEncoder
: public FilterStream
{
1214 LZWEncoder(Stream
*strA
);
1215 virtual ~LZWEncoder();
1216 virtual StreamKind
getKind() { return strWeird
; }
1217 virtual void reset();
1218 virtual int getChar();
1219 virtual int lookChar();
1220 virtual GooString
*getPSFilter(int psLevel
, const char *indent
)
1222 virtual GBool
isBinary(GBool last
= gTrue
) { return gTrue
; }
1223 virtual GBool
isEncoder() { return gTrue
; }
1227 LZWEncoderNode table
[4096];
1239 //------------------------------------------------------------------------
1241 //------------------------------------------------------------------------
1243 class CMYKGrayEncoder
: public FilterStream
{
1246 CMYKGrayEncoder(Stream
*strA
);
1247 virtual ~CMYKGrayEncoder();
1248 virtual StreamKind
getKind() { return strWeird
; }
1249 virtual void reset();
1250 virtual int getChar()
1251 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
1252 virtual int lookChar()
1253 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
1254 virtual GooString
*getPSFilter(int /*psLevel*/, const char * /*indent*/) { return NULL
; }
1255 virtual GBool
isBinary(GBool
/*last = gTrue*/) { return gFalse
; }
1256 virtual GBool
isEncoder() { return gTrue
; }
1268 //------------------------------------------------------------------------
1270 //------------------------------------------------------------------------
1272 class RGBGrayEncoder
: public FilterStream
{
1275 RGBGrayEncoder(Stream
*strA
);
1276 virtual ~RGBGrayEncoder();
1277 virtual StreamKind
getKind() { return strWeird
; }
1278 virtual void reset();
1279 virtual int getChar()
1280 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
1281 virtual int lookChar()
1282 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
1283 virtual GooString
*getPSFilter(int /*psLevel*/, const char * /*indent*/) { return NULL
; }
1284 virtual GBool
isBinary(GBool
/*last = gTrue*/) { return gFalse
; }
1285 virtual GBool
isEncoder() { return gTrue
; }