Coverage Report

Created: 2025-11-11 07:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xpdf-4.05/xpdf/Stream.cc
Line
Count
Source
1
//========================================================================
2
//
3
// Stream.cc
4
//
5
// Copyright 1996-2003 Glyph & Cog, LLC
6
//
7
//========================================================================
8
9
#include <aconf.h>
10
11
#include <stdio.h>
12
#include <stdlib.h>
13
#include <stddef.h>
14
#include <limits.h>
15
#ifdef _WIN32
16
#include <io.h>
17
#else
18
#include <unistd.h>
19
#endif
20
#include <string.h>
21
#include <ctype.h>
22
#include "gmem.h"
23
#include "gmempp.h"
24
#include "gfile.h"
25
#if MULTITHREADED
26
#include "GMutex.h"
27
#endif
28
#include "config.h"
29
#include "Error.h"
30
#include "Object.h"
31
#include "Lexer.h"
32
#include "GfxState.h"
33
#include "Stream.h"
34
#include "JBIG2Stream.h"
35
#include "JPXStream.h"
36
#include "Stream-CCITT.h"
37
38
#ifdef __DJGPP__
39
static GBool setDJSYSFLAGS = gFalse;
40
#endif
41
42
#ifdef VMS
43
#ifdef __GNUC__
44
#define SEEK_SET 0
45
#define SEEK_CUR 1
46
#define SEEK_END 2
47
#endif
48
#endif
49
50
//------------------------------------------------------------------------
51
52
// An LZW/Flate decompression bomb is detected if the output size
53
// exceeds decompressionBombSizeThreshold and the decompression ratio
54
// exceeds decompressionBombRatioThreshold.
55
4.50M
#define decompressionBombSizeThreshold 50000000
56
0
#define decompressionBombRatioThreshold 200
57
58
//------------------------------------------------------------------------
59
// Stream (base class)
60
//------------------------------------------------------------------------
61
62
202k
Stream::Stream() {
63
202k
}
64
65
196k
Stream::~Stream() {
66
196k
}
67
68
5.64k
void Stream::close() {
69
5.64k
}
70
71
0
int Stream::getRawChar() {
72
0
  error(errInternal, -1, "Called getRawChar() on non-predictor stream");
73
0
  return EOF;
74
0
}
75
76
7.01k
int Stream::getBlock(char *buf, int size) {
77
7.01k
  int n, c;
78
79
7.01k
  n = 0;
80
587k
  while (n < size) {
81
581k
    if ((c = getChar()) == EOF) {
82
285
      break;
83
285
    }
84
580k
    buf[n++] = (char)c;
85
580k
  }
86
7.01k
  return n;
87
7.01k
}
88
89
0
char *Stream::getLine(char *buf, int size) {
90
0
  int i;
91
0
  int c;
92
93
0
  if (lookChar() == EOF || size < 0)
94
0
    return NULL;
95
0
  for (i = 0; i < size - 1; ++i) {
96
0
    c = getChar();
97
0
    if (c == EOF || c == '\n')
98
0
      break;
99
0
    if (c == '\r') {
100
0
      if ((c = lookChar()) == '\n')
101
0
  getChar();
102
0
      break;
103
0
    }
104
0
    buf[i] = (char)c;
105
0
  }
106
0
  buf[i] = '\0';
107
0
  return buf;
108
0
}
109
110
10.5k
Guint Stream::discardChars(Guint n) {
111
10.5k
  char buf[4096];
112
10.5k
  Guint count, i, j;
113
114
10.5k
  count = 0;
115
20.9k
  while (count < n) {
116
11.6k
    if ((i = n - count) > sizeof(buf)) {
117
3.17k
      i = (Guint)sizeof(buf);
118
3.17k
    }
119
11.6k
    j = (Guint)getBlock(buf, (int)i);
120
11.6k
    count += j;
121
11.6k
    if (j != i) {
122
1.18k
      break;
123
1.18k
    }
124
11.6k
  }
125
10.5k
  return count;
126
10.5k
}
127
128
GString *Stream::getPSFilter(int psLevel, const char *indent,
129
0
           GBool okToReadStream) {
130
0
  return new GString();
131
0
}
132
133
9.61k
Stream *Stream::addFilters(Object *dict, int recursion) {
134
9.61k
  Object obj, obj2;
135
9.61k
  Object params, params2;
136
9.61k
  Stream *str;
137
9.61k
  int i;
138
139
9.61k
  str = this;
140
9.61k
  dict->dictLookup("Filter", &obj, recursion);
141
9.61k
  if (obj.isNull()) {
142
3.89k
    obj.free();
143
3.89k
    dict->dictLookup("F", &obj, recursion);
144
3.89k
  }
145
9.61k
  dict->dictLookup("DecodeParms", &params, recursion);
146
9.61k
  if (params.isNull()) {
147
9.20k
    params.free();
148
9.20k
    dict->dictLookup("DP", &params, recursion);
149
9.20k
  }
150
9.61k
  if (obj.isName()) {
151
3.75k
    str = makeFilter(obj.getName(), str, &params, recursion);
152
5.86k
  } else if (obj.isArray()) {
153
11.2k
    for (i = 0; i < obj.arrayGetLength(); ++i) {
154
9.07k
      obj.arrayGet(i, &obj2, recursion);
155
9.07k
      if (params.isArray() && i < params.arrayGetLength())
156
3
  params.arrayGet(i, &params2, recursion);
157
9.06k
      else
158
9.06k
  params2.initNull();
159
9.07k
      if (obj2.isName()) {
160
5.06k
  str = makeFilter(obj2.getName(), str, &params2, recursion);
161
5.06k
      } else {
162
4.00k
  error(errSyntaxError, getPos(), "Bad filter name");
163
4.00k
  str = new EOFStream(str);
164
4.00k
      }
165
9.07k
      obj2.free();
166
9.07k
      params2.free();
167
9.07k
    }
168
3.69k
  } else if (!obj.isNull()) {
169
138
    error(errSyntaxError, getPos(), "Bad 'Filter' attribute in stream");
170
138
  }
171
9.61k
  obj.free();
172
9.61k
  params.free();
173
174
9.61k
  return str;
175
9.61k
}
176
177
Stream *Stream::makeFilter(char *name, Stream *str, Object *params,
178
8.82k
         int recursion) {
179
8.82k
  int pred;     // parameters
180
8.82k
  int colors;
181
8.82k
  int bits;
182
8.82k
  int early;
183
8.82k
  int encoding;
184
8.82k
  GBool endOfLine, byteAlign, endOfBlock, black;
185
8.82k
  int columns, rows;
186
8.82k
  int colorXform;
187
8.82k
  Object globals, obj;
188
189
8.82k
  if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) {
190
13
    str = new ASCIIHexStream(str);
191
8.80k
  } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) {
192
52
    str = new ASCII85Stream(str);
193
8.75k
  } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) {
194
228
    pred = 1;
195
228
    columns = 1;
196
228
    colors = 1;
197
228
    bits = 8;
198
228
    early = 1;
199
228
    if (params->isDict()) {
200
169
      params->dictLookup("Predictor", &obj, recursion);
201
169
      if (obj.isInt())
202
3
  pred = obj.getInt();
203
169
      obj.free();
204
169
      params->dictLookup("Columns", &obj, recursion);
205
169
      if (obj.isInt())
206
166
  columns = obj.getInt();
207
169
      obj.free();
208
169
      params->dictLookup("Colors", &obj, recursion);
209
169
      if (obj.isInt())
210
0
  colors = obj.getInt();
211
169
      obj.free();
212
169
      params->dictLookup("BitsPerComponent", &obj, recursion);
213
169
      if (obj.isInt())
214
3
  bits = obj.getInt();
215
169
      obj.free();
216
169
      params->dictLookup("EarlyChange", &obj, recursion);
217
169
      if (obj.isInt())
218
0
  early = obj.getInt();
219
169
      obj.free();
220
169
    }
221
228
    str = new LZWStream(str, pred, columns, colors, bits, early);
222
8.52k
  } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) {
223
30
    str = new RunLengthStream(str);
224
8.49k
  } else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) {
225
15
    encoding = 0;
226
15
    endOfLine = gFalse;
227
15
    byteAlign = gFalse;
228
15
    columns = 1728;
229
15
    rows = 0;
230
15
    endOfBlock = gTrue;
231
15
    black = gFalse;
232
15
    if (params->isDict()) {
233
2
      params->dictLookup("K", &obj, recursion);
234
2
      if (obj.isInt()) {
235
2
  encoding = obj.getInt();
236
2
      }
237
2
      obj.free();
238
2
      params->dictLookup("EndOfLine", &obj, recursion);
239
2
      if (obj.isBool()) {
240
0
  endOfLine = obj.getBool();
241
0
      }
242
2
      obj.free();
243
2
      params->dictLookup("EncodedByteAlign", &obj, recursion);
244
2
      if (obj.isBool()) {
245
0
  byteAlign = obj.getBool();
246
0
      }
247
2
      obj.free();
248
2
      params->dictLookup("Columns", &obj, recursion);
249
2
      if (obj.isInt()) {
250
2
  columns = obj.getInt();
251
2
      }
252
2
      obj.free();
253
2
      params->dictLookup("Rows", &obj, recursion);
254
2
      if (obj.isInt()) {
255
0
  rows = obj.getInt();
256
0
      }
257
2
      obj.free();
258
2
      params->dictLookup("EndOfBlock", &obj, recursion);
259
2
      if (obj.isBool()) {
260
0
  endOfBlock = obj.getBool();
261
0
      }
262
2
      obj.free();
263
2
      params->dictLookup("BlackIs1", &obj, recursion);
264
2
      if (obj.isBool()) {
265
0
  black = obj.getBool();
266
0
      }
267
2
      obj.free();
268
2
    }
269
15
    str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign,
270
15
           columns, rows, endOfBlock, black);
271
8.48k
  } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) {
272
81
    colorXform = -1;
273
81
    if (params->isDict()) {
274
3
      if (params->dictLookup("ColorTransform", &obj, recursion)->isInt()) {
275
0
  colorXform = obj.getInt();
276
0
      }
277
3
      obj.free();
278
3
    }
279
81
    str = new DCTStream(str, colorXform);
280
8.40k
  } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) {
281
4.39k
    pred = 1;
282
4.39k
    columns = 1;
283
4.39k
    colors = 1;
284
4.39k
    bits = 8;
285
4.39k
    if (params->isDict()) {
286
201
      params->dictLookup("Predictor", &obj, recursion);
287
201
      if (obj.isInt())
288
199
  pred = obj.getInt();
289
201
      obj.free();
290
201
      params->dictLookup("Columns", &obj, recursion);
291
201
      if (obj.isInt())
292
197
  columns = obj.getInt();
293
201
      obj.free();
294
201
      params->dictLookup("Colors", &obj, recursion);
295
201
      if (obj.isInt())
296
0
  colors = obj.getInt();
297
201
      obj.free();
298
201
      params->dictLookup("BitsPerComponent", &obj, recursion);
299
201
      if (obj.isInt())
300
0
  bits = obj.getInt();
301
201
      obj.free();
302
201
    }
303
4.39k
    str = new FlateStream(str, pred, columns, colors, bits);
304
4.39k
  } else if (!strcmp(name, "JBIG2Decode")) {
305
251
    if (params->isDict()) {
306
31
      params->dictLookup("JBIG2Globals", &globals, recursion);
307
31
    }
308
251
    str = new JBIG2Stream(str, &globals);
309
251
    globals.free();
310
3.75k
  } else if (!strcmp(name, "JPXDecode")) {
311
52
    str = new JPXStream(str);
312
3.70k
  } else if (!strcmp(name, "Crypt")) {
313
    // this is handled in Parser::makeStream()
314
3.37k
  } else {
315
3.37k
    error(errSyntaxError, getPos(), "Unknown filter '{0:s}'", name);
316
3.37k
    str = new EOFStream(str);
317
3.37k
  }
318
8.82k
  return str;
319
8.82k
}
320
321
//------------------------------------------------------------------------
322
// BaseStream
323
//------------------------------------------------------------------------
324
325
133k
BaseStream::BaseStream(Object *dictA) {
326
133k
  dict = *dictA;
327
133k
}
328
329
130k
BaseStream::~BaseStream() {
330
130k
  dict.free();
331
130k
}
332
333
//------------------------------------------------------------------------
334
// FilterStream
335
//------------------------------------------------------------------------
336
337
68.6k
FilterStream::FilterStream(Stream *strA) {
338
68.6k
  str = strA;
339
68.6k
}
340
341
FilterStream::~FilterStream() {
342
}
343
344
36.8k
void FilterStream::close() {
345
36.8k
  str->close();
346
36.8k
}
347
348
0
void FilterStream::setPos(GFileOffset pos, int dir) {
349
0
  error(errInternal, -1, "Called setPos() on FilterStream");
350
0
}
351
352
//------------------------------------------------------------------------
353
// ImageStream
354
//------------------------------------------------------------------------
355
356
0
ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) {
357
0
  int imgLineSize;
358
359
0
  str = strA;
360
0
  width = widthA;
361
0
  nComps = nCompsA;
362
0
  nBits = nBitsA;
363
364
0
  nVals = width * nComps;
365
0
  inputLineSize = (nVals * nBits + 7) >> 3;
366
0
  if (width > INT_MAX / nComps ||
367
0
      nVals > (INT_MAX - 7) / nBits) {
368
    // force a call to gmallocn(-1,...), which will throw an exception
369
0
    inputLineSize = -1;
370
0
  }
371
0
  inputLine = (char *)gmallocn(inputLineSize, sizeof(char));
372
0
  if (nBits == 8) {
373
0
    imgLine = (Guchar *)inputLine;
374
0
  } else {
375
0
    if (nBits == 1) {
376
0
      imgLineSize = (nVals + 7) & ~7;
377
0
    } else {
378
0
      imgLineSize = nVals;
379
0
    }
380
0
    imgLine = (Guchar *)gmallocn(imgLineSize, sizeof(Guchar));
381
0
  }
382
0
  imgIdx = nVals;
383
0
}
384
385
0
ImageStream::~ImageStream() {
386
0
  if (imgLine != (Guchar *)inputLine) {
387
0
    gfree(imgLine);
388
0
  }
389
0
  gfree(inputLine);
390
0
}
391
392
0
void ImageStream::reset() {
393
0
  str->disableDecompressionBombChecking();
394
0
  str->reset();
395
0
}
396
397
0
void ImageStream::close() {
398
0
  str->close();
399
0
}
400
401
0
GBool ImageStream::getPixel(Guchar *pix) {
402
0
  int i;
403
404
0
  if (imgIdx >= nVals) {
405
0
    if (!getLine()) {
406
0
      return gFalse;
407
0
    }
408
0
    imgIdx = 0;
409
0
  }
410
0
  for (i = 0; i < nComps; ++i) {
411
0
    pix[i] = imgLine[imgIdx++];
412
0
  }
413
0
  return gTrue;
414
0
}
415
416
0
Guchar *ImageStream::getLine() {
417
0
  Gulong buf, bitMask;
418
0
  int bits;
419
0
  int c;
420
0
  int i;
421
0
  char *p;
422
423
0
  if (str->getBlock(inputLine, inputLineSize) != inputLineSize) {
424
0
    return NULL;
425
0
  }
426
0
  if (nBits == 1) {
427
0
    p = inputLine;
428
0
    for (i = 0; i < nVals; i += 8) {
429
0
      c = *p++;
430
0
      imgLine[i+0] = (Guchar)((c >> 7) & 1);
431
0
      imgLine[i+1] = (Guchar)((c >> 6) & 1);
432
0
      imgLine[i+2] = (Guchar)((c >> 5) & 1);
433
0
      imgLine[i+3] = (Guchar)((c >> 4) & 1);
434
0
      imgLine[i+4] = (Guchar)((c >> 3) & 1);
435
0
      imgLine[i+5] = (Guchar)((c >> 2) & 1);
436
0
      imgLine[i+6] = (Guchar)((c >> 1) & 1);
437
0
      imgLine[i+7] = (Guchar)(c & 1);
438
0
    }
439
0
  } else if (nBits == 8) {
440
    // special case: imgLine == inputLine
441
0
  } else if (nBits == 16) {
442
0
    for (i = 0; i < nVals; ++i) {
443
0
      imgLine[i] = (Guchar)inputLine[2*i];
444
0
    }
445
0
  } else {
446
0
    bitMask = (1 << nBits) - 1;
447
0
    buf = 0;
448
0
    bits = 0;
449
0
    p = inputLine;
450
0
    for (i = 0; i < nVals; ++i) {
451
0
      if (bits < nBits) {
452
0
  buf = (buf << 8) | (*p++ & 0xff);
453
0
  bits += 8;
454
0
      }
455
0
      imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask);
456
0
      bits -= nBits;
457
0
    }
458
0
  }
459
0
  return imgLine;
460
0
}
461
462
0
void ImageStream::skipLine() {
463
0
  str->getBlock(inputLine, inputLineSize);
464
0
}
465
466
467
//------------------------------------------------------------------------
468
// StreamPredictor
469
//------------------------------------------------------------------------
470
471
StreamPredictor::StreamPredictor(Stream *strA, int predictorA,
472
347
         int widthA, int nCompsA, int nBitsA) {
473
347
  str = strA;
474
347
  predictor = predictorA;
475
347
  width = widthA;
476
347
  nComps = nCompsA;
477
347
  nBits = nBitsA;
478
347
  predLine = NULL;
479
347
  ok = gFalse;
480
481
347
  nVals = width * nComps;
482
347
  pixBytes = (nComps * nBits + 7) >> 3;
483
347
  rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes;
484
347
  if (width <= 0 || nComps <= 0 || nBits <= 0 ||
485
347
      nComps > gfxColorMaxComps ||
486
347
      nBits > 16 ||
487
347
      width >= INT_MAX / nComps ||      // check for overflow in nVals 
488
347
      nVals >= (INT_MAX - 7) / nBits) { // check for overflow in rowBytes
489
71
    return;
490
71
  }
491
276
  predLine = (Guchar *)gmalloc(rowBytes);
492
493
276
  reset();
494
495
276
  ok = gTrue;
496
276
}
497
498
288
StreamPredictor::~StreamPredictor() {
499
288
  gfree(predLine);
500
288
}
501
502
335
void StreamPredictor::reset() {
503
335
  memset(predLine, 0, rowBytes);
504
335
  predIdx = rowBytes;
505
335
}
506
507
1
int StreamPredictor::lookChar() {
508
1
  if (predIdx >= rowBytes) {
509
1
    if (!getNextLine()) {
510
1
      return EOF;
511
1
    }
512
1
  }
513
0
  return predLine[predIdx];
514
1
}
515
516
39
int StreamPredictor::getChar() {
517
39
  if (predIdx >= rowBytes) {
518
22
    if (!getNextLine()) {
519
11
      return EOF;
520
11
    }
521
22
  }
522
28
  return predLine[predIdx++];
523
39
}
524
525
0
int StreamPredictor::getBlock(char *blk, int size) {
526
0
  int n, m;
527
528
0
  n = 0;
529
0
  while (n < size) {
530
0
    if (predIdx >= rowBytes) {
531
0
      if (!getNextLine()) {
532
0
  break;
533
0
      }
534
0
    }
535
0
    m = rowBytes - predIdx;
536
0
    if (m > size - n) {
537
0
      m = size - n;
538
0
    }
539
0
    memcpy(blk + n, predLine + predIdx, m);
540
0
    predIdx += m;
541
0
    n += m;
542
0
  }
543
0
  return n;
544
0
}
545
546
23
GBool StreamPredictor::getNextLine() {
547
23
  int curPred;
548
23
  Guchar upLeftBuf[gfxColorMaxComps * 2 + 1];
549
23
  int left, up, upLeft, p, pa, pb, pc;
550
23
  int c;
551
23
  Gulong inBuf, outBuf, bitMask;
552
23
  int inBits, outBits;
553
23
  int i, j, k, kk;
554
555
  // get PNG optimum predictor number
556
23
  if (predictor >= 10) {
557
12
    if ((curPred = str->getRawChar()) == EOF) {
558
10
      return gFalse;
559
10
    }
560
2
    curPred += 10;
561
11
  } else {
562
11
    curPred = predictor;
563
11
  }
564
565
  // read the raw line, apply PNG (byte) predictor
566
13
  memset(upLeftBuf, 0, pixBytes + 1);
567
41
  for (i = pixBytes; i < rowBytes; ++i) {
568
60
    for (j = pixBytes; j > 0; --j) {
569
30
      upLeftBuf[j] = upLeftBuf[j-1];
570
30
    }
571
30
    upLeftBuf[0] = predLine[i];
572
30
    if ((c = str->getRawChar()) == EOF) {
573
2
      if (i > pixBytes) {
574
  // this ought to return false, but some (broken) PDF files
575
  // contain truncated image data, and Adobe apparently reads the
576
  // last partial line
577
0
  break;
578
0
      }
579
2
      return gFalse;
580
2
    }
581
28
    switch (curPred) {
582
0
    case 11:      // PNG sub
583
0
      predLine[i] = (Guchar)(predLine[i - pixBytes] + c);
584
0
      break;
585
10
    case 12:      // PNG up
586
10
      predLine[i] = (Guchar)(predLine[i] + c);
587
10
      break;
588
0
    case 13:      // PNG average
589
0
      predLine[i] = (Guchar)(((predLine[i - pixBytes] + predLine[i]) >> 1) + c);
590
0
      break;
591
0
    case 14:      // PNG Paeth
592
0
      left = predLine[i - pixBytes];
593
0
      up = predLine[i];
594
0
      upLeft = upLeftBuf[pixBytes];
595
0
      p = left + up - upLeft;
596
0
      if ((pa = p - left) < 0)
597
0
  pa = -pa;
598
0
      if ((pb = p - up) < 0)
599
0
  pb = -pb;
600
0
      if ((pc = p - upLeft) < 0)
601
0
  pc = -pc;
602
0
      if (pa <= pb && pa <= pc)
603
0
  predLine[i] = (Guchar)(left + c);
604
0
      else if (pb <= pc)
605
0
  predLine[i] = (Guchar)(up + c);
606
0
      else
607
0
  predLine[i] = (Guchar)(upLeft + c);
608
0
      break;
609
0
    case 10:      // PNG none
610
18
    default:      // no predictor or TIFF predictor
611
18
      predLine[i] = (Guchar)c;
612
18
      break;
613
28
    }
614
28
  }
615
616
  // apply TIFF (component) predictor
617
11
  if (predictor == 2) {
618
9
    if (nBits == 8) {
619
0
      for (i = pixBytes; i < rowBytes; ++i) {
620
0
  predLine[i] = (Guchar)(predLine[i] + predLine[i - nComps]);
621
0
      }
622
9
    } else if (nBits == 16) {
623
0
      for (i = pixBytes; i < rowBytes; i += 2) {
624
0
  c = ((predLine[i] + predLine[i - 2*nComps]) << 8) +
625
0
      predLine[i + 1] + predLine[i + 1 - 2*nComps];
626
0
  predLine[i] = (Guchar)(c >> 8);
627
0
  predLine[i+1] = (Guchar)(c & 0xff);
628
0
      }
629
9
    } else {
630
9
      memset(upLeftBuf, 0, nComps);
631
9
      bitMask = (1 << nBits) - 1;
632
9
      inBuf = outBuf = 0;
633
9
      inBits = outBits = 0;
634
9
      j = k = pixBytes;
635
45
      for (i = 0; i < width; ++i) {
636
72
  for (kk = 0; kk < nComps; ++kk) {
637
36
    if (inBits < nBits) {
638
18
      inBuf = (inBuf << 8) | (predLine[j++] & 0xff);
639
18
      inBits += 8;
640
18
    }
641
36
    upLeftBuf[kk] = (Guchar)((upLeftBuf[kk] +
642
36
            (inBuf >> (inBits - nBits))) & bitMask);
643
36
    inBits -= nBits;
644
36
    outBuf = (outBuf << nBits) | upLeftBuf[kk];
645
36
    outBits += nBits;
646
36
    if (outBits >= 8) {
647
9
      predLine[k++] = (Guchar)(outBuf >> (outBits - 8));
648
9
      outBits -= 8;
649
9
    }
650
36
  }
651
36
      }
652
9
      if (outBits > 0) {
653
9
  predLine[k++] = (Guchar)((outBuf << (8 - outBits)) +
654
9
         (inBuf & ((1 << (8 - outBits)) - 1)));
655
9
      }
656
9
    }
657
9
  }
658
659
  // reset to start of line
660
11
  predIdx = pixBytes;
661
662
11
  return gTrue;
663
13
}
664
665
//------------------------------------------------------------------------
666
// SharedFile
667
//------------------------------------------------------------------------
668
669
class SharedFile {
670
public:
671
672
  SharedFile(FILE *fA);
673
  SharedFile *copy();
674
  void free();
675
  int readBlock(char *buf, GFileOffset pos, int size);
676
  GFileOffset getSize();
677
678
private:
679
680
  ~SharedFile();
681
682
  FILE *f;
683
  int refCnt;
684
#if MULTITHREADED
685
  GMutex mutex;
686
#endif
687
};
688
689
0
SharedFile::SharedFile(FILE *fA) {
690
0
  f = fA;
691
0
  refCnt = 1;
692
0
#if MULTITHREADED
693
0
  gInitMutex(&mutex);
694
0
#endif
695
0
}
696
697
0
SharedFile::~SharedFile() {
698
0
#if MULTITHREADED
699
0
  gDestroyMutex(&mutex);
700
0
#endif
701
0
}
702
703
0
SharedFile *SharedFile::copy() {
704
0
#if MULTITHREADED
705
0
  gLockMutex(&mutex);
706
0
#endif
707
0
  ++refCnt;
708
0
#if MULTITHREADED
709
0
  gUnlockMutex(&mutex);
710
0
#endif
711
0
  return this;
712
0
}
713
714
0
void SharedFile::free() {
715
0
  int newCount;
716
717
0
#if MULTITHREADED
718
0
  gLockMutex(&mutex);
719
0
#endif
720
0
  newCount = --refCnt;
721
0
#if MULTITHREADED
722
0
  gUnlockMutex(&mutex);
723
0
#endif
724
0
  if (newCount == 0) {
725
0
    delete this;
726
0
  }
727
0
}
728
729
0
int SharedFile::readBlock(char *buf, GFileOffset pos, int size) {
730
0
  int n;
731
732
0
#if MULTITHREADED
733
0
  gLockMutex(&mutex);
734
0
#endif
735
0
  gfseek(f, pos, SEEK_SET);
736
0
  n = (int)fread(buf, 1, size, f);
737
0
#if MULTITHREADED
738
0
  gUnlockMutex(&mutex);
739
0
#endif
740
0
  return n;
741
0
}
742
743
0
GFileOffset SharedFile::getSize() {
744
0
  GFileOffset size;
745
746
0
#if MULTITHREADED
747
0
  gLockMutex(&mutex);
748
0
#endif
749
0
  gfseek(f, 0, SEEK_END);
750
0
  size = gftell(f);
751
0
#if MULTITHREADED
752
0
  gUnlockMutex(&mutex);
753
0
#endif
754
0
  return size;
755
0
}
756
757
//------------------------------------------------------------------------
758
// FileStream
759
//------------------------------------------------------------------------
760
761
FileStream::FileStream(FILE *fA, GFileOffset startA, GBool limitedA,
762
           GFileOffset lengthA, Object *dictA):
763
0
    BaseStream(dictA) {
764
0
  f = new SharedFile(fA);
765
0
  start = startA;
766
0
  limited = limitedA;
767
0
  length = lengthA;
768
0
  bufPtr = bufEnd = buf;
769
0
  bufPos = start;
770
0
}
771
772
FileStream::FileStream(SharedFile *fA, GFileOffset startA, GBool limitedA,
773
           GFileOffset lengthA, Object *dictA):
