Coverage Report

Created: 2025-07-11 06:50

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