Coverage Report

Created: 2026-04-12 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xpdf-4.06/xpdf/Stream.h
Line
Count
Source
1
//========================================================================
2
//
3
// Stream.h
4
//
5
// Copyright 1996-2003 Glyph & Cog, LLC
6
//
7
//========================================================================
8
9
#ifndef STREAM_H
10
#define STREAM_H
11
12
#include <aconf.h>
13
14
#include <stdio.h>
15
#if HAVE_JPEGLIB
16
#include <jpeglib.h>
17
#include <setjmp.h>
18
#endif
19
#include "gtypes.h"
20
#include "gfile.h"
21
#include "Object.h"
22
23
class BaseStream;
24
class SharedFile;
25
26
//------------------------------------------------------------------------
27
28
enum StreamKind {
29
  strFile,
30
  strASCIIHex,
31
  strASCII85,
32
  strLZW,
33
  strRunLength,
34
  strCCITTFax,
35
  strDCT,
36
  strFlate,
37
  strJBIG2,
38
  strJPX,
39
  strWeird      // internal-use stream types
40
};
41
42
enum StreamColorSpaceMode {
43
  streamCSNone,
44
  streamCSDeviceGray,
45
  streamCSDeviceRGB,
46
  streamCSDeviceCMYK
47
};
48
49
//------------------------------------------------------------------------
50
51
// This is in Stream.h instead of Decrypt.h to avoid really annoying
52
// include file dependency loops.
53
enum CryptAlgorithm {
54
  cryptRC4,
55
  cryptAES,
56
  cryptAES256
57
};
58
59
//------------------------------------------------------------------------
60
// Stream (base class)
61
//------------------------------------------------------------------------
62
63
class Stream {
64
public:
65
66
  // Constructor.
67
  Stream();
68
69
  // Destructor.
70
  virtual ~Stream();
71
72
  virtual Stream *copy() = 0;
73
74
  // Get kind of stream.
75
  virtual StreamKind getKind() = 0;
76
77
0
  virtual GBool isEmbedStream() { return gFalse; }
78
79
  // Disable checking for 'decompression bombs', i.e., cases where the
80
  // encryption ratio looks suspiciously high.  This should be called
81
  // for things like images which (a) can have very high compression
82
  // ratios in certain cases, and (b) have fixed data sizes controlled
83
  // by the reader.
84
175k
  virtual void disableDecompressionBombChecking() {}
85
86
  // Reset stream to beginning.
87
  virtual void reset() = 0;
88
89
  // Close down the stream.
90
  virtual void close();
91
92
  // Get next char from stream.
93
  virtual int getChar() = 0;
94
95
  // Peek at next char in stream.
96
  virtual int lookChar() = 0;
97
98
  // Get next char from stream without using the predictor.
99
  // This is only used by StreamPredictor.
100
  virtual int getRawChar();
101
102
  // Get exactly <size> bytes from stream.  Returns the number of
103
  // bytes read -- the returned count will be less than <size> at EOF.
104
  virtual int getBlock(char *blk, int size);
105
106
  // Get next line from stream.
107
  virtual char *getLine(char *buf, int size);
108
109
  // Discard the next <n> bytes from stream.  Returns the number of
110
  // bytes discarded, which will be less than <n> only if EOF is
111
  // reached.
112
  virtual Guint discardChars(Guint n);
113
114
  // Get current position in file.
115
  virtual GFileOffset getPos() = 0;
116
117
  // Go to a position in the stream.  If <dir> is negative, the
118
  // position is from the end of the file; otherwise the position is
119
  // from the start of the file.
120
  virtual void setPos(GFileOffset pos, int dir = 0) = 0;
121
122
  // Get PostScript command for the filter(s).
123
  virtual GString *getPSFilter(int psLevel, const char *indent,
124
             GBool okToReadStream);
125
126
  // Does this stream type potentially contain non-printable chars?
127
  virtual GBool isBinary(GBool last = gTrue) = 0;
128
129
  // Does this stream include a "strong" compression filter (anything
130
  // other than RLE)?
131
0
  virtual GBool hasStrongCompression() { return gFalse; }
132
133
  // Get the BaseStream of this stream.
134
  virtual BaseStream *getBaseStream() = 0;
135
136
  // Get the stream after the last decoder (this may be a BaseStream
137
  // or a DecryptStream).
138
  virtual Stream *getUndecodedStream() = 0;
139
140
  // Get the dictionary associated with this stream.
141
  virtual Dict *getDict() = 0;
142
143
  // Is this an encoding filter?
144
0
  virtual GBool isEncoder() { return gFalse; }
145
146
  // Get image parameters which are defined by the stream contents.
147
  virtual void getImageParams(int *bitsPerComponent,
148
102k
            StreamColorSpaceMode *csMode) {}
149
150
  // Return the next stream in the "stack".
151
0
  virtual Stream *getNextStream() { return NULL; }
152
153
  // Add filters to this stream according to the parameters in <dict>.
154
  // Returns the new stream.
155
  Stream *addFilters(Object *dict, int recursion = 0);
156
157
private:
158
159
  Stream *makeFilter(char *name, Stream *str, Object *params,
160
         int recursion, GBool *ok);
161
};
162
163
//------------------------------------------------------------------------
164
// BaseStream
165
//
166
// This is the base class for all streams that read directly from a file.
167
//------------------------------------------------------------------------
168
169
class BaseStream: public Stream {
170
public:
171
172
  BaseStream(Object *dictA);
173
  virtual ~BaseStream();
174
  virtual Stream *makeSubStream(GFileOffset start, GBool limited,
175
        GFileOffset length, Object *dict) = 0;
176
  virtual void setPos(GFileOffset pos, int dir = 0) = 0;
177
0
  virtual GBool isBinary(GBool last = gTrue) { return last; }
178
179k
  virtual BaseStream *getBaseStream() { return this; }
179
5.30M
  virtual Stream *getUndecodedStream() { return this; }
180
925k
  virtual Dict *getDict() { return dict.getDict(); }
181
19.7k
  virtual GString *getFileName() { return NULL; }
182
183
  // Get/set position of first byte of stream within the file.
184
  virtual GFileOffset getStart() = 0;
185
  virtual void moveStart(int delta) = 0;
186
187
protected:
188
189
  Object dict;
190
};
191
192
//------------------------------------------------------------------------
193
// FilterStream
194
//
195
// This is the base class for all streams that filter another stream.
196
//------------------------------------------------------------------------
197
198
class FilterStream: public Stream {
199
public:
200
201
  FilterStream(Stream *strA);
202
  virtual ~FilterStream();
203
  virtual void disableDecompressionBombChecking()
204
20.8k
    { str->disableDecompressionBombChecking(); }
205
  virtual void close();
206
18.2M
  virtual GFileOffset getPos() { return str->getPos(); }
207
  virtual void setPos(GFileOffset pos, int dir = 0);
208
0
  virtual BaseStream *getBaseStream() { return str->getBaseStream(); }
209
514k
  virtual Stream *getUndecodedStream() { return str->getUndecodedStream(); }
210
515k
  virtual Dict *getDict() { return str->getDict(); }
211
0
  virtual Stream *getNextStream() { return str; }
212
213
protected:
214
215
  Stream *str;
216
};
217
218
//------------------------------------------------------------------------
219
// ImageStream
220
//------------------------------------------------------------------------
221
222
class ImageStream {
223
public:
224
225
  // Create an image stream object for an image with the specified
226
  // parameters.  Note that these are the actual image parameters,
227
  // which may be different from the predictor parameters.
228
  ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA);