774
0
    BaseStream(dictA) {
775
0
  f = fA->copy();
776
0
  start = startA;
777
0
  limited = limitedA;
778
0
  length = lengthA;
779
0
  bufPtr = bufEnd = buf;
780
0
  bufPos = start;
781
0
}
782
783
0
FileStream::~FileStream() {
784
0
  f->free();
785
0
}
786
787
0
Stream *FileStream::copy() {
788
0
  Object dictA;
789
790
0
  dict.copy(&dictA);
791
0
  return new FileStream(f, start, limited, length, &dictA);
792
0
}
793
794
Stream *FileStream::makeSubStream(GFileOffset startA, GBool limitedA,
795
0
          GFileOffset lengthA, Object *dictA) {
796
0
  return new FileStream(f, startA, limitedA, lengthA, dictA);
797
0
}
798
799
0
void FileStream::reset() {
800
0
  bufPtr = bufEnd = buf;
801
0
  bufPos = start;
802
0
}
803
804
0
int FileStream::getBlock(char *blk, int size) {
805
0
  int n, m;
806
807
0
  n = 0;
808
0
  while (n < size) {
809
0
    if (bufPtr >= bufEnd) {
810
0
      if (!fillBuf()) {
811
0
  break;
812
0
      }
813
0
    }
814
0
    m = (int)(bufEnd - bufPtr);
815
0
    if (m > size - n) {
816
0
      m = size - n;
817
0
    }
818
0
    memcpy(blk + n, bufPtr, m);
819
0
    bufPtr += m;
820
0
    n += m;
821
0
  }
822
0
  return n;
823
0
}
824
825
0
GBool FileStream::fillBuf() {
826
0
  int n;
827
828
0
  bufPos += (int)(bufEnd - buf);
829
0
  bufPtr = bufEnd = buf;
830
0
  if (limited && bufPos >= start + length) {
831
0
    return gFalse;
832
0
  }
833
0
  if (limited && bufPos + fileStreamBufSize > start + length) {
834
0
    n = (int)(start + length - bufPos);
835
0
  } else {
836
0
    n = fileStreamBufSize;
837
0
  }
838
0
  n = f->readBlock(buf, bufPos, n);
839
0
  bufEnd = buf + n;
840
0
  if (bufPtr >= bufEnd) {
841
0
    return gFalse;
842
0
  }
843
0
  return gTrue;
844
0
}
845
846
0
void FileStream::setPos(GFileOffset pos, int dir) {
847
0
  GFileOffset size;
848
849
0
  if (dir >= 0) {
850
0
    bufPos = pos;
851
0
  } else {
852
0
    size = f->getSize();
853
0
    if (pos <= size) {
854
0
      bufPos = size - pos;
855
0
    } else {
856
0
      bufPos = 0;
857
0
    }
858
0
  }
859
0
  bufPtr = bufEnd = buf;
860
0
}
861
862
0
void FileStream::moveStart(int delta) {
863
0
  start += delta;
864
0
  bufPtr = bufEnd = buf;
865
0
  bufPos = start;
866
0
}
867
868
//------------------------------------------------------------------------
869
// MemStream
870
//------------------------------------------------------------------------
871
872
MemStream::MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA):
873
122k
    BaseStream(dictA) {
874
122k
  buf = bufA;
875
122k
  start = startA;
876
122k
  length = lengthA;
877
122k
  bufEnd = buf + start + length;
878
122k
  bufPtr = buf + start;
879
122k
  needFree = gFalse;
880
122k
}
881
882
118k
MemStream::~MemStream() {
883
118k
  if (needFree) {
884
0
    gfree(buf);
885
0
  }
886
118k
}
887
888
80.6k
Stream *MemStream::copy() {
889
80.6k
  Object dictA;
890
891
80.6k
  dict.copy(&dictA);
892
80.6k
  return new MemStream(buf, start, length, &dictA);
893
80.6k
}
894
895
Stream *MemStream::makeSubStream(GFileOffset startA, GBool limited,
896
38.6k
         GFileOffset lengthA, Object *dictA) {
897
38.6k
  MemStream *subStr;
898
38.6k
  Guint newStart, newLength;
899
900
38.6k
  if (startA < start) {
901
0
    newStart = start;
902
38.6k
  } else if (startA > start + length) {
903
1
    newStart = start + (int)length;
904
38.6k
  } else {
905
38.6k
    newStart = (int)startA;
906
38.6k
  }
907
38.6k
  if (!limited || newStart + lengthA > start + length) {
908
29.1k
    newLength = start + length - newStart;
909
29.1k
  } else {
910
9.48k
    newLength = (Guint)lengthA;
911
9.48k
  }
912
38.6k
  subStr = new MemStream(buf, newStart, newLength, dictA);
913
38.6k
  return subStr;
914
38.6k
}
915
916
46.6k
void MemStream::reset() {
917
46.6k
  bufPtr = buf + start;
918
46.6k
}
919
920
66.3k
void MemStream::close() {
921
66.3k
}
922
923
41.7k
int MemStream::getBlock(char *blk, int size) {
924
41.7k
  int n;
925
926
41.7k
  if (size <= 0) {
927
0
    return 0;
928
0
  }
929
41.7k
  if (bufEnd - bufPtr < size) {
930
1.86k
    n = (int)(bufEnd - bufPtr);
931
39.8k
  } else {
932
39.8k
    n = size;
933
39.8k
  }
934
41.7k
  memcpy(blk, bufPtr, n);
935
41.7k
  bufPtr += n;
936
41.7k
  return n;
937
41.7k
}
938
939
9.28k
void MemStream::setPos(GFileOffset pos, int dir) {
940
9.28k
  Guint i;
941
942
9.28k
  if (dir >= 0) {
943
9.13k
    i = (Guint)pos;
944
9.13k
  } else {
945
146
    if (pos > start + length) {
946
0
      i = 0;
947
146
    } else {
948
146
      i = (Guint)(start + length - pos);
949
146
    }
950
146
  }
951
9.28k
  if (i < start) {
952
0
    i = start;
953
9.28k
  } else if (i > start + length) {
954
333
    i = start + length;
955
333
  }
956
9.28k
  bufPtr = buf + i;
957
9.28k
}
958
959
71
void MemStream::moveStart(int delta) {
960
71
  start += delta;
961
71
  length -= delta;
962
71
  bufPtr = buf + start;
963
71
}
964
965
//------------------------------------------------------------------------
966
// EmbedStream
967
//------------------------------------------------------------------------
968
969
EmbedStream::EmbedStream(Stream *strA, Object *dictA,
970
       GBool limitedA, GFileOffset lengthA):
971
11.2k
    BaseStream(dictA) {
972
11.2k
  str = strA;
973
11.2k
  limited = limitedA;
974
11.2k
  length = lengthA;
975
11.2k
}
976
977
EmbedStream::~EmbedStream() {
978
}
979
980
5.64k
Stream *EmbedStream::copy() {
981
5.64k
  Object dictA;
982
983
5.64k
  dict.copy(&dictA);
984
5.64k
  return new EmbedStream(str, &dictA, limited, length);
985
5.64k
}
986
987
Stream *EmbedStream::makeSubStream(GFileOffset start, GBool limitedA,
988
0
           GFileOffset lengthA, Object *dictA) {
989
0
  error(errInternal, -1, "Called makeSubStream() on EmbedStream");
990
0
  return NULL;
991
0
}
992
993
1.33M
int EmbedStream::getChar() {
994
1.33M
  if (limited && !length) {
995
3.25k
    return EOF;
996
3.25k
  }
997
1.33M
  --length;
998
1.33M
  return str->getChar();
999
1.33M
}
1000
1001
1.06M
int EmbedStream::lookChar() {
1002
1.06M
  if (limited && !length) {
1003
512
    return EOF;
1004
512
  }
1005
1.05M
  return str->lookChar();
1006
1.06M
}
1007
1008
0
int EmbedStream::getBlock(char *blk, int size) {
1009
0
  if (size <= 0) {
1010
0
    return 0;
1011
0
  }
1012
0
  if (limited && length < (Guint)size) {
1013
0
    size = (int)length;
1014
0
  }
1015
0
  length -= size;
1016
0
  return str->getBlock(blk, size);
1017
0
}
1018
1019
0
void EmbedStream::setPos(GFileOffset pos, int dir) {
1020
0
  error(errInternal, -1, "Called setPos() on EmbedStream");
1021
0
}
1022
1023
0
GFileOffset EmbedStream::getStart() {
1024
0
  error(errInternal, -1, "Called getStart() on EmbedStream");
1025
0
  return 0;
1026
0
}
1027
1028
0
void EmbedStream::moveStart(int delta) {
1029
0
  error(errInternal, -1, "Called moveStart() on EmbedStream");
1030
0
}
1031
1032
//------------------------------------------------------------------------
1033
// ASCIIHexStream
1034
//------------------------------------------------------------------------
1035
1036
ASCIIHexStream::ASCIIHexStream(Stream *strA):
1037
25
    FilterStream(strA) {
1038
25
  buf = EOF;
1039
25
  eof = gFalse;
1040
25
}
1041
1042
17
ASCIIHexStream::~ASCIIHexStream() {
1043
17
  delete str;
1044
17
}
1045
1046
12
Stream *ASCIIHexStream::copy() {
1047
12
  return new ASCIIHexStream(str->copy());
1048
12
}
1049
1050
5
void ASCIIHexStream::reset() {
1051
5
  str->reset();
1052
5
  buf = EOF;
1053
5
  eof = gFalse;
1054
5
}
1055
1056
22
int ASCIIHexStream::lookChar() {
1057
22
  int c1, c2, x;
1058
1059
22
  if (buf != EOF)
1060
0
    return buf;
1061
22
  if (eof) {
1062
5
    buf = EOF;
1063
5
    return EOF;
1064
5
  }
1065
18
  do {
1066
18
    c1 = str->getChar();
1067
18
  } while (isspace(c1));
1068
17
  if (c1 == '>') {
1069
0
    eof = gTrue;
1070
0
    buf = EOF;
1071
0
    return buf;
1072
0
  }
1073
18
  do {
1074
18
    c2 = str->getChar();
1075
18
  } while (isspace(c2));
1076
17
  if (c2 == '>') {
1077
1
    eof = gTrue;
1078
1
    c2 = '0';
1079
1
  }
1080
17
  if (c1 >= '0' && c1 <= '9') {
1081
0
    x = (c1 - '0') << 4;
1082
17
  } else if (c1 >= 'A' && c1 <= 'F') {
1083
1
    x = (c1 - 'A' + 10) << 4;
1084
16
  } else if (c1 >= 'a' && c1 <= 'f') {
1085
3
    x = (c1 - 'a' + 10) << 4;
1086
13
  } else if (c1 == EOF) {
1087
1
    eof = gTrue;
1088
1
    x = 0;
1089
12
  } else {
1090
12
    error(errSyntaxError, getPos(),
1091
12
    "Illegal character <{0:02x}> in ASCIIHex stream", c1);
1092
12
    x = 0;
1093
12
  }
1094
17
  if (c2 >= '0' && c2 <= '9') {
1095
2
    x += c2 - '0';
1096
15
  } else if (c2 >= 'A' && c2 <= 'F') {
1097
0
    x += c2 - 'A' + 10;
1098
15
  } else if (c2 >= 'a' && c2 <= 'f') {
1099
1
    x += c2 - 'a' + 10;
1100
14
  } else if (c2 == EOF) {
1101
1
    eof = gTrue;
1102
1
    x = 0;
1103
13
  } else {
1104
13
    error(errSyntaxError, getPos(),
1105
13
    "Illegal character <{0:02x}> in ASCIIHex stream", c2);
1106
13
  }
1107
17
  buf = x & 0xff;
1108
17
  return buf;
1109
17
}
1110
1111
GString *ASCIIHexStream::getPSFilter(int psLevel, const char *indent,
1112
0
             GBool okToReadStream) {
1113
0
  GString *s;
1114
1115
0
  if (psLevel < 2) {
1116
0
    return NULL;
1117
0
  }
1118
0
  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
1119
0
    return NULL;
1120
0
  }
1121
0
  s->append(indent)->append("/ASCIIHexDecode filter\n");
1122
0
  return s;
1123
0
}
1124
1125
0
GBool ASCIIHexStream::isBinary(GBool last) {
1126
0
  return str->isBinary(gFalse);
1127
0
}
1128
1129
//------------------------------------------------------------------------
1130
// ASCII85Stream
1131
//------------------------------------------------------------------------
1132
1133
ASCII85Stream::ASCII85Stream(Stream *strA):
1134
111
    FilterStream(strA) {
1135
111
  index = n = 0;
1136
111
  eof = gFalse;
1137
111
}
1138
1139
80
ASCII85Stream::~ASCII85Stream() {
1140
80
  delete str;
1141
80
}
1142
1143
59
Stream *ASCII85Stream::copy() {
1144
59
  return new ASCII85Stream(str->copy());
1145
59
}
1146
1147
13
void ASCII85Stream::reset() {
1148
13
  str->reset();
1149
13
  index = n = 0;
1150
13
  eof = gFalse;
1151
13
}
1152
1153
19.2k
int ASCII85Stream::lookChar() {
1154
19.2k
  int k;
1155
19.2k
  Gulong t;
1156
1157
19.2k
  if (index >= n) {
1158
3.88k
    if (eof)
1159
10
      return EOF;
1160
3.87k
    index = 0;
1161
3.88k
    do {
1162
3.88k
      c[0] = str->getChar();
1163
3.88k
    } while (Lexer::isSpace(c[0]));
1164
3.87k
    if (c[0] == '~' || c[0] == EOF) {
1165
0
      eof = gTrue;
1166
0
      n = 0;
1167
0
      return EOF;
1168
3.87k
    } else if (c[0] == 'z') {
1169
0
      b[0] = b[1] = b[2] = b[3] = 0;
1170
0
      n = 4;
1171
3.87k
    } else {
1172
19.3k
      for (k = 1; k < 5; ++k) {
1173
15.6k
  do {
1174
15.6k
    c[k] = str->getChar();
1175
15.6k
  } while (Lexer::isSpace(c[k]));
1176
15.4k
  if (c[k] == '~' || c[k] == EOF)
1177
10
    break;
1178
15.4k
      }
1179
3.87k
      n = k - 1;
1180
3.87k
      if (k < 5 && (c[k] == '~' || c[k] == EOF)) {
1181
20
  for (++k; k < 5; ++k)
1182
10
    c[k] = 0x21 + 84;
1183
10
  eof = gTrue;
1184
10
      }
1185
3.87k
      t = 0;
1186
23.2k
      for (k = 0; k < 5; ++k)
1187
19.3k
  t = t * 85 + (c[k] - 0x21);
1188
19.3k
      for (k = 3; k >= 0; --k) {
1189
15.4k
  b[k] = (int)(t & 0xff);
1190
15.4k
  t >>= 8;
1191
15.4k
      }
1192
3.87k
    }
1193
3.87k
  }
1194
19.2k
  return b[index];
1195
19.2k
}
1196
1197
GString *ASCII85Stream::getPSFilter(int psLevel, const char *indent,
1198
0
            GBool okToReadStream) {
1199
0
  GString *s;
1200
1201
0
  if (psLevel < 2) {
1202
0
    return NULL;
1203
0
  }
1204
0
  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
1205
0
    return NULL;
1206
0
  }
1207
0
  s->append(indent)->append("/ASCII85Decode filter\n");
1208
0
  return s;
1209
0
}
1210
1211
0
GBool ASCII85Stream::isBinary(GBool last) {
1212
0
  return str->isBinary(gFalse);
1213
0
}
1214
1215
//------------------------------------------------------------------------
1216
// LZWStream
1217
//------------------------------------------------------------------------
1218
1219
LZWStream::LZWStream(Stream *strA, int predictor, int columns, int colors,
1220
         int bits, int earlyA):
1221
1.63k
    FilterStream(strA) {
1222
1.63k
  if (predictor != 1) {
1223
6
    pred = new StreamPredictor(this, predictor, columns, colors, bits);
1224
6
    if (!pred->isOk()) {
1225
0
      delete pred;
1226
0
      pred = NULL;
1227
0
    }
1228
1.63k
  } else {
1229
1.63k
    pred = NULL;
1230
1.63k
  }
1231
1.63k
  early = earlyA;
1232
1.63k
  eof = gFalse;
1233
1.63k
  inputBits = 0;
1234
1.63k
  clearTable();
1235
1.63k
  checkForDecompressionBombs = gTrue;
1236
1.63k
}
1237
1238
1.60k
LZWStream::~LZWStream() {
1239
1.60k
  if (pred) {
1240
4
    delete pred;
1241
4
  }
1242
1.60k
  delete str;
1243
1.60k
}
1244
1245
1.41k
Stream *LZWStream::copy() {
1246
1.41k
  if (pred) {
1247
3
    return new LZWStream(str->copy(), pred->getPredictor(),
1248
3
       pred->getWidth(), pred->getNComps(),
1249
3
       pred->getNBits(), early);
1250
1.40k
  } else {
1251
1.40k
    return new LZWStream(str->copy(), 1, 0, 0, 0, early);
1252
1.40k
  }
1253
1.41k
}
1254
1255
0
void LZWStream::disableDecompressionBombChecking() {
1256
0
  checkForDecompressionBombs = gFalse;
1257
0
  FilterStream::disableDecompressionBombChecking();
1258
0
}
1259
1260
1.21M
int LZWStream::getChar() {
1261
1.21M
  if (pred) {
1262
19
    return pred->getChar();
1263
19
  }
1264
1.21M
  if (eof) {
1265
1.93k
    return EOF;
1266
1.93k
  }
1267
1.21M
  if (seqIndex >= seqLength) {
1268
1.21M
    if (!processNextCode()) {
1269
204
      return EOF;
1270
204
    }
1271
1.21M
  }
1272
1.21M
  return seqBuf[seqIndex++];
1273
1.21M
}
1274
1275
1.19k
int LZWStream::lookChar() {
1276
1.19k
  if (pred) {
1277
1
    return pred->lookChar();
1278
1
  }
1279
1.19k
  if (eof) {
1280
141
    return EOF;
1281
141
  }
1282
1.05k
  if (seqIndex >= seqLength) {
1283
979
    if (!processNextCode()) {
1284
212
      return EOF;
1285
212
    }
1286
979
  }
1287
839
  return seqBuf[seqIndex];
1288
1.05k
}
1289
1290
20
int LZWStream::getRawChar() {
1291
20
  if (eof) {
1292
1
    return EOF;
1293
1
  }
1294
19
  if (seqIndex >= seqLength) {
1295
19
    if (!processNextCode()) {
1296
1
      return EOF;
1297
1
    }
1298
19
  }
1299
18
  return seqBuf[seqIndex++];
1300
19
}
1301
1302
44
int LZWStream::getBlock(char *blk, int size) {
1303
44
  int n, m;
1304
1305
44
  if (pred) {
1306
0
    return pred->getBlock(blk, size);
1307
0
  }
1308
44
  if (eof) {
1309
1
    return 0;
1310
1
  }
1311
43
  n = 0;
1312
338
  while (n < size) {
1313
296
    if (seqIndex >= seqLength) {
1314
296
      if (!processNextCode()) {
1315
1
  break;
1316
1
      }
1317
296
    }
1318
295
    m = seqLength - seqIndex;
1319
295
    if (m > size - n) {
1320
42
      m = size - n;
1321
42
    }
1322
295
    memcpy(blk + n, seqBuf + seqIndex, m);
1323
295
    seqIndex += m;
1324
295
    n += m;
1325
295
  }
1326
43
  return n;
1327
44
}
1328
1329
428
void LZWStream::reset() {
1330
428
  str->reset();
1331
428
  if (pred) {
1332
1
    pred->reset();
1333
1
  }
1334
428
  eof = gFalse;
1335
428
  inputBits = 0;
1336
428
  clearTable();
1337
428
  totalIn = totalOut = 0;
1338
428
}
1339
1340
1.21M
GBool LZWStream::processNextCode() {
1341
1.21M
  int code;
1342
1.21M
  int nextLength;
1343
1.21M
  int i, j;
1344
1345
  // check for EOF
1346
1.21M
  if (eof) {
1347
0
    return gFalse;
1348
0
  }
1349
1350
  // check for eod and clear-table codes
1351
1.21M
 start:
1352
1.21M
  code = getCode();
1353
1.21M
  if (code == EOF || code == 257) {
1354
89
    eof = gTrue;
1355
89
    return gFalse;
1356
89
  }
1357
1.21M
  if (code == 256) {
1358
3
    clearTable();
1359
3
    goto start;
1360
3
  }
1361
1.21M
  if (nextCode >= 4097) {
1362
231
    error(errSyntaxError, getPos(),
1363
231
    "Bad LZW stream - expected clear-table code");
1364
231
    clearTable();
1365
231
  }
1366
1367
  // process the next code
1368
1.21M
  nextLength = seqLength + 1;
1369
1.21M
  if (code < 256) {
1370
1.21M
    seqBuf[0] = (Guchar)code;
1371
1.21M
    seqLength = 1;
1372
1.21M
  } else if (code < nextCode) {
1373
511
    seqLength = table[code].length;
1374
1.06k
    for (i = seqLength - 1, j = code; i > 0; --i) {
1375
553
      seqBuf[i] = table[j].tail;
1376
553
      j = table[j].head;
1377
553
    }
1378
511
    seqBuf[0] = (Guchar)j;
1379
511
  } else if (code == nextCode) {
1380
3
    seqBuf[seqLength] = (Guchar)newChar;
1381
3
    ++seqLength;
1382
329
  } else {
1383
329
    error(errSyntaxError, getPos(), "Bad LZW stream - unexpected code");
1384
329
    eof = gTrue;
1385
329
    return gFalse;
1386
329
  }
1387
1.21M
  newChar = seqBuf[0];
1388
1.21M
  if (first) {
1389
651
    first = gFalse;
1390
1.21M
  } else {
1391
1.21M
    table[nextCode].length = nextLength;
1392
1.21M
    table[nextCode].head = prevCode;
1393
1.21M
    table[nextCode].tail = (Guchar)newChar;
1394
1.21M
    ++nextCode;
1395
1.21M
    if (nextCode + early == 512)
1396
602
      nextBits = 10;
1397
1.21M
    else if (nextCode + early == 1024)
1398
535
      nextBits = 11;
1399
1.21M
    else if (nextCode + early == 2048)
1400
240
      nextBits = 12;
1401
1.21M
  }
1402
1.21M
  prevCode = code;
1403
1.21M
  totalOut += seqLength;
1404
1405
  // check for a 'decompression bomb'
1406
1.21M
  if (checkForDecompressionBombs &&
1407
1.21M
      totalOut > decompressionBombSizeThreshold &&
1408
0
      totalIn < totalOut / decompressionBombRatioThreshold) {
1409
0
    error(errSyntaxError, getPos(), "Decompression bomb in LZW stream");
1410
0
    eof = gTrue;
1411
0
    return gFalse;
1412
0
  }
1413
1414
  // reset buffer
1415
1.21M
  seqIndex = 0;
1416
1417
1.21M
  return gTrue;
1418
1.21M
}
1419
1420
2.30k
void LZWStream::clearTable() {
1421
2.30k
  nextCode = 258;
1422
2.30k
  nextBits = 9;
1423
2.30k
  seqIndex = seqLength = 0;
1424
2.30k
  first = gTrue;
1425
2.30k
}
1426
1427
1.21M
int LZWStream::getCode() {
1428
1.21M
  int c;
1429
1.21M
  int code;
1430
1431
2.86M
  while (inputBits < nextBits) {
1432
1.65M
    if ((c = str->getChar()) == EOF)
1433
88
      return EOF;
1434
1.65M
    inputBuf = (inputBuf << 8) | (c & 0xff);
1435
1.65M
    inputBits += 8;
1436
1.65M
    ++totalIn;
1437
1.65M
  }
1438
1.21M
  code = (inputBuf >> (inputBits - nextBits)) & ((1 << nextBits) - 1);
1439
1.21M
  inputBits -= nextBits;
1440
1.21M
  return code;
1441
1.21M
}
1442
1443
GString *LZWStream::getPSFilter(int psLevel, const char *indent,
1444
0
        GBool okToReadStream) {
1445
0
  GString *s;
1446
1447
0
  if (psLevel < 2 || pred) {
1448
0
    return NULL;
1449
0
  }
1450
0
  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
1451
0
    return NULL;
1452
0
  }
1453
0
  s->append(indent)->append("<< ");
1454
0
  if (!early) {
1455
0
    s->append("/EarlyChange 0 ");
1456
0
  }
1457
0
  s->append(">> /LZWDecode filter\n");
1458
0
  return s;
1459
0
}
1460
1461
0
GBool LZWStream::isBinary(GBool last) {
1462
0
  return str->isBinary(gTrue);
1463
0
}
1464
1465
//------------------------------------------------------------------------
1466
// RunLengthStream
1467
//------------------------------------------------------------------------
1468
1469
RunLengthStream::RunLengthStream(Stream *strA):
1470
323
    FilterStream(strA) {
1471
323
  bufPtr = bufEnd = buf;
1472
323
  eof = gFalse;
1473
323
}
1474
1475
315
RunLengthStream::~RunLengthStream() {
1476
315
  delete str;
1477
315
}
1478
1479
293
Stream *RunLengthStream::copy() {
1480
293
  return new RunLengthStream(str->copy());
1481
293
}
1482
1483
84
void RunLengthStream::reset() {
1484
84
  str->reset();
1485
84
  bufPtr = bufEnd = buf;
1486
84
  eof = gFalse;
1487
84
}
1488
1489
1.30k
int RunLengthStream::getBlock(char *blk, int size) {
1490
1.30k
  int n, m;
1491
1492
1.30k
  n = 0;
1493
106k
  while (n < size) {
1494
105k
    if (bufPtr >= bufEnd) {
1495
104k
      if (!fillBuf()) {
1496
52
  break;
1497
52
      }
1498
104k
    }
1499
105k
    m = (int)(bufEnd - bufPtr);
1500
105k
    if (m > size - n) {
1501
1.24k
      m = size - n;
1502
1.24k
    }
1503
105k
    memcpy(blk + n, bufPtr, m);
1504
105k
    bufPtr += m;
1505
105k
    n += m;
1506
105k
  }
1507
1.30k
  return n;
1508
1.30k
}
1509
1510
GString *RunLengthStream::getPSFilter(int psLevel, const char *indent,
1511
0
              GBool okToReadStream) {
1512
0
  GString *s;
1513
1514
0
  if (psLevel < 2) {
1515
0
    return NULL;
1516
0
  }
1517
0
  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
1518
0
    return NULL;
1519
0
  }
1520
0
  s->append(indent)->append("/RunLengthDecode filter\n");
1521
0
  return s;
1522
0
}
1523
1524
0
GBool RunLengthStream::isBinary(GBool last) {
1525
0
  return str->isBinary(gTrue);
1526
0
}
1527
1528
104k
GBool RunLengthStream::fillBuf() {
1529
104k
  int c;
1530
104k
  int n, i;
1531
1532
104k
  if (eof)
1533
0
    return gFalse;
1534
104k
  c = str->getChar();
1535
104k
  if (c == 0x80 || c == EOF) {
1536
52
    eof = gTrue;
1537
52
    return gFalse;
1538
52
  }
1539
104k
  if (c < 0x80) {
1540
63.3k
    n = c + 1;
1541
4.64M
    for (i = 0; i < n; ++i)
1542
4.58M
      buf[i] = (char)str->getChar();
1543
63.3k
  } else {
1544
41.4k
    n = 0x101 - c;
1545
41.4k
    c = str->getChar();
1546
481k
    for (i = 0; i < n; ++i)
1547
440k
      buf[i] = (char)c;
1548
41.4k
  }
1549
104k
  bufPtr = buf;
1550
104k
  bufEnd = buf + n;
1551
104k
  return gTrue;
1552
104k
}
1553
1554
//------------------------------------------------------------------------
1555
// CCITTFaxStream
1556
//------------------------------------------------------------------------
1557
1558
CCITTFaxStream::CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA,
1559
             GBool byteAlignA, int columnsA, int rowsA,
1560
             GBool endOfBlockA, GBool blackA):
