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 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 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.
87 //------------------------------------------------------------------------
89 typedef struct _ByteRange
{
94 //------------------------------------------------------------------------
95 // Stream (base class)
96 //------------------------------------------------------------------------
107 // Reference counting.
111 // Get kind of stream.
112 virtual StreamKind
getKind() = 0;
114 // Reset stream to beginning.
115 virtual void reset() = 0;
117 // Close down the stream.
118 virtual void close();
120 inline int doGetChars(int nChars
, Guchar
*buffer
)
123 return getChars(nChars
, buffer
);
125 for (int i
= 0; i
< nChars
; ++i
) {
126 const int c
= getChar();
127 if (likely(c
!= EOF
)) buffer
[i
] = c
;
134 inline void fillGooString(GooString
*s
)
136 Guchar readBuf
[4096];
139 while ((readChars
= doGetChars(4096, readBuf
)) != 0) {
140 s
->append((const char *)readBuf
, readChars
);
144 inline Guchar
*toUnsignedChars(int *length
, int initialSize
= 4096, int sizeIncrement
= 4096)
147 Guchar
*buf
= (Guchar
*)gmalloc(initialSize
);
148 int size
= initialSize
;
150 int charsToRead
= initialSize
;
151 bool continueReading
= true;
153 while (continueReading
&& (readChars
= doGetChars(charsToRead
, &buf
[*length
])) != 0) {
154 *length
+= readChars
;
155 if (readChars
== charsToRead
) {
156 if (lookChar() != EOF
) {
157 size
+= sizeIncrement
;
158 charsToRead
= sizeIncrement
;
159 buf
= (Guchar
*)grealloc(buf
, size
);
161 continueReading
= false;
164 continueReading
= false;
170 // Get next char from stream.
171 virtual int getChar() = 0;
173 // Peek at next char in stream.
174 virtual int lookChar() = 0;
176 // Get next char from stream without using the predictor.
177 // This is only used by StreamPredictor.
178 virtual int getRawChar();
179 virtual void getRawChars(int nChars
, int *buffer
);
181 // Get next char directly from stream source, without filtering it
182 virtual int getUnfilteredChar () = 0;
184 // Resets the stream without reading anything (even not the headers)
185 // WARNING: Reading the stream with something else than getUnfilteredChar
186 // may lead to unexcepted behaviour until you call reset ()
187 virtual void unfilteredReset () = 0;
189 // Get next line from stream.
190 virtual char *getLine(char *buf
, int size
);
192 // Get current position in file.
193 virtual Goffset
getPos() = 0;
195 // Go to a position in the stream. If <dir> is negative, the
196 // position is from the end of the file; otherwise the position is
197 // from the start of the file.
198 virtual void setPos(Goffset pos
, int dir
= 0) = 0;
200 // Get PostScript command for the filter(s).
201 virtual GooString
*getPSFilter(int psLevel
, const char *indent
);
203 // Does this stream type potentially contain non-printable chars?
204 virtual GBool
isBinary(GBool last
= gTrue
) = 0;
206 // Get the BaseStream of this stream.
207 virtual BaseStream
*getBaseStream() = 0;
209 // Get the stream after the last decoder (this may be a BaseStream
210 // or a DecryptStream).
211 virtual Stream
*getUndecodedStream() = 0;
213 // Get the dictionary associated with this stream.
214 virtual Dict
*getDict() = 0;
216 // Is this an encoding filter?
217 virtual GBool
isEncoder() { return gFalse
; }
219 // Get image parameters which are defined by the stream contents.
220 virtual void getImageParams(int * /*bitsPerComponent*/,
221 StreamColorSpaceMode
* /*csMode*/) {}
223 // Return the next stream in the "stack".
224 virtual Stream
*getNextStream() { return NULL
; }
226 // Add filters to this stream according to the parameters in <dict>.
227 // Returns the new stream.
228 Stream
*addFilters(Object
*dict
, int recursion
= 0);
231 virtual GBool
hasGetChars() { return false; }
232 virtual int getChars(int nChars
, Guchar
*buffer
);
234 Stream
*makeFilter(char *name
, Stream
*str
, Object
*params
, int recursion
= 0, Object
*dict
= NULL
);
236 int ref
; // reference count
243 //------------------------------------------------------------------------
246 // This is the base class for all streams that output to a file
247 //------------------------------------------------------------------------
254 virtual ~OutStream ();
256 // Reference counting.
257 int incRef() { return ++ref
; }
258 int decRef() { return --ref
; }
261 virtual void close() = 0;
263 // Return position in stream
264 virtual Goffset
getPos() = 0;
266 // Put a char in the stream
267 virtual void put (char c
) = 0;
269 virtual void printf (const char *format
, ...) GCC_PRINTF_FORMAT(2,3) = 0;
272 int ref
; // reference count
276 //------------------------------------------------------------------------
278 //------------------------------------------------------------------------
279 class FileOutStream
: public OutStream
{
281 FileOutStream (FILE* fa
, Goffset startA
);
283 virtual ~FileOutStream ();
285 virtual void close();
287 virtual Goffset
getPos();
289 virtual void put (char c
);
291 virtual void printf (const char *format
, ...);
299 //------------------------------------------------------------------------
302 // This is the base class for all streams that read directly from a file.
303 //------------------------------------------------------------------------
305 class BaseStream
: public Stream
{
308 BaseStream(Object
*dictA
, Goffset lengthA
);
309 virtual ~BaseStream();
310 virtual BaseStream
*copy() = 0;
311 virtual Stream
*makeSubStream(Goffset start
, GBool limited
,
312 Goffset length
, Object
*dict
) = 0;
313 virtual void setPos(Goffset pos
, int dir
= 0) = 0;
314 virtual GBool
isBinary(GBool last
= gTrue
) { return last
; }
315 virtual BaseStream
*getBaseStream() { return this; }
316 virtual Stream
*getUndecodedStream() { return this; }
317 virtual Dict
*getDict() { return dict
.getDict(); }
318 virtual GooString
*getFileName() { return NULL
; }
319 virtual Goffset
getLength() { return length
; }
321 // Get/set position of first byte of stream within the file.
322 virtual Goffset
getStart() = 0;
323 virtual void moveStart(Goffset delta
) = 0;
331 //------------------------------------------------------------------------
334 // This is the base class for all streams that filter another stream.
335 //------------------------------------------------------------------------
337 class FilterStream
: public Stream
{
340 FilterStream(Stream
*strA
);
341 virtual ~FilterStream();
342 virtual void close();
343 virtual Goffset
getPos() { return str
->getPos(); }
344 virtual void setPos(Goffset pos
, int dir
= 0);
345 virtual BaseStream
*getBaseStream() { return str
->getBaseStream(); }
346 virtual Stream
*getUndecodedStream() { return str
->getUndecodedStream(); }
347 virtual Dict
*getDict() { return str
->getDict(); }
348 virtual Stream
*getNextStream() { return str
; }
350 virtual int getUnfilteredChar () { return str
->getUnfilteredChar(); }
351 virtual void unfilteredReset () { str
->unfilteredReset(); }
358 //------------------------------------------------------------------------
360 //------------------------------------------------------------------------
365 // Create an image stream object for an image with the specified
366 // parameters. Note that these are the actual image parameters,
367 // which may be different from the predictor parameters.
368 ImageStream(Stream
*strA
, int widthA
, int nCompsA
, int nBitsA
);
375 // Close the stream previously reset
378 // Gets the next pixel from the stream. <pix> should be able to hold
379 // at least nComps elements. Returns false at end of file.
380 GBool
getPixel(Guchar
*pix
);
382 // Returns a pointer to the next line of pixels. Returns NULL at
386 // Skip an entire line from the image.
391 Stream
*str
; // base stream
392 int width
; // pixels per line
393 int nComps
; // components per pixel
394 int nBits
; // bits per component
395 int nVals
; // components per line
396 int inputLineSize
; // input line buffer size
397 Guchar
*inputLine
; // input line buffer
398 Guchar
*imgLine
; // line buffer
399 int imgIdx
; // current index in imgLine
402 //------------------------------------------------------------------------
404 //------------------------------------------------------------------------
406 class StreamPredictor
{
409 // Create a predictor object. Note that the parameters are for the
410 // predictor, and may not match the actual image parameters.
411 StreamPredictor(Stream
*strA
, int predictorA
,
412 int widthA
, int nCompsA
, int nBitsA
);
416 GBool
isOk() { return ok
; }
420 int getChars(int nChars
, Guchar
*buffer
);
426 Stream
*str
; // base stream
427 int predictor
; // predictor
428 int width
; // pixels per line
429 int nComps
; // components per pixel
430 int nBits
; // bits per component
431 int nVals
; // components per line
432 int pixBytes
; // bytes per pixel
433 int rowBytes
; // bytes per line
434 Guchar
*predLine
; // line buffer
435 int predIdx
; // current index in predLine
439 //------------------------------------------------------------------------
441 //------------------------------------------------------------------------
443 #define fileStreamBufSize 256
445 class FileStream
: public BaseStream
{
448 FileStream(GooFile
* fileA
, Goffset startA
, GBool limitedA
,
449 Goffset lengthA
, Object
*dictA
);
450 virtual ~FileStream();
451 virtual BaseStream
*copy();
452 virtual Stream
*makeSubStream(Goffset startA
, GBool limitedA
,
453 Goffset lengthA
, Object
*dictA
);
454 virtual StreamKind
getKind() { return strFile
; }
455 virtual void reset();
456 virtual void close();
457 virtual int getChar()
458 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
459 virtual int lookChar()
460 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
461 virtual Goffset
getPos() { return bufPos
+ (bufPtr
- buf
); }
462 virtual void setPos(Goffset pos
, int dir
= 0);
463 virtual Goffset
getStart() { return start
; }
464 virtual void moveStart(Goffset delta
);
466 virtual int getUnfilteredChar () { return getChar(); }
467 virtual void unfilteredReset () { reset(); }
473 virtual GBool
hasGetChars() { return true; }
474 virtual int getChars(int nChars
, Guchar
*buffer
)
480 if (bufPtr
>= bufEnd
) {
485 m
= (int)(bufEnd
- bufPtr
);
486 if (m
> nChars
- n
) {
489 memcpy(buffer
+ n
, bufPtr
, m
);
501 char buf
[fileStreamBufSize
];
509 //------------------------------------------------------------------------
511 //------------------------------------------------------------------------
513 #define cachedStreamBufSize 1024
515 class CachedFileStream
: public BaseStream
{
518 CachedFileStream(CachedFile
*ccA
, Goffset startA
, GBool limitedA
,
519 Goffset lengthA
, Object
*dictA
);
520 virtual ~CachedFileStream();
521 virtual BaseStream
*copy();
522 virtual Stream
*makeSubStream(Goffset startA
, GBool limitedA
,
523 Goffset lengthA
, Object
*dictA
);
524 virtual StreamKind
getKind() { return strCachedFile
; }
525 virtual void reset();
526 virtual void close();
527 virtual int getChar()
528 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
529 virtual int lookChar()
530 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
531 virtual Goffset
getPos() { return bufPos
+ (bufPtr
- buf
); }
532 virtual void setPos(Goffset pos
, int dir
= 0);
533 virtual Goffset
getStart() { return start
; }
534 virtual void moveStart(Goffset delta
);
536 virtual int getUnfilteredChar () { return getChar(); }
537 virtual void unfilteredReset () { reset(); }
546 char buf
[cachedStreamBufSize
];
555 //------------------------------------------------------------------------
557 //------------------------------------------------------------------------
559 class MemStream
: public BaseStream
{
562 MemStream(char *bufA
, Goffset startA
, Goffset lengthA
, Object
*dictA
);
563 virtual ~MemStream();
564 virtual BaseStream
*copy();
565 virtual Stream
*makeSubStream(Goffset start
, GBool limited
,
566 Goffset lengthA
, Object
*dictA
);
567 virtual StreamKind
getKind() { return strWeird
; }
568 virtual void reset();
569 virtual void close();
570 virtual int getChar()
571 { return (bufPtr
< bufEnd
) ? (*bufPtr
++ & 0xff) : EOF
; }
572 virtual int lookChar()
573 { return (bufPtr
< bufEnd
) ? (*bufPtr
& 0xff) : EOF
; }
574 virtual Goffset
getPos() { return (int)(bufPtr
- buf
); }
575 virtual void setPos(Goffset pos
, int dir
= 0);
576 virtual Goffset
getStart() { return start
; }
577 virtual void moveStart(Goffset delta
);
579 //if needFree = true, the stream will delete buf when it is destroyed
580 //otherwise it will not touch it. Default value is false
581 virtual void setNeedFree (GBool val
) { needFree
= val
; }
583 virtual int getUnfilteredChar () { return getChar(); }
584 virtual void unfilteredReset () { reset (); }
588 virtual GBool
hasGetChars() { return true; }
589 virtual int getChars(int nChars
, Guchar
*buffer
);
598 //------------------------------------------------------------------------
601 // This is a special stream type used for embedded streams (inline
602 // images). It reads directly from the base stream -- after the
603 // EmbedStream is deleted, reads from the base stream will proceed where
604 // the BaseStream left off. Note that this is very different behavior
605 // that creating a new FileStream (using makeSubStream).
606 //------------------------------------------------------------------------
608 class EmbedStream
: public BaseStream
{
611 EmbedStream(Stream
*strA
, Object
*dictA
, GBool limitedA
, Goffset lengthA
);
612 virtual ~EmbedStream();
613 virtual BaseStream
*copy();
614 virtual Stream
*makeSubStream(Goffset start
, GBool limitedA
,
615 Goffset lengthA
, Object
*dictA
);
616 virtual StreamKind
getKind() { return str
->getKind(); }
617 virtual void reset() {}
618 virtual int getChar();
619 virtual int lookChar();
620 virtual Goffset
getPos() { return str
->getPos(); }
621 virtual void setPos(Goffset pos
, int dir
= 0);
622 virtual Goffset
getStart();
623 virtual void moveStart(Goffset delta
);
625 virtual int getUnfilteredChar () { return str
->getUnfilteredChar(); }
626 virtual void unfilteredReset () { str
->unfilteredReset(); }
631 virtual GBool
hasGetChars() { return true; }
632 virtual int getChars(int nChars
, Guchar
*buffer
);
638 //------------------------------------------------------------------------
640 //------------------------------------------------------------------------
642 class ASCIIHexStream
: public FilterStream
{
645 ASCIIHexStream(Stream
*strA
);
646 virtual ~ASCIIHexStream();
647 virtual StreamKind
getKind() { return strASCIIHex
; }
648 virtual void reset();
649 virtual int getChar()
650 { int c
= lookChar(); buf
= EOF
; return c
; }
651 virtual int lookChar();
652 virtual GooString
*getPSFilter(int psLevel
, const char *indent
);
653 virtual GBool
isBinary(GBool last
= gTrue
);
661 //------------------------------------------------------------------------
663 //------------------------------------------------------------------------
665 class ASCII85Stream
: public FilterStream
{
668 ASCII85Stream(Stream
*strA
);
669 virtual ~ASCII85Stream();
670 virtual StreamKind
getKind() { return strASCII85
; }
671 virtual void reset();
672 virtual int getChar()
673 { int ch
= lookChar(); ++index
; return ch
; }
674 virtual int lookChar();
675 virtual GooString
*getPSFilter(int psLevel
, const char *indent
);
676 virtual GBool
isBinary(GBool last
= gTrue
);
686 //------------------------------------------------------------------------
688 //------------------------------------------------------------------------
690 class LZWStream
: public FilterStream
{
693 LZWStream(Stream
*strA
, int predictor
, int columns
, int colors
,
694 int bits
, int earlyA
);
695 virtual ~LZWStream();
696 virtual StreamKind
getKind() { return strLZW
; }
697 virtual void reset();
698 virtual int getChar();
699 virtual int lookChar();
700 virtual int getRawChar();
701 virtual void getRawChars(int nChars
, int *buffer
);
702 virtual GooString
*getPSFilter(int psLevel
, const char *indent
);
703 virtual GBool
isBinary(GBool last
= gTrue
);
707 virtual GBool
hasGetChars() { return true; }
708 virtual int getChars(int nChars
, Guchar
*buffer
);
710 inline int doGetRawChar() {
714 if (seqIndex
>= seqLength
) {
715 if (!processNextCode()) {
719 return seqBuf
[seqIndex
++];
722 StreamPredictor
*pred
; // predictor
723 int early
; // early parameter
724 GBool eof
; // true if at eof
725 int inputBuf
; // input buffer
726 int inputBits
; // number of bits in input buffer
727 struct { // decoding table
732 int nextCode
; // next code to be used
733 int nextBits
; // number of bits in next code word
734 int prevCode
; // previous code used in stream
735 int newChar
; // next char to be added to table
736 Guchar seqBuf
[4097]; // buffer for current sequence
737 int seqLength
; // length of current sequence
738 int seqIndex
; // index into current sequence
739 GBool first
; // first code after a table clear
741 GBool
processNextCode();
746 //------------------------------------------------------------------------
748 //------------------------------------------------------------------------
750 class RunLengthStream
: public FilterStream
{
753 RunLengthStream(Stream
*strA
);
754 virtual ~RunLengthStream();
755 virtual StreamKind
getKind() { return strRunLength
; }
756 virtual void reset();
757 virtual int getChar()
758 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
759 virtual int lookChar()
760 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
761 virtual GooString
*getPSFilter(int psLevel
, const char *indent
);
762 virtual GBool
isBinary(GBool last
= gTrue
);
766 virtual GBool
hasGetChars() { return true; }
767 virtual int getChars(int nChars
, Guchar
*buffer
);
769 char buf
[128]; // buffer
770 char *bufPtr
; // next char to read
771 char *bufEnd
; // end of buffer
777 //------------------------------------------------------------------------
779 //------------------------------------------------------------------------
781 struct CCITTCodeTable
;
783 class CCITTFaxStream
: public FilterStream
{
786 CCITTFaxStream(Stream
*strA
, int encodingA
, GBool endOfLineA
,
787 GBool byteAlignA
, int columnsA
, int rowsA
,
788 GBool endOfBlockA
, GBool blackA
);
789 virtual ~CCITTFaxStream();
790 virtual StreamKind
getKind() { return strCCITTFax
; }
791 virtual void reset();
792 virtual int getChar()
793 { int c
= lookChar(); buf
= EOF
; return c
; }
794 virtual int lookChar();
795 virtual GooString
*getPSFilter(int psLevel
, const char *indent
);
796 virtual GBool
isBinary(GBool last
= gTrue
);
798 virtual void unfilteredReset ();
800 int getEncoding() { return encoding
; }
801 GBool
getEndOfLine() { return endOfLine
; }
802 int getColumns() { return columns
; }
803 GBool
getBlackIs1() { return black
; }
807 void ccittReset(GBool unfiltered
);
808 int encoding
; // 'K' parameter
809 GBool endOfLine
; // 'EndOfLine' parameter
810 GBool byteAlign
; // 'EncodedByteAlign' parameter
811 int columns
; // 'Columns' parameter
812 int rows
; // 'Rows' parameter
813 GBool endOfBlock
; // 'EndOfBlock' parameter
814 GBool black
; // 'BlackIs1' parameter
815 GBool eof
; // true if at eof
816 GBool nextLine2D
; // true if next line uses 2D encoding
817 int row
; // current row
818 Guint inputBuf
; // input buffer
819 int inputBits
; // number of bits in input buffer
820 int *codingLine
; // coding line changing elements
821 int *refLine
; // reference line changing elements
822 int a0i
; // index into codingLine
823 GBool err
; // error on current line
824 int outputBits
; // remaining ouput bits
825 int buf
; // character buffer
827 void addPixels(int a1
, int blackPixels
);
828 void addPixelsNeg(int a1
, int blackPixels
);
829 short getTwoDimCode();
830 short getWhiteCode();
831 short getBlackCode();
832 short lookBits(int n
);
833 void eatBits(int n
) { if ((inputBits
-= n
) < 0) inputBits
= 0; }
836 #ifndef ENABLE_LIBJPEG
837 //------------------------------------------------------------------------
839 //------------------------------------------------------------------------
841 // DCT component info
843 int id
; // component ID
844 int hSample
, vSample
; // horiz/vert sampling resolutions
845 int quantTable
; // quantization table number
846 int prevDC
; // DC coefficient accumulator
850 GBool comp
[4]; // comp[i] is set if component i is
851 // included in this scan
852 int numComps
; // number of components in the scan
853 int dcHuffTable
[4]; // DC Huffman table numbers
854 int acHuffTable
[4]; // AC Huffman table numbers
855 int firstCoeff
, lastCoeff
; // first and last DCT coefficient
856 int ah
, al
; // successive approximation parameters
859 // DCT Huffman decoding table
860 struct DCTHuffTable
{
861 Guchar firstSym
[17]; // first symbol for this bit length
862 Gushort firstCode
[17]; // first code for this bit length
863 Gushort numCodes
[17]; // number of codes of this bit length
864 Guchar sym
[256]; // symbols
867 class DCTStream
: public FilterStream
{
870 DCTStream(Stream
*strA
, int colorXformA
, Object
*dict
, int recursion
);
871 virtual ~DCTStream();
872 virtual StreamKind
getKind() { return strDCT
; }
873 virtual void reset();
874 virtual void close();
875 virtual int getChar();
876 virtual int lookChar();
877 virtual GooString
*getPSFilter(int psLevel
, const char *indent
);
878 virtual GBool
isBinary(GBool last
= gTrue
);
880 virtual void unfilteredReset();
884 void dctReset(GBool unfiltered
);
885 GBool progressive
; // set if in progressive mode
886 GBool interleaved
; // set if in interleaved mode
887 int width
, height
; // image size
888 int mcuWidth
, mcuHeight
; // size of min coding unit, in data units
889 int bufWidth
, bufHeight
; // frameBuf size
890 DCTCompInfo compInfo
[4]; // info for each component
891 DCTScanInfo scanInfo
; // info for the current scan
892 int numComps
; // number of components in image
893 int colorXform
; // color transform: -1 = unspecified
895 // 1 = YUV/YUVK -> RGB/CMYK
896 GBool gotJFIFMarker
; // set if APP0 JFIF marker was present
897 GBool gotAdobeMarker
; // set if APP14 Adobe marker was present
898 int restartInterval
; // restart interval, in MCUs
899 Gushort quantTables
[4][64]; // quantization tables
900 int numQuantTables
; // number of quantization tables
901 DCTHuffTable dcHuffTables
[4]; // DC Huffman tables
902 DCTHuffTable acHuffTables
[4]; // AC Huffman tables
903 int numDCHuffTables
; // number of DC Huffman tables
904 int numACHuffTables
; // number of AC Huffman tables
905 Guchar
*rowBuf
[4][32]; // buffer for one MCU (non-progressive mode)
906 int *frameBuf
[4]; // buffer for frame (progressive mode)
907 int comp
, x
, y
, dy
; // current position within image/MCU
908 int restartCtr
; // MCUs left until restart
909 int restartMarker
; // next restart marker
910 int eobRun
; // number of EOBs left in the current run
911 int inputBuf
; // input buffer for variable length codes
912 int inputBits
; // number of valid bits in input buffer
917 GBool
readDataUnit(DCTHuffTable
*dcHuffTable
,
918 DCTHuffTable
*acHuffTable
,
919 int *prevDC
, int data
[64]);
920 GBool
readProgressiveDataUnit(DCTHuffTable
*dcHuffTable
,
921 DCTHuffTable
*acHuffTable
,
922 int *prevDC
, int data
[64]);
924 void transformDataUnit(Gushort
*quantTable
,
925 int dataIn
[64], Guchar dataOut
[64]);
926 int readHuffSym(DCTHuffTable
*table
);
927 int readAmp(int size
);
930 GBool
readBaselineSOF();
931 GBool
readProgressiveSOF();
932 GBool
readScanInfo();
933 GBool
readQuantTables();
934 GBool
readHuffmanTables();
935 GBool
readRestartInterval();
936 GBool
readJFIFMarker();
937 GBool
readAdobeMarker();
946 //------------------------------------------------------------------------
948 //------------------------------------------------------------------------
950 #define flateWindow 32768 // buffer size
951 #define flateMask (flateWindow-1)
952 #define flateMaxHuffman 15 // max Huffman code length
953 #define flateMaxCodeLenCodes 19 // max # code length codes
954 #define flateMaxLitCodes 288 // max # literal codes
955 #define flateMaxDistCodes 30 // max # distance codes
957 // Huffman code table entry
959 Gushort len
; // code length, in bits
960 Gushort val
; // value represented by this code
963 struct FlateHuffmanTab
{
968 // Decoding info for length and distance code words
970 int bits
; // # extra bits
971 int first
; // first length/distance
974 class FlateStream
: public FilterStream
{
977 FlateStream(Stream
*strA
, int predictor
, int columns
,
978 int colors
, int bits
);
979 virtual ~FlateStream();
980 virtual StreamKind
getKind() { return strFlate
; }
981 virtual void reset();
982 virtual int getChar();
983 virtual int lookChar();
984 virtual int getRawChar();
985 virtual void getRawChars(int nChars
, int *buffer
);
986 virtual GooString
*getPSFilter(int psLevel
, const char *indent
);
987 virtual GBool
isBinary(GBool last
= gTrue
);
988 virtual void unfilteredReset ();
991 void flateReset(GBool unfiltered
);
992 inline int doGetRawChar() {
995 while (remain
== 0) {
996 if (endOfBlock
&& eof
)
1001 index
= (index
+ 1) & flateMask
;
1006 virtual GBool
hasGetChars() { return true; }
1007 virtual int getChars(int nChars
, Guchar
*buffer
);
1009 StreamPredictor
*pred
; // predictor
1010 Guchar buf
[flateWindow
]; // output data buffer
1011 int index
; // current index into output buffer
1012 int remain
; // number valid bytes in output buffer
1013 int codeBuf
; // input buffer
1014 int codeSize
; // number of bits in input buffer
1015 int // literal and distance code lengths
1016 codeLengths
[flateMaxLitCodes
+ flateMaxDistCodes
];
1017 FlateHuffmanTab litCodeTab
; // literal code table
1018 FlateHuffmanTab distCodeTab
; // distance code table
1019 GBool compressedBlock
; // set if reading a compressed block
1020 int blockLen
; // remaining length of uncompressed block
1021 GBool endOfBlock
; // set when end of block is reached
1022 GBool eof
; // set when end of stream is reached
1024 static int // code length code reordering
1025 codeLenCodeMap
[flateMaxCodeLenCodes
];
1026 static FlateDecode
// length decoding info
1027 lengthDecode
[flateMaxLitCodes
-257];
1028 static FlateDecode
// distance decoding info
1029 distDecode
[flateMaxDistCodes
];
1030 static FlateHuffmanTab
// fixed literal code table
1032 static FlateHuffmanTab
// fixed distance code table
1037 void loadFixedCodes();
1038 GBool
readDynamicCodes();
1039 void compHuffmanCodes(int *lengths
, int n
, FlateHuffmanTab
*tab
);
1040 int getHuffmanCodeWord(FlateHuffmanTab
*tab
);
1041 int getCodeWord(int bits
);
1045 //------------------------------------------------------------------------
1047 //------------------------------------------------------------------------
1049 class EOFStream
: public FilterStream
{
1052 EOFStream(Stream
*strA
);
1053 virtual ~EOFStream();
1054 virtual StreamKind
getKind() { return strWeird
; }
1055 virtual void reset() {}
1056 virtual int getChar() { return EOF
; }
1057 virtual int lookChar() { return EOF
; }
1058 virtual GooString
*getPSFilter(int /*psLevel*/, const char * /*indent*/) { return NULL
; }
1059 virtual GBool
isBinary(GBool
/*last = gTrue*/) { return gFalse
; }
1062 //------------------------------------------------------------------------
1064 //------------------------------------------------------------------------
1066 class BufStream
: public FilterStream
{
1069 BufStream(Stream
*strA
, int bufSizeA
);
1070 virtual ~BufStream();
1071 virtual StreamKind
getKind() { return strWeird
; }
1072 virtual void reset();
1073 virtual int getChar();
1074 virtual int lookChar();
1075 virtual GooString
*getPSFilter(int psLevel
, const char *indent
)
1077 virtual GBool
isBinary(GBool last
= gTrue
);
1079 int lookChar(int idx
);
1087 //------------------------------------------------------------------------
1088 // FixedLengthEncoder
1089 //------------------------------------------------------------------------
1091 class FixedLengthEncoder
: public FilterStream
{
1094 FixedLengthEncoder(Stream
*strA
, int lengthA
);
1095 ~FixedLengthEncoder();
1096 virtual StreamKind
getKind() { return strWeird
; }
1097 virtual void reset();
1098 virtual int getChar();
1099 virtual int lookChar();
1100 virtual GooString
*getPSFilter(int /*psLevel*/, const char * /*indent*/) { return NULL
; }
1101 virtual GBool
isBinary(GBool
/*last = gTrue*/);
1102 virtual GBool
isEncoder() { return gTrue
; }
1110 //------------------------------------------------------------------------
1112 //------------------------------------------------------------------------
1114 class ASCIIHexEncoder
: public FilterStream
{
1117 ASCIIHexEncoder(Stream
*strA
);
1118 virtual ~ASCIIHexEncoder();
1119 virtual StreamKind
getKind() { return strWeird
; }
1120 virtual void reset();
1121 virtual int getChar()
1122 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
1123 virtual int lookChar()
1124 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
1125 virtual GooString
*getPSFilter(int /*psLevel*/, const char * /*indent*/) { return NULL
; }
1126 virtual GBool
isBinary(GBool
/*last = gTrue*/) { return gFalse
; }
1127 virtual GBool
isEncoder() { return gTrue
; }
1140 //------------------------------------------------------------------------
1142 //------------------------------------------------------------------------
1144 class ASCII85Encoder
: public FilterStream
{
1147 ASCII85Encoder(Stream
*strA
);
1148 virtual ~ASCII85Encoder();
1149 virtual StreamKind
getKind() { return strWeird
; }
1150 virtual void reset();
1151 virtual int getChar()
1152 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
1153 virtual int lookChar()
1154 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
1155 virtual GooString
*getPSFilter(int /*psLevel*/, const char * /*indent*/) { return NULL
; }
1156 virtual GBool
isBinary(GBool
/*last = gTrue*/) { return gFalse
; }
1157 virtual GBool
isEncoder() { return gTrue
; }
1170 //------------------------------------------------------------------------
1172 //------------------------------------------------------------------------
1174 class RunLengthEncoder
: public FilterStream
{
1177 RunLengthEncoder(Stream
*strA
);
1178 virtual ~RunLengthEncoder();
1179 virtual StreamKind
getKind() { return strWeird
; }
1180 virtual void reset();
1181 virtual int getChar()
1182 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
1183 virtual int lookChar()
1184 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
1185 virtual GooString
*getPSFilter(int /*psLevel*/, const char * /*indent*/) { return NULL
; }
1186 virtual GBool
isBinary(GBool
/*last = gTrue*/) { return gTrue
; }
1187 virtual GBool
isEncoder() { return gTrue
; }
1200 //------------------------------------------------------------------------
1202 //------------------------------------------------------------------------
1204 class CMYKGrayEncoder
: public FilterStream
{
1207 CMYKGrayEncoder(Stream
*strA
);
1208 virtual ~CMYKGrayEncoder();
1209 virtual StreamKind
getKind() { return strWeird
; }
1210 virtual void reset();
1211 virtual int getChar()
1212 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
1213 virtual int lookChar()
1214 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
1215 virtual GooString
*getPSFilter(int /*psLevel*/, const char * /*indent*/) { return NULL
; }
1216 virtual GBool
isBinary(GBool
/*last = gTrue*/) { return gFalse
; }
1217 virtual GBool
isEncoder() { return gTrue
; }
1229 //------------------------------------------------------------------------
1231 //------------------------------------------------------------------------
1233 class RGBGrayEncoder
: public FilterStream
{
1236 RGBGrayEncoder(Stream
*strA
);
1237 virtual ~RGBGrayEncoder();
1238 virtual StreamKind
getKind() { return strWeird
; }
1239 virtual void reset();
1240 virtual int getChar()
1241 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
++ & 0xff); }
1242 virtual int lookChar()
1243 { return (bufPtr
>= bufEnd
&& !fillBuf()) ? EOF
: (*bufPtr
& 0xff); }
1244 virtual GooString
*getPSFilter(int /*psLevel*/, const char * /*indent*/) { return NULL
; }
1245 virtual GBool
isBinary(GBool
/*last = gTrue*/) { return gFalse
; }
1246 virtual GBool
isEncoder() { return gTrue
; }