229
230
  ~ImageStream();
231
232
  // Reset the stream.
233
  void reset();
234
235
  // Close down the stream.
236
  void close();
237
238
  // Gets the next pixel from the stream.  <pix> should be able to hold
239
  // at least nComps elements.  Returns false at end of file.
240
  GBool getPixel(Guchar *pix);
241
242
  // Returns a pointer to the next line of pixels.  Returns NULL at
243
  // end of file.
244
  Guchar *getLine();
245
246
  // Skip an entire line from the image.
247
  void skipLine();
248
249
private:
250
251
  Stream *str;      // base stream
252
  int width;      // pixels per line
253
  int nComps;     // components per pixel
254
  int nBits;      // bits per component
255
  int nVals;      // components per line
256
  int inputLineSize;    // input line buffer size
257
  char *inputLine;    // input line buffer
258
  Guchar *imgLine;    // line buffer
259
  int imgIdx;     // current index in imgLine
260
};
261
262
263
//------------------------------------------------------------------------
264
// StreamPredictor
265
//------------------------------------------------------------------------
266
267
class StreamPredictor {
268
public:
269
270
  // Create a predictor object.  Note that the parameters are for the
271
  // predictor, and may not match the actual image parameters.
272
  StreamPredictor(Stream *strA, int predictorA,
273
      int widthA, int nCompsA, int nBitsA);
274
275
  ~StreamPredictor();
276
277
13.2k
  GBool isOk() { return ok; }
278
279
  void reset();
280
281
  int lookChar();
282
  int getChar();
283
  int getBlock(char *blk, int size);
284
285
8.23k
  int getPredictor() { return predictor; }
286
8.23k
  int getWidth() { return width; }
287
8.23k
  int getNComps() { return nComps; }
288
8.23k
  int getNBits() { return nBits; }
289
290
private:
291
292
  GBool getNextLine();
293
294
  Stream *str;      // base stream
295
  int predictor;    // predictor
296
  int width;      // pixels per line
297
  int nComps;     // components per pixel
298
  int nBits;      // bits per component
299
  int nVals;      // components per line
300
  int pixBytes;     // bytes per pixel
301
  int rowBytes;     // bytes per line
302
  Guchar *predLine;   // line buffer
303
  int predIdx;      // current index in predLine
304
  GBool ok;
305
};
306
307
//------------------------------------------------------------------------
308
// FileStream
309
//------------------------------------------------------------------------
310
311
0
#define fileStreamBufSize 256
312
313
class FileStream: public BaseStream {
314
public:
315
316
  FileStream(FILE *fA, GFileOffset startA, GBool limitedA,
317
       GFileOffset lengthA, Object *dictA);
318
  virtual ~FileStream();
319
  virtual Stream *copy();
320
  virtual Stream *makeSubStream(GFileOffset startA, GBool limitedA,
321
        GFileOffset lengthA, Object *dictA);
322
0
  virtual StreamKind getKind() { return strFile; }
323
  virtual void reset();
324
  virtual int getChar()
325
0
    { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
326
  virtual int lookChar()
327
0
    { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
328
  virtual int getBlock(char *blk, int size);
329
0
  virtual GFileOffset getPos() { return bufPos + (int)(bufPtr - buf); }
330
  virtual void setPos(GFileOffset pos, int dir = 0);
331
0
  virtual GFileOffset getStart() { return start; }
332
  virtual void moveStart(int delta);
333
334
private:
335
336
  FileStream(SharedFile *fA, GFileOffset startA, GBool limitedA,
337
       GFileOffset lengthA, Object *dictA);
338
  GBool fillBuf();
339
340
  SharedFile *f;
341
  GFileOffset start;
342
  GBool limited;
343
  GFileOffset length;
344
  char buf[fileStreamBufSize];
345
  char *bufPtr;
346
  char *bufEnd;
347
  GFileOffset bufPos;
348
};
349
350
//------------------------------------------------------------------------
351
// MemStream
352
//------------------------------------------------------------------------
353
354
class MemStream: public BaseStream {
355
public:
356
357
  MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA);
358
  virtual ~MemStream();
359
  virtual Stream *copy();
360
  virtual Stream *makeSubStream(GFileOffset start, GBool limited,
361
        GFileOffset lengthA, Object *dictA);
362
40.2k
  virtual StreamKind getKind() { return strWeird; }
363
  virtual void reset();
364
  virtual void close();
365
  virtual int getChar()
366
733M
    { return (bufPtr < bufEnd) ? (*bufPtr++ & 0xff) : EOF; }
367
  virtual int lookChar()
368
203M
    { return (bufPtr < bufEnd) ? (*bufPtr & 0xff) : EOF; }
369
  virtual int getBlock(char *blk, int size);
370
34.1M
  virtual GFileOffset getPos() { return (GFileOffset)(bufPtr - buf); }
371
  virtual void setPos(GFileOffset pos, int dir = 0);
372
55.8k
  virtual GFileOffset getStart() { return start; }
373
  virtual void moveStart(int delta);
374
375
private:
376
377
  char *buf;
378
  Guint start;
379
  Guint length;
380
  char *bufEnd;
381
  char *bufPtr;
382
  GBool needFree;
383
};
384
385
//------------------------------------------------------------------------
386
// EmbedStream
387
//
388
// This is a special stream type used for embedded streams (inline
389
// images).  It reads directly from the base stream -- after the
390
// EmbedStream is deleted, reads from the base stream will proceed where
391
// the BaseStream left off.  Note that this is very different behavior
392
// that creating a new FileStream (using makeSubStream).
393
//------------------------------------------------------------------------
394
395
class EmbedStream: public BaseStream {
396
public:
397
398
  EmbedStream(Stream *strA, Object *dictA, GBool limitedA, GFileOffset lengthA);
399
  virtual ~EmbedStream();
400
  virtual Stream *copy();
401
  virtual Stream *makeSubStream(GFileOffset start, GBool limitedA,
402
        GFileOffset lengthA, Object *dictA);
403
58.5k
  virtual StreamKind getKind() { return str->getKind(); }
404
0
  virtual GBool isEmbedStream() { return gTrue; }
405
102k
  virtual void reset() {}
406
  virtual int getChar();
407
  virtual int lookChar();
408
  virtual int getBlock(char *blk, int size);
409
98.7k
  virtual GFileOffset getPos() { return str->getPos(); }
410
  virtual void setPos(GFileOffset pos, int dir = 0);
411
  virtual GFileOffset getStart();
412
  virtual void moveStart(int delta);
413
414
private:
415
416
  Stream *str;
417
  GBool limited;
418
  GFileOffset length;
419
};
420
421
//------------------------------------------------------------------------
422
// ASCIIHexStream
423
//------------------------------------------------------------------------
424
425
class ASCIIHexStream: public FilterStream {
426
public:
427
428
  ASCIIHexStream(Stream *strA);
429
  virtual ~ASCIIHexStream();
430
  virtual Stream *copy();
431
82
  virtual StreamKind getKind() { return strASCIIHex; }
432
  virtual void reset();
433
  virtual int getChar()
434
69.1k
    { int c = lookChar(); buf = EOF; return c; }
435
  virtual int lookChar();
436
  virtual GString *getPSFilter(int psLevel, const char *indent,
437
             GBool okToReadStream);
438
  virtual GBool isBinary(GBool last = gTrue);
439
440
private:
441
442
  int buf;
443
  GBool eof;
444
};
445
446
//------------------------------------------------------------------------
447
// ASCII85Stream
448
//------------------------------------------------------------------------
449
450
class ASCII85Stream: public FilterStream {
451
public:
452
453
  ASCII85Stream(Stream *strA);
454
  virtual ~ASCII85Stream();
455
  virtual Stream *copy();
456
41
  virtual StreamKind getKind() { return strASCII85; }
457
  virtual void reset();
458
  virtual int getChar()
459
524k
    { int ch = lookChar(); ++index; return ch; }
460
  virtual int lookChar();
461
  virtual GString *getPSFilter(int psLevel, const char *indent,
462
             GBool okToReadStream);
463
  virtual GBool isBinary(GBool last = gTrue);
464
465
private:
466
467
  int c[5];
468
  int b[4];
469
  int index, n;
470
  GBool eof;
471
};
472
473
//------------------------------------------------------------------------
474
// LZWStream
475
//------------------------------------------------------------------------
476
477
class LZWStream: public FilterStream {
478
public:
479
480
  LZWStream(Stream *strA, int predictor, int columns, int colors,
481
      int bits, int earlyA);
482
  virtual ~LZWStream();
483
  virtual Stream *copy();
484
427
  virtual StreamKind getKind() { return strLZW; }
485
  virtual void disableDecompressionBombChecking();
486
  virtual void reset();
487
  virtual int getChar();
488
  virtual int lookChar();
489
  virtual int getRawChar();
490
  virtual int getBlock(char *blk, int size);
491
  virtual GString *getPSFilter(int psLevel, const char *indent,
492
             GBool okToReadStream);
493
  virtual GBool isBinary(GBool last = gTrue);
494
0
  virtual GBool hasStrongCompression() { return gTrue; }
495
496
private:
497
498
  StreamPredictor *pred;  // predictor
499
  int early;      // early parameter
500
  GBool eof;      // true if at eof
501
  int inputBuf;     // input buffer
502
  int inputBits;    // number of bits in input buffer
503
  struct {      // decoding table
504
    int length;
505
    int head;
506
    Guchar tail;
507
  } table[4097];
508
  int nextCode;     // next code to be used
509
  int nextBits;     // number of bits in next code word
510
  int prevCode;     // previous code used in stream
511
  int newChar;      // next char to be added to table
512
  Guchar seqBuf[4097];    // buffer for current sequence
513
  int seqLength;    // length of current sequence
514
  int seqIndex;     // index into current sequence
515
  GBool first;      // first code after a table clear
516
  GBool checkForDecompressionBombs;
517
  unsigned long long totalIn; // total number of encoded bytes read so far
518
  unsigned long long totalOut;  // total number of bytes decoded so far
519
520
  GBool processNextCode();
521
  void clearTable();
522
  int getCode();
523
};
524
525
//------------------------------------------------------------------------
526
// RunLengthStream
527
//------------------------------------------------------------------------
528
529
class RunLengthStream: public FilterStream {
530
public:
531
532
  RunLengthStream(Stream *strA);
533
  virtual ~RunLengthStream();
534
  virtual Stream *copy();
535
121
  virtual StreamKind getKind() { return strRunLength; }
536
  virtual void reset();
537
  virtual int getChar()
538
17.0M
    { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
539
  virtual int lookChar()
540
391k
    { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
541
  virtual int getBlock(char *blk, int size);
542
  virtual GString *getPSFilter(int psLevel, const char *indent,
543
             GBool okToReadStream);
544
  virtual GBool isBinary(GBool last = gTrue);
545
546
private:
547
548
  char buf[128];    // buffer
549
  char *bufPtr;     // next char to read
550
  char *bufEnd;     // end of buffer
551
  GBool eof;
552
553
  GBool fillBuf();
554
};
555
556
//------------------------------------------------------------------------
557
// CCITTFaxStream
558
//------------------------------------------------------------------------
559
560
struct CCITTCodeTable;
561
562
class CCITTFaxStream: public FilterStream {
563
public:
564
565
  CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA,
566
     GBool byteAlignA, int columnsA, int rowsA,
567
     GBool endOfBlockA, GBool blackA);
568
  virtual ~CCITTFaxStream();
569
  virtual Stream *copy();
570
592
  virtual StreamKind getKind() { return strCCITTFax; }
571
  virtual void reset();
572
  virtual int getChar();
573
  virtual int lookChar();
574
  virtual int getBlock(char *blk, int size);
575
  virtual GString *getPSFilter(int psLevel, const char *indent,
576
             GBool okToReadStream);
577
  virtual GBool isBinary(GBool last = gTrue);
578
0
  virtual GBool hasStrongCompression() { return gTrue; }
579
580
private:
581
582
  int encoding;     // 'K' parameter
583
  GBool endOfLine;    // 'EndOfLine' parameter
584
  GBool byteAlign;    // 'EncodedByteAlign' parameter
585
  int columns;      // 'Columns' parameter
586
  int rows;     // 'Rows' parameter
587
  GBool endOfBlock;   // 'EndOfBlock' parameter
588
  GBool black;      // 'BlackIs1' parameter
589
  int blackXOR;
590
  GBool eof;      // true if at eof
591
  GBool nextLine2D;   // true if next line uses 2D encoding
592
  int row;      // current row
593
  Guint inputBuf;   // input buffer
594
  int inputBits;    // number of bits in input buffer
595
  int *codingLine;    // coding line changing elements
596
  int *refLine;     // reference line changing elements
597
  int nextCol;      // next column to read
598
  int a0i;      // index into codingLine
599
  GBool err;      // error on current line
600
  int nErrors;      // number of errors so far in this stream
601
602
  void addPixels(int a1, int blackPixels);
603
  void addPixelsNeg(int a1, int blackPixels);
604
  GBool readRow();
605
  short getTwoDimCode();
606
  short getWhiteCode();
607
  short getBlackCode();
608
  short lookBits(int n);
609
17.1M
  void eatBits(int n) { if ((inputBits -= n) < 0) inputBits = 0; }
610
};
611
612
//------------------------------------------------------------------------
613
// DCTStream
614
//------------------------------------------------------------------------
615
616
#if HAVE_JPEGLIB
617
618
class DCTStream;
619
620
#define dctStreamBufSize 4096
621
622
struct DCTSourceMgr {
623
  jpeg_source_mgr src;
624
  DCTStream *str;
625
  char buf[dctStreamBufSize];
626
};
627
628
struct DCTErrorMgr {
629
  struct jpeg_error_mgr err;
630
  jmp_buf setjmpBuf;
631
};
632
633
#else // HAVE_JPEGLIB
634
635
// DCT component info
636
struct DCTCompInfo {
637
  int id;     // component ID
638
  int hSample, vSample;   // horiz/vert sampling resolutions
639
  int quantTable;   // quantization table number
640
  int prevDC;     // DC coefficient accumulator
641
};
642
643
struct DCTScanInfo {
644
  GBool comp[4];    // comp[i] is set if component i is
645
        //   included in this scan
646
  int numComps;     // number of components in the scan
647
  int dcHuffTable[4];   // DC Huffman table numbers
648
  int acHuffTable[4];   // AC Huffman table numbers
649
  int firstCoeff, lastCoeff;  // first and last DCT coefficient
650
  int ah, al;     // successive approximation parameters
651
};
652
653
// DCT Huffman decoding table
654
struct DCTHuffTable {
655
  Guchar firstSym[17];    // first symbol for this bit length
656
  Gushort firstCode[17];  // first code for this bit length
657
  Gushort numCodes[17];   // number of codes of this bit length
658
  Guchar sym[256];    // symbols
659
};
660
661
#endif // HAVE_JPEGLIB
662
663
class DCTStream: public FilterStream {
664
public:
665
666
  DCTStream(Stream *strA, int colorXformA);
667
  virtual ~DCTStream();
668
  virtual Stream *copy();
669
818
  virtual StreamKind getKind() { return strDCT; }
670
  virtual void reset();
671
  virtual void close();
672
  virtual int getChar();
673
  virtual int lookChar();
674
  virtual int getBlock(char *blk, int size);
675
  virtual GString *getPSFilter(int psLevel, const char *indent,
676
             GBool okToReadStream);
677
  virtual GBool isBinary(GBool last = gTrue);
678
0
  virtual GBool hasStrongCompression() { return gTrue; }
679
0
  Stream *getRawStream() { return str; }
680
681
private:
682
683
  GBool checkSequentialInterleaved();
684
685
#if HAVE_JPEGLIB
686
687
  int colorXform;   // color transform: -1 = unspecified
688
        //                   0 = none
689
        //                   1 = YUV/YUVK -> RGB/CMYK
690
  jpeg_decompress_struct decomp;
691
  DCTErrorMgr errorMgr;
692
  DCTSourceMgr sourceMgr;
693
  GBool error;
694
  char *lineBuf;
695
  int lineBufHeight;
696
  char *lineBufRows[4];
697
  char *bufPtr;
698
  char *bufEnd;
699
  GBool inlineImage;
700
701
  GBool fillBuf();
702
  static void errorExit(j_common_ptr d);
703
  static void errorMessage(j_common_ptr d);
704
  static void initSourceCbk(j_decompress_ptr d);
705
  static boolean fillInputBufferCbk(j_decompress_ptr d);
706
  static void skipInputDataCbk(j_decompress_ptr d, long numBytes);
707
  static void termSourceCbk(j_decompress_ptr d);
708
709
#else // HAVE_JPEGLIB
710
711
  GBool prepared;   // set after prepare() is called
712
  GBool progressive;    // set if in progressive mode
713
  GBool interleaved;    // set if in interleaved mode
714
  int width, height;    // image size
715
  int mcuWidth, mcuHeight;  // size of min coding unit, in data units
716
  int bufWidth, bufHeight;  // frameBuf size
717
  DCTCompInfo compInfo[4];  // info for each component
718
  DCTScanInfo scanInfo;   // info for the current scan
719
  int numComps;     // number of components in image
720
  int colorXform;   // color transform: -1 = unspecified
721
        //                   0 = none
722
        //                   1 = YUV/YUVK -> RGB/CMYK
723
  GBool gotJFIFMarker;    // set if APP0 JFIF marker was present
724
  GBool gotAdobeMarker;   // set if APP14 Adobe marker was present
725
  int restartInterval;    // restart interval, in MCUs
726
  Gushort quantTables[4][64]; // quantization tables
727
  int numQuantTables;   // number of quantization tables
728
  DCTHuffTable dcHuffTables[4]; // DC Huffman tables
729
  DCTHuffTable acHuffTables[4]; // AC Huffman tables
730
  int numDCHuffTables;    // number of DC Huffman tables
731
  int numACHuffTables;    // number of AC Huffman tables
732
  Guchar *rowBuf;
733
  Guchar *rowBufPtr;    // current position within rowBuf
734
  Guchar *rowBufEnd;    // end of valid data in rowBuf
735
  int *frameBuf[4];   // buffer for frame (progressive mode)
736
  int comp, x, y;   // current position within image/MCU
737
  int restartCtr;   // MCUs left until restart
738
  int restartMarker;    // next restart marker
739
  int eobRun;     // number of EOBs left in the current run
740
  int inputBuf;     // input buffer for variable length codes
741
  int inputBits;    // number of valid bits in input buffer
742
743
  void prepare();
744
  void restart();
745
  GBool readMCURow();
746
  void readScan();
747
  GBool readDataUnit(DCTHuffTable *dcHuffTable,
748
         DCTHuffTable *acHuffTable,
749
         int *prevDC, int data[64]);
750
  GBool readProgressiveDataUnit(DCTHuffTable *dcHuffTable,
751
        DCTHuffTable *acHuffTable,
752
        int *prevDC, int data[64]);
753
  void decodeImage();
754
  void transformDataUnit(Gushort *quantTable,
755
       int dataIn[64], Guchar dataOut[64]);
756
  int readHuffSym(DCTHuffTable *table);
757
  int readAmp(int size);
758
  int readBit();
759
  GBool readHeader(GBool frame);
760
  GBool readBaselineSOF();
761
  GBool readProgressiveSOF();
762
  GBool readScanInfo();
763
  GBool readQuantTables();
764
  GBool readHuffmanTables();
765
  GBool readRestartInterval();
766
  GBool readJFIFMarker();
767
  GBool readAdobeMarker();
768
  GBool readTrailer();
769
  int readMarker();
770
  int read16();
771
772
#endif // HAVE_JPEGLIB
773
};
774
775
//------------------------------------------------------------------------
776
// FlateStream
777
//------------------------------------------------------------------------
778
779
891M
#define flateWindow          32768    // buffer size
780
719M
#define flateMask            (flateWindow-1)
781
#define flateMaxHuffman         15    // max Huffman code length
782
2.60M
#define flateMaxCodeLenCodes    19    // max # code length codes
783
237k
#define flateMaxLitCodes       288    // max # literal codes
784
237k
#define flateMaxDistCodes       30    // max # distance codes
785
786
// Huffman code table entry
787
struct FlateCode {
788
  Gushort len;      // code length, in bits
789
  Gushort val;      // value represented by this code
790
};
791
792
struct FlateHuffmanTab {
793
  FlateCode *codes;
794
  int maxLen;
795
};
796
797
// Decoding info for length and distance code words
798
struct FlateDecode {
799
  int bits;     // # extra bits
800
  int first;      // first length/distance
801
};
802
803
class FlateStream: public FilterStream {
804
public:
805
806
  FlateStream(Stream *strA, int predictor, int columns,
807
        int colors, int bits);
808
  virtual ~FlateStream();
809
  virtual Stream *copy();
810
25.1k
  virtual StreamKind getKind() { return strFlate; }
811
  virtual void disableDecompressionBombChecking();
812
  virtual void reset();
813
  virtual int getChar();
814
  virtual int lookChar();
815
  virtual int getRawChar();
816
  virtual int getBlock(char *blk, int size);
817
  virtual GString *getPSFilter(int psLevel, const char *indent,
818
             GBool okToReadStream);
819
  virtual GBool isBinary(GBool last = gTrue);
820
0
  virtual GBool hasStrongCompression() { return gTrue; }
821
822
private:
823
824
  StreamPredictor *pred;  // predictor
825
  Guchar buf[flateWindow];  // output data buffer
826
  int index;      // current index into output buffer
827
  int remain;     // number valid bytes in output buffer
828
  int codeBuf;      // input buffer
829
  int codeSize;     // number of bits in input buffer
830
  int       // literal and distance code lengths
831
    codeLengths[flateMaxLitCodes + flateMaxDistCodes];
832
  FlateHuffmanTab litCodeTab; // literal code table
833
  FlateHuffmanTab distCodeTab;  // distance code table
834
  GBool compressedBlock;  // set if reading a compressed block
835
  int blockLen;     // remaining length of uncompressed block
836
  GBool endOfBlock;   // set when end of block is reached
837
  GBool eof;      // set when end of stream is reached
838
  GBool checkForDecompressionBombs;
839
  unsigned long long totalIn; // total number of encoded bytes read so far
840
  unsigned long long totalOut;  // total number of bytes decoded so far
841
842
  static int      // code length code reordering
843
    codeLenCodeMap[flateMaxCodeLenCodes];
844
  static FlateDecode    // length decoding info
845
    lengthDecode[flateMaxLitCodes-257];
846
  static FlateDecode    // distance decoding info
847
    distDecode[flateMaxDistCodes];
848
  static FlateHuffmanTab  // fixed literal code table
849
    fixedLitCodeTab;
850
  static FlateHuffmanTab  // fixed distance code table
851
    fixedDistCodeTab;
852
853
  void readSome();
854
  GBool startBlock();
855
  void loadFixedCodes();
856
  GBool readDynamicCodes();
857
  void compHuffmanCodes(int *lengths, int n, FlateHuffmanTab *tab);
858
  int getHuffmanCodeWord(FlateHuffmanTab *tab);
859
  int getCodeWord(int bits);
860
};
861
862
//------------------------------------------------------------------------
863
// EOFStream
864
//------------------------------------------------------------------------
865
866
class EOFStream: public FilterStream {
867
public:
868
869
  EOFStream(Stream *strA);
870
  virtual ~EOFStream();
871
  virtual Stream *copy();
872
586
  virtual StreamKind getKind() { return strWeird; }
873
10.6k
  virtual void reset() {}
874
3.17M
  virtual int getChar() { return EOF; }
875
0
  virtual int lookChar() { return EOF; }
876
15.7k
  virtual int getBlock(char *blk, int size) { return 0; }
877
  virtual GString *getPSFilter(int psLevel, const char *indent,
878
             GBool okToReadStream)
879
0
    { return NULL; }
880
0
  virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
881
};
882
883
//------------------------------------------------------------------------
884
// BufStream
885
//------------------------------------------------------------------------
886
887
class BufStream: public FilterStream {
888
public:
889
890
  BufStream(Stream *strA, int bufSizeA);
891
  virtual ~BufStream();
892
  virtual Stream *copy();
893
0
  virtual StreamKind getKind() { return strWeird; }
894
  virtual void reset();
895
  virtual int getChar();
896
  virtual int lookChar();
897
  virtual GString *getPSFilter(int psLevel, const char *indent,
898
             GBool okToReadStream)
899
0
    { return NULL; }
900
  virtual GBool isBinary(GBool last = gTrue);
901
902
  int lookChar(int idx);
903
904
private:
905
906
  int *buf;
907
  int bufSize;
908
};
909
910
//------------------------------------------------------------------------
911
// FixedLengthEncoder
912
//------------------------------------------------------------------------
913
914
class FixedLengthEncoder: public FilterStream {
915
public:
916
917
  FixedLengthEncoder(Stream *strA, int lengthA);
918
  ~FixedLengthEncoder();
919
  virtual Stream *copy();
920
0
  virtual StreamKind getKind() { return strWeird; }
921
  virtual void reset();
922
  virtual int getChar();
923
  virtual int lookChar();
924
  virtual GString *getPSFilter(int psLevel, const char *indent,
925
             GBool okToReadStream)
926
0
    { return NULL; }
927
  virtual GBool isBinary(GBool last = gTrue);
928
0
  virtual GBool isEncoder() { return gTrue; }
929
930
private:
931
932
  int length;
933
  int count;
934
};
935
936
//------------------------------------------------------------------------
937
// ASCIIHexEncoder
938
//------------------------------------------------------------------------
939
940
class ASCIIHexEncoder: public FilterStream {
941
public:
942
943
  ASCIIHexEncoder(Stream *strA);
944
  virtual ~ASCIIHexEncoder();
945
  virtual Stream *copy();
946
0
  virtual StreamKind getKind() { return strWeird; }
947
  virtual void reset();
948
  virtual int getChar()
949
0
    { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
950
  virtual int lookChar()
951
0
    { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
952
  virtual GString *getPSFilter(int psLevel, const char *indent,
953
             GBool okToReadStream)
954
0
    { return NULL; }
955
0
  virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
956
0
  virtual GBool isEncoder() { return gTrue; }
957
958
private:
959
960
  char buf[4];
961
  char *bufPtr;
962
  char *bufEnd;
963
  int lineLen;
964
  GBool eof;
965
966
  GBool fillBuf();
967
};
968
969
//------------------------------------------------------------------------
970
// ASCII85Encoder
971
//------------------------------------------------------------------------
972
973
class ASCII85Encoder: public FilterStream {
974
public:
975
976
  ASCII85Encoder(Stream *strA);
977
  virtual ~ASCII85Encoder();
978
  virtual Stream *copy();
979
0
  virtual StreamKind getKind() { return strWeird; }
980
  virtual void reset();
981
  virtual int getChar()
982
0
    { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
983
  virtual int lookChar()
984
0
    { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
985
  virtual GString *getPSFilter(int psLevel, const char *indent,
986
             GBool okToReadStream)
987
0
    { return NULL; }
988
0
  virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
989
0
  virtual GBool isEncoder() { return gTrue; }
990
991
private:
992
993
  char buf[8];
994
  char *bufPtr;
995
  char *bufEnd;
996
  int lineLen;
997
  GBool eof;
998
999
  GBool fillBuf();
1000
};
1001
1002
//------------------------------------------------------------------------
1003
// RunLengthEncoder
1004
//------------------------------------------------------------------------
1005
1006
class RunLengthEncoder: public FilterStream {
1007
public:
1008
1009
  RunLengthEncoder(Stream *strA);
1010
  virtual ~RunLengthEncoder();
1011
  virtual Stream *copy();
1012
0
  virtual StreamKind getKind() { return strWeird; }
1013
  virtual void reset();
1014
  virtual int getChar()
1015
0
    { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
1016
  virtual int lookChar()
1017
0
    { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
1018
  virtual GString *getPSFilter(int psLevel, const char *indent,
1019
             GBool okToReadStream)
1020
0
    { return NULL; }
1021
0
  virtual GBool isBinary(GBool last = gTrue) { return gTrue; }
1022
0
  virtual GBool isEncoder() { return gTrue; }
1023
1024
private:
1025
1026
  char buf[131];
1027
  char *bufPtr;
1028
  char *bufEnd;
1029
  char *nextEnd;
1030
  GBool eof;
1031
1032
  GBool fillBuf();
1033
};
1034
1035
//------------------------------------------------------------------------
1036
// LZWEncoder
1037
//------------------------------------------------------------------------
1038
1039
struct LZWEncoderNode {
1040
  int byte;
1041
  LZWEncoderNode *next;   // next sibling
1042
  LZWEncoderNode *children; // first child
1043
};
1044
1045
class LZWEncoder: public FilterStream {
1046
public:
1047
1048
  LZWEncoder(Stream *strA);
1049
  virtual ~LZWEncoder();
1050
  virtual Stream *copy();
1051
0
  virtual StreamKind getKind() { return strWeird; }
1052
  virtual void reset();
1053
  virtual int getChar();
1054
  virtual int lookChar();
1055
  virtual GString *getPSFilter(int psLevel, const char *indent,
1056
             GBool okToReadStream)
1057
0
    { return NULL; }
1058
0
  virtual GBool isBinary(GBool last = gTrue) { return gTrue; }
1059
0
  virtual GBool isEncoder() { return gTrue; }
1060
1061
private:
1062
1063
  LZWEncoderNode table[4096];
1064
  int nextSeq;
1065
  int codeLen;
1066
  Guchar inBuf[8192];
1067
  int inBufStart;
1068
  int inBufLen;
1069
  int outBuf;
1070
  int outBufLen;
1071
  GBool needEOD;
1072
1073
  void fillBuf();
1074
};
1075
1076
#endif