1561
86
    FilterStream(strA) {
1562
86
  encoding = encodingA;
1563
86
  endOfLine = endOfLineA;
1564
86
  byteAlign = byteAlignA;
1565
86
  columns = columnsA;
1566
86
  if (columns < 1) {
1567
0
    columns = 1;
1568
86
  } else if (columns > INT_MAX - 3) {
1569
0
    columns = INT_MAX - 3;
1570
0
  }
1571
86
  rows = rowsA;
1572
86
  endOfBlock = endOfBlockA;
1573
86
  black = blackA;
1574
86
  blackXOR = black ? 0xff : 0x00;
1575
  // 0 <= codingLine[0] < codingLine[1] < ... < codingLine[n] = columns
1576
  // ---> max codingLine size = columns + 1
1577
  // refLine has two extra guard entries at the end
1578
  // ---> max refLine size = columns + 3
1579
86
  codingLine = (int *)gmallocn(columns + 1, sizeof(int));
1580
86
  refLine = (int *)gmallocn(columns + 3, sizeof(int));
1581
1582
86
  eof = gFalse;
1583
86
  row = 0;
1584
86
  nextLine2D = encoding < 0;
1585
86
  inputBits = 0;
1586
86
  codingLine[0] = columns;
1587
86
  nextCol = columns;
1588
86
  a0i = 0;
1589
86
  err = gFalse;
1590
86
  nErrors = 0;
1591
86
}
1592
1593
77
CCITTFaxStream::~CCITTFaxStream() {
1594
77
  delete str;
1595
77
  gfree(refLine);
1596
77
  gfree(codingLine);
1597
77
}
1598
1599
71
Stream *CCITTFaxStream::copy() {
1600
71
  return new CCITTFaxStream(str->copy(), encoding, endOfLine,
1601
71
          byteAlign, columns, rows, endOfBlock, black);
1602
71
}
1603
1604
24
void CCITTFaxStream::reset() {
1605
24
  int code1;
1606
1607
24
  str->reset();
1608
24
  eof = gFalse;
1609
24
  row = 0;
1610
24
  nextLine2D = encoding < 0;
1611
24
  inputBits = 0;
1612
24
  codingLine[0] = columns;
1613
24
  nextCol = columns;
1614
24
  a0i = 0;
1615
1616
  // skip any initial zero bits and end-of-line marker, and get the 2D
1617
  // encoding tag
1618
24
  while ((code1 = lookBits(12)) == 0) {
1619
0
    eatBits(1);
1620
0
  }
1621
24
  if (code1 == 0x001) {
1622
0
    eatBits(12);
1623
0
    endOfLine = gTrue;
1624
0
  }
1625
24
  if (encoding > 0) {
1626
0
    nextLine2D = !lookBits(1);
1627
0
    eatBits(1);
1628
0
  }
1629
24
}
1630
1631
35.0k
int CCITTFaxStream::getChar() {
1632
35.0k
  int c, bitsNeeded, bitsAvail, bitsUsed;
1633
1634
35.0k
  if (nextCol >= columns) {
1635
186
    if (eof) {
1636
4
      return EOF;
1637
4
    }
1638
182
    if (!readRow()) {
1639
10
      return EOF;
1640
10
    }
1641
182
  }
1642
35.0k
  bitsAvail = codingLine[a0i] - nextCol;
1643
35.0k
  if (bitsAvail > 8) {
1644
14.8k
    c = (a0i & 1) ? 0x00 : 0xff;
1645
20.2k
  } else {
1646
20.2k
    c = 0;
1647
20.2k
    bitsNeeded = 8;
1648
53.9k
    do {
1649
53.9k
      bitsUsed = (bitsAvail < bitsNeeded) ? bitsAvail : bitsNeeded;
1650
53.9k
      c <<= bitsUsed;
1651
53.9k
      if (!(a0i & 1)) {
1652
32.3k
  c |= 0xff >> (8 - bitsUsed);
1653
32.3k
      }
1654
53.9k
      bitsAvail -= bitsUsed;
1655
53.9k
      bitsNeeded -= bitsUsed;
1656
53.9k
      if (bitsAvail == 0) {
1657
38.5k
  if (codingLine[a0i] >= columns) {
1658
162
    c <<= bitsNeeded;
1659
162
    break;
1660
162
  }
1661
38.3k
  ++a0i;
1662
38.3k
  bitsAvail = codingLine[a0i] - codingLine[a0i - 1];
1663
38.3k
      }
1664
53.9k
    } while (bitsNeeded > 0);
1665
20.2k
  }
1666
35.0k
  nextCol += 8;
1667
35.0k
  c ^= blackXOR;
1668
35.0k
  return c;
1669
35.0k
}
1670
1671
0
int CCITTFaxStream::lookChar() {
1672
0
  int c, bitsNeeded, bitsAvail, bitsUsed, i;
1673
1674
0
  if (nextCol >= columns) {
1675
0
    if (eof) {
1676
0
      return EOF;
1677
0
    }
1678
0
    if (!readRow()) {
1679
0
      return EOF;
1680
0
    }
1681
0
  }
1682
0
  bitsAvail = codingLine[a0i] - nextCol;
1683
0
  if (bitsAvail >= 8) {
1684
0
    c = (a0i & 1) ? 0x00 : 0xff;
1685
0
  } else {
1686
0
    i = a0i;
1687
0
    c = 0;
1688
0
    bitsNeeded = 8;
1689
0
    do {
1690
0
      bitsUsed = (bitsAvail < bitsNeeded) ? bitsAvail : bitsNeeded;
1691
0
      c <<= bitsUsed;
1692
0
      if (!(i & 1)) {
1693
0
  c |= 0xff >> (8 - bitsUsed);
1694
0
      }
1695
0
      bitsAvail -= bitsUsed;
1696
0
      bitsNeeded -= bitsUsed;
1697
0
      if (bitsAvail == 0) {
1698
0
  if (codingLine[i] >= columns) {
1699
0
    c <<= bitsNeeded;
1700
0
    break;
1701
0
  }
1702
0
  ++i;
1703
0
  bitsAvail = codingLine[i] - codingLine[i - 1];
1704
0
      }
1705
0
    } while (bitsNeeded > 0);
1706
0
  }
1707
0
  c ^= blackXOR;
1708
0
  return c;
1709
0
}
1710
1711
0
int CCITTFaxStream::getBlock(char *blk, int size) {
1712
0
  int bytesRead, bitsAvail, bitsNeeded, bitsUsed, byte, c;
1713
1714
0
  bytesRead = 0;
1715
0
  while (bytesRead < size) {
1716
0
    if (nextCol >= columns) {
1717
0
      if (eof) {
1718
0
  break;
1719
0
      }
1720
0
      if (!readRow()) {
1721
0
  break;
1722
0
      }
1723
0
    }
1724
0
    bitsAvail = codingLine[a0i] - nextCol;
1725
0
    byte = (a0i & 1) ? 0x00 : 0xff;
1726
0
    if (bitsAvail > 8) {
1727
0
      c = byte;
1728
0
      bitsAvail -= 8;
1729
0
    } else {
1730
0
      c = 0;
1731
0
      bitsNeeded = 8;
1732
0
      do {
1733
0
  bitsUsed = (bitsAvail < bitsNeeded) ? bitsAvail : bitsNeeded;
1734
0
  c <<= bitsUsed;
1735
0
  c |= byte >> (8 - bitsUsed);
1736
0
  bitsAvail -= bitsUsed;
1737
0
  bitsNeeded -= bitsUsed;
1738
0
  if (bitsAvail == 0) {
1739
0
    if (codingLine[a0i] >= columns) {
1740
0
      c <<= bitsNeeded;
1741
0
      break;
1742
0
    }
1743
0
    ++a0i;
1744
0
    bitsAvail = codingLine[a0i] - codingLine[a0i - 1];
1745
0
    byte ^= 0xff;
1746
0
  }
1747
0
      } while (bitsNeeded > 0);
1748
0
    }
1749
0
    nextCol += 8;
1750
0
    blk[bytesRead++] = (char)(c ^ blackXOR);
1751
0
  }
1752
0
  return bytesRead;
1753
0
}
1754
1755
52.3k
inline void CCITTFaxStream::addPixels(int a1, int blackPixels) {
1756
52.3k
  if (a1 > codingLine[a0i]) {
1757
52.3k
    if (a1 > columns) {
1758
140
      error(errSyntaxError, getPos(),
1759
140
      "CCITTFax row is wrong length ({0:d})", a1);
1760
140
      err = gTrue;
1761
140
      ++nErrors;
1762
140
      a1 = columns;
1763
140
    }
1764
52.3k
    if ((a0i & 1) ^ blackPixels) {
1765
52.1k
      ++a0i;
1766
52.1k
    }
1767
52.3k
    codingLine[a0i] = a1;
1768
52.3k
  }
1769
52.3k
}
1770
1771
0
inline void CCITTFaxStream::addPixelsNeg(int a1, int blackPixels) {
1772
0
  if (a1 > codingLine[a0i]) {
1773
0
    if (a1 > columns) {
1774
0
      error(errSyntaxError, getPos(),
1775
0
      "CCITTFax row is wrong length ({0:d})", a1);
1776
0
      err = gTrue;
1777
0
      ++nErrors;
1778
0
      a1 = columns;
1779
0
    }
1780
0
    if ((a0i & 1) ^ blackPixels) {
1781
0
      ++a0i;
1782
0
    }
1783
0
    codingLine[a0i] = a1;
1784
0
  } else if (a1 < codingLine[a0i]) {
1785
0
    if (a1 < 0) {
1786
0
      error(errSyntaxError, getPos(), "Invalid CCITTFax code");
1787
0
      err = gTrue;
1788
0
      ++nErrors;
1789
0
      a1 = 0;
1790
0
    }
1791
0
    while (a0i > 0 && a1 <= codingLine[a0i - 1]) {
1792
0
      --a0i;
1793
0
    }
1794
0
    codingLine[a0i] = a1;
1795
0
  }
1796
0
}
1797
1798
182
GBool CCITTFaxStream::readRow() {
1799
182
  int code1, code2, code3;
1800
182
  int b1i, blackPixels, i;
1801
182
  GBool gotEOL;
1802
1803
  // if at eof just return EOF
1804
182
  if (eof) {
1805
0
    return gFalse;
1806
0
  }
1807
1808
182
  err = gFalse;
1809
1810
  // 2-D encoding
1811
182
  if (nextLine2D) {
1812
0
    for (i = 0; codingLine[i] < columns; ++i) {
1813
0
      refLine[i] = codingLine[i];
1814
0
    }
1815
0
    refLine[i++] = columns;
1816
0
    refLine[i++] = columns;
1817
0
    refLine[i] = columns;
1818
0
    codingLine[0] = 0;
1819
0
    a0i = 0;
1820
0
    b1i = 0;
1821
0
    blackPixels = 0;
1822
    // invariant:
1823
    // refLine[b1i-1] <= codingLine[a0i] < refLine[b1i] < refLine[b1i+1]
1824
    //                                                             <= columns
1825
    // exception at left edge:
1826
    //   codingLine[a0i = 0] = refLine[b1i = 0] = 0 is possible
1827
    // exception at right edge:
1828
    //   refLine[b1i] = refLine[b1i+1] = columns is possible
1829
0
    while (codingLine[a0i] < columns) {
1830
0
      code1 = getTwoDimCode();
1831
0
      switch (code1) {
1832
0
      case twoDimPass:
1833
0
  addPixels(refLine[b1i + 1], blackPixels);
1834
0
  if (refLine[b1i + 1] < columns) {
1835
0
    b1i += 2;
1836
0
  }
1837
0
  break;
1838
0
      case twoDimHoriz:
1839
0
  code1 = code2 = 0;
1840
0
  if (blackPixels) {
1841
0
    do {
1842
0
      code1 += code3 = getBlackCode();
1843
0
    } while (code3 >= 64);
1844
0
    do {
1845
0
      code2 += code3 = getWhiteCode();
1846
0
    } while (code3 >= 64);
1847
0
  } else {
1848
0
    do {
1849
0
      code1 += code3 = getWhiteCode();
1850
0
    } while (code3 >= 64);
1851
0
    do {
1852
0
      code2 += code3 = getBlackCode();
1853
0
    } while (code3 >= 64);
1854
0
  }
1855
0
  addPixels(codingLine[a0i] + code1, blackPixels);
1856
0
  if (codingLine[a0i] < columns) {
1857
0
    addPixels(codingLine[a0i] + code2, blackPixels ^ 1);
1858
0
  }
1859
0
  while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1860
0
    b1i += 2;
1861
0
  }
1862
0
  break;
1863
0
      case twoDimVertR3:
1864
0
  addPixels(refLine[b1i] + 3, blackPixels);
1865
0
  blackPixels ^= 1;
1866
0
  if (codingLine[a0i] < columns) {
1867
0
    ++b1i;
1868
0
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1869
0
      b1i += 2;
1870
0
    }
1871
0
  }
1872
0
  break;
1873
0
      case twoDimVertR2:
1874
0
  addPixels(refLine[b1i] + 2, blackPixels);
1875
0
  blackPixels ^= 1;
1876
0
  if (codingLine[a0i] < columns) {
1877
0
    ++b1i;
1878
0
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1879
0
      b1i += 2;
1880
0
    }
1881
0
  }
1882
0
  break;
1883
0
      case twoDimVertR1:
1884
0
  addPixels(refLine[b1i] + 1, blackPixels);
1885
0
  blackPixels ^= 1;
1886
0
  if (codingLine[a0i] < columns) {
1887
0
    ++b1i;
1888
0
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1889
0
      b1i += 2;
1890
0
    }
1891
0
  }
1892
0
  break;
1893
0
      case twoDimVert0:
1894
0
  addPixels(refLine[b1i], blackPixels);
1895
0
  blackPixels ^= 1;
1896
0
  if (codingLine[a0i] < columns) {
1897
0
    ++b1i;
1898
0
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1899
0
      b1i += 2;
1900
0
    }
1901
0
  }
1902
0
  break;
1903
0
      case twoDimVertL3:
1904
0
  addPixelsNeg(refLine[b1i] - 3, blackPixels);
1905
0
  blackPixels ^= 1;
1906
0
  if (codingLine[a0i] < columns) {
1907
0
    if (b1i > 0) {
1908
0
      --b1i;
1909
0
    } else {
1910
0
      ++b1i;
1911
0
    }
1912
0
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1913
0
      b1i += 2;
1914
0
    }
1915
0
  }
1916
0
  break;
1917
0
      case twoDimVertL2:
1918
0
  addPixelsNeg(refLine[b1i] - 2, blackPixels);
1919
0
  blackPixels ^= 1;
1920
0
  if (codingLine[a0i] < columns) {
1921
0
    if (b1i > 0) {
1922
0
      --b1i;
1923
0
    } else {
1924
0
      ++b1i;
1925
0
    }
1926
0
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1927
0
      b1i += 2;
1928
0
    }
1929
0
  }
1930
0
  break;
1931
0
      case twoDimVertL1:
1932
0
  addPixelsNeg(refLine[b1i] - 1, blackPixels);
1933
0
  blackPixels ^= 1;
1934
0
  if (codingLine[a0i] < columns) {
1935
0
    if (b1i > 0) {
1936
0
      --b1i;
1937
0
    } else {
1938
0
      ++b1i;
1939
0
    }
1940
0
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1941
0
      b1i += 2;
1942
0
    }
1943
0
  }
1944
0
  break;
1945
0
      case EOF:
1946
0
  addPixels(columns, 0);
1947
0
  err = gTrue;
1948
0
  break;
1949
0
      default:
1950
0
  error(errSyntaxError, getPos(),
1951
0
        "Bad 2D code {0:04x} in CCITTFax stream", code1);
1952
0
  addPixels(columns, 0);
1953
0
  err = gTrue;
1954
0
  ++nErrors;
1955
0
  break;
1956
0
      }
1957
0
    }
1958
1959
  // 1-D encoding
1960
182
  } else {
1961
182
    codingLine[0] = 0;
1962
182
    a0i = 0;
1963
182
    blackPixels = 0;
1964
52.5k
    while (codingLine[a0i] < columns) {
1965
52.3k
      code1 = 0;
1966
52.3k
      if (blackPixels) {
1967
26.1k
  do {
1968
26.1k
    code1 += code3 = getBlackCode();
1969
26.1k
  } while (code3 >= 64);
1970
26.2k
      } else {
1971
26.4k
  do {
1972
26.4k
    code1 += code3 = getWhiteCode();
1973
26.4k
  } while (code3 >= 64);
1974
26.2k
      }
1975
52.3k
      addPixels(codingLine[a0i] + code1, blackPixels);
1976
52.3k
      blackPixels ^= 1;
1977
52.3k
    }
1978
182
  }
1979
1980
  // check for end-of-line marker, skipping over any extra zero bits
1981
  // (if EncodedByteAlign is true and EndOfLine is false, there can
1982
  // be "false" EOL markers -- i.e., if the last n unused bits in
1983
  // row i are set to zero, and the first 11-n bits in row i+1
1984
  // happen to be zero -- so we don't look for EOL markers in this
1985
  // case)
1986
182
  gotEOL = gFalse;
1987
182
  if (!endOfBlock && row == rows - 1) {
1988
0
    eof = gTrue;
1989
182
  } else if (endOfLine || !byteAlign) {
1990
182
    code1 = lookBits(12);
1991
182
    if (endOfLine) {
1992
0
      while (code1 != EOF && code1 != 0x001) {
1993
0
  eatBits(1);
1994
0
  code1 = lookBits(12);
1995
0
      }
1996
182
    } else {
1997
2.94k
      while (code1 == 0) {
1998
2.76k
  eatBits(1);
1999
2.76k
  code1 = lookBits(12);
2000
2.76k
      }
2001
182
    }
2002
182
    if (code1 == 0x001) {
2003
20
      eatBits(12);
2004
20
      gotEOL = gTrue;
2005
20
    }
2006
182
  }
2007
2008
  // byte-align the row
2009
  // (Adobe apparently doesn't do byte alignment after EOL markers
2010
  // -- I've seen CCITT image data streams in two different formats,
2011
  // both with the byteAlign flag set:
2012
  //   1. xx:x0:01:yy:yy
2013
  //   2. xx:00:1y:yy:yy
2014
  // where xx is the previous line, yy is the next line, and colons
2015
  // separate bytes.)
2016
182
  if (byteAlign && !gotEOL) {
2017
0
    inputBits &= ~7;
2018
0
  }
2019
2020
  // check for end of stream
2021
182
  if (lookBits(1) == EOF) {
2022
2
    eof = gTrue;
2023
2
  }
2024
2025
  // get 2D encoding tag
2026
182
  if (!eof && encoding > 0) {
2027
0
    nextLine2D = !lookBits(1);
2028
0
    eatBits(1);
2029
0
  }
2030
2031
  // check for end-of-block marker
2032
182
  if (endOfBlock && !endOfLine && byteAlign) {
2033
    // in this case, we didn't check for an EOL code above, so we
2034
    // need to check here
2035
0
    code1 = lookBits(24);
2036
0
    if (code1 == 0x001001) {
2037
0
      eatBits(12);
2038
0
      gotEOL = gTrue;
2039
0
    }
2040
0
  }
2041
182
  if (endOfBlock && gotEOL) {
2042
20
    code1 = lookBits(12);
2043
20
    if (code1 == 0x001) {
2044
0
      eatBits(12);
2045
0
      if (encoding > 0) {
2046
0
  lookBits(1);
2047
0
  eatBits(1);
2048
0
      }
2049
0
      if (encoding > 0) {
2050
0
  for (i = 0; i < 4; ++i) {
2051
0
    code1 = lookBits(12);
2052
0
    if (code1 != 0x001) {
2053
0
      error(errSyntaxError, getPos(),
2054
0
      "Bad RTC code in CCITTFax stream");
2055
0
      ++nErrors;
2056
0
    }
2057
0
    eatBits(12);
2058
0
    if (encoding > 0) {
2059
0
      lookBits(1);
2060
0
      eatBits(1);
2061
0
    }
2062
0
  }
2063
0
      }
2064
0
      eof = gTrue;
2065
0
    }
2066
2067
  // look for an end-of-line marker after an error -- we only do
2068
  // this if we know the stream contains end-of-line markers because
2069
  // the "just plow on" technique tends to work better otherwise
2070
162
  } else if (err && endOfLine) {
2071
0
    while (1) {
2072
0
      code1 = lookBits(13);
2073
0
      if (code1 == EOF) {
2074
0
  eof = gTrue;
2075
0
  return gFalse;
2076
0
      }
2077
0
      if ((code1 >> 1) == 0x001) {
2078
0
  break;
2079
0
      }
2080
0
      eatBits(1);
2081
0
    }
2082
0
    eatBits(12); 
2083
0
    if (encoding > 0) {
2084
0
      eatBits(1);
2085
0
      nextLine2D = !(code1 & 1);
2086
0
    }
2087
0
  }
2088
2089
  // corrupt CCITTFax streams can generate huge data expansion -- we
2090
  // avoid that case by aborting decode after 1000 errors
2091
182
  if (nErrors > 1000) {
2092
10
    error(errSyntaxError, getPos(), "Too many errors in CCITTFaxStream - aborting decode");
2093
10
    eof = gTrue;
2094
10
    return gFalse;
2095
10
  }
2096
2097
  // set up for output
2098
172
  nextCol = 0;
2099
172
  a0i = (codingLine[0] > 0) ? 0 : 1;
2100
2101
172
  ++row;
2102
2103
172
  return gTrue;
2104
182
}
2105
2106
0
short CCITTFaxStream::getTwoDimCode() {
2107
0
  int code;
2108
0
  CCITTCode *p;
2109
0
  int n;
2110
2111
0
  code = 0; // make gcc happy
2112
0
  if (endOfBlock) {
2113
0
    if ((code = lookBits(7)) != EOF) {
2114
0
      p = &twoDimTab1[code];
2115
0
      if (p->bits > 0) {
2116
0
  eatBits(p->bits);
2117
0
  return p->n;
2118
0
      }
2119
0
    }
2120
0
  } else {
2121
0
    for (n = 1; n <= 7; ++n) {
2122
0
      if ((code = lookBits(n)) == EOF) {
2123
0
  break;
2124
0
      }
2125
0
      if (n < 7) {
2126
0
  code <<= 7 - n;
2127
0
      }
2128
0
      p = &twoDimTab1[code];
2129
0
      if (p->bits == n) {
2130
0
  eatBits(n);
2131
0
  return p->n;
2132
0
      }
2133
0
    }
2134
0
  }
2135
0
  error(errSyntaxError, getPos(),
2136
0
  "Bad two dim code ({0:04x}) in CCITTFax stream", code);
2137
0
  ++nErrors;
2138
0
  return EOF;
2139
0
}
2140
2141
26.4k
short CCITTFaxStream::getWhiteCode() {
2142
26.4k
  short code;
2143
26.4k
  CCITTCode *p;
2144
26.4k
  int n;
2145
2146
26.4k
  code = 0; // make gcc happy
2147
26.4k
  if (endOfBlock) {
2148
26.4k
    code = lookBits(12);
2149
26.4k
    if (code == EOF) {
2150
1.72k
      return 1;
2151
1.72k
    }
2152
24.7k
    if ((code >> 5) == 0) {
2153
6.48k
      p = &whiteTab1[code];
2154
18.2k
    } else {
2155
18.2k
      p = &whiteTab2[code >> 3];
2156
18.2k
    }
2157
24.7k
    if (p->bits > 0) {
2158
18.2k
      eatBits(p->bits);
2159
18.2k
      return p->n;
2160
18.2k
    }
2161
24.7k
  } else {
2162
0
    for (n = 1; n <= 9; ++n) {
2163
0
      code = lookBits(n);
2164
0
      if (code == EOF) {
2165
0
  return 1;
2166
0
      }
2167
0
      if (n < 9) {
2168
0
  code = (short)(code << (9 - n));
2169
0
      }
2170
0
      p = &whiteTab2[code];
2171
0
      if (p->bits == n) {
2172
0
  eatBits(n);
2173
0
  return p->n;
2174
0
      }
2175
0
    }
2176
0
    for (n = 11; n <= 12; ++n) {
2177
0
      code = lookBits(n);
2178
0
      if (code == EOF) {
2179
0
  return 1;
2180
0
      }
2181
0
      if (n < 12) {
2182
0
  code = (short)(code << (12 - n));
2183
0
      }
2184
0
      p = &whiteTab1[code];
2185
0
      if (p->bits == n) {
2186
0
  eatBits(n);
2187
0
  return p->n;
2188
0
      }
2189
0
    }
2190
0
  }
2191
6.48k
  error(errSyntaxError, getPos(),
2192
6.48k
  "Bad white code ({0:04x}) in CCITTFax stream", code);
2193
6.48k
  ++nErrors;
2194
  // eat a bit and return a positive number so that the caller doesn't
2195
  // go into an infinite loop
2196
6.48k
  eatBits(1);
2197
6.48k
  return 1;
2198
26.4k
}
2199
2200
26.1k
short CCITTFaxStream::getBlackCode() {
2201
26.1k
  short code;
2202
26.1k
  CCITTCode *p;
2203
26.1k
  int n;
2204
2205
26.1k
  code = 0; // make gcc happy
2206
26.1k
  if (endOfBlock) {
2207
26.1k
    code = lookBits(13);
2208
26.1k
    if (code == EOF) {
2209
1.72k
      return 1;
2210
1.72k
    }
2211
24.4k
    if ((code >> 7) == 0) {
2212
6.55k
      p = &blackTab1[code];
2213
17.8k
    } else if ((code >> 9) == 0 && (code >> 7) != 0) {
2214
70
      p = &blackTab2[(code >> 1) - 64];
2215
17.7k
    } else {
2216
17.7k
      p = &blackTab3[code >> 7];
2217
17.7k
    }
2218
24.4k
    if (p->bits > 0) {
2219
17.9k
      eatBits(p->bits);
2220
17.9k
      return p->n;
2221
17.9k
    }
2222
24.4k
  } else {
2223
0
    for (n = 2; n <= 6; ++n) {
2224
0
      code = lookBits(n);
2225
0
      if (code == EOF) {
2226
0
  return 1;
2227
0
      }
2228
0
      if (n < 6) {
2229
0
  code = (short)(code << (6 - n));
2230
0
      }
2231
0
      p = &blackTab3[code];
2232
0
      if (p->bits == n) {
2233
0
  eatBits(n);
2234
0
  return p->n;
2235
0
      }
2236
0
    }
2237
0
    for (n = 7; n <= 12; ++n) {
2238
0
      code = lookBits(n);
2239
0
      if (code == EOF) {
2240
0
  return 1;
2241
0
      }
2242
0
      if (n < 12) {
2243
0
  code = (short)(code << (12 - n));
2244
0
      }
2245
0
      if (code >= 64) {
2246
0
  p = &blackTab2[code - 64];
2247
0
  if (p->bits == n) {
2248
0
    eatBits(n);
2249
0
    return p->n;
2250
0
  }
2251
0
      }
2252
0
    }
2253
0
    for (n = 10; n <= 13; ++n) {
2254
0
      code = lookBits(n);
2255
0
      if (code == EOF) {
2256
0
  return 1;
2257
0
      }
2258
0
      if (n < 13) {
2259
0
  code = (short)(code << (13 - n));
2260
0
      }
2261
0
      p = &blackTab1[code];
2262
0
      if (p->bits == n) {
2263
0
  eatBits(n);
2264
0
  return p->n;
2265
0
      }
2266
0
    }
2267
0
  }
2268
6.49k
  error(errSyntaxError, getPos(),
2269
6.49k
  "Bad black code ({0:04x}) in CCITTFax stream", code);
2270
6.49k
  ++nErrors;
2271
  // eat a bit and return a positive number so that the caller doesn't
2272
  // go into an infinite loop
2273
6.49k
  eatBits(1);
2274
6.49k
  return 1;
2275
26.1k
}
2276
2277
55.7k
short CCITTFaxStream::lookBits(int n) {
2278
55.7k
  int c;
2279
2280
71.8k
  while (inputBits < n) {
2281
19.5k
    if ((c = str->getChar()) == EOF) {
2282
3.46k
      if (inputBits == 0) {
2283
3.46k
  return EOF;
2284
3.46k
      }
2285
      // near the end of the stream, the caller may ask for more bits
2286
      // than are available, but there may still be a valid code in
2287
      // however many bits are available -- we need to return correct
2288
      // data in this case
2289
0
      return (short)((inputBuf << (n - inputBits)) & (0xffffffff >> (32 - n)));
2290
3.46k
    }
2291
16.0k
    inputBuf = (inputBuf << 8) + c;
2292
16.0k
    inputBits += 8;
2293
16.0k
  }
2294
52.3k
  return (short)((inputBuf >> (inputBits - n)) & (0xffffffff >> (32 - n)));
2295
55.7k
}
2296
2297
GString *CCITTFaxStream::getPSFilter(int psLevel, const char *indent,
2298
0
             GBool okToReadStream) {
2299
0
  GString *s;
2300
2301
0
  if (psLevel < 2) {
2302
0
    return NULL;
2303
0
  }
2304
0
  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
2305
0
    return NULL;
2306
0
  }
2307
0
  s->append(indent)->append("<< ");
2308
0
  if (encoding != 0) {
2309
0
    s->appendf("/K {0:d} ", encoding);
2310
0
  }
2311
0
  if (endOfLine) {
2312
0
    s->append("/EndOfLine true ");
2313
0
  }
2314
0
  if (byteAlign) {
2315
0
    s->append("/EncodedByteAlign true ");
2316
0
  }
2317
0
  s->appendf("/Columns {0:d} ", columns);
2318
0
  if (rows != 0) {
2319
0
    s->appendf("/Rows {0:d} ", rows);
2320
0
  }
2321
0
  if (!endOfBlock) {
2322
0
    s->append("/EndOfBlock false ");
2323
0
  }
2324
0
  if (black) {
2325
0
    s->append("/BlackIs1 true ");
2326
0
  }
2327
0
  s->append(">> /CCITTFaxDecode filter\n");
2328
0
  return s;
