Coverage Report

Created: 2026-08-13 06:56

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