beta-0.89.2
[luatex.git] / source / libs / poppler / poppler-src / poppler / Stream.h
blob00b2925b3d561eb12b069d5803be74f8defab48d
1 //========================================================================
2 //
3 // Stream.h
4 //
5 // Copyright 1996-2003 Glyph & Cog, LLC
6 //
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 //========================================================================
35 #ifndef STREAM_H
36 #define STREAM_H
38 #ifdef USE_GCC_PRAGMAS
39 #pragma interface
40 #endif
42 #include "poppler-config.h"
43 #include <stdio.h>
44 #include "goo/gtypes.h"
45 #include "Object.h"
46 #include "goo/GooMutex.h"
48 class GooFile;
49 class BaseStream;
50 class CachedFile;
52 //------------------------------------------------------------------------
54 enum StreamKind {
55 strFile,
56 strCachedFile,
57 strASCIIHex,
58 strASCII85,
59 strLZW,
60 strRunLength,
61 strCCITTFax,
62 strDCT,
63 strFlate,
64 strJBIG2,
65 strJPX,
66 strWeird, // internal-use stream types
67 strCrypt // internal-use to detect decode streams
70 enum StreamColorSpaceMode {
71 streamCSNone,
72 streamCSDeviceGray,
73 streamCSDeviceRGB,
74 streamCSDeviceCMYK
77 //------------------------------------------------------------------------
79 // This is in Stream.h instead of Decrypt.h to avoid really annoying
80 // include file dependency loops.
81 enum CryptAlgorithm {
82 cryptRC4,
83 cryptAES,
84 cryptAES256
87 //------------------------------------------------------------------------
89 typedef struct _ByteRange {
90 Guint offset;
91 Guint length;
92 } ByteRange;
94 //------------------------------------------------------------------------
95 // Stream (base class)
96 //------------------------------------------------------------------------
98 class Stream {
99 public:
101 // Constructor.
102 Stream();
104 // Destructor.
105 virtual ~Stream();
107 // Reference counting.
108 int incRef();
109 int decRef();
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)
122 if (hasGetChars()) {
123 return getChars(nChars, buffer);
124 } else {
125 for (int i = 0; i < nChars; ++i) {
126 const int c = getChar();
127 if (likely(c != EOF)) buffer[i] = c;
128 else return i;
130 return nChars;
134 inline void fillGooString(GooString *s)
136 Guchar readBuf[4096];
137 int readChars;
138 reset();
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)
146 int readChars;
147 Guchar *buf = (Guchar *)gmalloc(initialSize);
148 int size = initialSize;
149 *length = 0;
150 int charsToRead = initialSize;
151 bool continueReading = true;
152 reset();
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);
160 } else {
161 continueReading = false;
163 } else {
164 continueReading = false;
167 return buf;
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);
230 private:
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
237 #if MULTITHREADED
238 GooMutex mutex;
239 #endif
243 //------------------------------------------------------------------------
244 // OutStream
246 // This is the base class for all streams that output to a file
247 //------------------------------------------------------------------------
248 class OutStream {
249 public:
250 // Constructor.
251 OutStream ();
253 // Desctructor.
254 virtual ~OutStream ();
256 // Reference counting.
257 int incRef() { return ++ref; }
258 int decRef() { return --ref; }
260 // Close the stream
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;
271 private:
272 int ref; // reference count
276 //------------------------------------------------------------------------
277 // FileOutStream
278 //------------------------------------------------------------------------
279 class FileOutStream : public OutStream {
280 public:
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, ...);
292 private:
293 FILE *f;
294 Goffset start;
299 //------------------------------------------------------------------------
300 // BaseStream
302 // This is the base class for all streams that read directly from a file.
303 //------------------------------------------------------------------------
305 class BaseStream: public Stream {
306 public:
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;
325 protected:
327 Goffset length;
328 Object dict;
331 //------------------------------------------------------------------------
332 // FilterStream
334 // This is the base class for all streams that filter another stream.
335 //------------------------------------------------------------------------
337 class FilterStream: public Stream {
338 public:
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(); }
353 protected:
355 Stream *str;
358 //------------------------------------------------------------------------
359 // ImageStream
360 //------------------------------------------------------------------------
362 class ImageStream {
363 public:
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);
370 ~ImageStream();
372 // Reset the stream.
373 void reset();
375 // Close the stream previously reset
376 void close();
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
383 // end of file.
384 Guchar *getLine();
386 // Skip an entire line from the image.
387 void skipLine();
389 private:
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 //------------------------------------------------------------------------
403 // StreamPredictor
404 //------------------------------------------------------------------------
406 class StreamPredictor {
407 public:
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);
414 ~StreamPredictor();
416 GBool isOk() { return ok; }
418 int lookChar();
419 int getChar();
420 int getChars(int nChars, Guchar *buffer);
422 private:
424 GBool getNextLine();
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
436 GBool ok;
439 //------------------------------------------------------------------------
440 // FileStream
441 //------------------------------------------------------------------------
443 #define fileStreamBufSize 256
445 class FileStream: public BaseStream {
446 public:
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(); }
469 private:
471 GBool fillBuf();
473 virtual GBool hasGetChars() { return true; }
474 virtual int getChars(int nChars, Guchar *buffer)
476 int n, m;
478 n = 0;
479 while (n < nChars) {
480 if (bufPtr >= bufEnd) {
481 if (!fillBuf()) {
482 break;
485 m = (int)(bufEnd - bufPtr);
486 if (m > nChars - n) {
487 m = nChars - n;
489 memcpy(buffer + n, bufPtr, m);
490 bufPtr += m;
491 n += m;
493 return n;
496 private:
497 GooFile* file;
498 Goffset offset;
499 Goffset start;
500 GBool limited;
501 char buf[fileStreamBufSize];
502 char *bufPtr;
503 char *bufEnd;
504 Goffset bufPos;
505 Goffset savePos;
506 GBool saved;
509 //------------------------------------------------------------------------
510 // CachedFileStream
511 //------------------------------------------------------------------------
513 #define cachedStreamBufSize 1024
515 class CachedFileStream: public BaseStream {
516 public:
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(); }
539 private:
541 GBool fillBuf();
543 CachedFile *cc;
544 Goffset start;
545 GBool limited;
546 char buf[cachedStreamBufSize];
547 char *bufPtr;
548 char *bufEnd;
549 Guint bufPos;
550 int savePos;
551 GBool saved;
555 //------------------------------------------------------------------------
556 // MemStream
557 //------------------------------------------------------------------------
559 class MemStream: public BaseStream {
560 public:
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 (); }
586 private:
588 virtual GBool hasGetChars() { return true; }
589 virtual int getChars(int nChars, Guchar *buffer);
591 char *buf;
592 Goffset start;
593 char *bufEnd;
594 char *bufPtr;
595 GBool needFree;
598 //------------------------------------------------------------------------
599 // EmbedStream
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 {
609 public:
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(); }
629 private:
631 virtual GBool hasGetChars() { return true; }
632 virtual int getChars(int nChars, Guchar *buffer);
634 Stream *str;
635 GBool limited;
638 //------------------------------------------------------------------------
639 // ASCIIHexStream
640 //------------------------------------------------------------------------
642 class ASCIIHexStream: public FilterStream {
643 public:
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);
655 private:
657 int buf;
658 GBool eof;
661 //------------------------------------------------------------------------
662 // ASCII85Stream
663 //------------------------------------------------------------------------
665 class ASCII85Stream: public FilterStream {
666 public:
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);
678 private:
680 int c[5];
681 int b[4];
682 int index, n;
683 GBool eof;
686 //------------------------------------------------------------------------
687 // LZWStream
688 //------------------------------------------------------------------------
690 class LZWStream: public FilterStream {
691 public:
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);
705 private:
707 virtual GBool hasGetChars() { return true; }
708 virtual int getChars(int nChars, Guchar *buffer);
710 inline int doGetRawChar() {
711 if (eof) {
712 return EOF;
714 if (seqIndex >= seqLength) {
715 if (!processNextCode()) {
716 return EOF;
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
728 int length;
729 int head;
730 Guchar tail;
731 } table[4097];
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();
742 void clearTable();
743 int getCode();
746 //------------------------------------------------------------------------
747 // RunLengthStream
748 //------------------------------------------------------------------------
750 class RunLengthStream: public FilterStream {
751 public:
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);
764 private:
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
772 GBool eof;
774 GBool fillBuf();
777 //------------------------------------------------------------------------
778 // CCITTFaxStream
779 //------------------------------------------------------------------------
781 struct CCITTCodeTable;
783 class CCITTFaxStream: public FilterStream {
784 public:
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; }
805 private:
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 //------------------------------------------------------------------------
838 // DCTStream
839 //------------------------------------------------------------------------
841 // DCT component info
842 struct DCTCompInfo {
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
849 struct DCTScanInfo {
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 {
868 public:
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();
882 private:
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
894 // 0 = none
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
914 void restart();
915 GBool readMCURow();
916 void readScan();
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]);
923 void decodeImage();
924 void transformDataUnit(Gushort *quantTable,
925 int dataIn[64], Guchar dataOut[64]);
926 int readHuffSym(DCTHuffTable *table);
927 int readAmp(int size);
928 int readBit();
929 GBool readHeader();
930 GBool readBaselineSOF();
931 GBool readProgressiveSOF();
932 GBool readScanInfo();
933 GBool readQuantTables();
934 GBool readHuffmanTables();
935 GBool readRestartInterval();
936 GBool readJFIFMarker();
937 GBool readAdobeMarker();
938 GBool readTrailer();
939 int readMarker();
940 int read16();
943 #endif
945 #ifndef ENABLE_ZLIB
946 //------------------------------------------------------------------------
947 // FlateStream
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
958 struct FlateCode {
959 Gushort len; // code length, in bits
960 Gushort val; // value represented by this code
963 struct FlateHuffmanTab {
964 FlateCode *codes;
965 int maxLen;
968 // Decoding info for length and distance code words
969 struct FlateDecode {
970 int bits; // # extra bits
971 int first; // first length/distance
974 class FlateStream: public FilterStream {
975 public:
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 ();
990 private:
991 void flateReset(GBool unfiltered);
992 inline int doGetRawChar() {
993 int c;
995 while (remain == 0) {
996 if (endOfBlock && eof)
997 return EOF;
998 readSome();
1000 c = buf[index];
1001 index = (index + 1) & flateMask;
1002 --remain;
1003 return c;
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
1031 fixedLitCodeTab;
1032 static FlateHuffmanTab // fixed distance code table
1033 fixedDistCodeTab;
1035 void readSome();
1036 GBool startBlock();
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);
1043 #endif
1045 //------------------------------------------------------------------------
1046 // EOFStream
1047 //------------------------------------------------------------------------
1049 class EOFStream: public FilterStream {
1050 public:
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 //------------------------------------------------------------------------
1063 // BufStream
1064 //------------------------------------------------------------------------
1066 class BufStream: public FilterStream {
1067 public:
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)
1076 { return NULL; }
1077 virtual GBool isBinary(GBool last = gTrue);
1079 int lookChar(int idx);
1081 private:
1083 int *buf;
1084 int bufSize;
1087 //------------------------------------------------------------------------
1088 // FixedLengthEncoder
1089 //------------------------------------------------------------------------
1091 class FixedLengthEncoder: public FilterStream {
1092 public:
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; }
1104 private:
1106 int length;
1107 int count;
1110 //------------------------------------------------------------------------
1111 // ASCIIHexEncoder
1112 //------------------------------------------------------------------------
1114 class ASCIIHexEncoder: public FilterStream {
1115 public:
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; }
1129 private:
1131 char buf[4];
1132 char *bufPtr;
1133 char *bufEnd;
1134 int lineLen;
1135 GBool eof;
1137 GBool fillBuf();
1140 //------------------------------------------------------------------------
1141 // ASCII85Encoder
1142 //------------------------------------------------------------------------
1144 class ASCII85Encoder: public FilterStream {
1145 public:
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; }
1159 private:
1161 char buf[8];
1162 char *bufPtr;
1163 char *bufEnd;
1164 int lineLen;
1165 GBool eof;
1167 GBool fillBuf();
1170 //------------------------------------------------------------------------
1171 // RunLengthEncoder
1172 //------------------------------------------------------------------------
1174 class RunLengthEncoder: public FilterStream {
1175 public:
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; }
1189 private:
1191 char buf[131];
1192 char *bufPtr;
1193 char *bufEnd;
1194 char *nextEnd;
1195 GBool eof;
1197 GBool fillBuf();
1200 //------------------------------------------------------------------------
1201 // CMYKGrayEncoder
1202 //------------------------------------------------------------------------
1204 class CMYKGrayEncoder: public FilterStream {
1205 public:
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; }
1219 private:
1221 char buf[2];
1222 char *bufPtr;
1223 char *bufEnd;
1224 GBool eof;
1226 GBool fillBuf();
1229 //------------------------------------------------------------------------
1230 // RGBGrayEncoder
1231 //------------------------------------------------------------------------
1233 class RGBGrayEncoder: public FilterStream {
1234 public:
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; }
1248 private:
1250 char buf[2];
1251 char *bufPtr;
1252 char *bufEnd;
1253 GBool eof;
1255 GBool fillBuf();
1258 #endif