2329
0
}
2330
2331
0
GBool CCITTFaxStream::isBinary(GBool last) {
2332
0
  return str->isBinary(gTrue);
2333
0
}
2334
2335
//------------------------------------------------------------------------
2336
// DCTStream
2337
//------------------------------------------------------------------------
2338
2339
#if HAVE_JPEGLIB
2340
2341
DCTStream::DCTStream(Stream *strA, GBool colorXformA):
2342
    FilterStream(strA) {
2343
  colorXform = colorXformA;
2344
  lineBuf = NULL;
2345
  inlineImage = str->isEmbedStream();
2346
}
2347
2348
DCTStream::~DCTStream() {
2349
  delete str;
2350
}
2351
2352
Stream *DCTStream::copy() {
2353
  return new DCTStream(str->copy(), colorXform);
2354
}
2355
2356
void DCTStream::reset() {
2357
  int i;
2358
2359
  lineBuf = NULL;
2360
  error = gFalse;
2361
2362
  str->reset();
2363
2364
  // initialize the libjpeg decompression object
2365
  decomp.err = jpeg_std_error(&errorMgr.err);
2366
  errorMgr.err.error_exit = &errorExit;
2367
  errorMgr.err.output_message = &errorMessage;
2368
  if (setjmp(errorMgr.setjmpBuf)) {
2369
    error = gTrue;
2370
    return;
2371
  }
2372
  jpeg_create_decompress(&decomp);
2373
2374
  // set up the data source manager
2375
  sourceMgr.src.next_input_byte = NULL;
2376
  sourceMgr.src.bytes_in_buffer = 0;
2377
  sourceMgr.src.init_source = &initSourceCbk;
2378
  sourceMgr.src.fill_input_buffer = &fillInputBufferCbk;
2379
  sourceMgr.src.skip_input_data = &skipInputDataCbk;
2380
  sourceMgr.src.resync_to_restart = &jpeg_resync_to_restart;
2381
  sourceMgr.src.term_source = &termSourceCbk;
2382
  sourceMgr.str = this;
2383
  decomp.src = &sourceMgr.src;
2384
2385
  // read the header
2386
  jpeg_read_header(&decomp, TRUE);
2387
  jpeg_calc_output_dimensions(&decomp);
2388
2389
  // set up the color transform
2390
  if (!decomp.saw_Adobe_marker && colorXform >= 0) {
2391
    if (decomp.num_components == 3) {
2392
      decomp.jpeg_color_space = colorXform ? JCS_YCbCr : JCS_RGB;
2393
      decomp.out_color_space = JCS_RGB;
2394
      decomp.out_color_components = 3;
2395
    } else if (decomp.num_components == 4) {
2396
      decomp.jpeg_color_space = colorXform ? JCS_YCCK : JCS_CMYK;
2397
      decomp.out_color_space = JCS_CMYK;
2398
      decomp.out_color_components = 4;
2399
    }
2400
  }
2401
2402
  // allocate a line buffer
2403
  if ((lineBufHeight = decomp.rec_outbuf_height) > 4) {
2404
    lineBufHeight = 4;
2405
  }
2406
  lineBuf = (char *)gmallocn(lineBufHeight * decomp.out_color_components,
2407
           decomp.output_width);
2408
  for (i = 0; i < lineBufHeight; ++i) {
2409
    lineBufRows[i] = lineBuf +
2410
                     i * decomp.out_color_components * decomp.output_width;
2411
  }
2412
  bufPtr = bufEnd = lineBuf;
2413
2414
  // start up the decompression process
2415
  jpeg_start_decompress(&decomp);
2416
}
2417
2418
GBool DCTStream::checkSequentialInterleaved() {
2419
  //~ this is unimplemented
2420
  return gTrue;
2421
}
2422
2423
void DCTStream::close() {
2424
  // we don't call jpeg_finish_decompress() here because it will report
2425
  // an error if the full image wasn't read
2426
  if (setjmp(errorMgr.setjmpBuf)) {
2427
    goto skip;
2428
  }
2429
  jpeg_destroy_decompress(&decomp);
2430
 skip:
2431
  gfree(lineBuf);
2432
  FilterStream::close();
2433
}
2434
2435
int DCTStream::getChar() {
2436
  if (error) {
2437
    return EOF;
2438
  }
2439
  if (bufPtr == bufEnd) {
2440
    if (!fillBuf()) {
2441
      return EOF;
2442
    }
2443
  }
2444
  return *bufPtr++ & 0xff;
2445
}
2446
2447
int DCTStream::lookChar() {
2448
  if (error) {
2449
    return EOF;
2450
  }
2451
  if (bufPtr == bufEnd) {
2452
    if (!fillBuf()) {
2453
      return EOF;
2454
    }
2455
  }
2456
  return *bufPtr & 0xff;
2457
}
2458
2459
int DCTStream::getBlock(char *blk, int size) {
2460
  int nRead, nAvail, n;
2461
2462
  if (error) {
2463
    return 0;
2464
  }
2465
  nRead = 0;
2466
  while (nRead < size) {
2467
    if (bufPtr == bufEnd) {
2468
      if (!fillBuf()) {
2469
  break;
2470
      }
2471
    }
2472
    nAvail = bufEnd - bufPtr;
2473
    n = (nAvail < size - nRead) ? nAvail : size - nRead;
2474
    memcpy(blk + nRead, bufPtr, n);
2475
    bufPtr += n;
2476
    nRead += n;
2477
  }
2478
  return nRead;
2479
}
2480
2481
GBool DCTStream::fillBuf() {
2482
  int nLines;
2483
2484
  if (setjmp(errorMgr.setjmpBuf)) {
2485
    error = gTrue;
2486
    return gFalse;
2487
  }
2488
  nLines = jpeg_read_scanlines(&decomp, (JSAMPARRAY)lineBufRows,
2489
             lineBufHeight);
2490
  bufPtr = lineBuf;
2491
  bufEnd = lineBuf +
2492
           nLines * decomp.out_color_components * decomp.output_width;
2493
  return nLines > 0;
2494
}
2495
2496
void DCTStream::errorExit(j_common_ptr d) {
2497
  DCTErrorMgr *errMgr = (DCTErrorMgr *)d->err;
2498
  longjmp(errMgr->setjmpBuf, 1);
2499
}
2500
2501
void DCTStream::errorMessage(j_common_ptr d) {
2502
#if 0 // for debugging
2503
  char buf[JMSG_LENGTH_MAX];
2504
2505
  (*d->err->format_message)(d, buf);
2506
  fprintf(stderr, "%s\n", buf);
2507
#endif
2508
}
2509
2510
void DCTStream::initSourceCbk(j_decompress_ptr d) {
2511
  DCTSourceMgr *sourceMgr = (DCTSourceMgr *)d->src;
2512
2513
  sourceMgr->src.next_input_byte = NULL;
2514
  sourceMgr->src.bytes_in_buffer = 0;
2515
}
2516
2517
boolean DCTStream::fillInputBufferCbk(j_decompress_ptr d) {
2518
  DCTSourceMgr *sourceMgr = (DCTSourceMgr *)d->src;
2519
  int c, n;
2520
2521
  // for inline images, we need to read one byte at a time so we don't
2522
  // read past the end of the input data
2523
  if (sourceMgr->str->inlineImage) {
2524
    c = sourceMgr->str->str->getChar();
2525
    if (c == EOF) {
2526
      sourceMgr->buf[0] = (char)0xff;
2527
      sourceMgr->buf[1] = (char)JPEG_EOI;
2528
      sourceMgr->src.bytes_in_buffer = 2;
2529
    } else {
2530
      sourceMgr->buf[0] = (char)c;
2531
      sourceMgr->src.bytes_in_buffer = 1;
2532
    }
2533
  } else {
2534
    n = sourceMgr->str->str->getBlock(sourceMgr->buf, dctStreamBufSize);
2535
    if (n > 0) {
2536
      sourceMgr->src.bytes_in_buffer = (size_t)n;
2537
    } else {
2538
      sourceMgr->buf[0] = (char)0xff;
2539
      sourceMgr->buf[1] = (char)JPEG_EOI;
2540
      sourceMgr->src.bytes_in_buffer = 2;
2541
    }
2542
  }
2543
  sourceMgr->src.next_input_byte = (JOCTET *)sourceMgr->buf;
2544
  return TRUE;
2545
}
2546
2547
void DCTStream::skipInputDataCbk(j_decompress_ptr d, long numBytes) {
2548
  DCTSourceMgr *sourceMgr = (DCTSourceMgr *)d->src;
2549
2550
  if (numBytes > 0) {
2551
    if ((long)sourceMgr->src.bytes_in_buffer < numBytes) {
2552
      sourceMgr->str->str->discardChars(
2553
       (Guint)(numBytes - sourceMgr->src.bytes_in_buffer));
2554
      sourceMgr->src.bytes_in_buffer = 0;
2555
    } else {
2556
      sourceMgr->src.bytes_in_buffer -= numBytes;
2557
      sourceMgr->src.next_input_byte += numBytes;
2558
    }
2559
  }
2560
}
2561
2562
void DCTStream::termSourceCbk(j_decompress_ptr d) {
2563
}
2564
2565
#else // HAVE_JPEGLIB
2566
2567
#define idctScaleA 1024
2568
#define idctScaleB 1138
2569
#define idctScaleC 1730
2570
#define idctScaleD 1609
2571
#define idctScaleE 1264
2572
#define idctScaleF 1922
2573
#define idctScaleG 1788
2574
#define idctScaleH 2923
2575
#define idctScaleI 2718
2576
#define idctScaleJ 2528
2577
2578
static int idctScaleMat[64] = {
2579
  idctScaleA, idctScaleB, idctScaleC, idctScaleD, idctScaleA, idctScaleD, idctScaleC, idctScaleB,
2580
  idctScaleB, idctScaleE, idctScaleF, idctScaleG, idctScaleB, idctScaleG, idctScaleF, idctScaleE,
2581
  idctScaleC, idctScaleF, idctScaleH, idctScaleI, idctScaleC, idctScaleI, idctScaleH, idctScaleF,
2582
  idctScaleD, idctScaleG, idctScaleI, idctScaleJ, idctScaleD, idctScaleJ, idctScaleI, idctScaleG,
2583
  idctScaleA, idctScaleB, idctScaleC, idctScaleD, idctScaleA, idctScaleD, idctScaleC, idctScaleB,
2584
  idctScaleD, idctScaleG, idctScaleI, idctScaleJ, idctScaleD, idctScaleJ, idctScaleI, idctScaleG,
2585
  idctScaleC, idctScaleF, idctScaleH, idctScaleI, idctScaleC, idctScaleI, idctScaleH, idctScaleF,
2586
  idctScaleB, idctScaleE, idctScaleF, idctScaleG, idctScaleB, idctScaleG, idctScaleF, idctScaleE
2587
};
2588
2589
// color conversion parameters (16.16 fixed point format)
2590
46.0k
#define dctCrToR   91881  //  1.4020
2591
46.0k
#define dctCbToG  -22553  // -0.3441363
2592
46.0k
#define dctCrToG  -46802  // -0.71413636
2593
46.0k
#define dctCbToB  116130  //  1.772
2594
2595
// The dctClip function clips signed integers to the [0,255] range.
2596
// To handle valid DCT inputs, this must support an input range of at
2597
// least [-256,511].  Invalid DCT inputs (e.g., from damaged PDF
2598
// files) can result in arbitrary values, so we want to mask those
2599
// out.  We round the input range size up to a power of 2 (so we can
2600
// use a bit mask), which gives us an input range of [-384,639].  The
2601
// end result is:
2602
//     input       output
2603
//     ----------  ------
2604
//     <-384       X        invalid inputs -> output is "don't care"
2605
//     -384..-257  0        invalid inputs, clipped
2606
//     -256..-1    0        valid inputs, need to be clipped
2607
//     0..255      0..255
2608
//     256..511    255      valid inputs, need to be clipped
2609
//     512..639    255      invalid inputs, clipped
2610
//     >=512       X        invalid inputs -> output is "don't care"
2611
2612
250k
#define dctClipOffset  384
2613
249k
#define dctClipMask   1023
2614
static Guchar dctClipData[1024];
2615
2616
1.56k
static inline void dctClipInit() {
2617
1.56k
  static int initDone = 0;
2618
1.56k
  int i;
2619
1.56k
  if (!initDone) {
2620
385
    for (i = -384; i < 0; ++i) {
2621
384
      dctClipData[dctClipOffset + i] = 0;
2622
384
    }
2623
257
    for (i = 0; i < 256; ++i) {
2624
256
      dctClipData[dctClipOffset + i] = (Guchar)i;
2625
256
    }
2626
384
    for (i = 256; i < 639; ++i) {
2627
383
      dctClipData[dctClipOffset + i] = 255;
2628
383
    }
2629
1
    initDone = 1;
2630
1
  }
2631
1.56k
}
2632
2633
249k
static inline Guchar dctClip(int x) {
2634
249k
  return dctClipData[(dctClipOffset + x) & dctClipMask];
2635
249k
}
2636
2637
// zig zag decode map
2638
static int dctZigZag[64] = {
2639
   0,
2640
   1,  8,
2641
  16,  9,  2,
2642
   3, 10, 17, 24,
2643
  32, 25, 18, 11, 4,
2644
   5, 12, 19, 26, 33, 40,
2645
  48, 41, 34, 27, 20, 13,  6,
2646
   7, 14, 21, 28, 35, 42, 49, 56,
2647
  57, 50, 43, 36, 29, 22, 15,
2648
  23, 30, 37, 44, 51, 58,
2649
  59, 52, 45, 38, 31,
2650
  39, 46, 53, 60,
2651
  61, 54, 47,
2652
  55, 62,
2653
  63
2654
};
2655
2656
DCTStream::DCTStream(Stream *strA, GBool colorXformA):
2657
1.56k
    FilterStream(strA) {
2658
1.56k
  int i;
2659
2660
1.56k
  prepared = gFalse;
2661
1.56k
  colorXform = colorXformA;
2662
1.56k
  progressive = interleaved = gFalse;
2663
1.56k
  width = height = 0;
2664
1.56k
  mcuWidth = mcuHeight = 0;
2665
1.56k
  numComps = 0;
2666
1.56k
  comp = 0;
2667
1.56k
  x = y = 0;
2668
7.80k
  for (i = 0; i < 4; ++i) {
2669
6.24k
    frameBuf[i] = NULL;
2670
6.24k
  }
2671
1.56k
  rowBuf = NULL;
2672
1.56k
  memset(quantTables, 0, sizeof(quantTables));
2673
1.56k
  memset(dcHuffTables, 0, sizeof(dcHuffTables));
2674
1.56k
  memset(acHuffTables, 0, sizeof(acHuffTables));
2675
2676
1.56k
  dctClipInit();
2677
1.56k
}
2678
2679
1.51k
DCTStream::~DCTStream() {
2680
1.51k
  close();
2681
1.51k
  delete str;
2682
1.51k
}
2683
2684
1.47k
Stream *DCTStream::copy() {
2685
1.47k
  return new DCTStream(str->copy(), colorXform);
2686
1.47k
}
2687
2688
502
void DCTStream::reset() {
2689
502
  int i;
2690
2691
502
  str->reset();
2692
2693
502
  progressive = interleaved = gFalse;
2694
502
  width = height = 0;
2695
502
  numComps = 0;
2696
502
  numQuantTables = 0;
2697
502
  numDCHuffTables = 0;
2698
502
  numACHuffTables = 0;
2699
502
  gotJFIFMarker = gFalse;
2700
502
  gotAdobeMarker = gFalse;
2701
502
  restartInterval = 0;
2702
2703
502
  if (!readHeader(gTrue)) {
2704
    // force an EOF condition
2705
486
    progressive = gTrue;
2706
486
    y = height;
2707
486
    prepared = gTrue;
2708
486
    return;
2709
486
  }
2710
2711
  // compute MCU size
2712
16
  if (numComps == 1) {
2713
10
    compInfo[0].hSample = compInfo[0].vSample = 1;
2714
10
  }
2715
16
  mcuWidth = compInfo[0].hSample;
2716
16
  mcuHeight = compInfo[0].vSample;
2717
28
  for (i = 1; i < numComps; ++i) {
2718
12
    if (compInfo[i].hSample > mcuWidth) {
2719
0
      mcuWidth = compInfo[i].hSample;
2720
0
    }
2721
12
    if (compInfo[i].vSample > mcuHeight) {
2722
0
      mcuHeight = compInfo[i].vSample;
2723
0
    }
2724
12
  }
2725
16
  mcuWidth *= 8;
2726
16
  mcuHeight *= 8;
2727
2728
  // figure out color transform
2729
16
  if (colorXform == -1) {
2730
6
    if (numComps == 3) {
2731
6
      if (gotJFIFMarker) {
2732
6
  colorXform = 1;
2733
6
      } else if (compInfo[0].id == 82 && compInfo[1].id == 71 &&
2734
0
     compInfo[2].id == 66) { // ASCII "RGB"
2735
0
  colorXform = 0;
2736
0
      } else {
2737
0
  colorXform = 1;
2738
0
      }
2739
6
    } else {
2740
0
      colorXform = 0;
2741
0
    }
2742
6
  }
2743
2744
16
  prepared = gFalse;
2745
16
}
2746
2747
0
GBool DCTStream::checkSequentialInterleaved() {
2748
0
  GBool headerOk;
2749
2750
0
  str->reset();
2751
2752
0
  progressive = interleaved = gFalse;
2753
0
  width = height = 0;
2754
0
  numComps = 0;
2755
0
  numQuantTables = 0;
2756
0
  numDCHuffTables = 0;
2757
0
  numACHuffTables = 0;
2758
0
  gotJFIFMarker = gFalse;
2759
0
  gotAdobeMarker = gFalse;
2760
0
  restartInterval = 0;
2761
2762
0
  headerOk = readHeader(gTrue);
2763
2764
0
  FilterStream::close();
2765
2766
0
  return headerOk && !progressive && interleaved;
2767
0
}
2768
2769
1.99k
void DCTStream::close() {
2770
1.99k
  int i;
2771
2772
9.99k
  for (i = 0; i < 4; ++i) {
2773
7.99k
    gfree(frameBuf[i]);
2774
7.99k
    frameBuf[i] = NULL;
2775
7.99k
  }
2776
1.99k
  gfree(rowBuf);
2777
1.99k
  rowBuf = NULL;
2778
1.99k
  FilterStream::close();
2779
1.99k
}
2780
2781
150k
int DCTStream::getChar() {
2782
150k
  int c;
2783
2784
150k
  if (!prepared) {
2785
12
    prepare();
2786
12
  }
2787
150k
  if (progressive || !interleaved) {
2788
137k
    if (y >= height) {
2789
474
      return EOF;
2790
474
    }
2791
136k
    c = frameBuf[comp][y * bufWidth + x];
2792
136k
    if (++comp == numComps) {
2793
45.6k
      comp = 0;
2794
45.6k
      if (++x == width) {
2795
480
  x = 0;
2796
480
  ++y;
2797
480
      }
2798
45.6k
    }
2799
136k
  } else {
2800
13.2k
    if (rowBufPtr == rowBufEnd) {
2801
12
      if (y + mcuHeight >= height) {
2802
0
  return EOF;
2803
0
      }
2804
12
      y += mcuHeight;
2805
12
      if (!readMCURow()) {
2806
6
  y = height;
2807
6
  return EOF;
2808
6
      }
2809
12
    }
2810
13.2k
    c = *rowBufPtr++;
2811
13.2k
  }
2812
150k
  return c;
2813
150k
}
2814
2815
540
int DCTStream::lookChar() {
2816
540
  if (!prepared) {
2817
0
    prepare();
2818
0
  }
2819
540
  if (progressive || !interleaved) {
2820
540
    if (y >= height) {
2821
0
      return EOF;
2822
0
    }
2823
540
    return frameBuf[comp][y * bufWidth + x];
2824
540
  } else {
2825
0
    if (rowBufPtr == rowBufEnd) {
2826
0
      if (y + mcuHeight >= height) {
2827
0
  return EOF;
2828
0
      }
2829
0
      if (!readMCURow()) {
2830
0
  y = height;
2831
0
  return EOF;
2832
0
      }
2833
0
    }
2834
0
    return *rowBufPtr;
2835
0
  }
2836
540
}
2837
2838
0
int DCTStream::getBlock(char *blk, int size) {
2839
0
  int nRead, nAvail, n;
2840
2841
0
  if (!prepared) {
2842
0
    prepare();
2843
0
  }
2844
0
  if (progressive || !interleaved) {
2845
0
    if (y >= height) {
2846
0
      return 0;
2847
0
    }
2848
0
    for (nRead = 0; nRead < size; ++nRead) {
2849
0
      blk[nRead] = (char)frameBuf[comp][y * bufWidth + x];
2850
0
      if (++comp == numComps) {
2851
0
  comp = 0;
2852
0
  if (++x == width) {
2853
0
    x = 0;
2854
0
    ++y;
2855
0
    if (y >= height) {
2856
0
      ++nRead;
2857
0
      break;
2858
0
    }
2859
0
  }
2860
0
      }
2861
0
    }
2862
0
  } else {
2863
0
    nRead = 0;
2864
0
    while (nRead < size) {
2865
0
      if (rowBufPtr == rowBufEnd) {
2866
0
  if (y + mcuHeight >= height) {
2867
0
    break;
2868
0
  }
2869
0
  y += mcuHeight;
2870
0
  if (!readMCURow()) {
2871
0
    y = height;
2872
0
    break;
2873
0
  }
2874
0
      }
2875
0
      nAvail = (int)(rowBufEnd - rowBufPtr);
2876
0
      n = (nAvail < size - nRead) ? nAvail : size - nRead;
2877
0
      memcpy(blk + nRead, rowBufPtr, n);
2878
0
      rowBufPtr += n;
2879
0
      nRead += n;
2880
0
    }
2881
0
  }
2882
0
  return nRead;
2883
0
}
2884
2885
12
void DCTStream::prepare() {
2886
12
  int i;
2887
2888
12
  if (progressive || !interleaved) {
2889
2890
    // allocate a buffer for the whole image
2891
6
    bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
2892
6
    bufHeight = ((height + mcuHeight - 1) / mcuHeight) * mcuHeight;
2893
6
    if (bufWidth <= 0 || bufHeight <= 0 ||
2894
6
  bufWidth > INT_MAX / bufHeight / (int)sizeof(int)) {
2895
3
      error(errSyntaxError, getPos(), "Invalid image size in DCT stream");
2896
3
      y = height;
2897
3
      prepared = gTrue;
2898
3
      return;
2899
3
    }
2900
3
#if USE_EXCEPTIONS
2901
3
    try {
2902
3
#endif
2903
12
      for (i = 0; i < numComps; ++i) {
2904
9
  frameBuf[i] = (int *)gmallocn(bufWidth * bufHeight, sizeof(int));
2905
9
  memset(frameBuf[i], 0, bufWidth * bufHeight * sizeof(int));
2906
9
      }
2907
3
#if USE_EXCEPTIONS
2908
3
    } catch (GMemException) {
2909
0
      error(errSyntaxError, getPos(), "Out of memory in DCT stream");
2910
0
      y = height;
2911
0
      prepared = gTrue;
2912
0
      return;
2913
0
    }
2914
0
#endif
2915
2916
    // read the image data
2917
9
    do {
2918
9
      restartMarker = 0xd0;
2919
9
      restart();
2920
9
      readScan();
2921
9
    } while (readHeader(gFalse));
2922
2923
    // decode
2924
3
    decodeImage();
2925
2926
    // initialize counters
2927
3
    comp = 0;
2928
3
    x = 0;
2929
3
    y = 0;
2930
2931
6
  } else {
2932
2933
6
    if (scanInfo.numComps != numComps) {
2934
0
      error(errSyntaxError, getPos(), "Invalid scan in sequential DCT stream");
2935
0
      y = height;
2936
0
      prepared = gTrue;
2937
0
      return;
2938
0
    }
2939
2940
    // allocate a buffer for one row of MCUs
2941
6
    bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
2942
6
    if (bufWidth <= 0 || bufWidth > INT_MAX / numComps / mcuHeight) {
2943
0
      error(errSyntaxError, getPos(), "Invalid image size in DCT stream");
2944
0
      y = height;
2945
0
      prepared = gTrue;
2946
0
      return;
2947
0
    }
2948
6
    rowBuf = (Guchar *)gmallocn(bufWidth, numComps * mcuHeight);
2949
6
    rowBufPtr = rowBufEnd = rowBuf;
2950
2951
    // initialize counters
2952
6
    y = -mcuHeight;
2953
2954
6
    restartMarker = 0xd0;
2955
6
    restart();
2956
6
  }
2957
2958
9
  prepared = gTrue;
2959
9
}
2960
2961
21
void DCTStream::restart() {
2962
21
  int i;
2963
2964
21
  inputBits = 0;
2965
21
  restartCtr = restartInterval;
2966
60
  for (i = 0; i < numComps; ++i) {
2967
39
    compInfo[i].prevDC = 0;
2968
39
  }
2969
21
  eobRun = 0;
2970
21
}
2971
2972
// Read one row of MCUs from a sequential JPEG stream.
2973
12
GBool DCTStream::readMCURow() {
2974
12
  int data1[64];
2975
12
  Guchar data2[64];
2976
12
  Guchar *p1, *p2;
2977
12
  int pY, pCb, pCr, pR, pG, pB;
2978
12
  int h, v, horiz, vert, hSub, vSub;
2979
12
  int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
2980
12
  int c;
2981
2982
24
  for (cc = 0; cc < numComps; ++cc) {
2983
12
    if (scanInfo.dcHuffTable[cc] >= numDCHuffTables ||
2984
12
  scanInfo.acHuffTable[cc] >= numACHuffTables) {
2985
0
      error(errSyntaxError, getPos(),
2986
0
      "Bad DCT data: invalid Huffman table index");
2987
0
      return gFalse;
2988
0
    }
2989
12
    if (compInfo[cc].quantTable > numQuantTables) {
2990
0
      error(errSyntaxError, getPos(),
2991
0
      "Bad DCT data: invalid quant table index");
2992
0
      return gFalse;
2993
0
    }
2994
12
  }
2995
2996
312
  for (x1 = 0; x1 < width; x1 += mcuWidth) {
2997
2998
    // deal with restart marker
2999
306
    if (restartInterval > 0 && restartCtr == 0) {
3000
6
      c = readMarker();
3001
6
      if (c != restartMarker) {
3002
0
  error(errSyntaxError, getPos(),
3003
0
        "Bad DCT data: incorrect restart marker");
3004
0
  return gFalse;
3005
0
      }
3006
6
      if (++restartMarker == 0xd8)
3007
0
  restartMarker = 0xd0;
3008
6
      restart();
3009
6
    }
3010
3011
    // read one MCU
3012
606
    for (cc = 0; cc < numComps; ++cc) {
3013
306
      h = compInfo[cc].hSample;
3014
306
      v = compInfo[cc].vSample;
3015
306
      horiz = mcuWidth / h;
3016
306
      vert = mcuHeight / v;
3017
306
      hSub = horiz / 8;
3018
306
      vSub = vert / 8;
3019
606
      for (y2 = 0; y2 < mcuHeight; y2 += vert) {
3020
606
  for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
3021
306
    if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]],
3022
306
          &acHuffTables[scanInfo.acHuffTable[cc]],
3023
306
          &compInfo[cc].prevDC,
3024
306
          data1)) {
3025
6
      return gFalse;
3026
6
    }
3027
300
    transformDataUnit(quantTables[compInfo[cc].quantTable],
3028
300
          data1, data2);
3029
300
    if (hSub == 1 && vSub == 1 && x1+x2+8 <= width) {
3030
2.64k
      for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3031
2.35k
        p1 = &rowBuf[((y2+y3) * width + (x1+x2)) * numComps + cc];
3032
2.35k
        p1[0]          = data2[i];
3033
2.35k
        p1[  numComps] = data2[i+1];
3034
2.35k
        p1[2*numComps] = data2[i+2];
3035
2.35k
        p1[3*numComps] = data2[i+3];
3036
2.35k
        p1[4*numComps] = data2[i+4];
3037
2.35k
        p1[5*numComps] = data2[i+5];
3038
2.35k
        p1[6*numComps] = data2[i+6];
3039
2.35k
        p1[7*numComps] = data2[i+7];
3040
2.35k
      }
3041
294
    } else if (hSub == 2 && vSub == 2 && x1+x2+16 <= width) {
3042
0
      for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
3043
0
        p1 = &rowBuf[((y2+y3) * width + (x1+x2)) * numComps + cc];
3044
0
        p2 = p1 + width * numComps;
3045
0
        p1[0] = p1[numComps] =
3046
0
    p2[0] = p2[numComps] = data2[i];
3047
0
        p1[2*numComps] = p1[3*numComps] =
3048
0
    p2[2*numComps] = p2[3*numComps] = data2[i+1];
3049
0
        p1[4*numComps] = p1[5*numComps] =
3050
0
    p2[4*numComps] = p2[5*numComps] = data2[i+2];
3051
0
        p1[6*numComps] = p1[7*numComps] =
3052
0
    p2[6*numComps] = p2[7*numComps] = data2[i+3];
3053
0
        p1[8*numComps] = p1[9*numComps] =
3054
0
    p2[8*numComps] = p2[9*numComps] = data2[i+4];
3055
0
        p1[10*numComps] = p1[11*numComps] =
3056
0
    p2[10*numComps] = p2[11*numComps] = data2[i+5];
3057
0
        p1[12*numComps] = p1[13*numComps] =
3058
0
    p2[12*numComps] = p2[13*numComps] = data2[i+6];
3059
0
        p1[14*numComps] = p1[15*numComps] =
3060
0
    p2[14*numComps] = p2[15*numComps] = data2[i+7];
3061
0
      }
3062
6
    } else {
3063
6
      p1 = &rowBuf[(y2 * width + (x1+x2)) * numComps + cc];
3064
6
      i = 0;
3065
54
      for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
3066
432
        for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
3067
768
    for (y5 = 0; y5 < vSub; ++y5) {
3068
528
      for (x5 = 0; x5 < hSub && x1+x2+x4+x5 < width; ++x5) {
3069
144
        p1[((y4+y5) * width + (x4+x5)) * numComps] = data2[i];
3070
144
      }
3071
384
    }
3072
384
    ++i;
3073
384
        }
3074
48
      }
3075
6
    }
3076
300
  }
3077
306
      }
3078
306
    }
3079
300
    --restartCtr;
3080
300
  }
3081
3082
  // color space conversion
3083
6
  if (colorXform) {
3084
    // convert YCbCr to RGB
3085
6
    if (numComps == 3) {
3086
0
      for (i = 0, p1 = rowBuf; i < width * mcuHeight; ++i, p1 += 3) {
3087
0
  pY = p1[0];
3088
0
  pCb = p1[1] - 128;
3089
0
  pCr = p1[2] - 128;
3090
0
  pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
3091
0
  p1[0] = dctClip(pR);
3092
0
  pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
3093
0
  p1[1] = dctClip(pG);
3094
0
  pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
3095
0
  p1[2] = dctClip(pB);
3096
0
      }
3097
    // convert YCbCrK to CMYK (K is passed through unchanged)
3098
6
    } else if (numComps == 4) {
3099
0
      for (i = 0, p1 = rowBuf; i < width * mcuHeight; ++i, p1 += 4) {
3100
0
  pY = p1[0];
3101
0
  pCb = p1[1] - 128;
3102
0
  pCr = p1[2] - 128;
3103
0
  pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
3104
0
  p1[0] = (Guchar)(255 - dctClip(pR));
3105
0
  pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
3106
0
  p1[1] = (Guchar)(255 - dctClip(pG));
3107
0
  pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
3108
0
  p1[2] = (Guchar)(255 - dctClip(pB));
3109
0
      }
3110
0
    }
3111
6
  }
3112
3113
6
  rowBufPtr = rowBuf;
3114
6
  if (y + mcuHeight <= height) {
3115
6
    rowBufEnd = rowBuf + numComps * width * mcuHeight;
3116
6
  } else {
3117
0
    rowBufEnd = rowBuf + numComps * width * (height - y);
3118
0
  }
3119
3120
6
  return gTrue;
3121
12
}
3122
3123
// Read one scan from a progressive or non-interleaved JPEG stream.
3124
9
void DCTStream::readScan() {
3125
9
  int data[64];
3126
9
  int x1, y1, dx1, dy1, x2, y2, y3, cc, i;
3127
9
  int h, v, horiz, vert, vSub;
3128
9
  int *p1;
3129
9
  int c;
3130
3131
36
  for (cc = 0; cc < numComps; ++cc) {
3132
27
    if (scanInfo.comp[cc] &&
3133
27
  (scanInfo.dcHuffTable[cc] >= numDCHuffTables ||
3134
27
   ((!progressive || scanInfo.lastCoeff > 0) &&
3135
27
    scanInfo.acHuffTable[cc] >= numACHuffTables))) {
3136
0
      error(errSyntaxError, getPos(),
3137
0
      "Bad DCT data: invalid Huffman table index");
3138
0
      return;
3139
0
    }
3140
27
    if (compInfo[cc].quantTable > numQuantTables) {
3141
0
      error(errSyntaxError, getPos(),
3142
0
      "Bad DCT data: invalid quant table index");
3143
0
      return;
3144
0
    }
3145
27
  }
3146
3147
9
  if (scanInfo.numComps == 1) {
3148
0
    for (cc = 0; cc < numComps; ++cc) {
3149
0
      if (scanInfo.comp[cc]) {
3150
0
  break;
3151
0
      }
3152
0
    }
3153
0
    dx1 = mcuWidth / compInfo[cc].hSample;
3154
0
    dy1 = mcuHeight / compInfo[cc].vSample;
3155
9
  } else {
3156
9
    dx1 = mcuWidth;
3157
9
    dy1 = mcuHeight;
3158
9
  }
3159
3160
21
  for (y1 = 0; y1 < height; y1 += dy1) {
3161
111
    for (x1 = 0; x1 < width; x1 += dx1) {
3162
3163
      // deal with restart marker
3164
99
      if (restartInterval > 0 && restartCtr == 0) {
3165
0
  c = readMarker();
3166
0
  if (c != restartMarker) {
3167
0
    error(errSyntaxError, getPos(),
3168
0
    "Bad DCT data: incorrect restart marker");
3169
0
    return;
3170
0
  }
3171
0
  if (++restartMarker == 0xd8) {
3172
0
    restartMarker = 0xd0;
3173
0
  }
3174
0
  restart();
3175
0
      }
3176
3177
      // read one MCU
3178
369
      for (cc = 0; cc < numComps; ++cc) {
3179
279
  if (!scanInfo.comp[cc]) {
3180
0
    continue;
3181
0
  }
3182
3183
279
  h = compInfo[cc].hSample;
3184
279
  v = compInfo[cc].vSample;
3185
279
  horiz = mcuWidth / h;
3186
279
  vert = mcuHeight / v;
3187
279
  vSub = vert / 8;
3188
549
  for (y2 = 0; y2 < dy1; y2 += vert) {
3189
639
    for (x2 = 0; x2 < dx1; x2 += horiz) {
3190
3191
      // pull out the current values
3192
369
      p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
3193
3.32k
      for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3194
2.95k
        data[i] = p1[0];
3195
2.95k
        data[i+1] = p1[1];
3196
2.95k
        data[i+2] = p1[2];
3197
2.95k
        data[i+3] = p1[3];
3198
2.95k
        data[i+4] = p1[4];
3199
2.95k
        data[i+5] = p1[5];
3200
2.95k
        data[i+6] = p1[6];
3201
2.95k
        data[i+7] = p1[7];
3202
2.95k
        p1 += bufWidth * vSub;
3203
2.95k
      }
3204
3205
      // read one data unit
3206
369
      if (progressive) {
3207
369
        if (!readProgressiveDataUnit(
3208
369
           &dcHuffTables[scanInfo.dcHuffTable[cc]],
3209
369
           &acHuffTables[scanInfo.acHuffTable[cc]],
3210
369
           &compInfo[cc].prevDC,
3211
369
           data)) {
3212
9
    return;
3213
9
        }
3214
369
      } else {
3215
0
        if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]],
3216
0
        &acHuffTables[scanInfo.acHuffTable[cc]],
3217
0
        &compInfo[cc].prevDC,
3218
0
        data)) {
3219
0
    return;
3220
0
        }
3221
0
      }
3222
3223
      // add the data unit into frameBuf
3224
360
      p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
3225
3.24k
      for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3226
2.88k
        p1[0] = data[i];
3227
2.88k
        p1[1] = data[i+1];
3228
2.88k
        p1[2] = data[i+2];
3229
2.88k
        p1[3] = data[i+3];
3230
2.88k
        p1[4] = data[i+4];
3231
2.88k
        p1[5] = data[i+5];
3232
2.88k
        p1[6] = data[i+6];
3233
2.88k
        p1[7] = data[i+7];
3234
2.88k
        p1 += bufWidth * vSub;
3235
2.88k
      }
3236
360
    }
3237
279
  }
3238
279
      }
3239
90
      --restartCtr;
3240
90
    }
3241
21
  }
3242
9
}
3243
3244
// Read one data unit from a sequential JPEG stream.
3245
GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
3246
            DCTHuffTable *acHuffTable,
3247
306
            int *prevDC, int data[64]) {
3248
306
  int run, size, amp;
3249
306
  int c;
3250
306
  int i, j;
3251
3252
306
  if ((size = readHuffSym(dcHuffTable)) == 9999) {
3253
6
    return gFalse;
3254
6
  }
3255
300
  if (size > 0) {
3256
12
    if ((amp = readAmp(size)) == 9999) {
3257
0
      return gFalse;
3258
0
    }
3259
288
  } else {
3260
288
    amp = 0;
3261
288
  }
3262
300
  data[0] = *prevDC += amp;
3263
19.2k
  for (i = 1; i < 64; ++i) {
3264
18.9k
    data[i] = 0;
3265
18.9k
  }
3266
300
  i = 1;
3267
300
  while (i < 64) {
3268
300
    run = 0;
3269
300
    while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30) {
3270
0
      run += 0x10;
3271
0
    }
3272
300
    if (c == 9999) {
3273
0
      return gFalse;
3274
0
    }
3275
300
    if (c == 0x00) {
3276
300
      break;
3277
300
    } else {
3278
0
      run += (c >> 4) & 0x0f;
3279
0
      size = c & 0x0f;
3280
0
      amp = readAmp(size);
3281
0
      if (amp == 9999) {
3282
0
  return gFalse;
3283
0
      }
3284
0
      i += run;
3285
0
      if (i < 64) {
3286
0
  j = dctZigZag[i++];
3287
0
  data[j] = amp;
3288
0
      }
3289
0
    }
3290
300
  }
3291
300
  return gTrue;
3292
300
}
3293
3294
// Read one data unit from a progressive JPEG stream.
3295
GBool DCTStream::readProgressiveDataUnit(DCTHuffTable *dcHuffTable,
3296
           DCTHuffTable *acHuffTable,
3297
369
           int *prevDC, int data[64]) {
3298
369
  int run, size, amp, bit, c;
3299
369
  int i, j, k;
3300
3301
  // get the DC coefficient
3302
369
  i = scanInfo.firstCoeff;
3303
369
  if (i == 0) {
3304
0
    if (scanInfo.ah == 0) {
3305
0
      if ((size = readHuffSym(dcHuffTable)) == 9999) {
3306
0
  return gFalse;
3307
0
      }
3308
0
      if (size > 0) {
3309
0
  if ((amp = readAmp(size)) == 9999) {
3310
0
    return gFalse;
3311
0
  }
3312
0
      } else {
3313
0
  amp = 0;
3314
0
      }
3315
0
      data[0] += (*prevDC += amp) << scanInfo.al;
3316
0
    } else {
3317
0
      if ((bit = readBit()) == 9999) {
3318
0
  return gFalse;
3319
0
      }
3320
0
      if (bit) {
3321
0
  data[0] += 1 << scanInfo.al;
3322
0
      }
3323
0
    }
3324
0
    ++i;
3325
0
  }
3326
369
  if (scanInfo.lastCoeff == 0) {
3327
0
    return gTrue;
3328
0
  }
3329
3330
  // check for an EOB run
3331
369
  if (eobRun > 0) {
3332
0
    while (i <= scanInfo.lastCoeff) {
3333
0
      j = dctZigZag[i++];
3334
0
      if (data[j] != 0) {
3335
0
  if ((bit = readBit()) == EOF) {
3336
0
    return gFalse;
3337
0
  }
3338
0
  if (bit) {
3339
0
    if (data[j] >= 0) {
3340
0
      data[j] += 1 << scanInfo.al;
3341
0
    } else {
3342
0
      data[j] -= 1 << scanInfo.al;
3343
0
    }
3344
0
  }
3345
0
      }
3346
0
    }
3347
0
    --eobRun;
3348
0
    return gTrue;
3349
0
  }
3350
3351
  // read the AC coefficients
3352
1.02k
  while (i <= scanInfo.lastCoeff) {
3353
825
    if ((c = readHuffSym(acHuffTable)) == 9999) {
3354
6
      return gFalse;
3355
6
    }
3356
3357
    // ZRL
3358
819
    if (c == 0xf0) {
3359
0
      k = 0;
3360
0
      while (k < 16 && i <= scanInfo.lastCoeff) {
3361
0
  j = dctZigZag[i++];
3362
0
  if (data[j] == 0) {
3363
0
    ++k;
3364
0
  } else {
3365
0
    if ((bit = readBit()) == EOF) {
3366
0
      return gFalse;
3367
0
    }
3368
0
    if (bit) {
3369
0
      if (data[j] >= 0) {
3370
0
        data[j] += 1 << scanInfo.al;
3371
0
      } else {
3372
0
        data[j] -= 1 << scanInfo.al;
3373
0
      }
3374
0
    }
3375
0
  }
3376
0
      }
3377
3378
    // EOB run
3379
819
    } else if ((c & 0x0f) == 0x00) {
3380
159
      j = c >> 4;
3381
159
      eobRun = 0;
3382
159
      for (k = 0; k < j; ++k) {
3383
0
  if ((bit = readBit()) == EOF) {
3384
0
    return gFalse;
3385
0
  }
3386
0
  eobRun = (eobRun << 1) | bit;
3387
0
      }
3388
159
      eobRun += 1 << j;
3389
654
      while (i <= scanInfo.lastCoeff) {
3390
495
  j = dctZigZag[i++];
3391
495
  if (data[j] != 0) {
3392
45
    if ((bit = readBit()) == EOF) {
3393
0
      return gFalse;
3394
0
    }
3395
45
    if (bit) {
3396
21
      if (data[j] >= 0) {
3397
9
        data[j] += 1 << scanInfo.al;
3398
12
      } else {
3399
12
        data[j] -= 1 << scanInfo.al;
3400
12
      }
3401
21
    }
3402
45
  }
3403
495
      }
3404
159
      --eobRun;
3405
159
      break;
3406
3407
    // zero run and one AC coefficient
3408
660
    } else {
3409
660
      run = (c >> 4) & 0x0f;
3410
660
      size = c & 0x0f;
3411
660
      if ((amp = readAmp(size)) == 9999) {
3412
0
  return gFalse;
3413
0
      }
3414
660
      j = 0; // make gcc happy
3415
1.50k
      for (k = 0; k <= run && i <= scanInfo.lastCoeff; ++k) {
3416
849
  j = dctZigZag[i++];
3417
954
  while (data[j] != 0 && i <= scanInfo.lastCoeff) {
3418
108
    if ((bit = readBit()) == EOF) {
3419
3
      return gFalse;
3420
3
    }
3421
105
    if (bit) {
3422
36
      if (data[j] >= 0) {
3423
12
        data[j] += 1 << scanInfo.al;
3424
24
      } else {
3425
24
        data[j] -= 1 << scanInfo.al;
3426
24
      }
3427
36
    }
3428
105
    j = dctZigZag[i++];
3429
105
  }
3430
849
      }
3431
657
      data[j] = amp << scanInfo.al;
3432
657
    }
3433
819
  }
3434
3435
360
  return gTrue;
3436
369
}
3437
3438
// Decode a progressive JPEG image.
3439
3
void DCTStream::decodeImage() {
3440
3
  int dataIn[64];
3441
3
  Guchar dataOut[64];
3442
3
  Gushort *quantTable;
3443
3
  int pY, pCb, pCr, pR, pG, pB;
3444
3
  int x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
3445
3
  int h, v, horiz, vert, hSub, vSub;
3446
3
  int *p0, *p1, *p2;
3447
3448
63
  for (y1 = 0; y1 < bufHeight; y1 += mcuHeight) {
3449
420
    for (x1 = 0; x1 < bufWidth; x1 += mcuWidth) {
3450
1.44k
      for (cc = 0; cc < numComps; ++cc) {
3451
1.08k
  quantTable = quantTables[compInfo[cc].quantTable];
3452
1.08k
  h = compInfo[cc].hSample;
3453
1.08k
  v = compInfo[cc].vSample;
3454
1.08k
  horiz = mcuWidth / h;
3455
1.08k
  vert = mcuHeight / v;
3456
1.08k
  hSub = horiz / 8;
3457
1.08k
  vSub = vert / 8;
3458
2.16k
  for (y2 = 0; y2 < mcuHeight; y2 += vert) {
3459
2.52k
    for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
3460
3461
      // pull out the coded data unit
3462
1.44k
      p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
3463
12.9k
      for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3464
11.5k
        dataIn[i]   = p1[0];
3465
11.5k
        dataIn[i+1] = p1[1];
3466
11.5k
        dataIn[i+2] = p1[2];
3467
11.5k
        dataIn[i+3] = p1[3];
3468
11.5k
        dataIn[i+4] = p1[4];
3469
11.5k
        dataIn[i+5] = p1[5];
3470
11.5k
        dataIn[i+6] = p1[6];
3471
11.5k
        dataIn[i+7] = p1[7];
3472
11.5k
        p1 += bufWidth * vSub;
3473
11.5k
      }
3474
3475
      // transform
3476
1.44k
      transformDataUnit(quantTable, dataIn, dataOut);
3477
3478
      // store back into frameBuf, doing replication for
3479
      // subsampled components
3480
1.44k
      p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
3481
1.44k
      if (hSub == 1 && vSub == 1) {
3482
6.48k
        for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3483
5.76k
    p1[0] = dataOut[i] & 0xff;
3484
5.76k
    p1[1] = dataOut[i+1] & 0xff;
3485
5.76k
    p1[2] = dataOut[i+2] & 0xff;
3486
5.76k
    p1[3] = dataOut[i+3] & 0xff;
3487
5.76k
    p1[4] = dataOut[i+4] & 0xff;
3488
5.76k
    p1[5] = dataOut[i+5] & 0xff;
3489
5.76k
    p1[6] = dataOut[i+6] & 0xff;
3490
5.76k
    p1[7] = dataOut[i+7] & 0xff;
3491
5.76k
    p1 += bufWidth;
3492
5.76k
        }
3493
720
      } else if (hSub == 2 && vSub == 2) {
3494
0
        p2 = p1 + bufWidth;
3495
0
        for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
3496
0
    p1[0] = p1[1] = p2[0] = p2[1] = dataOut[i] & 0xff;
3497
0
    p1[2] = p1[3] = p2[2] = p2[3] = dataOut[i+1] & 0xff;
3498
0
    p1[4] = p1[5] = p2[4] = p2[5] = dataOut[i+2] & 0xff;
3499
0
    p1[6] = p1[7] = p2[6] = p2[7] = dataOut[i+3] & 0xff;
3500
0
    p1[8] = p1[9] = p2[8] = p2[9] = dataOut[i+4] & 0xff;
3501
0
    p1[10] = p1[11] = p2[10] = p2[11] = dataOut[i+5] & 0xff;
3502
0
    p1[12] = p1[13] = p2[12] = p2[13] = dataOut[i+6] & 0xff;
3503
0
    p1[14] = p1[15] = p2[14] = p2[15] = dataOut[i+7] & 0xff;
3504
0
    p1 += bufWidth * 2;
3505
0
    p2 += bufWidth * 2;
3506
0
        }
3507
720
      } else {
3508
720
        i = 0;
3509
6.48k
        for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
3510
51.8k
    for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
3511
46.0k
      p2 = p1 + x4;
3512
92.1k
      for (y5 = 0; y5 < vSub; ++y5) {
3513
138k
        for (x5 = 0; x5 < hSub; ++x5) {
3514
92.1k
          p2[x5] = dataOut[i] & 0xff;
3515
92.1k
        }
3516
46.0k
        p2 += bufWidth;
3517
46.0k
      }
3518
46.0k
      ++i;
3519
46.0k
    }
3520
5.76k
    p1 += bufWidth * vSub;
3521
5.76k
        }
3522
720
      }
3523
1.44k
    }
3524
1.08k
  }
3525
1.08k
      }
3526
3527
      // color space conversion
3528
360
      if (colorXform) {
3529
  // convert YCbCr to RGB
3530
360
  if (numComps == 3) {
3531
3.24k
    for (y2 = 0; y2 < mcuHeight; ++y2) {
3532
2.88k
      p0 = &frameBuf[0][(y1+y2) * bufWidth + x1];
3533
2.88k
      p1 = &frameBuf[1][(y1+y2) * bufWidth + x1];
3534
2.88k
      p2 = &frameBuf[2][(y1+y2) * bufWidth + x1];
3535
48.9k
      for (x2 = 0; x2 < mcuWidth; ++x2) {
3536
46.0k
        pY = *p0;
3537
46.0k
        pCb = *p1 - 128;
3538
46.0k
        pCr = *p2 - 128;
3539
46.0k
        pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
3540
46.0k
        *p0++ = dctClip(pR);
3541
46.0k
        pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr +
3542
46.0k
        32768) >> 16;
3543
46.0k
        *p1++ = dctClip(pG);
3544
46.0k
        pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
3545
46.0k
        *p2++ = dctClip(pB);
3546
46.0k
      }
3547
2.88k
    }
3548
  // convert YCbCrK to CMYK (K is passed through unchanged)
3549
360
  } else if (numComps == 4) {
3550
0
    for (y2 = 0; y2 < mcuHeight; ++y2) {
3551
0
      p0 = &frameBuf[0][(y1+y2) * bufWidth + x1];
3552
0
      p1 = &frameBuf[1][(y1+y2) * bufWidth + x1];
3553
0
      p2 = &frameBuf[2][(y1+y2) * bufWidth + x1];
3554
0
      for (x2 = 0; x2 < mcuWidth; ++x2) {
3555
0
        pY = *p0;
3556
0
        pCb = *p1 - 128;
3557
0
        pCr = *p2 - 128;
3558
0
        pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
3559
0
        *p0++ = 255 - dctClip(pR);
3560
0
        pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr +
3561
0
        32768) >> 16;
3562
0
        *p1++ = 255 - dctClip(pG);
3563
0
        pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
3564
0
        *p2++ = 255 - dctClip(pB);
3565
0
      }
3566
0
    }
3567
0
  }
3568
360
      }
3569
360
    }
3570
60
  }
3571
3
}
3572
3573
// Transform one data unit -- this performs the dequantization and
3574
// IDCT steps.  This IDCT algorithm is taken from:
3575
//   Y. A. Reznik, A. T. Hinds, L. Yu, Z. Ni, and C-X. Zhang,
3576
//   "Efficient fixed-point approximations of the 8x8 inverse discrete
3577
//   cosine transform" (invited paper), Proc. SPIE Vol. 6696, Sep. 24,
3578
//   2007.
3579
// which is based on:
3580
//   Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,
3581
//   "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
3582
//   IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
3583
//   988-991.
3584
// The stage numbers mentioned in the comments refer to Figure 1 in the
3585
// Loeffler paper.
3586
void DCTStream::transformDataUnit(Gushort *quantTable,
3587
1.74k
          int dataIn[64], Guchar dataOut[64]) {
3588
1.74k
  int v0, v1, v2, v3, v4, v5, v6, v7;
3589
1.74k
  int t0, t1, t2, t3, t4, t5, t6, t7;
3590
1.74k
  int *p, *scale;
3591
1.74k
  Gushort *q;
3592
1.74k
  int i;
3593
3594
  // dequant; inverse DCT on rows
3595
15.6k
  for (i = 0; i < 64; i += 8) {
3596
13.9k
    p = dataIn + i;
3597
13.9k
    q = quantTable + i;
3598
13.9k
    scale = idctScaleMat + i;
3599
3600
    // check for all-zero AC coefficients
3601
13.9k
    if (p[1] == 0 && p[2] == 0 && p[3] == 0 &&
3602
13.9k
  p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] == 0) {
3603
13.4k
      t0 = p[0] * q[0] * scale[0];
3604
13.4k
      if (i == 0) {
3605
1.74k
  t0 += 1 << 12;    // rounding bias
3606
1.74k
      }
3607
13.4k
      p[0] = t0;
3608
13.4k
      p[1] = t0;
3609
13.4k
      p[2] = t0;
3610
13.4k
      p[3] = t0;
3611
13.4k
      p[4] = t0;
3612
13.4k
      p[5] = t0;
3613
13.4k
      p[6] = t0;
3614
13.4k
      p[7] = t0;
3615
13.4k
      continue;
3616
13.4k
    }
3617
3618
    // stage 4
3619
507
    v0 = p[0] * q[0] * scale[0];
3620
507
    if (i == 0) {
3621
0
      v0 += 1 << 12;    // rounding bias
3622
0
    }
3623
507
    v1 = p[4] * q[4] * scale[4];
3624
507
    v2 = p[2] * q[2] * scale[2];
3625
507
    v3 = p[6] * q[6] * scale[6];
3626
507
    t0 = p[1] * q[1] * scale[1];
3627
507
    t1 = p[7] * q[7] * scale[7];
3628
507
    v4 = t0 - t1;
3629
507
    v7 = t0 + t1;
3630
507
    v5 = p[3] * q[3] * scale[3];
3631
507
    v6 = p[5] * q[5] * scale[5];
3632
3633
    // stage 3
3634
507
    t0 = v0 - v1;
3635
507
    v0 = v0 + v1;
3636
507
    v1 = t0;
3637
507
    t0 = v2 + (v2 >> 5);
3638
507
    t1 = t0 >> 2;
3639
507
    t2 = t1 + (v2 >> 4);  // 41/128 * v2
3640
507
    t3 = t0 - t1;   // 99/128 * v2
3641
507
    t4 = v3 + (v3 >> 5);
3642
507
    t5 = t4 >> 2;
3643
507
    t6 = t5 + (v3 >> 4);  // 41/128 * v3
3644
507
    t7 = t4 - t5;   // 99/128 * v3
3645
507
    v2 = t2 - t7;
3646
507
    v3 = t3 + t6;
3647
507
    t0 = v4 - v6;
3648
507
    v4 = v4 + v6;
3649
507
    v6 = t0;
3650
507
    t0 = v7 + v5;
3651
507
    v5 = v7 - v5;
3652
507
    v7 = t0;
3653
3654
    // stage 2
3655
507
    t0 = v0 - v3;
3656
507
    v0 = v0 + v3;
3657
507
    v3 = t0;
3658
507
    t0 = v1 - v2;
3659
507
    v1 = v1 + v2;
3660
507
    v2 = t0;
3661
507
    t0 = (v4 >> 9) - v4;
3662
507
    t1 = v4 >> 1;   // 1/2 * v4
3663
507
    t2 = (t0 >> 2) - t0;  // 1533/2048 * v4
3664
507
    t3 = (v7 >> 9) - v7;
3665
507
    t4 = v7 >> 1;   // 1/2 * v7
3666
507
    t5 = (t3 >> 2) - t3;  // 1533/2048 * v7
3667
507
    v4 = t2 - t4;
3668
507
    v7 = t1 + t5;
3669
507
    t0 = (v5 >> 3) - (v5 >> 7);
3670
507
    t1 = t0 - (v5 >> 11);
3671
507
    t2 = t0 + (t1 >> 1);  // 719/4096 * v5
3672
507
    t3 = v5 - t0;   // 113/256 * v5
3673
507
    t4 = (v6 >> 3) - (v6 >> 7);
3674
507
    t5 = t4 - (v6 >> 11);
3675
507
    t6 = t4 + (t5 >> 1);  // 719/4096 * v6
3676
507
    t7 = v6 - t4;   // 113/256 * v6
3677
507
    v5 = t3 - t6;
3678
507
    v6 = t2 + t7;
3679
3680
    // stage 1
3681
507
    p[0] = v0 + v7;
3682
507
    p[7] = v0 - v7;
3683
507
    p[1] = v1 + v6;
3684
507
    p[6] = v1 - v6;
3685
507
    p[2] = v2 + v5;
3686
507
    p[5] = v2 - v5;
3687
507
    p[3] = v3 + v4;
3688
507
    p[4] = v3 - v4;
3689
507
  }
3690
3691
  // inverse DCT on columns
3692
15.6k
  for (i = 0; i < 8; ++i) {
3693
13.9k
    p = dataIn + i;
3694
3695
    // check for all-zero AC coefficients
3696
13.9k
    if (p[1*8] == 0 && p[2*8] == 0 && p[3*8] == 0 &&
3697
13.9k
  p[4*8] == 0 && p[5*8] == 0 && p[6*8] == 0 && p[7*8] == 0) {
3698
12.1k
      t0 = p[0*8];
3699
12.1k
      p[1*8] = t0;
3700
12.1k
      p[2*8] = t0;
3701
12.1k
      p[3*8] = t0;
3702
12.1k
      p[4*8] = t0;
3703
12.1k
      p[5*8] = t0;
3704
12.1k
      p[6*8] = t0;
3705
12.1k
      p[7*8] = t0;
3706
12.1k
      continue;
3707
12.1k
    }
3708
3709
    // stage 4
3710
1.72k
    v0 = p[0*8];
3711
1.72k
    v1 = p[4*8];
3712
1.72k
    v2 = p[2*8];
3713
1.72k
    v3 = p[6*8];
3714
1.72k
    t0 = p[1*8];
3715
1.72k
    t1 = p[7*8];
3716
1.72k
    v4 = t0 - t1;
3717
1.72k
    v7 = t0 + t1;
3718
1.72k
    v5 = p[3*8];
3719
1.72k
    v6 = p[5*8];
3720
3721
    // stage 3
3722
1.72k
    t0 = v0 - v1;
3723
1.72k
    v0 = v0 + v1;
3724
1.72k
    v1 = t0;
3725
1.72k
    t0 = v2 + (v2 >> 5);
3726
1.72k
    t1 = t0 >> 2;
3727
1.72k
    t2 = t1 + (v2 >> 4);  // 41/128 * v2
3728
1.72k
    t3 = t0 - t1;   // 99/128 * v2
3729
1.72k
    t4 = v3 + (v3 >> 5);
3730
1.72k
    t5 = t4 >> 2;
3731
1.72k
    t6 = t5 + (v3 >> 4);  // 41/128 * v3
3732
1.72k
    t7 = t4 - t5;   // 99/128 * v3
3733
1.72k
    v2 = t2 - t7;
3734
1.72k
    v3 = t3 + t6;
3735
1.72k
    t0 = v4 - v6;
3736
1.72k
    v4 = v4 + v6;
3737
1.72k
    v6 = t0;
3738
1.72k
    t0 = v7 + v5;
3739
1.72k
    v5 = v7 - v5;
3740
1.72k
    v7 = t0;
3741
3742
    // stage 2
3743
1.72k
    t0 = v0 - v3;
3744
1.72k
    v0 = v0 + v3;
3745
1.72k
    v3 = t0;
3746
1.72k
    t0 = v1 - v2;
3747
1.72k
    v1 = v1 + v2;
3748
1.72k
    v2 = t0;
3749
1.72k
    t0 = (v4 >> 9) - v4;
3750
1.72k
    t1 = v4 >> 1;   // 1/2 * v4
3751
1.72k
    t2 = (t0 >> 2) - t0;  // 1533/2048 * v4
3752
1.72k
    t3 = (v7 >> 9) - v7;
3753
1.72k
    t4 = v7 >> 1;   // 1/2 * v7
3754
1.72k
    t5 = (t3 >> 2) - t3;  // 1533/2048 * v7
3755
1.72k
    v4 = t2 - t4;
3756
1.72k
    v7 = t1 + t5;
3757
1.72k
    t0 = (v5 >> 3) - (v5 >> 7);
3758
1.72k
    t1 = t0 - (v5 >> 11);
3759
1.72k
    t2 = t0 + (t1 >> 1);  // 719/4096 * v5
3760
1.72k
    t3 = v5 - t0;   // 113/256 * v5
3761
1.72k
    t4 = (v6 >> 3) - (v6 >> 7);
3762
1.72k
    t5 = t4 - (v6 >> 11);
3763
1.72k
    t6 = t4 + (t5 >> 1);  // 719/4096 * v6
3764
1.72k
    t7 = v6 - t4;   // 113/256 * v6
3765
1.72k
    v5 = t3 - t6;
3766
1.72k
    v6 = t2 + t7;
3767
3768
    // stage 1
3769
1.72k
    p[0*8] = v0 + v7;
3770
1.72k
    p[7*8] = v0 - v7;
3771
1.72k
    p[1*8] = v1 + v6;
3772
1.72k
    p[6*8] = v1 - v6;
3773
1.72k
    p[2*8] = v2 + v5;
3774
1.72k
    p[5*8] = v2 - v5;
3775
1.72k
    p[3*8] = v3 + v4;
3776
1.72k
    p[4*8] = v3 - v4;
3777
1.72k
  }
3778
3779
  // convert to 8-bit integers
3780
113k
  for (i = 0; i < 64; ++i) {
3781
111k
    dataOut[i] = dctClip(128 + (dataIn[i] >> 13));
3782
111k
  }
3783
1.74k
}
3784
3785
1.43k
int DCTStream::readHuffSym(DCTHuffTable *table) {
3786
1.43k
  Gushort code;
3787
1.43k
  int bit;
3788
1.43k
  int codeBits;
3789
3790
1.43k
  code = 0;
3791
1.43k
  codeBits = 0;
3792
3.34k
  do {
3793
    // add a bit to the code
3794
3.34k
    if ((bit = readBit()) == EOF) {
3795
12
      return 9999;
3796
12
    }
3797
3.33k
    code = (Gushort)((code << 1) + bit);
3798
3.33k
    ++codeBits;
3799
3800
    // look up code
3801
3.33k
    if (code < table->firstCode[codeBits]) {
3802
0
      break;
3803
0
    }
3804
3.33k
    if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
3805
1.41k
      code = (Gushort)(code - table->firstCode[codeBits]);
3806
1.41k
      return table->sym[table->firstSym[codeBits] + code];
3807
1.41k
    }
3808
3.33k
  } while (codeBits < 16);
3809
3810
0
  error(errSyntaxError, getPos(), "Bad Huffman code in DCT stream");
3811
0
  return 9999;
3812
1.43k
}
3813
3814
672
int DCTStream::readAmp(int size) {
3815
672
  int amp, bit;
3816
672
  int bits;
3817
3818
672
  amp = 0;
3819
2.32k
  for (bits = 0; bits < size; ++bits) {
3820
1.65k
    if ((bit = readBit()) == EOF)
3821
0
      return 9999;
3822
1.65k
    amp = (amp << 1) + bit;
3823
1.65k
  }
3824
672
  if (amp < (1 << (size - 1)))
3825
456
    amp -= (1 << size) - 1;
3826
672
  return amp;
3827
672
}
3828
3829
5.15k
int DCTStream::readBit() {
3830
5.15k
  int bit;
3831
5.15k
  int c, c2;
3832
3833
5.15k
  if (inputBits == 0) {
3834
660
    if ((c = str->getChar()) == EOF)
3835
0
      return EOF;
3836
660
    if (c == 0xff) {
3837
54
      do {
3838
54
  c2 = str->getChar();
3839
54
      } while (c2 == 0xff);
3840
15
      if (c2 != 0x00) {
3841
15
  error(errSyntaxError, getPos(), "Bad DCT data: missing 00 after ff");
3842
15
  return EOF;
3843
15
      }
3844
15
    }
3845
645
    inputBuf = c;
3846
645
    inputBits = 8;
3847
645
  }
3848
5.13k
  bit = (inputBuf >> (inputBits - 1)) & 1;
3849
5.13k
  --inputBits;
3850
5.13k
  return bit;
3851
5.15k
}
3852
3853
511
GBool DCTStream::readHeader(GBool frame) {
3854
511
  GBool haveSOF, doScan;
3855
511
  int n, i;
3856
511
  int c = 0;
3857
3858
  // read headers
3859
511
  haveSOF = gFalse;
3860
511
  doScan = gFalse;
3861
1.27k
  while (!doScan) {
3862
1.25k
    c = readMarker();
3863
1.25k
    switch (c) {
3864
10
    case 0xc0:      // SOF0 (sequential)
3865
351
    case 0xc1:      // SOF1 (extended sequential)
3866
351
      if (!frame) {
3867
0
  error(errSyntaxError, getPos(),
3868
0
        "Invalid DCT marker in scan <{0:02x}>", c);
3869
0
  return gFalse;
3870
0
      }
3871
351
      if (!readBaselineSOF()) {
3872
339
  return gFalse;
3873
339
      }
3874
12
      haveSOF = gTrue;
3875
12
      break;
3876
111
    case 0xc2:      // SOF2 (progressive)
3877
111
      if (!frame) {
3878
0
  error(errSyntaxError, getPos(),
3879
0
        "Invalid DCT marker in scan <{0:02x}>", c);
3880
0
  return gFalse;
3881
0
      }
3882
111
      if (!readProgressiveSOF()) {
3883
0
  return gFalse;
3884
0
      }
3885
111
      haveSOF = gTrue;
3886
111
      break;
3887
85
    case 0xc4:      // DHT
3888
85
      if (!readHuffmanTables()) {
3889
23
  return gFalse;
3890
23
      }
3891
62
      break;
3892
62
    case 0xd8:      // SOI
3893
39
      if (!frame) {
3894
0
  error(errSyntaxError, getPos(),
3895
0
        "Invalid DCT marker in scan <{0:02x}>", c);
3896
0
  return gFalse;
3897
0
      }
3898
39
      break;
3899
39
    case 0xd9:      // EOI
3900
0
      return gFalse;
3901
22
    case 0xda:      // SOS
3902
22
      if (frame && !haveSOF) {
3903
0
  error(errSyntaxError, getPos(), "Missing SOF in DCT stream");
3904
0
  return gFalse;
3905
0
      }
3906
22
      if (!readScanInfo()) {
3907
0
  return gFalse;
3908
0
      }
3909
22
      if (frame) {
3910
16
  interleaved = scanInfo.numComps == numComps;
3911
16
      }
3912
22
      doScan = gTrue;
3913
22
      break;
3914
421
    case 0xdb:      // DQT
3915
421
      if (!readQuantTables()) {
3916
0
  return gFalse;
3917
0
      }
3918
421
      break;
3919
421
    case 0xdd:      // DRI
3920
10
      if (!readRestartInterval()) {
3921
0
  return gFalse;
3922
0
      }
3923
10
      break;
3924
29
    case 0xe0:      // APP0
3925
29
      if (!frame) {
3926
0
  error(errSyntaxError, getPos(),
3927
0
        "Invalid DCT marker in scan <{0:02x}>", c);
3928
0
  return gFalse;
3929
0
      }
3930
29
      if (!readJFIFMarker()) {
3931
0
  return gFalse;
3932
0
      }
3933
29
      break;
3934
29
    case 0xee:      // APP14
3935
10
      if (!frame) {
3936
0
  error(errSyntaxError, getPos(),
3937
0
        "Invalid DCT marker in scan <{0:02x}>", c);
3938
0
  return gFalse;
3939
0
      }
3940
10
      if (!readAdobeMarker()) {
3941
0
  return gFalse;
3942
0
      }
3943
10
      break;
3944
11
    case EOF:
3945
11
      error(errSyntaxError, getPos(), "Bad DCT header");
3946
11
      return gFalse;
3947
161
    default:
3948
      // skip APPn / COM / etc.
3949
161
      if (c >= 0xe0) {
3950
45
  n = read16() - 2;
3951
45
  str->discardChars(n);
3952
116
      } else {
3953
116
  error(errSyntaxError, getPos(), "Unknown DCT marker <{0:02x}>", c);
3954
116
  return gFalse;
3955
116
      }
3956
45
      break;
3957
1.25k
    }
3958
1.25k
  }
3959
3960
68
  for (i = 0; i < numComps; ++i) {
3961
46
    if (compInfo[i].quantTable >= numQuantTables) {
3962
0
      error(errSyntaxError, getPos(), "Invalid DCT quant table selector");
3963
0
      return gFalse;
3964
0
    }
3965
46
  }
3966
3967
22
  return gTrue;
3968
22
}
3969
3970
351
GBool DCTStream::readBaselineSOF() {
3971
351
  int prec;
3972
351
  int i;
3973
351
  int c;
3974
3975
351
  read16(); // length
3976
351
  prec = str->getChar();
3977
351
  height = read16();
3978
351
  width = read16();
3979
351
  numComps = str->getChar();
3980
351
  if (numComps <= 0 || numComps > 4) {
3981
0
    error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
3982
0
    numComps = 0;
3983
0
    return gFalse;
3984
0
  }
3985
351
  if (prec != 8) {
3986
0
    error(errSyntaxError, getPos(), "Bad DCT precision {0:d}", prec);
3987
0
    return gFalse;
3988
0
  }
3989
367
  for (i = 0; i < numComps; ++i) {
3990
355
    compInfo[i].id = str->getChar();
3991
355
    c = str->getChar();
3992
355
    compInfo[i].hSample = (c >> 4) & 0x0f;
3993
355
    compInfo[i].vSample = c & 0x0f;
3994
355
    compInfo[i].quantTable = str->getChar();
3995
    // a sampling factor of 3 is allowed by the spec, but requires
3996
    // messy upsampling, and appears not to be used in practice
3997
355
    if (!(compInfo[i].hSample == 1 ||
3998
341
    compInfo[i].hSample == 2 ||
3999
0
    compInfo[i].hSample == 4) ||
4000
355
  !(compInfo[i].vSample == 1 ||
4001
0
    compInfo[i].vSample == 2 ||
4002
0
    compInfo[i].vSample == 4)) {
4003
0
      error(errSyntaxError, getPos(), "Bad DCT sampling factor");
4004
0
      return gFalse;
4005
0
    }
4006
355
    if (compInfo[i].quantTable < 0 || compInfo[i].quantTable > 3) {
4007
339
      error(errSyntaxError, getPos(), "Bad DCT quant table selector");
4008
339
      return gFalse;
4009
339
    }
4010
355
  }
4011
12
  progressive = gFalse;
4012
12
  return gTrue;
4013
351
}
4014
4015
111
GBool DCTStream::readProgressiveSOF() {
4016
111
  int prec;
4017
111
  int i;
4018
111
  int c;
4019
4020
111
  read16(); // length
4021
111
  prec = str->getChar();
4022
111
  height = read16();
4023
111
  width = read16();
4024
111
  numComps = str->getChar();
4025
111
  if (numComps <= 0 || numComps > 4) {
4026
0
    error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
4027
0
    numComps = 0;
4028
0
    return gFalse;
4029
0
  }
4030
111
  if (prec != 8) {
4031
0
    error(errSyntaxError, getPos(), "Bad DCT precision {0:d}", prec);
4032
0
    return gFalse;
4033
0
  }
4034
444
  for (i = 0; i < numComps; ++i) {
4035
333
    compInfo[i].id = str->getChar();
4036
333
    c = str->getChar();
4037
333
    compInfo[i].hSample = (c >> 4) & 0x0f;
4038
333
    compInfo[i].vSample = c & 0x0f;
4039
333
    compInfo[i].quantTable = str->getChar();
4040
    // a sampling factor of 3 is allowed by the spec, but requires
4041
    // messy upsampling, and appears not to be used in practice
4042
333
    if (!(compInfo[i].hSample == 1 ||
4043
111
    compInfo[i].hSample == 2 ||
4044
0
    compInfo[i].hSample == 4) ||
4045
333
  !(compInfo[i].vSample == 1 ||
4046
0
    compInfo[i].vSample == 2 ||
4047
0
    compInfo[i].vSample == 4)) {
4048
0
      error(errSyntaxError, getPos(), "Bad DCT sampling factor");
4049
0
      return gFalse;
4050
0
    }
4051
333
    if (compInfo[i].quantTable < 0 || compInfo[i].quantTable > 3) {
4052
0
      error(errSyntaxError, getPos(), "Bad DCT quant table selector");
4053
0
      return gFalse;
4054
0
    }
4055
333
  }
4056
111
  progressive = gTrue;
4057
111
  return gTrue;
4058
111
}
4059
4060
22
GBool DCTStream::readScanInfo() {
4061
22
  int length;
4062
22
  int id, c;
4063
22
  int i, j;
4064
4065
22
  length = read16() - 2;
4066
22
  scanInfo.numComps = str->getChar();
4067
22
  if (scanInfo.numComps <= 0 || scanInfo.numComps > 4) {
4068
0
    error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
4069
0
    scanInfo.numComps = 0;
4070
0
    return gFalse;
4071
0
  }
4072
22
  --length;
4073
22
  if (length != 2 * scanInfo.numComps + 3) {
4074
0
    error(errSyntaxError, getPos(), "Bad DCT scan info block");
4075
0
    return gFalse;
4076
0
  }
4077
68
  for (j = 0; j < numComps; ++j) {
4078
46
    scanInfo.comp[j] = gFalse;
4079
46
  }
4080
68
  for (i = 0; i < scanInfo.numComps; ++i) {
4081
46
    id = str->getChar();
4082
    // some (broken) DCT streams reuse ID numbers, but at least they
4083
    // keep the components in order, so we check compInfo[i] first to
4084
    // work around the problem
4085
46
    if (id == compInfo[i].id) {
4086
46
      j = i;
4087
46
    } else {
4088
0
      for (j = 0; j < numComps; ++j) {
4089
0
  if (id == compInfo[j].id) {
4090
0
    break;
4091
0
  }
4092
0
      }
4093
0
      if (j == numComps) {
4094
0
  error(errSyntaxError, getPos(),
4095
0
        "Bad DCT component ID in scan info block");
4096
0
  return gFalse;
4097
0
      }
4098
0
    }
4099
46
    if (scanInfo.comp[j]) {
4100
0
      error(errSyntaxError, getPos(),
4101
0
      "Invalid DCT component ID in scan info block");
4102
0
      return gFalse;
4103
0
    }
4104
46
    scanInfo.comp[j] = gTrue;
4105
46
    c = str->getChar();
4106
46
    scanInfo.dcHuffTable[j] = (c >> 4) & 0x0f;
4107
46
    scanInfo.acHuffTable[j] = c & 0x0f;
4108
46
  }
4109
22
  scanInfo.firstCoeff = str->getChar();
4110
22
  scanInfo.lastCoeff = str->getChar();
4111
22
  if (scanInfo.firstCoeff < 0 || scanInfo.lastCoeff > 63 ||
4112
22
      scanInfo.firstCoeff > scanInfo.lastCoeff) {
4113
0
    error(errSyntaxError, getPos(),
4114
0
    "Bad DCT coefficient numbers in scan info block");
4115
0
    return gFalse;
4116
0
  }
4117
22
  c = str->getChar();
4118
22
  scanInfo.ah = (c >> 4) & 0x0f;
4119
22
  scanInfo.al = c & 0x0f;
4120
22
  return gTrue;
4121
22
}
4122
4123
421
GBool DCTStream::readQuantTables() {
4124
421
  int length, prec, i, index;
4125
4126
421
  length = read16() - 2;
4127
1.25k
  while (length > 0) {
4128
832
    index = str->getChar();
4129
832
    prec = (index >> 4) & 0x0f;
4130
832
    index &= 0x0f;
4131
832
    if (prec > 1 || index >= 4) {
4132
0
      error(errSyntaxError, getPos(), "Bad DCT quantization table");
4133
0
      return gFalse;
4134
0
    }
4135
832
    if (index >= numQuantTables) {
4136
832
      numQuantTables = index + 1;
4137
832
    }
4138
54.0k
    for (i = 0; i < 64; ++i) {
4139
53.2k
      if (prec) {
4140
0
  quantTables[index][dctZigZag[i]] = (Gushort)read16();
4141
53.2k
      } else {
4142
53.2k
  quantTables[index][dctZigZag[i]] = (Gushort)str->getChar();
4143
53.2k
      }
4144
53.2k
    }
4145
832
    if (prec) {
4146
0
      length -= 129;
4147
832
    } else {
4148
832
      length -= 65;
4149
832
    }
4150
832
  }
4151
421
  return gTrue;
4152
421
}
4153
4154
85
GBool DCTStream::readHuffmanTables() {
4155
85
  DCTHuffTable *tbl;
4156
85
  int length;
4157
85
  int index;
4158
85
  Gushort code;
4159
85
  Guchar sym;
4160
85
  int i;
4161
85
  int c;
4162
4163
85
  length = read16() - 2;
4164
391
  while (length > 0) {
4165
329
    index = str->getChar();
4166
329
    --length;
4167
329
    if ((index & 0x0f) >= 4) {
4168
23
      error(errSyntaxError, getPos(), "Bad DCT Huffman table");
4169
23
      return gFalse;
4170
23
    }
4171
306
    if (index & 0x10) {
4172
89
      index &= 0x0f;
4173
89
      if (index >= numACHuffTables)
4174
86
  numACHuffTables = index+1;
4175
89
      tbl = &acHuffTables[index];
4176
217
    } else {
4177
217
      index &= 0x0f;
4178
217
      if (index >= numDCHuffTables)
4179
159
  numDCHuffTables = index+1;
4180
217
      tbl = &dcHuffTables[index];
4181
217
    }
4182
306
    sym = 0;
4183
306
    code = 0;
4184
5.20k
    for (i = 1; i <= 16; ++i) {
4185
4.89k
      c = str->getChar();
4186
4.89k
      tbl->firstSym[i] = sym;
4187
4.89k
      tbl->firstCode[i] = code;
4188
4.89k
      tbl->numCodes[i] = (Gushort)c;
4189
4.89k
      sym = (Guchar)(sym + c);
4190
4.89k
      code = (Gushort)((code + c) << 1);
4191
4.89k
    }
4192
306
    length -= 16;
4193
19.4k
    for (i = 0; i < sym; ++i)
4194
19.1k
      tbl->sym[i] = (Guchar)str->getChar();
4195
306
    length -= sym;
4196
306
  }
4197
62
  return gTrue;
4198
85
}
4199
4200
10
GBool DCTStream::readRestartInterval() {
4201
10
  int length;
4202
4203
10
  length = read16();
4204
10
  if (length != 4) {
4205
0
    error(errSyntaxError, getPos(), "Bad DCT restart interval");
4206
0
    return gFalse;
4207
0
  }
4208
10
  restartInterval = read16();
4209
10
  return gTrue;
4210
10
}
4211
4212
29
GBool DCTStream::readJFIFMarker() {
4213
29
  int length, i;
4214
29
  char buf[5];
4215
29
  int c;
4216
4217
29
  length = read16();
4218
29
  length -= 2;
4219
29
  if (length >= 5) {
4220
174
    for (i = 0; i < 5; ++i) {
4221
145
      if ((c = str->getChar()) == EOF) {
4222
0
  error(errSyntaxError, getPos(), "Bad DCT APP0 marker");
4223
0
  return gFalse;
4224
0
      }
4225
145
      buf[i] = (char)c;
4226
145
    }
4227
29
    length -= 5;
4228
29
    if (!memcmp(buf, "JFIF\0", 5)) {
4229
29
      gotJFIFMarker = gTrue;
4230
29
    }
4231
29
  }
4232
290
  while (length > 0) {
4233
261
    if (str->getChar() == EOF) {
4234
0
      error(errSyntaxError, getPos(), "Bad DCT APP0 marker");
4235
0
      return gFalse;
4236
0
    }
4237
261
    --length;
4238
261
  }
4239
29
  return gTrue;
4240
29
}
4241
4242
10
GBool DCTStream::readAdobeMarker() {
4243
10
  int length, i;
4244
10
  char buf[12];
4245
10
  int c;
4246
4247
10
  length = read16();
4248
10
  if (length < 14) {
4249
0
    goto err;
4250
0
  }
4251
130
  for (i = 0; i < 12; ++i) {
4252
120
    if ((c = str->getChar()) == EOF) {
4253
0
      goto err;
4254
0
    }
4255
120
    buf[i] = (char)c;
4256
120
  }
4257
10
  if (!strncmp(buf, "Adobe", 5)) {
4258
10
    colorXform = buf[11];
4259
10
    gotAdobeMarker = gTrue;
4260
10
  }
4261
10
  for (i = 14; i < length; ++i) {
4262
0
    if (str->getChar() == EOF) {
4263
0
      goto err;
4264
0
    }
4265
0
  }
4266
10
  return gTrue;
4267
4268
0
 err:
4269
0
  error(errSyntaxError, getPos(), "Bad DCT Adobe APP14 marker");
4270
0
  return gFalse;
4271
10
}
4272
4273
0
GBool DCTStream::readTrailer() {
4274
0
  int c;
4275
4276
0
  c = readMarker();
4277
0
  if (c != 0xd9) {   // EOI
4278
0
    error(errSyntaxError, getPos(), "Bad DCT trailer");
4279
0
    return gFalse;
4280
0
  }
4281
0
  return gTrue;
4282
0
}
4283
4284
1.25k
int DCTStream::readMarker() {
4285
1.25k
  int c;
4286
4287
1.32k
  do {
4288
83.6k
    do {
4289
83.6k
      c = str->getChar();
4290
83.6k
    } while (c != 0xff && c != EOF);
4291
1.46k
    do {
4292
1.46k
      c = str->getChar();
4293
1.46k
    } while (c == 0xff);
4294
1.32k
  } while (c == 0x00);
4295
1.25k
  return c;
4296
1.25k
}
4297
4298
2.01k
int DCTStream::read16() {
4299
2.01k
  int c1, c2;
4300
4301
2.01k
  if ((c1 = str->getChar()) == EOF)
4302
0
    return EOF;
4303
2.01k
  if ((c2 = str->getChar()) == EOF)
4304
0
    return EOF;
4305
2.01k
  return (c1 << 8) + c2;
4306
2.01k
}
4307
4308
#endif // HAVE_JPEGLIB
4309
4310
GString *DCTStream::getPSFilter(int psLevel, const char *indent,
4311
0
        GBool okToReadStream) {
4312
0
  GString *s;
4313
4314
0
  if (psLevel < 2) {
4315
0
    return NULL;
4316
0
  }
4317
0
  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
4318
0
    return NULL;
4319
0
  }
4320
0
  if (okToReadStream && !checkSequentialInterleaved()) {
4321
    // PostScript does not allow progressive or interleaved JPEG
4322
0
    delete s;
4323
0
    return NULL;
4324
0
  }
4325
0
  s->append(indent)->append("<< >> /DCTDecode filter\n");
4326
0
  return s;
4327
0
}
4328
4329
0
GBool DCTStream::isBinary(GBool last) {
4330
0
  return str->isBinary(gTrue);
4331
0
}
4332
4333
//------------------------------------------------------------------------
4334
// FlateStream
4335
//------------------------------------------------------------------------
4336
4337
int FlateStream::codeLenCodeMap[flateMaxCodeLenCodes] = {
4338
  16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
4339
};
4340
4341
FlateDecode FlateStream::lengthDecode[flateMaxLitCodes-257] = {
4342
  {0,   3},
4343
  {0,   4},
4344
  {0,   5},
4345
  {0,   6},
4346
  {0,   7},
4347
  {0,   8},
4348
  {0,   9},
4349
  {0,  10},
4350
  {1,  11},
4351
  {1,  13},
4352
  {1,  15},
4353
  {1,  17},
4354
  {2,  19},
4355
  {2,  23},
4356
  {2,  27},
4357
  {2,  31},
4358
  {3,  35},
4359
  {3,  43},
4360
  {3,  51},
4361
  {3,  59},
4362
  {4,  67},
4363
  {4,  83},
4364
  {4,  99},
4365
  {4, 115},
4366
  {5, 131},
4367
  {5, 163},
4368
  {5, 195},
4369
  {5, 227},
4370
  {0, 258},
4371
  {0, 258},
4372
  {0, 258}
4373
};
4374
4375
FlateDecode FlateStream::distDecode[flateMaxDistCodes] = {
4376
  { 0,     1},
4377
  { 0,     2},
4378
  { 0,     3},
4379
  { 0,     4},
4380
  { 1,     5},
4381
  { 1,     7},
4382
  { 2,     9},
4383
  { 2,    13},
4384
  { 3,    17},
4385
  { 3,    25},
4386
  { 4,    33},
4387
  { 4,    49},
4388
  { 5,    65},
4389
  { 5,    97},
4390
  { 6,   129},
4391
  { 6,   193},
4392
  { 7,   257},
4393
  { 7,   385},
4394
  { 8,   513},
4395
  { 8,   769},
4396
  { 9,  1025},
4397
  { 9,  1537},
4398
  {10,  2049},
4399
  {10,  3073},
4400
  {11,  4097},
4401
  {11,  6145},
4402
  {12,  8193},
4403
  {12, 12289},
4404
  {13, 16385},
4405
  {13, 24577}
4406
};
4407
4408
static FlateCode flateFixedLitCodeTabCodes[512] = {
4409
  {7, 0x0100},
4410
  {8, 0x0050},
4411
  {8, 0x0010},
4412
  {8, 0x0118},
4413
  {7, 0x0110},
4414
  {8, 0x0070},
4415
  {8, 0x0030},
4416
  {9, 0x00c0},
4417
  {7, 0x0108},
4418
  {8, 0x0060},
4419
  {8, 0x0020},
4420
  {9, 0x00a0},
4421
  {8, 0x0000},
4422
  {8, 0x0080},
4423
  {8, 0x0040},
4424
  {9, 0x00e0},
4425
  {7, 0x0104},
4426
  {8, 0x0058},
4427
  {8, 0x0018},
4428
  {9, 0x0090},
4429
  {7, 0x0114},
4430
  {8, 0x0078},
4431
  {8, 0x0038},
4432
  {9, 0x00d0},
4433
  {7, 0x010c},
4434
  {8, 0x0068},
4435
  {8, 0x0028},
4436
  {9, 0x00b0},
4437
  {8, 0x0008},
4438
  {8, 0x0088},
4439
  {8, 0x0048},
4440
  {9, 0x00f0},
4441
  {7, 0x0102},
4442
  {8, 0x0054},
4443
  {8, 0x0014},
4444
  {8, 0x011c},
4445
  {7, 0x0112},
4446
  {8, 0x0074},
4447
  {8, 0x0034},
4448
  {9, 0x00c8},
4449
  {7, 0x010a},
4450
  {8, 0x0064},
4451
  {8, 0x0024},
4452
  {9, 0x00a8},
4453
  {8, 0x0004},
4454
  {8, 0x0084},
4455
  {8, 0x0044},
4456
  {9, 0x00e8},
4457
  {7, 0x0106},
4458
  {8, 0x005c},
4459
  {8, 0x001c},
4460
  {9, 0x0098},
4461
  {7, 0x0116},
4462
  {8, 0x007c},
4463
  {8, 0x003c},
4464
  {9, 0x00d8},
4465
  {7, 0x010e},
4466
  {8, 0x006c},
4467
  {8, 0x002c},
4468
  {9, 0x00b8},
4469
  {8, 0x000c},
4470
  {8, 0x008c},
4471
  {8, 0x004c},
4472
  {9, 0x00f8},
4473
  {7, 0x0101},
4474
  {8, 0x0052},
4475
  {8, 0x0012},
4476
  {8, 0x011a},
4477
  {7, 0x0111},
4478
  {8, 0x0072},
4479
  {8, 0x0032},
4480
  {9, 0x00c4},
4481
  {7, 0x0109},
4482
  {8, 0x0062},
4483
  {8, 0x0022},
4484
  {9, 0x00a4},
4485
  {8, 0x0002},
4486
  {8, 0x0082},
4487
  {8, 0x0042},
4488
  {9, 0x00e4},
4489
  {7, 0x0105},
4490
  {8, 0x005a},
4491
  {8, 0x001a},
4492
  {9, 0x0094},
4493
  {7, 0x0115},
4494
  {8, 0x007a},
4495
  {8, 0x003a},
4496
  {9, 0x00d4},
4497
  {7, 0x010d},
4498
  {8, 0x006a},
4499
  {8, 0x002a},
4500
  {9, 0x00b4},
4501
  {8, 0x000a},
4502
  {8, 0x008a},
4503
  {8, 0x004a},
4504
  {9, 0x00f4},
4505
  {7, 0x0103},
4506
  {8, 0x0056},
4507
  {8, 0x0016},
4508
  {8, 0x011e},
4509
  {7, 0x0113},
4510
  {8, 0x0076},
4511
  {8, 0x0036},
4512
  {9, 0x00cc},
4513
  {7, 0x010b},
4514
  {8, 0x0066},
4515
  {8, 0x0026},
4516
  {9, 0x00ac},
4517
  {8, 0x0006},
4518
  {8, 0x0086},
4519
  {8, 0x0046},
4520
  {9, 0x00ec},
4521
  {7, 0x0107},
4522
  {8, 0x005e},
4523
  {8, 0x001e},
4524
  {9, 0x009c},
4525
  {7, 0x0117},
4526
  {8, 0x007e},
4527
  {8, 0x003e},
4528
  {9, 0x00dc},
4529
  {7, 0x010f},
4530
  {8, 0x006e},
4531
  {8, 0x002e},
4532
  {9, 0x00bc},
4533
  {8, 0x000e},
4534
  {8, 0x008e},
4535
  {8, 0x004e},
4536
  {9, 0x00fc},
4537
  {7, 0x0100},
4538
  {8, 0x0051},
4539
  {8, 0x0011},
4540
  {8, 0x0119},
4541
  {7, 0x0110},
4542
  {8, 0x0071},
4543
  {8, 0x0031},
4544
  {9, 0x00c2},
4545
  {7, 0x0108},
4546
  {8, 0x0061},
4547
  {8, 0x0021},
4548
  {9, 0x00a2},
4549
  {8, 0x0001},
4550
  {8, 0x0081},
4551
  {8, 0x0041},
4552
  {9, 0x00e2},
4553
  {7, 0x0104},
4554
  {8, 0x0059},
4555
  {8, 0x0019},
4556
  {9, 0x0092},
4557
  {7, 0x0114},
4558
  {8, 0x0079},
4559
  {8, 0x0039},
4560
  {9, 0x00d2},
4561
  {7, 0x010c},
4562
  {8, 0x0069},
4563
  {8, 0x0029},
4564
  {9, 0x00b2},
4565
  {8, 0x0009},
4566
  {8, 0x0089},
4567
  {8, 0x0049},
4568
  {9, 0x00f2},
4569
  {7, 0x0102},
4570
  {8, 0x0055},
4571
  {8, 0x0015},
4572
  {8, 0x011d},
4573
  {7, 0x0112},
4574
  {8, 0x0075},
4575
  {8, 0x0035},
4576
  {9, 0x00ca},
4577
  {7, 0x010a},
4578
  {8, 0x0065},
4579
  {8, 0x0025},
4580
  {9, 0x00aa},
4581
  {8, 0x0005},
4582
  {8, 0x0085},
4583
  {8, 0x0045},
4584
  {9, 0x00ea},
4585
  {7, 0x0106},
4586
  {8, 0x005d},
4587
  {8, 0x001d},
4588
  {9, 0x009a},
4589
  {7, 0x0116},
4590
  {8, 0x007d},
4591
  {8, 0x003d},
4592
  {9, 0x00da},
4593
  {7, 0x010e},
4594
  {8, 0x006d},
4595
  {8, 0x002d},
4596
  {9, 0x00ba},
4597
  {8, 0x000d},
4598
  {8, 0x008d},
4599
  {8, 0x004d},
4600
  {9, 0x00fa},
4601
  {7, 0x0101},
4602
  {8, 0x0053},
4603
  {8, 0x0013},
4604
  {8, 0x011b},
4605
  {7, 0x0111},
4606
  {8, 0x0073},
4607
  {8, 0x0033},
4608
  {9, 0x00c6},
4609
  {7, 0x0109},
4610
  {8, 0x0063},
4611
  {8, 0x0023},
4612
  {9, 0x00a6},
4613
  {8, 0x0003},
4614
  {8, 0x0083},
4615
  {8, 0x0043},
4616
  {9, 0x00e6},
4617
  {7, 0x0105},
4618
  {8, 0x005b},
4619
  {8, 0x001b},
4620
  {9, 0x0096},
4621
  {7, 0x0115},
4622
  {8, 0x007b},
4623
  {8, 0x003b},
4624
  {9, 0x00d6},
4625
  {7, 0x010d},
4626
  {8, 0x006b},
4627
  {8, 0x002b},
4628
  {9, 0x00b6},
4629
  {8, 0x000b},
4630
  {8, 0x008b},
4631
  {8, 0x004b},
4632
  {9, 0x00f6},
4633
  {7, 0x0103},
4634
  {8, 0x0057},
4635
  {8, 0x0017},
4636
  {8, 0x011f},
4637
  {7, 0x0113},
4638
  {8, 0x0077},
4639
  {8, 0x0037},
4640
  {9, 0x00ce},
4641
  {7, 0x010b},
4642
  {8, 0x0067},
4643
  {8, 0x0027},
4644
  {9, 0x00ae},
4645
  {8, 0x0007},
4646
  {8, 0x0087},
4647
  {8, 0x0047},
4648
  {9, 0x00ee},
4649
  {7, 0x0107},
4650
  {8, 0x005f},
4651
  {8, 0x001f},
4652
  {9, 0x009e},
4653
  {7, 0x0117},
4654
  {8, 0x007f},
4655
  {8, 0x003f},
4656
  {9, 0x00de},
4657
  {7, 0x010f},
4658
  {8, 0x006f},
4659
  {8, 0x002f},
4660
  {9, 0x00be},
4661
  {8, 0x000f},
4662
  {8, 0x008f},
4663
  {8, 0x004f},
4664
  {9, 0x00fe},
4665
  {7, 0x0100},
4666
  {8, 0x0050},
4667
  {8, 0x0010},
4668
  {8, 0x0118},
4669
  {7, 0x0110},
4670
  {8, 0x0070},
4671
  {8, 0x0030},
4672
  {9, 0x00c1},
4673
  {7, 0x0108},
4674
  {8, 0x0060},
4675
  {8, 0x0020},
4676
  {9, 0x00a1},
4677
  {8, 0x0000},
4678
  {8, 0x0080},
4679
  {8, 0x0040},
4680
  {9, 0x00e1},
4681
  {7, 0x0104},
4682
  {8, 0x0058},
4683
  {8, 0x0018},
4684
  {9, 0x0091},
4685
  {7, 0x0114},
4686
  {8, 0x0078},
4687
  {8, 0x0038},
4688
  {9, 0x00d1},
4689
  {7, 0x010c},
4690
  {8, 0x0068},
4691
  {8, 0x0028},
4692
  {9, 0x00b1},
4693
  {8, 0x0008},
4694
  {8, 0x0088},
4695
  {8, 0x0048},
4696
  {9, 0x00f1},
4697
  {7, 0x0102},
4698
  {8, 0x0054},
4699
  {8, 0x0014},
4700
  {8, 0x011c},
4701
  {7, 0x0112},
4702
  {8, 0x0074},
4703
  {8, 0x0034},
4704
  {9, 0x00c9},
4705
  {7, 0x010a},
4706
  {8, 0x0064},
4707
  {8, 0x0024},
4708
  {9, 0x00a9},
4709
  {8, 0x0004},
4710
  {8, 0x0084},
4711
  {8, 0x0044},
4712
  {9, 0x00e9},
4713
  {7, 0x0106},
4714
  {8, 0x005c},
4715
  {8, 0x001c},
4716
  {9, 0x0099},
4717
  {7, 0x0116},
4718
  {8, 0x007c},
4719
  {8, 0x003c},
4720
  {9, 0x00d9},
4721
  {7, 0x010e},
4722
  {8, 0x006c},
4723
  {8, 0x002c},
4724
  {9, 0x00b9},
4725
  {8, 0x000c},
4726
  {8, 0x008c},
4727
  {8, 0x004c},
4728
  {9, 0x00f9},
4729
  {7, 0x0101},
4730
  {8, 0x0052},
4731
  {8, 0x0012},
4732
  {8, 0x011a},
4733
  {7, 0x0111},
4734
  {8, 0x0072},
4735
  {8, 0x0032},
4736
  {9, 0x00c5},
4737
  {7, 0x0109},
4738
  {8, 0x0062},
4739
  {8, 0x0022},
4740
  {9, 0x00a5},
4741
  {8, 0x0002},
4742
  {8, 0x0082},
4743
  {8, 0x0042},
4744
  {9, 0x00e5},
4745
  {7, 0x0105},
4746
  {8, 0x005a},
4747
  {8, 0x001a},
4748
  {9, 0x0095},
4749
  {7, 0x0115},
4750
  {8, 0x007a},
4751
  {8, 0x003a},
4752
  {9, 0x00d5},
4753
  {7, 0x010d},
4754
  {8, 0x006a},
4755
  {8, 0x002a},
4756
  {9, 0x00b5},
4757
  {8, 0x000a},
4758
  {8, 0x008a},
4759
  {8, 0x004a},
4760
  {9, 0x00f5},
4761
  {7, 0x0103},
4762
  {8, 0x0056},
4763
  {8, 0x0016},
4764
  {8, 0x011e},
4765
  {7, 0x0113},
4766
  {8, 0x0076},
4767
  {8, 0x0036},
4768
  {9, 0x00cd},
4769
  {7, 0x010b},
4770
  {8, 0x0066},
4771
  {8, 0x0026},
4772
  {9, 0x00ad},
4773
  {8, 0x0006},
4774
  {8, 0x0086},
4775
  {8, 0x0046},
4776
  {9, 0x00ed},
4777
  {7, 0x0107},
4778
  {8, 0x005e},
4779
  {8, 0x001e},
4780
  {9, 0x009d},
4781
  {7, 0x0117},
4782
  {8, 0x007e},
4783
  {8, 0x003e},
4784
  {9, 0x00dd},
4785
  {7, 0x010f},
4786
  {8, 0x006e},
4787
  {8, 0x002e},
4788
  {9, 0x00bd},
4789
  {8, 0x000e},
4790
  {8, 0x008e},
4791
  {8, 0x004e},
4792
  {9, 0x00fd},
4793
  {7, 0x0100},
4794
  {8, 0x0051},
4795
  {8, 0x0011},
4796
  {8, 0x0119},
4797
  {7, 0x0110},
4798
  {8, 0x0071},
4799
  {8, 0x0031},
4800
  {9, 0x00c3},
4801
  {7, 0x0108},
4802
  {8, 0x0061},
4803
  {8, 0x0021},
4804
  {9, 0x00a3},
4805
  {8, 0x0001},
4806
  {8, 0x0081},
4807
  {8, 0x0041},
4808
  {9, 0x00e3},
4809
  {7, 0x0104},
4810
  {8, 0x0059},
4811
  {8, 0x0019},
4812
  {9, 0x0093},
4813
  {7, 0x0114},
4814
  {8, 0x0079},
4815
  {8, 0x0039},
4816
  {9, 0x00d3},
4817
  {7, 0x010c},
4818
  {8, 0x0069},
4819
  {8, 0x0029},
4820
  {9, 0x00b3},
4821
  {8, 0x0009},
4822
  {8, 0x0089},
4823
  {8, 0x0049},
4824
  {9, 0x00f3},
4825
  {7, 0x0102},
4826
  {8, 0x0055},
4827
  {8, 0x0015},
4828
  {8, 0x011d},
4829
  {7, 0x0112},
4830
  {8, 0x0075},
4831
  {8, 0x0035},
4832
  {9, 0x00cb},
4833
  {7, 0x010a},
4834
  {8, 0x0065},
4835
  {8, 0x0025},
4836
  {9, 0x00ab},
4837
  {8, 0x0005},
4838
  {8, 0x0085},
4839
  {8, 0x0045},
4840
  {9, 0x00eb},
4841
  {7, 0x0106},
4842
  {8, 0x005d},
4843
  {8, 0x001d},
4844
  {9, 0x009b},
4845
  {7, 0x0116},
4846
  {8, 0x007d},
4847
  {8, 0x003d},
4848
  {9, 0x00db},
4849
  {7, 0x010e},
4850
  {8, 0x006d},
4851
  {8, 0x002d},
4852
  {9, 0x00bb},
4853
  {8, 0x000d},
4854
  {8, 0x008d},
4855
  {8, 0x004d},
4856
  {9, 0x00fb},
4857
  {7, 0x0101},
4858
  {8, 0x0053},
4859
  {8, 0x0013},
4860
  {8, 0x011b},
4861
  {7, 0x0111},
4862
  {8, 0x0073},
4863
  {8, 0x0033},
4864
  {9, 0x00c7},
4865
  {7, 0x0109},
4866
  {8, 0x0063},
4867
  {8, 0x0023},
4868
  {9, 0x00a7},
4869
  {8, 0x0003},
4870
  {8, 0x0083},
4871
  {8, 0x0043},
4872
  {9, 0x00e7},
4873
  {7, 0x0105},
4874
  {8, 0x005b},
4875
  {8, 0x001b},
4876
  {9, 0x0097},
4877
  {7, 0x0115},
4878
  {8, 0x007b},
4879
  {8, 0x003b},
4880
  {9, 0x00d7},
4881
  {7, 0x010d},
4882
  {8, 0x006b},
4883
  {8, 0x002b},
4884
  {9, 0x00b7},
4885
  {8, 0x000b},
4886
  {8, 0x008b},
4887
  {8, 0x004b},
4888
  {9, 0x00f7},
4889
  {7, 0x0103},
4890
  {8, 0x0057},
4891
  {8, 0x0017},
4892
  {8, 0x011f},
4893
  {7, 0x0113},
4894
  {8, 0x0077},
4895
  {8, 0x0037},
4896
  {9, 0x00cf},
4897
  {7, 0x010b},
4898
  {8, 0x0067},
4899
  {8, 0x0027},
4900
  {9, 0x00af},
4901
  {8, 0x0007},
4902
  {8, 0x0087},
4903
  {8, 0x0047},
4904
  {9, 0x00ef},
4905
  {7, 0x0107},
4906
  {8, 0x005f},
4907
  {8, 0x001f},
4908
  {9, 0x009f},
4909
  {7, 0x0117},
4910
  {8, 0x007f},
4911
  {8, 0x003f},
4912
  {9, 0x00df},
4913
  {7, 0x010f},
4914
  {8, 0x006f},
4915
  {8, 0x002f},
4916
  {9, 0x00bf},
4917
  {8, 0x000f},
4918
  {8, 0x008f},
4919
  {8, 0x004f},
4920
  {9, 0x00ff}
4921
};
4922
4923
FlateHuffmanTab FlateStream::fixedLitCodeTab = {
4924
  flateFixedLitCodeTabCodes, 9
4925
};
4926
4927
static FlateCode flateFixedDistCodeTabCodes[32] = {
4928
  {5, 0x0000},
4929
  {5, 0x0010},
4930
  {5, 0x0008},
4931
  {5, 0x0018},
4932
  {5, 0x0004},
4933
  {5, 0x0014},
4934
  {5, 0x000c},
4935
  {5, 0x001c},
4936
  {5, 0x0002},
4937
  {5, 0x0012},
4938
  {5, 0x000a},
4939
  {5, 0x001a},
4940
  {5, 0x0006},
4941
  {5, 0x0016},
4942
  {5, 0x000e},
4943
  {0, 0x0000},
4944
  {5, 0x0001},
4945
  {5, 0x0011},
4946
  {5, 0x0009},
4947
  {5, 0x0019},
4948
  {5, 0x0005},
4949
  {5, 0x0015},
4950
  {5, 0x000d},
4951
  {5, 0x001d},
4952
  {5, 0x0003},
4953
  {5, 0x0013},
4954
  {5, 0x000b},
4955
  {5, 0x001b},
4956
  {5, 0x0007},
4957
  {5, 0x0017},
4958
  {5, 0x000f},
4959
  {0, 0x0000}
4960
};
4961
4962
FlateHuffmanTab FlateStream::fixedDistCodeTab = {
4963
  flateFixedDistCodeTabCodes, 5
4964
};
4965
4966
FlateStream::FlateStream(Stream *strA, int predictor, int columns,
4967
       int colors, int bits):
4968
12.3k
    FilterStream(strA) {
4969
12.3k
  if (predictor != 1) {
4970
341
    pred = new StreamPredictor(this, predictor, columns, colors, bits);
4971
341
    if (!pred->isOk()) {
4972
71
      delete pred;
4973
71
      pred = NULL;
4974
71
    }
4975
12.0k
  } else {
4976
12.0k
    pred = NULL;
4977
12.0k
  }
4978
12.3k
  litCodeTab.codes = NULL;
4979
12.3k
  distCodeTab.codes = NULL;
4980
12.3k
  memset(buf, 0, flateWindow);
4981
12.3k
  checkForDecompressionBombs = gTrue;
4982
12.3k
}
4983
4984
10.5k
FlateStream::~FlateStream() {
4985
10.5k
  if (litCodeTab.codes != fixedLitCodeTab.codes) {
4986
10.1k
    gfree(litCodeTab.codes);
4987
10.1k
  }
4988
10.5k
  if (distCodeTab.codes != fixedDistCodeTab.codes) {
4989
10.1k
    gfree(distCodeTab.codes);
4990
10.1k
  }
4991
10.5k
  if (pred) {
4992
213
    delete pred;
4993
213
  }
4994
10.5k
  delete str;
4995
10.5k
}
4996
4997
7.98k
Stream *FlateStream::copy() {
4998
7.98k
  if (pred) {
4999
142
    return new FlateStream(str->copy(), pred->getPredictor(),
5000
142
         pred->getWidth(), pred->getNComps(),
5001
142
         pred->getNBits());
5002
7.83k
  } else {
5003
7.83k
    return new FlateStream(str->copy(), 1, 0, 0, 0);
5004
7.83k
  }
5005
7.98k
}
5006
5007
0
void FlateStream::disableDecompressionBombChecking() {
5008
0
  checkForDecompressionBombs = gFalse;
5009
0
  FilterStream::disableDecompressionBombChecking();
5010
0
}
5011
5012
4.35k
void FlateStream::reset() {
5013
4.35k
  int cmf, flg;
5014
5015
4.35k
  index = 0;
5016
4.35k
  remain = 0;
5017
4.35k
  codeBuf = 0;
5018
4.35k
  codeSize = 0;
5019
4.35k
  compressedBlock = gFalse;
5020
4.35k
  endOfBlock = gTrue;
5021
4.35k
  eof = gTrue;
5022
5023
4.35k
  str->reset();
5024
4.35k
  if (pred) {
5025
58
    pred->reset();
5026
58
  }
5027
5028
  // read header
5029
  //~ need to look at window size?
5030
4.35k
  endOfBlock = eof = gTrue;
5031
4.35k
  cmf = str->getChar();
5032
4.35k
  flg = str->getChar();
5033
4.35k
  totalIn = 2;
5034
4.35k
  totalOut = 0;
5035
4.35k
  if (cmf == EOF || flg == EOF)
5036
1
    return;
5037
4.35k
  if ((cmf & 0x0f) != 0x08) {
5038
55
    error(errSyntaxError, getPos(),
5039
55
    "Unknown compression method in flate stream");
5040
55
    return;
5041
55
  }
5042
4.29k
  if ((((cmf << 8) + flg) % 31) != 0) {
5043
25
    error(errSyntaxError, getPos(), "Bad FCHECK in flate stream");
5044
25
    return;
5045
25
  }
5046
4.27k
  if (flg & 0x20) {
5047
0
    error(errSyntaxError, getPos(), "FDICT bit set in flate stream");
5048
0
    return;
5049
0
  }
5050
5051
4.27k
  eof = gFalse;
5052
4.27k
}
5053
5054
1.37M
int FlateStream::getChar() {
5055
1.37M
  int c;
5056
5057
1.37M
  if (pred) {
5058
20
    return pred->getChar();
5059
20
  }
5060
1.50M
  while (remain == 0) {
5061
135k
    if (endOfBlock && eof)
5062
839
      return EOF;
5063
135k
    readSome();
5064
135k
  }
5065
1.37M
  c = buf[index];
5066
1.37M
  index = (index + 1) & flateMask;
5067
1.37M
  --remain;
5068
1.37M
  return c;
5069
1.37M
}
5070
5071
1.12M
int FlateStream::lookChar() {
5072
1.12M
  int c;
5073
5074
1.12M
  if (pred) {
5075
0
    return pred->lookChar();
5076
0
  }
5077
1.61M
  while (remain == 0) {
5078
490k
    if (endOfBlock && eof)
5079
43
      return EOF;
5080
490k
    readSome();
5081
490k
  }
5082
1.12M
  c = buf[index];
5083
1.12M
  return c;
5084
1.12M
}
5085
5086
22
int FlateStream::getRawChar() {
5087
22
  int c;
5088
5089
40
  while (remain == 0) {
5090
28
    if (endOfBlock && eof)
5091
10
      return EOF;
5092
18
    readSome();
5093
18
  }
5094
12
  c = buf[index];
5095
12
  index = (index + 1) & flateMask;
5096
12
  --remain;
5097
12
  return c;
5098
22
}
5099
5100
1.92k
int FlateStream::getBlock(char *blk, int size) {
5101
1.92k
  int n, k;
5102
5103
1.92k
  if (pred) {
5104
0
    return pred->getBlock(blk, size);
5105
0
  }
5106
5107
1.92k
  n = 0;
5108
419k
  while (n < size) {
5109
418k
    if (remain == 0) {
5110
416k
      if (endOfBlock && eof) {
5111
295
  break;
5112
295
      }
5113
416k
      readSome();
5114
416k
    }
5115
417k
    k = remain;
5116
417k
    if (size - n < k) {
5117
1.53k
      k = size - n;
5118
1.53k
    }
5119
417k
    if (flateWindow - index < k) {
5120
0
      k = flateWindow - index;
5121
0
    }
5122
417k
    memcpy(blk + n, buf + index, k);
5123
417k
    n += k;
5124
417k
    index = (index + k) & flateMask;
5125
417k
    remain -= k;
5126
417k
  }
5127
1.92k
  return n;
5128
1.92k
}
5129
5130
GString *FlateStream::getPSFilter(int psLevel, const char *indent,
5131
0
          GBool okToReadStream) {
5132
0
  GString *s;
5133
5134
0
  if (psLevel < 3 || pred) {
5135
0
    return NULL;
5136
0
  }
5137
0
  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
5138
0
    return NULL;
5139
0
  }
5140
0
  s->append(indent)->append("<< >> /FlateDecode filter\n");
5141
0
  return s;
5142
0
}
5143
5144
0
GBool FlateStream::isBinary(GBool last) {
5145
0
  return str->isBinary(gTrue);
5146
0
}
5147
5148
1.04M
void FlateStream::readSome() {
5149
1.04M
  int code1, code2;
5150
1.04M
  int len, dist;
5151
1.04M
  int src, dest, n1, n2, n3, i, j, k;
5152
1.04M
  int c;
5153
5154
1.04M
  if (endOfBlock) {
5155
3.80k
    if (!startBlock())
5156
523
      return;
5157
3.80k
  }
5158
5159
1.04M
  if (compressedBlock) {
5160
1.04M
    if ((code1 = getHuffmanCodeWord(&litCodeTab)) == EOF)
5161
59
      goto err;
5162
1.04M
    if (code1 < 256) {
5163
741k
      buf[index] = (Guchar)code1;
5164
741k
      remain = 1;
5165
741k
    } else if (code1 == 256) {
5166
626
      endOfBlock = gTrue;
5167
626
      remain = 0;
5168
299k
    } else {
5169
299k
      code1 -= 257;
5170
299k
      code2 = lengthDecode[code1].bits;
5171
299k
      if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
5172
0
  goto err;
5173
299k
      len = lengthDecode[code1].first + code2;
5174
299k
      if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF)
5175
123
  goto err;
5176
299k
      code2 = distDecode[code1].bits;
5177
299k
      if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
5178
1
  goto err;
5179
299k
      dist = distDecode[code1].first + code2;
5180
299k
      dest = index;
5181
299k
      src = (index - dist) & flateMask;
5182
      // the following is an optimized version of:
5183
      // for (k = 0; k < len; ++k) {
5184
      //   buf[dest] = buf[src];
5185
      //   dest = (dest + 1) & flateMask;
5186
      //   src = (src + 1) & flateMask;
5187
      // }
5188
299k
      if (dest + len <= flateWindow) {
5189
298k
  if (src + len <= flateWindow) {
5190
7.73M
    for (k = 0; k < len; ++k) {
5191
7.43M
      buf[dest + k] = buf[src + k];
5192
7.43M
    }
5193
298k
  } else {
5194
196
    n1 = flateWindow - src;
5195
196
    n2 = len - n1;
5196
8.75k
    for (k = 0; k < n1; ++k) {
5197
8.55k
      buf[dest + k] = buf[src + k];
5198
8.55k
    }
5199
196
    dest = dest + n1;
5200
196
    src = 0;
5201
9.13k
    for (k = 0; k < n2; ++k) {
5202
8.94k
      buf[dest + k] = buf[src + k];
5203
8.94k
    }
5204
196
  }
5205
298k
      } else {
5206
184
  if (src + len <= flateWindow) {
5207
178
    n1 = flateWindow - dest;
5208
178
    n2 = len - n1;
5209
10.0k
    for (k = 0; k < n1; ++k) {
5210
9.88k
      buf[dest + k] = buf[src + k];
5211
9.88k
    }
5212
178
    dest = 0;
5213
178
    src = src + n1;
5214
7.91k
    for (k = 0; k < n2; ++k) {
5215
7.73k
      buf[dest + k] = buf[src + k];
5216
7.73k
    }
5217
178
  } else if (src < dest) {
5218
6
    n1 = flateWindow - dest;
5219
6
    n2 = dest - src;
5220
6
    n3 = len - n1 - n2;
5221
129
    for (k = 0; k < n1; ++k) {
5222
123
      buf[dest + k] = buf[src + k];
5223
123
    }
5224
6
    dest = 0;
5225
6
    src = src + n1;
5226
123
    for (k = 0; k < n2; ++k) {
5227
117
      buf[dest + k] = buf[src + k];
5228
117
    }
5229
6
    dest = n2;
5230
6
    src = 0;
5231
149
    for (k = 0; k < n3; ++k) {
5232
143
      buf[dest + k] = buf[src + k];
5233
143
    }
5234
6
  } else {
5235
0
    n1 = flateWindow - src;
5236
0
    n2 = src - dest;
5237
0
    n3 = len - n1 - n2;
5238
0
    for (k = 0; k < n1; ++k) {
5239
0
      buf[dest + k] = buf[src + k];
5240
0
    }
5241
0
    dest = dest + n1;
5242
0
    src = 0;
5243
0
    for (k = 0; k < n2; ++k) {
5244
0
      buf[dest + k] = buf[src + k];
5245
0
    }
5246
0
    dest = 0;
5247
0
    src = n2;
5248
0
    for (k = 0; k < n3; ++k) {
5249
0
      buf[dest + k] = buf[src + k];
5250
0
    }
5251
0
  }
5252
184
      }
5253
299k
      remain = len;
5254
299k
    }
5255
5256
1.04M
  } else {
5257
0
    len = (blockLen < flateWindow) ? blockLen : flateWindow;
5258
0
    for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) {
5259
0
      if ((c = str->getChar()) == EOF) {
5260
0
  endOfBlock = eof = gTrue;
5261
0
  break;
5262
0
      }
5263
0
      buf[j] = (Guchar)c;
5264
0
    }
5265
0
    remain = i;
5266
0
    blockLen -= len;
5267
0
    if (blockLen == 0)
5268
0
      endOfBlock = gTrue;
5269
0
    totalIn += remain;
5270
0
  }
5271
1.04M
  totalOut += remain;
5272
5273
  // check for a 'decompression bomb'
5274
1.04M
  if (checkForDecompressionBombs &&
5275
1.04M
      totalOut > decompressionBombSizeThreshold &&
5276
0
      totalIn < totalOut / decompressionBombRatioThreshold) {
5277
0
    error(errSyntaxError, getPos(), "Decompression bomb in flate stream");
5278
0
    endOfBlock = eof = gTrue;
5279
0
    remain = 0;
5280
0
  }
5281
5282
1.04M
  return;
5283
5284
183
err:
5285
183
  error(errSyntaxError, getPos(), "Unexpected end of file in flate stream");
5286
183
  endOfBlock = eof = gTrue;
5287
183
  remain = 0;
5288
183
}
5289
5290
3.80k
GBool FlateStream::startBlock() {
5291
3.80k
  int blockHdr;
5292
3.80k
  int c;
5293
3.80k
  int check;
5294
5295
  // free the code tables from the previous block
5296
3.80k
  if (litCodeTab.codes != fixedLitCodeTab.codes) {
5297
3.55k
    gfree(litCodeTab.codes);
5298
3.55k
  }
5299
3.80k
  litCodeTab.codes = NULL;
5300
3.80k
  if (distCodeTab.codes != fixedDistCodeTab.codes) {
5301
3.55k
    gfree(distCodeTab.codes);
5302
3.55k
  }
5303
3.80k
  distCodeTab.codes = NULL;
5304
5305
  // read block header
5306
3.80k
  blockHdr = getCodeWord(3);
5307
3.80k
  if (blockHdr & 1)
5308
327
    eof = gTrue;
5309
3.80k
  blockHdr >>= 1;
5310
5311
  // uncompressed block
5312
3.80k
  if (blockHdr == 0) {
5313
8
    compressedBlock = gFalse;
5314
8
    if ((c = str->getChar()) == EOF)
5315
0
      goto err;
5316
8
    blockLen = c & 0xff;
5317
8
    if ((c = str->getChar()) == EOF)
5318
0
      goto err;
5319
8
    blockLen |= (c & 0xff) << 8;
5320
8
    if ((c = str->getChar()) == EOF)
5321
0
      goto err;
5322
8
    check = c & 0xff;
5323
8
    if ((c = str->getChar()) == EOF)
5324
0
      goto err;
5325
8
    check |= (c & 0xff) << 8;
5326
8
    if (check != (~blockLen & 0xffff))
5327
8
      goto err;
5328
0
    codeBuf = 0;
5329
0
    codeSize = 0;
5330
0
    totalIn += 4;
5331
5332
  // compressed block with fixed codes
5333
3.79k
  } else if (blockHdr == 1) {
5334
642
    compressedBlock = gTrue;
5335
642
    loadFixedCodes();
5336
5337
  // compressed block with dynamic codes
5338
3.15k
  } else if (blockHdr == 2) {
5339
3.15k
    compressedBlock = gTrue;
5340
3.15k
    if (!readDynamicCodes()) {
5341
514
      goto err;
5342
514
    }
5343
5344
  // unknown block type
5345
3.15k
  } else {
5346
1
    goto err;
5347
1
  }
5348
5349
3.27k
  endOfBlock = gFalse;
5350
3.27k
  return gTrue;
5351
5352
523
err:
5353
523
  error(errSyntaxError, getPos(), "Bad block header in flate stream");
5354
523
  endOfBlock = eof = gTrue;
5355
523
  return gFalse;
5356
3.80k
}
5357
5358
642
void FlateStream::loadFixedCodes() {
5359
642
  litCodeTab.codes = fixedLitCodeTab.codes;
5360
642
  litCodeTab.maxLen = fixedLitCodeTab.maxLen;
5361
642
  distCodeTab.codes = fixedDistCodeTab.codes;
5362
642
  distCodeTab.maxLen = fixedDistCodeTab.maxLen;
5363
642
}
5364
5365
3.15k
GBool FlateStream::readDynamicCodes() {
5366
3.15k
  int numCodeLenCodes;
5367
3.15k
  int numLitCodes;
5368
3.15k
  int numDistCodes;
5369
3.15k
  int codeLenCodeLengths[flateMaxCodeLenCodes];
5370
3.15k
  FlateHuffmanTab codeLenCodeTab;
5371
3.15k
  int len, repeat, code;
5372
3.15k
  int i;
5373
5374
3.15k
  codeLenCodeTab.codes = NULL;
5375
5376
  // read lengths
5377
3.15k
  if ((numLitCodes = getCodeWord(5)) == EOF) {
5378
0
    goto err;
5379
0
  }
5380
3.15k
  numLitCodes += 257;
5381
3.15k
  if ((numDistCodes = getCodeWord(5)) == EOF) {
5382
0
    goto err;
5383
0
  }
5384
3.15k
  numDistCodes += 1;
5385
3.15k
  if ((numCodeLenCodes = getCodeWord(4)) == EOF) {
5386
0
    goto err;
5387
0
  }
5388
3.15k
  numCodeLenCodes += 4;
5389
3.15k
  if (numLitCodes > flateMaxLitCodes ||
5390
3.15k
      numDistCodes > flateMaxDistCodes ||
5391
3.15k
      numCodeLenCodes > flateMaxCodeLenCodes) {
5392
0
    goto err;
5393
0
  }
5394
5395
  // build the code length code table
5396
63.0k
  for (i = 0; i < flateMaxCodeLenCodes; ++i) {
5397
59.8k
    codeLenCodeLengths[i] = 0;
5398
59.8k
  }
5399
50.6k
  for (i = 0; i < numCodeLenCodes; ++i) {
5400
47.4k
    if ((codeLenCodeLengths[codeLenCodeMap[i]] = getCodeWord(3)) == -1) {
5401
0
      goto err;
5402
0
    }
5403
47.4k
  }
5404
3.15k
  compHuffmanCodes(codeLenCodeLengths, flateMaxCodeLenCodes, &codeLenCodeTab);
5405
5406
  // build the literal and distance code tables
5407
3.15k
  len = 0;
5408
3.15k
  repeat = 0;
5409
3.15k
  i = 0;
5410
282k
  while (i < numLitCodes + numDistCodes) {
5411
280k
    if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF) {
5412
472
      goto err;
5413
472
    }
5414
279k
    if (code == 16) {
5415
3.66k
      if ((repeat = getCodeWord(2)) == EOF) {
5416
0
  goto err;
5417
0
      }
5418
3.66k
      repeat += 3;
5419
3.66k
      if (i + repeat > numLitCodes + numDistCodes) {
5420
0
  goto err;
5421
0
      }
5422
17.7k
      for (; repeat > 0; --repeat) {
5423
14.0k
  codeLengths[i++] = len;
5424
14.0k
      }
5425
275k
    } else if (code == 17) {
5426
17.7k
      if ((repeat = getCodeWord(3)) == EOF) {
5427
0
  goto err;
5428
0
      }
5429
17.7k
      repeat += 3;
5430
17.7k
      if (i + repeat > numLitCodes + numDistCodes) {
5431
20
  goto err;
5432
20
      }
5433
17.6k
      len = 0;
5434
100k
      for (; repeat > 0; --repeat) {
5435
82.6k
  codeLengths[i++] = 0;
5436
82.6k
      }
5437
258k
    } else if (code == 18) {
5438
8.20k
      if ((repeat = getCodeWord(7)) == EOF) {
5439
0
  goto err;
5440
0
      }
5441
8.20k
      repeat += 11;
5442
8.20k
      if (i + repeat > numLitCodes + numDistCodes) {
5443
22
  goto err;
5444
22
      }
5445
8.18k
      len = 0;
5446
488k
      for (; repeat > 0; --repeat) {
5447
480k
  codeLengths[i++] = 0;
5448
480k
      }
5449
250k
    } else {
5450
250k
      codeLengths[i++] = len = code;
5451
250k
    }
5452
279k
  }
5453
2.63k
  compHuffmanCodes(codeLengths, numLitCodes, &litCodeTab);
5454
2.63k
  compHuffmanCodes(codeLengths + numLitCodes, numDistCodes, &distCodeTab);
5455
5456
2.63k
  gfree(codeLenCodeTab.codes);
5457
2.63k
  return gTrue;
5458
5459
514
err:
5460
514
  error(errSyntaxError, getPos(), "Bad dynamic code table in flate stream");
5461
514
  gfree(codeLenCodeTab.codes);
5462
514
  return gFalse;
5463
3.15k
}
5464
5465
// Convert an array <lengths> of <n> lengths, in value order, into a
5466
// Huffman code lookup table.
5467
8.42k
void FlateStream::compHuffmanCodes(int *lengths, int n, FlateHuffmanTab *tab) {
5468
8.42k
  int tabSize, len, code, code2, skip, val, i, t;
5469
5470
  // find max code length
5471
8.42k
  tab->maxLen = 0;
5472
860k
  for (val = 0; val < n; ++val) {
5473
852k
    if (lengths[val] > tab->maxLen) {
5474
19.1k
      tab->maxLen = lengths[val];
5475
19.1k
    }
5476
852k
  }
5477
5478
  // allocate the table
5479
8.42k
  tabSize = 1 << tab->maxLen;
5480
8.42k
  tab->codes = (FlateCode *)gmallocn(tabSize, sizeof(FlateCode));
5481
5482
  // clear the table
5483
3.76M
  for (i = 0; i < tabSize; ++i) {
5484
3.75M
    tab->codes[i].len = 0;
5485
3.75M
    tab->codes[i].val = 0;
5486
3.75M
  }
5487
5488
  // build the table
5489
8.42k
  for (len = 1, code = 0, skip = 2;
5490
72.5k
       len <= tab->maxLen;
5491
64.1k
       ++len, code <<= 1, skip <<= 1) {
5492
7.96M
    for (val = 0; val < n; ++val) {
5493
7.90M
      if (lengths[val] == len) {
5494
5495
  // bit-reverse the code
5496
243k
  code2 = 0;
5497
243k
  t = code;
5498
1.80M
  for (i = 0; i < len; ++i) {
5499
1.55M
    code2 = (code2 << 1) | (t & 1);
5500
1.55M
    t >>= 1;
5501
1.55M
  }
5502
5503
  // fill in the table entries
5504
5.71M
  for (i = code2; i < tabSize; i += skip) {
5505
5.47M
    tab->codes[i].len = (Gushort)len;
5506
5.47M
    tab->codes[i].val = (Gushort)val;
5507
5.47M
  }
5508
5509
243k
  ++code;
5510
243k
      }
5511
7.90M
    }
5512
64.1k
  }
5513
8.42k
}
5514
5515
1.62M
int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) {
5516
1.62M
  FlateCode *code;
5517
1.62M
  int c;
5518
5519
2.63M
  while (codeSize < tab->maxLen) {
5520
1.01M
    if ((c = str->getChar()) == EOF) {
5521
532
      break;
5522
532
    }
5523
1.01M
    codeBuf |= (c & 0xff) << codeSize;
5524
1.01M
    codeSize += 8;
5525
1.01M
    ++totalIn;
5526
1.01M
  }
5527
1.62M
  code = &tab->codes[codeBuf & ((1 << tab->maxLen) - 1)];
5528
1.62M
  if (codeSize == 0 || codeSize < code->len || code->len == 0) {
5529
654
    return EOF;
5530
654
  }
5531
1.62M
  codeBuf >>= code->len;
5532
1.62M
  codeSize -= code->len;
5533
1.62M
  return (int)code->val;
5534
1.62M
}
5535
5536
482k
int FlateStream::getCodeWord(int bits) {
5537
482k
  int c;
5538
5539
547k
  while (codeSize < bits) {
5540
65.1k
    if ((c = str->getChar()) == EOF)
5541
1
      return EOF;
5542
65.1k
    codeBuf |= (c & 0xff) << codeSize;
5543
65.1k
    codeSize += 8;
5544
65.1k
    ++totalIn;
5545
65.1k
  }
5546
482k
  c = codeBuf & ((1 << bits) - 1);
5547
482k
  codeBuf >>= bits;
5548
482k
  codeSize -= bits;
5549
482k
  return c;
5550
482k
}
5551
5552
//------------------------------------------------------------------------
5553
// EOFStream
5554
//------------------------------------------------------------------------
5555
5556
EOFStream::EOFStream(Stream *strA):
5557
7.84k
    FilterStream(strA) {
5558
7.84k
}
5559
5560
7.74k
EOFStream::~EOFStream() {
5561
7.74k
  delete str;
5562
7.74k
}
5563
5564
475
Stream *EOFStream::copy() {
5565
475
  return new EOFStream(str->copy());
5566
475
}
5567
5568
//------------------------------------------------------------------------
5569
// BufStream
5570
//------------------------------------------------------------------------
5571
5572
17.7k
BufStream::BufStream(Stream *strA, int bufSizeA): FilterStream(strA) {
5573
17.7k
  bufSize = bufSizeA;
5574
17.7k
  buf = (int *)gmallocn(bufSize, sizeof(int));
5575
17.7k
}
5576
5577
17.7k
BufStream::~BufStream() {
5578
17.7k
  gfree(buf);
5579
17.7k
  delete str;
5580
17.7k
}
5581
5582
0
Stream *BufStream::copy() {
5583
0
  return new BufStream(str->copy(), bufSize);
5584
0
}
5585
5586
5.90k
void BufStream::reset() {
5587
5.90k
  int i;
5588
5589
5.90k
  str->reset();
5590
23.6k
  for (i = 0; i < bufSize; ++i) {
5591
17.7k
    buf[i] = str->getChar();
5592
17.7k
  }
5593
5.90k
}
5594
5595
1.59M
int BufStream::getChar() {
5596
1.59M
  int c, i;
5597
5598
1.59M
  c = buf[0];
5599
4.77M
  for (i = 1; i < bufSize; ++i) {
5600
3.18M
    buf[i-1] = buf[i];
5601
3.18M
  }
5602
1.59M
  buf[bufSize - 1] = str->getChar();
5603
1.59M
  return c;
5604
1.59M
}
5605
5606
5.89k
int BufStream::lookChar() {
5607
5.89k
  return buf[0];
5608
5.89k
}
5609
5610
0
int BufStream::lookChar(int idx) {
5611
0
  return buf[idx];
5612
0
}
5613
5614
0
GBool BufStream::isBinary(GBool last) {
5615
0
  return str->isBinary(gTrue);
5616
0
}
5617
5618
//------------------------------------------------------------------------
5619
// FixedLengthEncoder
5620
//------------------------------------------------------------------------
5621
5622
FixedLengthEncoder::FixedLengthEncoder(Stream *strA, int lengthA):
5623
0
    FilterStream(strA) {
5624
0
  length = lengthA;
5625
0
  count = 0;
5626
0
}
5627
5628
0
FixedLengthEncoder::~FixedLengthEncoder() {
5629
0
  if (str->isEncoder())
5630
0
    delete str;
5631
0
}
5632
5633
0
Stream *FixedLengthEncoder::copy() {
5634
0
  error(errInternal, -1, "Called copy() on FixedLengthEncoder");
5635
0
  return NULL;
5636
0
}
5637
5638
0
void FixedLengthEncoder::reset() {
5639
0
  str->reset();
5640
0
  count = 0;
5641
0
}
5642
5643
0
int FixedLengthEncoder::getChar() {
5644
0
  if (length >= 0 && count >= length)
5645
0
    return EOF;
5646
0
  ++count;
5647
0
  return str->getChar();
5648
0
}
5649
5650
0
int FixedLengthEncoder::lookChar() {
5651
0
  if (length >= 0 && count >= length)
5652
0
    return EOF;
5653
0
  return str->getChar();
5654
0
}
5655
5656
0
GBool FixedLengthEncoder::isBinary(GBool last) {
5657
0
  return str->isBinary(gTrue);
5658
0
}
5659
5660
//------------------------------------------------------------------------
5661
// ASCIIHexEncoder
5662
//------------------------------------------------------------------------
5663
5664
ASCIIHexEncoder::ASCIIHexEncoder(Stream *strA):
5665
0
    FilterStream(strA) {
5666
0
  bufPtr = bufEnd = buf;
5667
0
  lineLen = 0;
5668
0
  eof = gFalse;
5669
0
}
5670
5671
0
ASCIIHexEncoder::~ASCIIHexEncoder() {
5672
0
  if (str->isEncoder()) {
5673
0
    delete str;
5674
0
  }
5675
0
}
5676
5677
0
Stream *ASCIIHexEncoder::copy() {
5678
0
  error(errInternal, -1, "Called copy() on ASCIIHexEncoder");
5679
0
  return NULL;
5680
0
}
5681
5682
0
void ASCIIHexEncoder::reset() {
5683
0
  str->reset();
5684
0
  bufPtr = bufEnd = buf;
5685
0
  lineLen = 0;
5686
0
  eof = gFalse;
5687
0
}
5688
5689
0
GBool ASCIIHexEncoder::fillBuf() {
5690
0
  static const char *hex = "0123456789abcdef";
5691
0
  int c;
5692
5693
0
  if (eof) {
5694
0
    return gFalse;
5695
0
  }
5696
0
  bufPtr = bufEnd = buf;
5697
0
  if ((c = str->getChar()) == EOF) {
5698
0
    *bufEnd++ = '>';
5699
0
    eof = gTrue;
5700
0
  } else {
5701
0
    if (lineLen >= 64) {
5702
0
      *bufEnd++ = '\n';
5703
0
      lineLen = 0;
5704
0
    }
5705
0
    *bufEnd++ = hex[(c >> 4) & 0x0f];
5706
0
    *bufEnd++ = hex[c & 0x0f];
5707
0
    lineLen += 2;
5708
0
  }
5709
0
  return gTrue;
5710
0
}
5711
5712
//------------------------------------------------------------------------
5713
// ASCII85Encoder
5714
//------------------------------------------------------------------------
5715
5716
ASCII85Encoder::ASCII85Encoder(Stream *strA):
5717
0
    FilterStream(strA) {
5718
0
  bufPtr = bufEnd = buf;
5719
0
  lineLen = 0;
5720
0
  eof = gFalse;
5721
0
}
5722
5723
0
ASCII85Encoder::~ASCII85Encoder() {
5724
0
  if (str->isEncoder())
5725
0
    delete str;
5726
0
}
5727
5728
0
Stream *ASCII85Encoder::copy() {
5729
0
  error(errInternal, -1, "Called copy() on ASCII85Encoder");
5730
0
  return NULL;
5731
0
}
5732
5733
0
void ASCII85Encoder::reset() {
5734
0
  str->reset();
5735
0
  bufPtr = bufEnd = buf;
5736
0
  lineLen = 0;
5737
0
  eof = gFalse;
5738
0
}
5739
5740
0
GBool ASCII85Encoder::fillBuf() {
5741
0
  Guint t;
5742
0
  char buf1[5];
5743
0
  int c0, c1, c2, c3;
5744
0
  int n, i;
5745
5746
0
  if (eof) {
5747
0
    return gFalse;
5748
0
  }
5749
0
  c0 = str->getChar();
5750
0
  c1 = str->getChar();
5751
0
  c2 = str->getChar();
5752
0
  c3 = str->getChar();
5753
0
  bufPtr = bufEnd = buf;
5754
0
  if (c3 == EOF) {
5755
0
    if (c0 == EOF) {
5756
0
      n = 0;
5757
0
      t = 0;
5758
0
    } else {
5759
0
      if (c1 == EOF) {
5760
0
  n = 1;
5761
0
  t = c0 << 24;
5762
0
      } else if (c2 == EOF) {
5763
0
  n = 2;
5764
0
  t = (c0 << 24) | (c1 << 16);
5765
0
      } else {
5766
0
  n = 3;
5767
0
  t = (c0 << 24) | (c1 << 16) | (c2 << 8);
5768
0
      }
5769
0
      for (i = 4; i >= 0; --i) {
5770
0
  buf1[i] = (char)(t % 85 + 0x21);
5771
0
  t /= 85;
5772
0
      }
5773
0
      for (i = 0; i <= n; ++i) {
5774
0
  *bufEnd++ = buf1[i];
5775
0
  if (++lineLen == 65) {
5776
0
    *bufEnd++ = '\n';
5777
0
    lineLen = 0;
5778
0
  }
5779
0
      }
5780
0
    }
5781
0
    *bufEnd++ = '~';
5782
0
    *bufEnd++ = '>';
5783
0
    eof = gTrue;
5784
0
  } else {
5785
0
    t = (c0 << 24) | (c1 << 16) | (c2 << 8) | c3;
5786
0
    if (t == 0) {
5787
0
      *bufEnd++ = 'z';
5788
0
      if (++lineLen == 65) {
5789
0
  *bufEnd++ = '\n';
5790
0
  lineLen = 0;
5791
0
      }
5792
0
    } else {
5793
0
      for (i = 4; i >= 0; --i) {
5794
0
  buf1[i] = (char)(t % 85 + 0x21);
5795
0
  t /= 85;
5796
0
      }
5797
0
      for (i = 0; i <= 4; ++i) {
5798
0
  *bufEnd++ = buf1[i];
5799
0
  if (++lineLen == 65) {
5800
0
    *bufEnd++ = '\n';
5801
0
    lineLen = 0;
5802
0
  }
5803
0
      }
5804
0
    }
5805
0
  }
5806
0
  return gTrue;
5807
0
}
5808
5809
//------------------------------------------------------------------------
5810
// RunLengthEncoder
5811
//------------------------------------------------------------------------
5812
5813
RunLengthEncoder::RunLengthEncoder(Stream *strA):
5814
0
    FilterStream(strA) {
5815
0
  bufPtr = bufEnd = nextEnd = buf;
5816
0
  eof = gFalse;
5817
0
}
5818
5819
0
RunLengthEncoder::~RunLengthEncoder() {
5820
0
  if (str->isEncoder())
5821
0
    delete str;
5822
0
}
5823
5824
0
Stream *RunLengthEncoder::copy() {
5825
0
  error(errInternal, -1, "Called copy() on RunLengthEncoder");
5826
0
  return NULL;
5827
0
}
5828
5829
0
void RunLengthEncoder::reset() {
5830
0
  str->reset();
5831
0
  bufPtr = bufEnd = nextEnd = buf;
5832
0
  eof = gFalse;
5833
0
}
5834
5835
//
5836
// When fillBuf finishes, buf[] looks like this:
5837
//   +-----+--------------+-----------------+--
5838
//   + tag | ... data ... | next 0, 1, or 2 |
5839
//   +-----+--------------+-----------------+--
5840
//    ^                    ^                 ^
5841
//    bufPtr               bufEnd            nextEnd
5842
//
5843
0
GBool RunLengthEncoder::fillBuf() {
5844
0
  int c, c1, c2;
5845
0
  int n;
5846
5847
  // already hit EOF?
5848
0
  if (eof)
5849
0
    return gFalse;
5850
5851
  // grab two bytes
5852
0
  if (nextEnd < bufEnd + 1) {
5853
0
    if ((c1 = str->getChar()) == EOF) {
5854
0
      eof = gTrue;
5855
0
      return gFalse;
5856
0
    }
5857
0
  } else {
5858
0
    c1 = bufEnd[0] & 0xff;
5859
0
  }
5860
0
  if (nextEnd < bufEnd + 2) {
5861
0
    if ((c2 = str->getChar()) == EOF) {
5862
0
      eof = gTrue;
5863
0
      buf[0] = 0;
5864
0
      buf[1] = (char)c1;
5865
0
      bufPtr = buf;
5866
0
      bufEnd = &buf[2];
5867
0
      return gTrue;
5868
0
    }
5869
0
  } else {
5870
0
    c2 = bufEnd[1] & 0xff;
5871
0
  }
5872
5873
  // check for repeat
5874
0
  c = 0; // make gcc happy
5875
0
  if (c1 == c2) {
5876
0
    n = 2;
5877
0
    while (n < 128 && (c = str->getChar()) == c1)
5878
0
      ++n;
5879
0
    buf[0] = (char)(257 - n);
5880
0
    buf[1] = (char)c1;
5881
0
    bufEnd = &buf[2];
5882
0
    if (c == EOF) {
5883
0
      eof = gTrue;
5884
0
    } else if (n < 128) {
5885
0
      buf[2] = (char)c;
5886
0
      nextEnd = &buf[3];
5887
0
    } else {
5888
0
      nextEnd = bufEnd;
5889
0
    }
5890
5891
  // get up to 128 chars
5892
0
  } else {
5893
0
    buf[1] = (char)c1;
5894
0
    buf[2] = (char)c2;
5895
0
    n = 2;
5896
0
    while (n < 128) {
5897
0
      if ((c = str->getChar()) == EOF) {
5898
0
  eof = gTrue;
5899
0
  break;
5900
0
      }
5901
0
      ++n;
5902
0
      buf[n] = (char)c;
5903
0
      if (buf[n] == buf[n-1])
5904
0
  break;
5905
0
    }
5906
0
    if (buf[n] == buf[n-1]) {
5907
0
      buf[0] = (char)(n-2-1);
5908
0
      bufEnd = &buf[n-1];
5909
0
      nextEnd = &buf[n+1];
5910
0
    } else {
5911
0
      buf[0] = (char)(n-1);
5912
0
      bufEnd = nextEnd = &buf[n+1];
5913
0
    }
5914
0
  }
5915
0
  bufPtr = buf;
5916
0
  return gTrue;
5917
0
}
5918
5919
//------------------------------------------------------------------------
5920
// LZWEncoder
5921
//------------------------------------------------------------------------
5922
5923
LZWEncoder::LZWEncoder(Stream *strA):
5924
0
  FilterStream(strA)
5925
0
{
5926
0
  inBufStart = 0;
5927
0
  inBufLen = 0;
5928
0
  outBufLen = 0;
5929
0
}
5930
5931
0
LZWEncoder::~LZWEncoder() {
5932
0
  if (str->isEncoder()) {
5933
0
    delete str;
5934
0
  }
5935
0
}
5936
5937
0
Stream *LZWEncoder::copy() {
5938
0
  error(errInternal, -1, "Called copy() on LZWEncoder");
5939
0
  return NULL;
5940
0
}
5941
5942
0
void LZWEncoder::reset() {
5943
0
  int i;
5944
5945
0
  str->reset();
5946
5947
  // initialize code table
5948
0
  for (i = 0; i < 256; ++i) {
5949
0
    table[i].byte = i;
5950
0
    table[i].next = NULL;
5951
0
    table[i].children = NULL;
5952
0
  }
5953
0
  nextSeq = 258;
5954
0
  codeLen = 9;
5955
5956
  // initialize input buffer
5957
0
  inBufLen = str->getBlock((char *)inBuf, sizeof(inBuf));
5958
0
  inBufStart = 0;
5959
5960
  // initialize output buffer with a clear-table code
5961
0
  outBuf = 256;
5962
0
  outBufLen = 9;
5963
0
  needEOD = gFalse;
5964
0
}
5965
5966
0
int LZWEncoder::getChar() {
5967
0
  int ret;
5968
5969
0
  if (inBufLen == 0 && !needEOD && outBufLen == 0) {
5970
0
    return EOF;
5971
0
  }
5972
0
  if (outBufLen < 8 && (inBufLen > 0 || needEOD)) {
5973
0
    fillBuf();
5974
0
  }
5975
0
  if (outBufLen >= 8) {
5976
0
    ret = (outBuf >> (outBufLen - 8)) & 0xff;
5977
0
    outBufLen -= 8;
5978
0
  } else {
5979
0
    ret = (outBuf << (8 - outBufLen)) & 0xff;
5980
0
    outBufLen = 0;
5981
0
  }
5982
0
  return ret;
5983
0
}
5984
5985
0
int LZWEncoder::lookChar() {
5986
0
  if (inBufLen == 0 && !needEOD && outBufLen == 0) {
5987
0
    return EOF;
5988
0
  }
5989
0
  if (outBufLen < 8 && (inBufLen > 0 || needEOD)) {
5990
0
    fillBuf();
5991
0
  }
5992
0
  if (outBufLen >= 8) {
5993
0
    return (outBuf >> (outBufLen - 8)) & 0xff;
5994
0
  } else {
5995
0
    return (outBuf << (8 - outBufLen)) & 0xff;
5996
0
  }
5997
0
}
5998
5999
// On input, outBufLen < 8.
6000
// This function generates, at most, 2 12-bit codes
6001
//   --> outBufLen < 8 + 12 + 12 = 32
6002
0
void LZWEncoder::fillBuf() {
6003
0
  LZWEncoderNode *p0, *p1;
6004
0
  int seqLen, code, i;
6005
6006
0
  if (needEOD) {
6007
0
    outBuf = (outBuf << codeLen) | 257;
6008
0
    outBufLen += codeLen;
6009
0
    needEOD = gFalse;
6010
0
    return;
6011
0
  }
6012
6013
  // find longest matching sequence (if any)
6014
0
  p0 = table + inBuf[inBufStart];
6015
0
  seqLen = 1;
6016
0
  while (inBufLen > seqLen) {
6017
0
    for (p1 = p0->children; p1; p1 = p1->next) {
6018
0
      if (p1->byte == inBuf[inBufStart + seqLen]) {
6019
0
  break;
6020
0
      }
6021
0
    }
6022
0
    if (!p1) {
6023
0
      break;
6024
0
    }
6025
0
    p0 = p1;
6026
0
    ++seqLen;
6027
0
  }
6028
0
  code = (int)(p0 - table);
6029
6030
  // generate an output code
6031
0
  outBuf = (outBuf << codeLen) | code;
6032
0
  outBufLen += codeLen;
6033
6034
  // update the table
6035
0
  table[nextSeq].byte = seqLen < inBufLen ? inBuf[inBufStart + seqLen] : 0;
6036
0
  table[nextSeq].children = NULL;
6037
0
  if (table[code].children) {
6038
0
    table[nextSeq].next = table[code].children;
6039
0
  } else {
6040
0
    table[nextSeq].next = NULL;
6041
0
  }
6042
0
  table[code].children = table + nextSeq;
6043
0
  ++nextSeq;
6044
6045
  // update the input buffer
6046
0
  inBufStart += seqLen;
6047
0
  inBufLen -= seqLen;
6048
0
  if (inBufStart >= 4096 && inBufStart + inBufLen == sizeof(inBuf)) {
6049
0
    memcpy(inBuf, inBuf + inBufStart, inBufLen);
6050
0
    inBufStart = 0;
6051
0
    inBufLen += str->getBlock((char *)inBuf + inBufLen,
6052
0
            (int)sizeof(inBuf) - inBufLen);
6053
0
  }
6054
6055
  // increment codeLen; generate clear-table code
6056
0
  if (nextSeq == (1 << codeLen)) {
6057
0
    ++codeLen;
6058
0
    if (codeLen == 13) {
6059
0
      outBuf = (outBuf << 12) | 256;
6060
0
      outBufLen += 12;
6061
0
      for (i = 0; i < 256; ++i) {
6062
0
  table[i].next = NULL;
6063
0
  table[i].children = NULL;
6064
0
      }
6065
0
      nextSeq = 258;
6066
0
      codeLen = 9;
6067
0
    }
6068
0
  }
6069
6070
  // generate EOD next time
6071
0
  if (inBufLen == 0) {
6072
0
    needEOD = gTrue;
6073
0
  }
6074
0
}