Coverage Report

Created: 2026-08-31 06:45

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
250M
#define decompressionBombSizeThreshold 50000000
56
0
#define decompressionBombRatioThreshold 200
57
58
//------------------------------------------------------------------------
59
// Stream (base class)
60
//------------------------------------------------------------------------
61
62
3.45M
Stream::Stream() {
63
3.45M
}
64
65
3.45M
Stream::~Stream() {
66
3.45M
}
67
68
59.5k
void Stream::close() {
69
59.5k
}
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
26.4k
int Stream::getBlock(char *buf, int size) {
77
26.4k
  int n, c;
78
79
26.4k
  n = 0;
80
13.4M
  while (n < size) {
81
13.4M
    if ((c = getChar()) == EOF) {
82
7.66k
      break;
83
7.66k
    }
84
13.4M
    buf[n++] = (char)c;
85
13.4M
  }
86
26.4k
  return n;
87
26.4k
}
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
63.7k
Guint Stream::discardChars(Guint n) {
111
63.7k
  char buf[4096];
112
63.7k
  Guint count, i, j;
113
114
63.7k
  count = 0;
115
112k
  while (count < n) {
116
62.2k
    if ((i = n - count) > sizeof(buf)) {
117
14.6k
      i = (Guint)sizeof(buf);
118
14.6k
    }
119
62.2k
    j = (Guint)getBlock(buf, (int)i);
120
62.2k
    count += j;
121
62.2k
    if (j != i) {
122
13.0k
      break;
123
13.0k
    }
124
62.2k
  }
125
63.7k
  return count;
126
63.7k
}
127
128
GString *Stream::getPSFilter(int psLevel, const char *indent,
129
0
           GBool okToReadStream) {
130
0
  return new GString();
131
0
}
132
133
192k
Stream *Stream::addFilters(Object *dict, int recursion) {
134
192k
  Object obj, obj2;
135
192k
  Object params, params2;
136
192k
  Stream *str;
137
192k
  GBool ok;
138
192k
  int i;
139
140
192k
  str = this;
141
192k
  dict->dictLookup("Filter", &obj, recursion);
142
192k
  if (obj.isNull()) {
143
73.3k
    obj.free();
144
73.3k
    dict->dictLookup("F", &obj, recursion);
145
73.3k
  }
146
192k
  dict->dictLookup("DecodeParms", &params, recursion);
147
192k
  if (params.isNull()) {
148
182k
    params.free();
149
182k
    dict->dictLookup("DP", &params, recursion);
150
182k
  }
151
192k
  ok = gTrue;
152
192k
  if (obj.isName()) {
153
105k
    str = makeFilter(obj.getName(), str, &params, recursion, &ok);
154
105k
  } else if (obj.isArray()) {
155
39.0k
    for (i = 0; ok && i < obj.arrayGetLength(); ++i) {
156
20.9k
      obj.arrayGet(i, &obj2, recursion);
157
20.9k
      if (params.isArray() && i < params.arrayGetLength()) {
158
1.10k
  params.arrayGet(i, &params2, recursion);
159
19.8k
      } else {
160
19.8k
  params2.initNull();
161
19.8k
      }
162
20.9k
      if (obj2.isName()) {
163
20.7k
  str = makeFilter(obj2.getName(), str, &params2, recursion, &ok);
164
20.7k
      } else {
165
160
  error(errSyntaxError, getPos(), "Bad filter name");
166
160
  str = new EOFStream(str);
167
160
  ok = gFalse;
168
160
      }
169
20.9k
      obj2.free();
170
20.9k
      params2.free();
171
20.9k
    }
172
68.7k
  } else if (!obj.isNull()) {
173
4.30k
    error(errSyntaxError, getPos(), "Bad 'Filter' attribute in stream");
174
4.30k
  }
175
192k
  obj.free();
176
192k
  params.free();
177
178
192k
  return str;
179
192k
}
180
181
Stream *Stream::makeFilter(char *name, Stream *str, Object *params,
182
125k
         int recursion, GBool *ok) {
183
125k
  int pred;     // parameters
184
125k
  int colors;
185
125k
  int bits;
186
125k
  int early;
187
125k
  int encoding;
188
125k
  GBool endOfLine, byteAlign, endOfBlock, black;
189
125k
  int columns, rows;
190
125k
  int colorXform;
191
125k
  Object globals, obj;
192
193
125k
  if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) {
194
863
    str = new ASCIIHexStream(str);
195
125k
  } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) {
196
877
    str = new ASCII85Stream(str);
197
124k
  } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) {
198
824
    pred = 1;
199
824
    columns = 1;
200
824
    colors = 1;
201
824
    bits = 8;
202
824
    early = 1;
203
824
    if (params->isDict()) {
204
45
      params->dictLookup("Predictor", &obj, recursion);
205
45
      if (obj.isInt())
206
34
  pred = obj.getInt();
207
45
      obj.free();
208
45
      params->dictLookup("Columns", &obj, recursion);
209
45
      if (obj.isInt())
210
1
  columns = obj.getInt();
211
45
      obj.free();
212
45
      params->dictLookup("Colors", &obj, recursion);
213
45
      if (obj.isInt())
214
0
  colors = obj.getInt();
215
45
      obj.free();
216
45
      params->dictLookup("BitsPerComponent", &obj, recursion);
217
45
      if (obj.isInt())
218
1
  bits = obj.getInt();
219
45
      obj.free();
220
45
      params->dictLookup("EarlyChange", &obj, recursion);
221
45
      if (obj.isInt())
222
0
  early = obj.getInt();
223
45
      obj.free();
224
45
    }
225
824
    str = new LZWStream(str, pred, columns, colors, bits, early);
226
123k
  } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) {
227
983
    str = new RunLengthStream(str);
228
122k
  } else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) {
229
1.96k
    encoding = 0;
230
1.96k
    endOfLine = gFalse;
231
1.96k
    byteAlign = gFalse;
232
1.96k
    columns = 1728;
233
1.96k
    rows = 0;
234
1.96k
    endOfBlock = gTrue;
235
1.96k
    black = gFalse;
236
1.96k
    if (params->isDict()) {
237
1.21k
      params->dictLookup("K", &obj, recursion);
238
1.21k
      if (obj.isInt()) {
239
351
  encoding = obj.getInt();
240
351
      }
241
1.21k
      obj.free();
242
1.21k
      params->dictLookup("EndOfLine", &obj, recursion);
243
1.21k
      if (obj.isBool()) {
244
0
  endOfLine = obj.getBool();
245
0
      }
246
1.21k
      obj.free();
247
1.21k
      params->dictLookup("EncodedByteAlign", &obj, recursion);
248
1.21k
      if (obj.isBool()) {
249
0
  byteAlign = obj.getBool();
250
0
      }
251
1.21k
      obj.free();
252
1.21k
      params->dictLookup("Columns", &obj, recursion);
253
1.21k
      if (obj.isInt()) {
254
297
  columns = obj.getInt();
255
297
      }
256
1.21k
      obj.free();
257
1.21k
      params->dictLookup("Rows", &obj, recursion);
258
1.21k
      if (obj.isInt()) {
259
95
  rows = obj.getInt();
260
95
      }
261
1.21k
      obj.free();
262
1.21k
      params->dictLookup("EndOfBlock", &obj, recursion);
263
1.21k
      if (obj.isBool()) {
264
96
  endOfBlock = obj.getBool();
265
96
      }
266
1.21k
      obj.free();
267
1.21k
      params->dictLookup("BlackIs1", &obj, recursion);
268
1.21k
      if (obj.isBool()) {
269
14
  black = obj.getBool();
270
14
      }
271
1.21k
      obj.free();
272
1.21k
    }
273
1.96k
    str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign,
274
1.96k
           columns, rows, endOfBlock, black);
275
120k
  } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) {
276
5.62k
    colorXform = -1;
277
5.62k
    if (params->isDict()) {
278
105
      if (params->dictLookup("ColorTransform", &obj, recursion)->isInt()) {
279
0
  colorXform = obj.getInt();
280
0
      }
281
105
      obj.free();
282
105
    }
283
5.62k
    str = new DCTStream(str, colorXform);
284
114k
  } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) {
285
103k
    pred = 1;
286
103k
    columns = 1;
287
103k
    colors = 1;
288
103k
    bits = 8;
289
103k
    if (params->isDict()) {
290
6.83k
      params->dictLookup("Predictor", &obj, recursion);
291
6.83k
      if (obj.isInt())
292
5.46k
  pred = obj.getInt();
293
6.83k
      obj.free();
294
6.83k
      params->dictLookup("Columns", &obj, recursion);
295
6.83k
      if (obj.isInt())
296
5.91k
  columns = obj.getInt();
297
6.83k
      obj.free();
298
6.83k
      params->dictLookup("Colors", &obj, recursion);
299
6.83k
      if (obj.isInt())
300
2.35k
  colors = obj.getInt();
301
6.83k
      obj.free();
302
6.83k
      params->dictLookup("BitsPerComponent", &obj, recursion);
303
6.83k
      if (obj.isInt())
304
3.97k
  bits = obj.getInt();
305
6.83k
      obj.free();
306
6.83k
    }
307
103k
    str = new FlateStream(str, pred, columns, colors, bits);
308
103k
  } else if (!strcmp(name, "JBIG2Decode")) {
309
1.95k
    if (params->isDict()) {
310
61
      params->dictLookup("JBIG2Globals", &globals, recursion);
311
61
    }
312
1.95k
    str = new JBIG2Stream(str, &globals);
313
1.95k
    globals.free();
314
9.56k
  } else if (!strcmp(name, "JPXDecode")) {
315
3.44k
    str = new JPXStream(str);
316
6.12k
  } else if (!strcmp(name, "Crypt")) {
317
    // this is handled in Parser::makeStream()
318
6.12k
  } else {
319
6.12k
    error(errSyntaxError, getPos(), "Unknown filter '{0:s}'", name);
320
6.12k
    str = new EOFStream(str);
321
6.12k
    *ok = gFalse;
322
6.12k
  }
323
125k
  return str;
324
125k
}
325
326
//------------------------------------------------------------------------
327
// BaseStream
328
//------------------------------------------------------------------------
329
330
2.42M
BaseStream::BaseStream(Object *dictA) {
331
2.42M
  dict = *dictA;
332
2.42M
}
333
334
2.42M
BaseStream::~BaseStream() {
335
2.42M
  dict.free();
336
2.42M
}
337
338
//------------------------------------------------------------------------
339
// FilterStream
340
//------------------------------------------------------------------------
341
342
1.03M
FilterStream::FilterStream(Stream *strA) {
343
1.03M
  str = strA;
344
1.03M
}
345
346
FilterStream::~FilterStream() {
347
}
348
349
630k
void FilterStream::close() {
350
630k
  str->close();
351
630k
}
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
30.2k
ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) {
362
30.2k
  int imgLineSize;
363
364
30.2k
  str = strA;
365
30.2k
  width = widthA;
366
30.2k
  nComps = nCompsA;
367
30.2k
  nBits = nBitsA;
368
369
30.2k
  nVals = width * nComps;
370
30.2k
  inputLineSize = (nVals * nBits + 7) >> 3;
371
30.2k
  if (width > INT_MAX / nComps ||
372
30.2k
      nVals > (INT_MAX - 7) / nBits) {
373
    // force a call to gmallocn(-1,...), which will throw an exception
374
2
    inputLineSize = -1;
375
2
  }
376
30.2k
  inputLine = (char *)gmallocn(inputLineSize, sizeof(char));
377
30.2k
  if (nBits == 8) {
378
12.1k
    imgLine = (Guchar *)inputLine;
379
18.1k
  } else {
380
18.1k
    if (nBits == 1) {
381
16.9k
      imgLineSize = (nVals + 7) & ~7;
382
16.9k
    } else {
383
1.19k
      imgLineSize = nVals;
384
1.19k
    }
385
18.1k
    imgLine = (Guchar *)gmallocn(imgLineSize, sizeof(Guchar));
386
18.1k
  }
387
30.2k
  imgIdx = nVals;
388
30.2k
}
389
390
30.2k
ImageStream::~ImageStream() {
391
30.2k
  if (imgLine != (Guchar *)inputLine) {
392
18.1k
    gfree(imgLine);
393
18.1k
  }
394
30.2k
  gfree(inputLine);
395
30.2k
}
396
397
30.2k
void ImageStream::reset() {
398
30.2k
  str->disableDecompressionBombChecking();
399
30.2k
  str->reset();
400
30.2k
}
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
2.62M
Guchar *ImageStream::getLine() {
422
2.62M
  Gulong buf, bitMask;
423
2.62M
  int bits;
424
2.62M
  int c;
425
2.62M
  int i;
426
2.62M
  char *p;
427
428
2.62M
  if (str->getBlock(inputLine, inputLineSize) != inputLineSize) {
429
1.97M
    return NULL;
430
1.97M
  }
431
649k
  if (nBits == 1) {
432
493k
    p = inputLine;
433
2.28M
    for (i = 0; i < nVals; i += 8) {
434
1.79M
      c = *p++;
435
1.79M
      imgLine[i+0] = (Guchar)((c >> 7) & 1);
436
1.79M
      imgLine[i+1] = (Guchar)((c >> 6) & 1);
437
1.79M
      imgLine[i+2] = (Guchar)((c >> 5) & 1);
438
1.79M
      imgLine[i+3] = (Guchar)((c >> 4) & 1);
439
1.79M
      imgLine[i+4] = (Guchar)((c >> 3) & 1);
440
1.79M
      imgLine[i+5] = (Guchar)((c >> 2) & 1);
441
1.79M
      imgLine[i+6] = (Guchar)((c >> 1) & 1);
442
1.79M
      imgLine[i+7] = (Guchar)(c & 1);
443
1.79M
    }
444
493k
  } else if (nBits == 8) {
445
    // special case: imgLine == inputLine
446
142k
  } else if (nBits == 16) {
447
16.4k
    for (i = 0; i < nVals; ++i) {
448
16.3k
      imgLine[i] = (Guchar)inputLine[2*i];
449
16.3k
    }
450
14.0k
  } else {
451
14.0k
    bitMask = (1 << nBits) - 1;
452
14.0k
    buf = 0;
453
14.0k
    bits = 0;
454
14.0k
    p = inputLine;
455
391k
    for (i = 0; i < nVals; ++i) {
456
377k
      if (bits < nBits) {
457
116k
  buf = (buf << 8) | (*p++ & 0xff);
458
116k
  bits += 8;
459
116k
      }
460
377k
      imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask);
461
377k
      bits -= nBits;
462
377k
    }
463
14.0k
  }
464
649k
  return imgLine;
465
2.62M
}
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
10.9k
         int widthA, int nCompsA, int nBitsA) {
478
10.9k
  str = strA;
479
10.9k
  predictor = predictorA;
480
10.9k
  width = widthA;
481
10.9k
  nComps = nCompsA;
482
10.9k
  nBits = nBitsA;
483
10.9k
  predLine = NULL;
484
10.9k
  ok = gFalse;
485
486
10.9k
  nVals = width * nComps;
487
10.9k
  pixBytes = (nComps * nBits + 7) >> 3;
488
10.9k
  rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes;
489
10.9k
  if (width <= 0 || nComps <= 0 || nBits <= 0 ||
490
10.8k
      nComps > gfxColorMaxComps ||
491
10.8k
      nBits > 16 ||
492
8.72k
      width >= INT_MAX / nComps ||      // check for overflow in nVals 
493
8.71k
      nVals >= (INT_MAX - 7) / nBits) { // check for overflow in rowBytes
494
2.29k
    return;
495
2.29k
  }
496
8.65k
  predLine = (Guchar *)gmalloc(rowBytes);
497
498
8.65k
  reset();
499
500
8.65k
  ok = gTrue;
501
8.65k
}
502
503
10.9k
StreamPredictor::~StreamPredictor() {
504
10.9k
  gfree(predLine);
505
10.9k
}
506
507
10.3k
void StreamPredictor::reset() {
508
10.3k
  memset(predLine, 0, rowBytes);
509
10.3k
  predIdx = rowBytes;
510
10.3k
}
511
512
4.48M
int StreamPredictor::lookChar() {
513
4.48M
  if (predIdx >= rowBytes) {
514
2.86k
    if (!getNextLine()) {
515
246
      return EOF;
516
246
    }
517
2.86k
  }
518
4.48M
  return predLine[predIdx];
519
4.48M
}
520
521
4.58M
int StreamPredictor::getChar() {
522
4.58M
  if (predIdx >= rowBytes) {
523
20.3k
    if (!getNextLine()) {
524
304
      return EOF;
525
304
    }
526
20.3k
  }
527
4.58M
  return predLine[predIdx++];
528
4.58M
}
529
530
39.4k
int StreamPredictor::getBlock(char *blk, int size) {
531
39.4k
  int n, m;
532
533
39.4k
  n = 0;
534
157k
  while (n < size) {
535
128k
    if (predIdx >= rowBytes) {
536
123k
      if (!getNextLine()) {
537
11.1k
  break;
538
11.1k
      }
539
123k
    }
540
117k
    m = rowBytes - predIdx;
541
117k
    if (m > size - n) {
542
5.50k
      m = size - n;
543
5.50k
    }
544
117k
    memcpy(blk + n, predLine + predIdx, m);
545
117k
    predIdx += m;
546
117k
    n += m;
547
117k
  }
548
39.4k
  return n;
549
39.4k
}
550
551
146k
GBool StreamPredictor::getNextLine() {
552
146k
  int curPred;
553
146k
  Guchar upLeftBuf[gfxColorMaxComps * 2 + 1];
554
146k
  int left, up, upLeft, p, pa, pb, pc;
555
146k
  int c;
556
146k
  Gulong inBuf, outBuf, bitMask;
557
146k
  int inBits, outBits;
558
146k
  int i, j, k, kk;
559
560
  // get PNG optimum predictor number
561
146k
  if (predictor >= 10) {
562
145k
    if ((curPred = str->getRawChar()) == EOF) {
563
11.5k
      return gFalse;
564
11.5k
    }
565
134k
    curPred += 10;
566
134k
  } else {
567
1.12k
    curPred = predictor;
568
1.12k
  }
569
570
  // read the raw line, apply PNG (byte) predictor
571
135k
  memset(upLeftBuf, 0, pixBytes + 1);
572
2.59M
  for (i = pixBytes; i < rowBytes; ++i) {
573
4.96M
    for (j = pixBytes; j > 0; --j) {
574
2.50M
      upLeftBuf[j] = upLeftBuf[j-1];
575
2.50M
    }
576
2.46M
    upLeftBuf[0] = predLine[i];
577
2.46M
    if ((c = str->getRawChar()) == EOF) {
578
274
      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
135
  break;
583
135
      }
584
139
      return gFalse;
585
274
    }
586
2.45M
    switch (curPred) {
587
8.07k
    case 11:      // PNG sub
588
8.07k
      predLine[i] = (Guchar)(predLine[i - pixBytes] + c);
589
8.07k
      break;
590
12.6k
    case 12:      // PNG up
591
12.6k
      predLine[i] = (Guchar)(predLine[i] + c);
592
12.6k
      break;
593
1.83k
    case 13:      // PNG average
594
1.83k
      predLine[i] = (Guchar)(((predLine[i - pixBytes] + predLine[i]) >> 1) + c);
595
1.83k
      break;
596
11.0k
    case 14:      // PNG Paeth
597
11.0k
      left = predLine[i - pixBytes];
598
11.0k
      up = predLine[i];
599
11.0k
      upLeft = upLeftBuf[pixBytes];
600
11.0k
      p = left + up - upLeft;
601
11.0k
      if ((pa = p - left) < 0)
602
4.76k
  pa = -pa;
603
11.0k
      if ((pb = p - up) < 0)
604
2.85k
  pb = -pb;
605
11.0k
      if ((pc = p - upLeft) < 0)
606
3.56k
  pc = -pc;
607
11.0k
      if (pa <= pb && pa <= pc)
608
5.11k
  predLine[i] = (Guchar)(left + c);
609
5.90k
      else if (pb <= pc)
610
5.15k
  predLine[i] = (Guchar)(up + c);
611
753
      else
612
753
  predLine[i] = (Guchar)(upLeft + c);
613
11.0k
      break;
614
1.69M
    case 10:      // PNG none
615
2.42M
    default:      // no predictor or TIFF predictor
616
2.42M
      predLine[i] = (Guchar)c;
617
2.42M
      break;
618
2.45M
    }
619
2.45M
  }
620
621
  // apply TIFF (component) predictor
622
134k
  if (predictor == 2) {
623
1.01k
    if (nBits == 8) {
624
1.09k
      for (i = pixBytes; i < rowBytes; ++i) {
625
873
  predLine[i] = (Guchar)(predLine[i] + predLine[i - nComps]);
626
873
      }
627
798
    } else if (nBits == 16) {
628
80
      for (i = pixBytes; i < rowBytes; i += 2) {
629
40
  c = ((predLine[i] + predLine[i - 2*nComps]) << 8) +
630
40
      predLine[i + 1] + predLine[i + 1 - 2*nComps];
631
40
  predLine[i] = (Guchar)(c >> 8);
632
40
  predLine[i+1] = (Guchar)(c & 0xff);
633
40
      }
634
758
    } else {
635
758
      memset(upLeftBuf, 0, nComps);
636
758
      bitMask = (1 << nBits) - 1;
637
758
      inBuf = outBuf = 0;
638
758
      inBits = outBits = 0;
639
758
      j = k = pixBytes;
640
17.8M
      for (i = 0; i < width; ++i) {
641
35.7M
  for (kk = 0; kk < nComps; ++kk) {
642
17.8M
    if (inBits < nBits) {
643
4.46M
      inBuf = (inBuf << 8) | (predLine[j++] & 0xff);
644
4.46M
      inBits += 8;
645
4.46M
    }
646
17.8M
    upLeftBuf[kk] = (Guchar)((upLeftBuf[kk] +
647
17.8M
            (inBuf >> (inBits - nBits))) & bitMask);
648
17.8M
    inBits -= nBits;
649
17.8M
    outBuf = (outBuf << nBits) | upLeftBuf[kk];
650
17.8M
    outBits += nBits;
651
17.8M
    if (outBits >= 8) {
652
4.46M
      predLine[k++] = (Guchar)(outBuf >> (outBits - 8));
653
4.46M
      outBits -= 8;
654
4.46M
    }
655
17.8M
  }
656
17.8M
      }
657
758
      if (outBits > 0) {
658
279
  predLine[k++] = (Guchar)((outBuf << (8 - outBits)) +
659
279
         (inBuf & ((1 << (8 - outBits)) - 1)));
660
279
      }
661
758
    }
662
1.01k
  }
663
664
  // reset to start of line
665
134k
  predIdx = pixBytes;
666
667
134k
  return gTrue;
668
135k
}
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
2.31M
    BaseStream(dictA) {
879
2.31M
  buf = bufA;
880
2.31M
  start = startA;
881
2.31M
  length = lengthA;
882
2.31M
  bufEnd = buf + start + length;
883
2.31M
  bufPtr = buf + start;
884
2.31M
  needFree = gFalse;
885
2.31M
}
886
887
2.31M
MemStream::~MemStream() {
888
2.31M
  if (needFree) {
889
0
    gfree(buf);
890
0
  }
891
2.31M
}
892
893
1.77M
Stream *MemStream::copy() {
894
1.77M
  Object dictA;
895
896
1.77M
  dict.copy(&dictA);
897
1.77M
  return new MemStream(buf, start, length, &dictA);
898
1.77M
}
899
900
Stream *MemStream::makeSubStream(GFileOffset startA, GBool limited,
901
511k
         GFileOffset lengthA, Object *dictA) {
902
511k
  MemStream *subStr;
903
511k
  Guint newStart, newLength;
904
905
511k
  if (startA < start) {
906
0
    newStart = start;
907
511k
  } else if (startA > start + length) {
908
101
    newStart = start + (int)length;
909
511k
  } else {
910
511k
    newStart = (int)startA;
911
511k
  }
912
511k
  if (!limited || newStart + lengthA > start + length) {
913
360k
    newLength = start + length - newStart;
914
360k
  } else {
915
150k
    newLength = (Guint)lengthA;
916
150k
  }
917
511k
  subStr = new MemStream(buf, newStart, newLength, dictA);
918
511k
  return subStr;
919
511k
}
920
921
711k
void MemStream::reset() {
922
711k
  bufPtr = buf + start;
923
711k
}
924
925
949k
void MemStream::close() {
926
949k
}
927
928
927k
int MemStream::getBlock(char *blk, int size) {
929
927k
  int n;
930
931
927k
  if (size <= 0) {
932
974
    return 0;
933
974
  }
934
926k
  if (bufEnd - bufPtr < size) {
935
206k
    n = (int)(bufEnd - bufPtr);
936
719k
  } else {
937
719k
    n = size;
938
719k
  }
939
926k
  memcpy(blk, bufPtr, n);
940
926k
  bufPtr += n;
941
926k
  return n;
942
927k
}
943
944
174k
void MemStream::setPos(GFileOffset pos, int dir) {
945
174k
  Guint i;
946
947
174k
  if (dir >= 0) {
948
154k
    i = (Guint)pos;
949
154k
  } else {
950
19.9k
    if (pos > start + length) {
951
2.11k
      i = 0;
952
17.8k
    } else {
953
17.8k
      i = (Guint)(start + length - pos);
954
17.8k
    }
955
19.9k
  }
956
174k
  if (i < start) {
957
82
    i = start;
958
174k
  } else if (i > start + length) {
959
7.54k
    i = start + length;
960
7.54k
  }
961
174k
  bufPtr = buf + i;
962
174k
}
963
964
12.8k
void MemStream::moveStart(int delta) {
965
12.8k
  start += delta;
966
12.8k
  length -= delta;
967
12.8k
  bufPtr = buf + start;
968
12.8k
}
969
970
//------------------------------------------------------------------------
971
// EmbedStream
972
//------------------------------------------------------------------------
973
974
EmbedStream::EmbedStream(Stream *strA, Object *dictA,
975
       GBool limitedA, GFileOffset lengthA):
976
105k
    BaseStream(dictA) {
977
105k
  str = strA;
978
105k
  limited = limitedA;
979
105k
  length = lengthA;
980
105k
}
981
982
EmbedStream::~EmbedStream() {
983
}
984
985
35.5k
Stream *EmbedStream::copy() {
986
35.5k
  Object dictA;
987
988
35.5k
  dict.copy(&dictA);
989
35.5k
  return new EmbedStream(str, &dictA, limited, length);
990
35.5k
}
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.93M
int EmbedStream::getChar() {
999
6.93M
  if (limited && !length) {
1000
91.3k
    return EOF;
1001
91.3k
  }
1002
6.84M
  --length;
1003
6.84M
  return str->getChar();
1004
6.93M
}
1005
1006
3.68M
int EmbedStream::lookChar() {
1007
3.68M
  if (limited && !length) {
1008
1.99k
    return EOF;
1009
1.99k
  }
1010
3.68M
  return str->lookChar();
1011
3.68M
}
1012
1013
2.42M
int EmbedStream::getBlock(char *blk, int size) {
1014
2.42M
  if (size <= 0) {
1015
0
    return 0;
1016
0
  }
1017
2.42M
  if (limited && length < (Guint)size) {
1018
1.33k
    size = (int)length;
1019
1.33k
  }
1020
2.42M
  length -= size;
1021
2.42M
  return str->getBlock(blk, size);
1022
2.42M
}
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
7.24k
    FilterStream(strA) {
1043
7.24k
  buf = EOF;
1044
7.24k
  eof = gFalse;
1045
7.24k
}
1046
1047
7.24k
ASCIIHexStream::~ASCIIHexStream() {
1048
7.24k
  delete str;
1049
7.24k
}
1050
1051
6.37k
Stream *ASCIIHexStream::copy() {
1052
6.37k
  return new ASCIIHexStream(str->copy());
1053
6.37k
}
1054
1055
913
void ASCIIHexStream::reset() {
1056
913
  str->reset();
1057
913
  buf = EOF;
1058
913
  eof = gFalse;
1059
913
}
1060
1061
77.7k
int ASCIIHexStream::lookChar() {
1062
77.7k
  int c1, c2, x;
1063
1064
77.7k
  if (buf != EOF)
1065
2.45k
    return buf;
1066
75.3k
  if (eof) {
1067
706
    buf = EOF;
1068
706
    return EOF;
1069
706
  }
1070
84.6k
  do {
1071
84.6k
    c1 = str->getChar();
1072
84.6k
  } while (isspace(c1));
1073
74.5k
  if (c1 == '>') {
1074
248
    eof = gTrue;
1075
248
    buf = EOF;
1076
248
    return buf;
1077
248
  }
1078
81.0k
  do {
1079
81.0k
    c2 = str->getChar();
1080
81.0k
  } while (isspace(c2));
1081
74.3k
  if (c2 == '>') {
1082
337
    eof = gTrue;
1083
337
    c2 = '0';
1084
337
  }
1085
74.3k
  if (c1 >= '0' && c1 <= '9') {
1086
30.2k
    x = (c1 - '0') << 4;
1087
44.0k
  } else if (c1 >= 'A' && c1 <= 'F') {
1088
1.46k
    x = (c1 - 'A' + 10) << 4;
1089
42.5k
  } else if (c1 >= 'a' && c1 <= 'f') {
1090
23.5k
    x = (c1 - 'a' + 10) << 4;
1091
23.5k
  } else if (c1 == EOF) {
1092
74
    eof = gTrue;
1093
74
    x = 0;
1094
18.9k
  } else {
1095
18.9k
    error(errSyntaxError, getPos(),
1096
18.9k
    "Illegal character <{0:02x}> in ASCIIHex stream", c1);
1097
18.9k
    x = 0;
1098
18.9k
  }
1099
74.3k
  if (c2 >= '0' && c2 <= '9') {
1100
29.7k
    x += c2 - '0';
1101
44.6k
  } else if (c2 >= 'A' && c2 <= 'F') {
1102
1.93k
    x += c2 - 'A' + 10;
1103
42.6k
  } else if (c2 >= 'a' && c2 <= 'f') {
1104
22.3k
    x += c2 - 'a' + 10;
1105
22.3k
  } else if (c2 == EOF) {
1106
135
    eof = gTrue;
1107
135
    x = 0;
1108
20.2k
  } else {
1109
20.2k
    error(errSyntaxError, getPos(),
1110
20.2k
    "Illegal character <{0:02x}> in ASCIIHex stream", c2);
1111
20.2k
  }
1112
74.3k
  buf = x & 0xff;
1113
74.3k
  return buf;
1114
74.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
3.21k
    FilterStream(strA) {
1140
3.21k
  index = n = 0;
1141
3.21k
  eof = gFalse;
1142
3.21k
}
1143
1144
3.20k
ASCII85Stream::~ASCII85Stream() {
1145
3.20k
  delete str;
1146
3.20k
}
1147
1148
2.33k
Stream *ASCII85Stream::copy() {
1149
2.33k
  return new ASCII85Stream(str->copy());
1150
2.33k
}
1151
1152
534
void ASCII85Stream::reset() {
1153
534
  str->reset();
1154
534
  index = n = 0;
1155
534
  eof = gFalse;
1156
534
}
1157
1158
370k
int ASCII85Stream::lookChar() {
1159
370k
  int k;
1160
370k
  Gulong t;
1161
1162
370k
  if (index >= n) {
1163
92.1k
    if (eof)
1164
18.2k
      return EOF;
1165
73.8k
    index = 0;
1166
80.8k
    do {
1167
80.8k
      c[0] = str->getChar();
1168
80.8k
    } while (Lexer::isSpace(c[0]));
1169
73.8k
    if (c[0] == '~' || c[0] == EOF) {
1170
220
      eof = gTrue;
1171
220
      n = 0;
1172
220
      return EOF;
1173
73.6k
    } else if (c[0] == 'z') {
1174
229
      b[0] = b[1] = b[2] = b[3] = 0;
1175
229
      n = 4;
1176
73.4k
    } else {
1177
366k
      for (k = 1; k < 5; ++k) {
1178
319k
  do {
1179
319k
    c[k] = str->getChar();
1180
319k
  } while (Lexer::isSpace(c[k]));
1181
293k
  if (c[k] == '~' || c[k] == EOF)
1182
268
    break;
1183
293k
      }
1184
73.4k
      n = k - 1;
1185
73.4k
      if (k < 5 && (c[k] == '~' || c[k] == EOF)) {
1186
963
  for (++k; k < 5; ++k)
1187
695
    c[k] = 0x21 + 84;
1188
268
  eof = gTrue;
1189
268
      }
1190
73.4k
      t = 0;
1191
440k
      for (k = 0; k < 5; ++k)
1192
367k
  t = t * 85 + (c[k] - 0x21);
1193
367k
      for (k = 3; k >= 0; --k) {
1194
293k
  b[k] = (int)(t & 0xff);
1195
293k
  t >>= 8;
1196
293k
      }
1197
73.4k
    }
1198
73.8k
  }
1199
352k
  return b[index];
1200
370k
}
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
14.1k
    FilterStream(strA) {
1227
14.1k
  if (predictor != 1) {
1228
630
    pred = new StreamPredictor(this, predictor, columns, colors, bits);
1229
630
    if (!pred->isOk()) {
1230
0
      delete pred;
1231
0
      pred = NULL;
1232
0
    }
1233
13.5k
  } else {
1234
13.5k
    pred = NULL;
1235
13.5k
  }
1236
14.1k
  early = earlyA;
1237
14.1k
  eof = gFalse;
1238
14.1k
  inputBits = 0;
1239
14.1k
  clearTable();
1240
14.1k
  checkForDecompressionBombs = gTrue;
1241
14.1k
}
1242
1243
14.1k
LZWStream::~LZWStream() {
1244
14.1k
  if (pred) {
1245
630
    delete pred;
1246
630
  }
1247
14.1k
  delete str;
1248
14.1k
}
1249
1250
13.3k
Stream *LZWStream::copy() {
1251
13.3k
  if (pred) {
1252
597
    return new LZWStream(str->copy(), pred->getPredictor(),
1253
597
       pred->getWidth(), pred->getNComps(),
1254
597
       pred->getNBits(), early);
1255
12.7k
  } else {
1256
12.7k
    return new LZWStream(str->copy(), 1, 0, 0, 0, early);
1257
12.7k
  }
1258
13.3k
}
1259
1260
804
void LZWStream::disableDecompressionBombChecking() {
1261
804
  checkForDecompressionBombs = gFalse;
1262
804
  FilterStream::disableDecompressionBombChecking();
1263
804
}
1264
1265
1.69M
int LZWStream::getChar() {
1266
1.69M
  if (pred) {
1267
607
    return pred->getChar();
1268
607
  }
1269
1.69M
  if (eof) {
1270
1.37k
    return EOF;
1271
1.37k
  }
1272
1.69M
  if (seqIndex >= seqLength) {
1273
1.66M
    if (!processNextCode()) {
1274
3.95k
      return EOF;
1275
3.95k
    }
1276
1.66M
  }
1277
1.69M
  return seqBuf[seqIndex++];
1278
1.69M
}
1279
1280
1.79k
int LZWStream::lookChar() {
1281
1.79k
  if (pred) {
1282
267
    return pred->lookChar();
1283
267
  }
1284
1.52k
  if (eof) {
1285
22
    return EOF;
1286
22
  }
1287
1.50k
  if (seqIndex >= seqLength) {
1288
1.25k
    if (!processNextCode()) {
1289
73
      return EOF;
1290
73
    }
1291
1.25k
  }
1292
1.42k
  return seqBuf[seqIndex];
1293
1.50k
}
1294
1295
1.21k
int LZWStream::getRawChar() {
1296
1.21k
  if (eof) {
1297
208
    return EOF;
1298
208
  }
1299
1.00k
  if (seqIndex >= seqLength) {
1300
987
    if (!processNextCode()) {
1301
207
      return EOF;
1302
207
    }
1303
987
  }
1304
797
  return seqBuf[seqIndex++];
1305
1.00k
}
1306
1307
9.61k
int LZWStream::getBlock(char *blk, int size) {
1308
9.61k
  int n, m;
1309
1310
9.61k
  if (pred) {
1311
25
    return pred->getBlock(blk, size);
1312
25
  }
1313
9.59k
  if (eof) {
1314
9.18k
    return 0;
1315
9.18k
  }
1316
403
  n = 0;
1317
1.50k
  while (n < size) {
1318
1.48k
    if (seqIndex >= seqLength) {
1319
1.47k
      if (!processNextCode()) {
1320
380
  break;
1321
380
      }
1322
1.47k
    }
1323
1.10k
    m = seqLength - seqIndex;
1324
1.10k
    if (m > size - n) {
1325
0
      m = size - n;
1326
0
    }
1327
1.10k
    memcpy(blk + n, seqBuf + seqIndex, m);
1328
1.10k
    seqIndex += m;
1329
1.10k
    n += m;
1330
1.10k
  }
1331
403
  return n;
1332
9.59k
}
1333
1334
4.69k
void LZWStream::reset() {
1335
4.69k
  str->reset();
1336
4.69k
  if (pred) {
1337
207
    pred->reset();
1338
207
  }
1339
4.69k
  eof = gFalse;
1340
4.69k
  inputBits = 0;
1341
4.69k
  clearTable();
1342
4.69k
  totalIn = totalOut = 0;
1343
4.69k
}
1344
1345
1.66M
GBool LZWStream::processNextCode() {
1346
1.66M
  int code;
1347
1.66M
  int nextLength;
1348
1.66M
  int i, j;
1349
1350
  // check for EOF
1351
1.66M
  if (eof) {
1352
0
    return gFalse;
1353
0
  }
1354
1355
  // check for eod and clear-table codes
1356
1.66M
 start:
1357
1.66M
  code = getCode();
1358
1.66M
  if (code == EOF || code == 257) {
1359
3.28k
    eof = gTrue;
1360
3.28k
    return gFalse;
1361
3.28k
  }
1362
1.66M
  if (code == 256) {
1363
513
    clearTable();
1364
513
    goto start;
1365
513
  }
1366
1.66M
  if (nextCode >= 4097) {
1367
337
    error(errSyntaxError, getPos(),
1368
337
    "Bad LZW stream - expected clear-table code");
1369
337
    clearTable();
1370
337
  }
1371
1372
  // process the next code
1373
1.66M
  nextLength = seqLength + 1;
1374
1.66M
  if (code < 256) {
1375
1.63M
    seqBuf[0] = (Guchar)code;
1376
1.63M
    seqLength = 1;
1377
1.63M
  } else if (code < nextCode) {
1378
29.7k
    seqLength = table[code].length;
1379
60.6k
    for (i = seqLength - 1, j = code; i > 0; --i) {
1380
30.8k
      seqBuf[i] = table[j].tail;
1381
30.8k
      j = table[j].head;
1382
30.8k
    }
1383
29.7k
    seqBuf[0] = (Guchar)j;
1384
29.7k
  } else if (code == nextCode) {
1385
29
    seqBuf[seqLength] = (Guchar)newChar;
1386
29
    ++seqLength;
1387
1.33k
  } else {
1388
1.33k
    error(errSyntaxError, getPos(), "Bad LZW stream - unexpected code");
1389
1.33k
    eof = gTrue;
1390
1.33k
    return gFalse;
1391
1.33k
  }
1392
1.66M
  newChar = seqBuf[0];
1393
1.66M
  if (first) {
1394
1.96k
    first = gFalse;
1395
1.65M
  } else {
1396
1.65M
    table[nextCode].length = nextLength;
1397
1.65M
    table[nextCode].head = prevCode;
1398
1.65M
    table[nextCode].tail = (Guchar)newChar;
1399
1.65M
    ++nextCode;
1400
1.65M
    if (nextCode + early == 512)
1401
484
      nextBits = 10;
1402
1.65M
    else if (nextCode + early == 1024)
1403
461
      nextBits = 11;
1404
1.65M
    else if (nextCode + early == 2048)
1405
461
      nextBits = 12;
1406
1.65M
  }
1407
1.66M
  prevCode = code;
1408
1.66M
  totalOut += seqLength;
1409
1410
  // check for a 'decompression bomb'
1411
1.66M
  if (checkForDecompressionBombs &&
1412
1.66M
      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
1.66M
  seqIndex = 0;
1421
1422
1.66M
  return gTrue;
1423
1.66M
}
1424
1425
19.6k
void LZWStream::clearTable() {
1426
19.6k
  nextCode = 258;
1427
19.6k
  nextBits = 9;
1428
19.6k
  seqIndex = seqLength = 0;
1429
19.6k
  first = gTrue;
1430
19.6k
}
1431
1432
1.66M
int LZWStream::getCode() {
1433
1.66M
  int c;
1434
1.66M
  int code;
1435
1436
3.98M
  while (inputBits < nextBits) {
1437
2.32M
    if ((c = str->getChar()) == EOF)
1438
3.24k
      return EOF;
1439
2.32M
    inputBuf = (inputBuf << 8) | (c & 0xff);
1440
2.32M
    inputBits += 8;
1441
2.32M
    ++totalIn;
1442
2.32M
  }
1443
1.66M
  code = (inputBuf >> (inputBits - nextBits)) & ((1 << nextBits) - 1);
1444
1.66M
  inputBits -= nextBits;
1445
1.66M
  return code;
1446
1.66M
}
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
44.7k
    FilterStream(strA) {
1476
44.7k
  bufPtr = bufEnd = buf;
1477
44.7k
  eof = gFalse;
1478
44.7k
}
1479
1480
44.7k
RunLengthStream::~RunLengthStream() {
1481
44.7k
  delete str;
1482
44.7k
}
1483
1484
43.7k
Stream *RunLengthStream::copy() {
1485
43.7k
  return new RunLengthStream(str->copy());
1486
43.7k
}
1487
1488
14.5k
void RunLengthStream::reset() {
1489
14.5k
  str->reset();
1490
14.5k
  bufPtr = bufEnd = buf;
1491
14.5k
  eof = gFalse;
1492
14.5k
}
1493
1494
6.19k
int RunLengthStream::getBlock(char *blk, int size) {
1495
6.19k
  int n, m;
1496
1497
6.19k
  n = 0;
1498
935k
  while (n < size) {
1499
929k
    if (bufPtr >= bufEnd) {
1500
923k
      if (!fillBuf()) {
1501
451
  break;
1502
451
      }
1503
923k
    }
1504
929k
    m = (int)(bufEnd - bufPtr);
1505
929k
    if (m > size - n) {
1506
5.57k
      m = size - n;
1507
5.57k
    }
1508
929k
    memcpy(blk + n, bufPtr, m);
1509
929k
    bufPtr += m;
1510
929k
    n += m;
1511
929k
  }
1512
6.19k
  return n;
1513
6.19k
}
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.40M
GBool RunLengthStream::fillBuf() {
1534
1.40M
  int c;
1535
1.40M
  int n, i;
1536
1537
1.40M
  if (eof)
1538
159k
    return gFalse;
1539
1.24M
  c = str->getChar();
1540
1.24M
  if (c == 0x80 || c == EOF) {
1541
10.3k
    eof = gTrue;
1542
10.3k
    return gFalse;
1543
10.3k
  }
1544
1.23M
  if (c < 0x80) {
1545
299k
    n = c + 1;
1546
16.4M
    for (i = 0; i < n; ++i)
1547
16.1M
      buf[i] = (char)str->getChar();
1548
939k
  } else {
1549
939k
    n = 0x101 - c;
1550
939k
    c = str->getChar();
1551
7.42M
    for (i = 0; i < n; ++i)
1552
6.48M
      buf[i] = (char)c;
1553
939k
  }
1554
1.23M
  bufPtr = buf;
1555
1.23M
  bufEnd = buf + n;
1556
1.23M
  return gTrue;
1557
1.24M
}
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
8.46k
    FilterStream(strA) {
1567
8.46k
  encoding = encodingA;
1568
8.46k
  endOfLine = endOfLineA;
1569
8.46k
  byteAlign = byteAlignA;
1570
8.46k
  columns = columnsA;
1571
8.46k
  if (columns < 1) {
1572
17
    columns = 1;
1573
8.44k
  } else if (columns > INT_MAX - 3) {
1574
0
    columns = INT_MAX - 3;
1575
0
  }
1576
8.46k
  rows = rowsA;
1577
8.46k
  endOfBlock = endOfBlockA;
1578
8.46k
  black = blackA;
1579
8.46k
  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
8.46k
  codingLine = (int *)gmallocn(columns + 1, sizeof(int));
1585
8.46k
  refLine = (int *)gmallocn(columns + 3, sizeof(int));
1586
1587
8.46k
  eof = gFalse;
1588
8.46k
  row = 0;
1589
8.46k
  nextLine2D = encoding < 0;
1590
8.46k
  inputBits = 0;
1591
8.46k
  codingLine[0] = columns;
1592
8.46k
  nextCol = columns;
1593
8.46k
  a0i = 0;
1594
8.46k
  err = gFalse;
1595
8.46k
  nErrors = 0;
1596
8.46k
}
1597
1598
8.46k
CCITTFaxStream::~CCITTFaxStream() {
1599
8.46k
  delete str;
1600
8.46k
  gfree(refLine);
1601
8.46k
  gfree(codingLine);
1602
8.46k
}
1603
1604
6.50k
Stream *CCITTFaxStream::copy() {
1605
6.50k
  return new CCITTFaxStream(str->copy(), encoding, endOfLine,
1606
6.50k
          byteAlign, columns, rows, endOfBlock, black);
1607
6.50k
}
1608
1609
2.33k
void CCITTFaxStream::reset() {
1610
2.33k
  int code1;
1611
1612
2.33k
  str->reset();
1613
2.33k
  eof = gFalse;
1614
2.33k
  row = 0;
1615
2.33k
  nextLine2D = encoding < 0;
1616
2.33k
  inputBits = 0;
1617
2.33k
  codingLine[0] = columns;
1618
2.33k
  nextCol = columns;
1619
2.33k
  a0i = 0;
1620
1621
  // skip any initial zero bits and end-of-line marker, and get the 2D
1622
  // encoding tag
1623
16.3k
  while ((code1 = lookBits(12)) == 0) {
1624
14.0k
    eatBits(1);
1625
14.0k
  }
1626
2.33k
  if (code1 == 0x001) {
1627
390
    eatBits(12);
1628
390
    endOfLine = gTrue;
1629
390
  }
1630
2.33k
  if (encoding > 0) {
1631
876
    nextLine2D = !lookBits(1);
1632
876
    eatBits(1);
1633
876
  }
1634
2.33k
}
1635
1636
42.2M
int CCITTFaxStream::getChar() {
1637
42.2M
  int c, bitsNeeded, bitsAvail, bitsUsed;
1638
1639
42.2M
  if (nextCol >= columns) {
1640
43.4k
    if (eof) {
1641
1.34k
      return EOF;
1642
1.34k
    }
1643
42.0k
    if (!readRow()) {
1644
127
      return EOF;
1645
127
    }
1646
42.0k
  }
1647
42.2M
  bitsAvail = codingLine[a0i] - nextCol;
1648
42.2M
  if (bitsAvail > 8) {
1649
40.4M
    c = (a0i & 1) ? 0x00 : 0xff;
1650
40.4M
  } else {
1651
1.79M
    c = 0;
1652
1.79M
    bitsNeeded = 8;
1653
6.82M
    do {
1654
6.82M
      bitsUsed = (bitsAvail < bitsNeeded) ? bitsAvail : bitsNeeded;
1655
6.82M
      c <<= bitsUsed;
1656
6.82M
      if (!(a0i & 1)) {
1657
3.67M
  c |= 0xff >> (8 - bitsUsed);
1658
3.67M
      }
1659
6.82M
      bitsAvail -= bitsUsed;
1660
6.82M
      bitsNeeded -= bitsUsed;
1661
6.82M
      if (bitsAvail == 0) {
1662
5.95M
  if (codingLine[a0i] >= columns) {
1663
234k
    c <<= bitsNeeded;
1664
234k
    break;
1665
234k
  }
1666
5.72M
  ++a0i;
1667
5.72M
  bitsAvail = codingLine[a0i] - codingLine[a0i - 1];
1668
5.72M
      }
1669
6.82M
    } while (bitsNeeded > 0);
1670
1.79M
  }
1671
42.2M
  nextCol += 8;
1672
42.2M
  c ^= blackXOR;
1673
42.2M
  return c;
1674
42.2M
}
1675
1676
34.2M
int CCITTFaxStream::lookChar() {
1677
34.2M
  int c, bitsNeeded, bitsAvail, bitsUsed, i;
1678
1679
34.2M
  if (nextCol >= columns) {
1680
194k
    if (eof) {
1681
838
      return EOF;
1682
838
    }
1683
193k
    if (!readRow()) {
1684
338
      return EOF;
1685
338
    }
1686
193k
  }
1687
34.2M
  bitsAvail = codingLine[a0i] - nextCol;
1688
34.2M
  if (bitsAvail >= 8) {
1689
32.8M
    c = (a0i & 1) ? 0x00 : 0xff;
1690
32.8M
  } else {
1691
1.35M
    i = a0i;
1692
1.35M
    c = 0;
1693
1.35M
    bitsNeeded = 8;
1694
5.96M
    do {
1695
5.96M
      bitsUsed = (bitsAvail < bitsNeeded) ? bitsAvail : bitsNeeded;
1696
5.96M
      c <<= bitsUsed;
1697
5.96M
      if (!(i & 1)) {
1698
3.14M
  c |= 0xff >> (8 - bitsUsed);
1699
3.14M
      }
1700
5.96M
      bitsAvail -= bitsUsed;
1701
5.96M
      bitsNeeded -= bitsUsed;
1702
5.96M
      if (bitsAvail == 0) {
1703
5.28M
  if (codingLine[i] >= columns) {
1704
83.2k
    c <<= bitsNeeded;
1705
83.2k
    break;
1706
83.2k
  }
1707
5.20M
  ++i;
1708
5.20M
  bitsAvail = codingLine[i] - codingLine[i - 1];
1709
5.20M
      }
1710
5.96M
    } while (bitsNeeded > 0);
1711
1.35M
  }
1712
34.2M
  c ^= blackXOR;
1713
34.2M
  return c;
1714
34.2M
}
1715
1716
35.7k
int CCITTFaxStream::getBlock(char *blk, int size) {
1717
35.7k
  int bytesRead, bitsAvail, bitsNeeded, bitsUsed, byte, c;
1718
1719
35.7k
  bytesRead = 0;
1720
307k
  while (bytesRead < size) {
1721
272k
    if (nextCol >= columns) {
1722
13.0k
      if (eof) {
1723
905
  break;
1724
905
      }
1725
12.1k
      if (!readRow()) {
1726
18
  break;
1727
18
      }
1728
12.1k
    }
1729
271k
    bitsAvail = codingLine[a0i] - nextCol;
1730
271k
    byte = (a0i & 1) ? 0x00 : 0xff;
1731
271k
    if (bitsAvail > 8) {
1732
191k
      c = byte;
1733
191k
      bitsAvail -= 8;
1734
191k
    } else {
1735
80.1k
      c = 0;
1736
80.1k
      bitsNeeded = 8;
1737
285k
      do {
1738
285k
  bitsUsed = (bitsAvail < bitsNeeded) ? bitsAvail : bitsNeeded;
1739
285k
  c <<= bitsUsed;
1740
285k
  c |= byte >> (8 - bitsUsed);
1741
285k
  bitsAvail -= bitsUsed;
1742
285k
  bitsNeeded -= bitsUsed;
1743
285k
  if (bitsAvail == 0) {
1744
243k
    if (codingLine[a0i] >= columns) {
1745
11.9k
      c <<= bitsNeeded;
1746
11.9k
      break;
1747
11.9k
    }
1748
231k
    ++a0i;
1749
231k
    bitsAvail = codingLine[a0i] - codingLine[a0i - 1];
1750
231k
    byte ^= 0xff;
1751
231k
  }
1752
285k
      } while (bitsNeeded > 0);
1753
80.1k
    }
1754
271k
    nextCol += 8;
1755
271k
    blk[bytesRead++] = (char)(c ^ blackXOR);
1756
271k
  }
1757
35.7k
  return bytesRead;
1758
35.7k
}
1759
1760
6.41M
inline void CCITTFaxStream::addPixels(int a1, int blackPixels) {
1761
6.41M
  if (a1 > codingLine[a0i]) {
1762
6.39M
    if (a1 > columns) {
1763
151k
      error(errSyntaxError, getPos(),
1764
151k
      "CCITTFax row is wrong length ({0:d})", a1);
1765
151k
      err = gTrue;
1766
151k
      ++nErrors;
1767
151k
      a1 = columns;
1768
151k
    }
1769
6.39M
    if ((a0i & 1) ^ blackPixels) {
1770
6.12M
      ++a0i;
1771
6.12M
    }
1772
6.39M
    codingLine[a0i] = a1;
1773
6.39M
  }
1774
6.41M
}
1775
1776
40.2k
inline void CCITTFaxStream::addPixelsNeg(int a1, int blackPixels) {
1777
40.2k
  if (a1 > codingLine[a0i]) {
1778
30.8k
    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
30.8k
    if ((a0i & 1) ^ blackPixels) {
1786
22.4k
      ++a0i;
1787
22.4k
    }
1788
30.8k
    codingLine[a0i] = a1;
1789
30.8k
  } else if (a1 < codingLine[a0i]) {
1790
1.89k
    if (a1 < 0) {
1791
1.61k
      error(errSyntaxError, getPos(), "Invalid CCITTFax code");
1792
1.61k
      err = gTrue;
1793
1.61k
      ++nErrors;
1794
1.61k
      a1 = 0;
1795
1.61k
    }
1796
1.92k
    while (a0i > 0 && a1 <= codingLine[a0i - 1]) {
1797
27
      --a0i;
1798
27
    }
1799
1.89k
    codingLine[a0i] = a1;
1800
1.89k
  }
1801
40.2k
}
1802
1803
248k
GBool CCITTFaxStream::readRow() {
1804
248k
  int code1, code2, code3;
1805
248k
  int b1i, blackPixels, i;
1806
248k
  GBool gotEOL;
1807
1808
  // if at eof just return EOF
1809
248k
  if (eof) {
1810
0
    return gFalse;
1811
0
  }
1812
1813
248k
  err = gFalse;
1814
1815
  // 2-D encoding
1816
248k
  if (nextLine2D) {
1817
699k
    for (i = 0; codingLine[i] < columns; ++i) {
1818
578k
      refLine[i] = codingLine[i];
1819
578k
    }
1820
121k
    refLine[i++] = columns;
1821
121k
    refLine[i++] = columns;
1822
121k
    refLine[i] = columns;
1823
121k
    codingLine[0] = 0;
1824
121k
    a0i = 0;
1825
121k
    b1i = 0;
1826
121k
    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
492k
    while (codingLine[a0i] < columns) {
1835
370k
      code1 = getTwoDimCode();
1836
370k
      switch (code1) {
1837
20.3k
      case twoDimPass:
1838
20.3k
  addPixels(refLine[b1i + 1], blackPixels);
1839
20.3k
  if (refLine[b1i + 1] < columns) {
1840
11.9k
    b1i += 2;
1841
11.9k
  }
1842
20.3k
  break;
1843
44.0k
      case twoDimHoriz:
1844
44.0k
  code1 = code2 = 0;
1845
44.0k
  if (blackPixels) {
1846
27.3k
    do {
1847
27.3k
      code1 += code3 = getBlackCode();
1848
27.3k
    } while (code3 >= 64);
1849
35.7k
    do {
1850
35.7k
      code2 += code3 = getWhiteCode();
1851
35.7k
    } while (code3 >= 64);
1852
26.9k
  } else {
1853
20.2k
    do {
1854
20.2k
      code1 += code3 = getWhiteCode();
1855
20.2k
    } while (code3 >= 64);
1856
17.5k
    do {
1857
17.5k
      code2 += code3 = getBlackCode();
1858
17.5k
    } while (code3 >= 64);
1859
17.0k
  }
1860
44.0k
  addPixels(codingLine[a0i] + code1, blackPixels);
1861
44.0k
  if (codingLine[a0i] < columns) {
1862
38.6k
    addPixels(codingLine[a0i] + code2, blackPixels ^ 1);
1863
38.6k
  }
1864
129k
  while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1865
85.2k
    b1i += 2;
1866
85.2k
  }
1867
44.0k
  break;
1868
10.2k
      case twoDimVertR3:
1869
10.2k
  addPixels(refLine[b1i] + 3, blackPixels);
1870
10.2k
  blackPixels ^= 1;
1871
10.2k
  if (codingLine[a0i] < columns) {
1872
2.22k
    ++b1i;
1873
3.09k
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1874
868
      b1i += 2;
1875
868
    }
1876
2.22k
  }
1877
10.2k
  break;
1878
5.06k
      case twoDimVertR2:
1879
5.06k
  addPixels(refLine[b1i] + 2, blackPixels);
1880
5.06k
  blackPixels ^= 1;
1881
5.06k
  if (codingLine[a0i] < columns) {
1882
2.51k
    ++b1i;
1883
3.09k
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1884
582
      b1i += 2;
1885
582
    }
1886
2.51k
  }
1887
5.06k
  break;
1888
39.6k
      case twoDimVertR1:
1889
39.6k
  addPixels(refLine[b1i] + 1, blackPixels);
1890
39.6k
  blackPixels ^= 1;
1891
39.6k
  if (codingLine[a0i] < columns) {
1892
28.5k
    ++b1i;
1893
31.6k
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1894
3.09k
      b1i += 2;
1895
3.09k
    }
1896
28.5k
  }
1897
39.6k
  break;
1898
178k
      case twoDimVert0:
1899
178k
  addPixels(refLine[b1i], blackPixels);
1900
178k
  blackPixels ^= 1;
1901
178k
  if (codingLine[a0i] < columns) {
1902
126k
    ++b1i;
1903
126k
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1904
0
      b1i += 2;
1905
0
    }
1906
126k
  }
1907
178k
  break;
1908
4.99k
      case twoDimVertL3:
1909
4.99k
  addPixelsNeg(refLine[b1i] - 3, blackPixels);
1910
4.99k
  blackPixels ^= 1;
1911
4.99k
  if (codingLine[a0i] < columns) {
1912
4.99k
    if (b1i > 0) {
1913
1.46k
      --b1i;
1914
3.53k
    } else {
1915
3.53k
      ++b1i;
1916
3.53k
    }
1917
5.94k
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1918
949
      b1i += 2;
1919
949
    }
1920
4.99k
  }
1921
4.99k
  break;
1922
5.86k
      case twoDimVertL2:
1923
5.86k
  addPixelsNeg(refLine[b1i] - 2, blackPixels);
1924
5.86k
  blackPixels ^= 1;
1925
5.86k
  if (codingLine[a0i] < columns) {
1926
5.86k
    if (b1i > 0) {
1927
4.99k
      --b1i;
1928
4.99k
    } else {
1929
869
      ++b1i;
1930
869
    }
1931
10.2k
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1932
4.39k
      b1i += 2;
1933
4.39k
    }
1934
5.86k
  }
1935
5.86k
  break;
1936
29.3k
      case twoDimVertL1:
1937
29.3k
  addPixelsNeg(refLine[b1i] - 1, blackPixels);
1938
29.3k
  blackPixels ^= 1;
1939
29.3k
  if (codingLine[a0i] < columns) {
1940
29.3k
    if (b1i > 0) {
1941
20.6k
      --b1i;
1942
20.6k
    } else {
1943
8.74k
      ++b1i;
1944
8.74k
    }
1945
48.7k
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1946
19.3k
      b1i += 2;
1947
19.3k
    }
1948
29.3k
  }
1949
29.3k
  break;
1950
32.9k
      case EOF:
1951
32.9k
  addPixels(columns, 0);
1952
32.9k
  err = gTrue;
1953
32.9k
  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
370k
      }
1962
370k
    }
1963
1964
  // 1-D encoding
1965
126k
  } else {
1966
126k
    codingLine[0] = 0;
1967
126k
    a0i = 0;
1968
126k
    blackPixels = 0;
1969
6.17M
    while (codingLine[a0i] < columns) {
1970
6.04M
      code1 = 0;
1971
6.04M
      if (blackPixels) {
1972
2.97M
  do {
1973
2.97M
    code1 += code3 = getBlackCode();
1974
2.97M
  } while (code3 >= 64);
1975
3.08M
      } else {
1976
3.37M
  do {
1977
3.37M
    code1 += code3 = getWhiteCode();
1978
3.37M
  } while (code3 >= 64);
1979
3.08M
      }
1980
6.04M
      addPixels(codingLine[a0i] + code1, blackPixels);
1981
6.04M
      blackPixels ^= 1;
1982
6.04M
    }
1983
126k
  }
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
248k
  gotEOL = gFalse;
1992
248k
  if (!endOfBlock && row == rows - 1) {
1993
1
    eof = gTrue;
1994
248k
  } else if (endOfLine || !byteAlign) {
1995
248k
    code1 = lookBits(12);
1996
248k
    if (endOfLine) {
1997
2.46M
      while (code1 != EOF && code1 != 0x001) {
1998
2.45M
  eatBits(1);
1999
2.45M
  code1 = lookBits(12);
2000
2.45M
      }
2001
242k
    } else {
2002
644k
      while (code1 == 0) {
2003
401k
  eatBits(1);
2004
401k
  code1 = lookBits(12);
2005
401k
      }
2006
242k
    }
2007
248k
    if (code1 == 0x001) {
2008
11.9k
      eatBits(12);
2009
11.9k
      gotEOL = gTrue;
2010
11.9k
    }
2011
248k
  }
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
248k
  if (byteAlign && !gotEOL) {
2022
0
    inputBits &= ~7;
2023
0
  }
2024
2025
  // check for end of stream
2026
248k
  if (lookBits(1) == EOF) {
2027
1.14k
    eof = gTrue;
2028
1.14k
  }
2029
2030
  // get 2D encoding tag
2031
248k
  if (!eof && encoding > 0) {
2032
145k
    nextLine2D = !lookBits(1);
2033
145k
    eatBits(1);
2034
145k
  }
2035
2036
  // check for end-of-block marker
2037
248k
  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
248k
  if (endOfBlock && gotEOL) {
2047
6.45k
    code1 = lookBits(12);
2048
6.45k
    if (code1 == 0x001) {
2049
141
      eatBits(12);
2050
141
      if (encoding > 0) {
2051
123
  lookBits(1);
2052
123
  eatBits(1);
2053
123
      }
2054
141
      if (encoding > 0) {
2055
615
  for (i = 0; i < 4; ++i) {
2056
492
    code1 = lookBits(12);
2057
492
    if (code1 != 0x001) {
2058
489
      error(errSyntaxError, getPos(),
2059
489
      "Bad RTC code in CCITTFax stream");
2060
489
      ++nErrors;
2061
489
    }
2062
492
    eatBits(12);
2063
492
    if (encoding > 0) {
2064
492
      lookBits(1);
2065
492
      eatBits(1);
2066
492
    }
2067
492
  }
2068
123
      }
2069
141
      eof = gTrue;
2070
141
    }
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
241k
  } else if (err && endOfLine) {
2076
1.33M
    while (1) {
2077
1.33M
      code1 = lookBits(13);
2078
1.33M
      if (code1 == EOF) {
2079
226
  eof = gTrue;
2080
226
  return gFalse;
2081
226
      }
2082
1.33M
      if ((code1 >> 1) == 0x001) {
2083
3.88k
  break;
2084
3.88k
      }
2085
1.33M
      eatBits(1);
2086
1.33M
    }
2087
3.88k
    eatBits(12); 
2088
3.88k
    if (encoding > 0) {
2089
3.66k
      eatBits(1);
2090
3.66k
      nextLine2D = !(code1 & 1);
2091
3.66k
    }
2092
3.88k
  }
2093
2094
  // corrupt CCITTFax streams can generate huge data expansion -- we
2095
  // avoid that case by aborting decode after 1000 errors
2096
247k
  if (nErrors > 1000) {
2097
257
    error(errSyntaxError, getPos(), "Too many errors in CCITTFaxStream - aborting decode");
2098
257
    eof = gTrue;
2099
257
    return gFalse;
2100
257
  }
2101
2102
  // set up for output
2103
247k
  nextCol = 0;
2104
247k
  a0i = (codingLine[0] > 0) ? 0 : 1;
2105
2106
247k
  ++row;
2107
2108
247k
  return gTrue;
2109
247k
}
2110
2111
370k
short CCITTFaxStream::getTwoDimCode() {
2112
370k
  int code;
2113
370k
  CCITTCode *p;
2114
370k
  int n;
2115
2116
370k
  code = 0; // make gcc happy
2117
370k
  if (endOfBlock) {
2118
280k
    if ((code = lookBits(7)) != EOF) {
2119
280k
      p = &twoDimTab1[code];
2120
280k
      if (p->bits > 0) {
2121
253k
  eatBits(p->bits);
2122
253k
  return p->n;
2123
253k
      }
2124
280k
    }
2125
280k
  } else {
2126
220k
    for (n = 1; n <= 7; ++n) {
2127
215k
      if ((code = lookBits(n)) == EOF) {
2128
47
  break;
2129
47
      }
2130
215k
      if (n < 7) {
2131
207k
  code <<= 7 - n;
2132
207k
      }
2133
215k
      p = &twoDimTab1[code];
2134
215k
      if (p->bits == n) {
2135
84.3k
  eatBits(n);
2136
84.3k
  return p->n;
2137
84.3k
      }
2138
215k
    }
2139
90.0k
  }
2140
32.9k
  error(errSyntaxError, getPos(),
2141
32.9k
  "Bad two dim code ({0:04x}) in CCITTFax stream", code);
2142
32.9k
  ++nErrors;
2143
32.9k
  return EOF;
2144
370k
}
2145
2146
3.42M
short CCITTFaxStream::getWhiteCode() {
2147
3.42M
  short code;
2148
3.42M
  CCITTCode *p;
2149
3.42M
  int n;
2150
2151
3.42M
  code = 0; // make gcc happy
2152
3.42M
  if (endOfBlock) {
2153
3.16M
    code = lookBits(12);
2154
3.16M
    if (code == EOF) {
2155
1.85M
      return 1;
2156
1.85M
    }
2157
1.31M
    if ((code >> 5) == 0) {
2158
226k
      p = &whiteTab1[code];
2159
1.08M
    } else {
2160
1.08M
      p = &whiteTab2[code >> 3];
2161
1.08M
    }
2162
1.31M
    if (p->bits > 0) {
2163
1.09M
      eatBits(p->bits);
2164
1.09M
      return p->n;
2165
1.09M
    }
2166
1.31M
  } else {
2167
1.41M
    for (n = 1; n <= 9; ++n) {
2168
1.35M
      code = lookBits(n);
2169
1.35M
      if (code == EOF) {
2170
64.3k
  return 1;
2171
64.3k
      }
2172
1.29M
      if (n < 9) {
2173
1.23M
  code = (short)(code << (9 - n));
2174
1.23M
      }
2175
1.29M
      p = &whiteTab2[code];
2176
1.29M
      if (p->bits == n) {
2177
141k
  eatBits(n);
2178
141k
  return p->n;
2179
141k
      }
2180
1.29M
    }
2181
161k
    for (n = 11; n <= 12; ++n) {
2182
109k
      code = lookBits(n);
2183
109k
      if (code == EOF) {
2184
0
  return 1;
2185
0
      }
2186
109k
      if (n < 12) {
2187
55.2k
  code = (short)(code << (12 - n));
2188
55.2k
      }
2189
109k
      p = &whiteTab1[code];
2190
109k
      if (p->bits == n) {
2191
4.03k
  eatBits(n);
2192
4.03k
  return p->n;
2193
4.03k
      }
2194
109k
    }
2195
55.2k
  }
2196
266k
  error(errSyntaxError, getPos(),
2197
266k
  "Bad white code ({0:04x}) in CCITTFax stream", code);
2198
266k
  ++nErrors;
2199
  // eat a bit and return a positive number so that the caller doesn't
2200
  // go into an infinite loop
2201
266k
  eatBits(1);
2202
266k
  return 1;
2203
3.42M
}
2204
2205
3.02M
short CCITTFaxStream::getBlackCode() {
2206
3.02M
  short code;
2207
3.02M
  CCITTCode *p;
2208
3.02M
  int n;
2209
2210
3.02M
  code = 0; // make gcc happy
2211
3.02M
  if (endOfBlock) {
2212
2.80M
    code = lookBits(13);
2213
2.80M
    if (code == EOF) {
2214
1.85M
      return 1;
2215
1.85M
    }
2216
946k
    if ((code >> 7) == 0) {
2217
232k
      p = &blackTab1[code];
2218
714k
    } else if ((code >> 9) == 0 && (code >> 7) != 0) {
2219
27.7k
      p = &blackTab2[(code >> 1) - 64];
2220
686k
    } else {
2221
686k
      p = &blackTab3[code >> 7];
2222
686k
    }
2223
946k
    if (p->bits > 0) {
2224
733k
      eatBits(p->bits);
2225
733k
      return p->n;
2226
733k
    }
2227
946k
  } else {
2228
590k
    for (n = 2; n <= 6; ++n) {
2229
528k
      code = lookBits(n);
2230
528k
      if (code == EOF) {
2231
64.3k
  return 1;
2232
64.3k
      }
2233
464k
      if (n < 6) {
2234
400k
  code = (short)(code << (6 - n));
2235
400k
      }
2236
464k
      p = &blackTab3[code];
2237
464k
      if (p->bits == n) {
2238
91.5k
  eatBits(n);
2239
91.5k
  return p->n;
2240
91.5k
      }
2241
464k
    }
2242
406k
    for (n = 7; n <= 12; ++n) {
2243
351k
      code = lookBits(n);
2244
351k
      if (code == EOF) {
2245
0
  return 1;
2246
0
      }
2247
351k
      if (n < 12) {
2248
293k
  code = (short)(code << (12 - n));
2249
293k
      }
2250
351k
      if (code >= 64) {
2251
15.6k
  p = &blackTab2[code - 64];
2252
15.6k
  if (p->bits == n) {
2253
5.91k
    eatBits(n);
2254
5.91k
    return p->n;
2255
5.91k
  }
2256
15.6k
      }
2257
351k
    }
2258
266k
    for (n = 10; n <= 13; ++n) {
2259
217k
      code = lookBits(n);
2260
217k
      if (code == EOF) {
2261
0
  return 1;
2262
0
      }
2263
217k
      if (n < 13) {
2264
166k
  code = (short)(code << (13 - n));
2265
166k
      }
2266
217k
      p = &blackTab1[code];
2267
217k
      if (p->bits == n) {
2268
6.00k
  eatBits(n);
2269
6.00k
  return p->n;
2270
6.00k
      }
2271
217k
    }
2272
55.8k
  }
2273
262k
  error(errSyntaxError, getPos(),
2274
262k
  "Bad black code ({0:04x}) in CCITTFax stream", code);
2275
262k
  ++nErrors;
2276
  // eat a bit and return a positive number so that the caller doesn't
2277
  // go into an infinite loop
2278
262k
  eatBits(1);
2279
262k
  return 1;
2280
3.02M
}
2281
2282
13.8M
short CCITTFaxStream::lookBits(int n) {
2283
13.8M
  int c;
2284
2285
15.8M
  while (inputBits < n) {
2286
5.83M
    if ((c = str->getChar()) == EOF) {
2287
3.85M
      if (inputBits == 0) {
2288
3.84M
  return EOF;
2289
3.84M
      }
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
6.70k
      return (short)((inputBuf << (n - inputBits)) & (0xffffffff >> (32 - n)));
2295
3.85M
    }
2296
1.98M
    inputBuf = (inputBuf << 8) + c;
2297
1.98M
    inputBits += 8;
2298
1.98M
  }
2299
10.0M
  return (short)((inputBuf >> (inputBits - n)) & (0xffffffff >> (32 - n)));
2300
13.8M
}
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
111M
#define dctCrToR   91881  //  1.4020
2596
111M
#define dctCbToG  -22553  // -0.3441363
2597
111M
#define dctCrToG  -46802  // -0.71413636
2598
111M
#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
606M
#define dctClipOffset  384
2618
606M
#define dctClipMask   1023
2619
static Guchar dctClipData[1024];
2620
2621
85.8k
static inline void dctClipInit() {
2622
85.8k
  static int initDone = 0;
2623
85.8k
  int i;
2624
85.8k
  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
85.8k
}
2637
2638
606M
static inline Guchar dctClip(int x) {
2639
606M
  return dctClipData[(dctClipOffset + x) & dctClipMask];
2640
606M
}
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
85.8k
    FilterStream(strA) {
2663
85.8k
  int i;
2664
2665
85.8k
  prepared = gFalse;
2666
85.8k
  colorXform = colorXformA;
2667
85.8k
  progressive = interleaved = gFalse;
2668
85.8k
  width = height = 0;
2669
85.8k
  mcuWidth = mcuHeight = 0;
2670
85.8k
  numComps = 0;
2671
85.8k
  comp = 0;
2672
85.8k
  x = y = 0;
2673
429k
  for (i = 0; i < 4; ++i) {
2674
343k
    frameBuf[i] = NULL;
2675
343k
  }
2676
85.8k
  rowBuf = NULL;
2677
85.8k
  memset(quantTables, 0, sizeof(quantTables));
2678
85.8k
  memset(dcHuffTables, 0, sizeof(dcHuffTables));
2679
85.8k
  memset(acHuffTables, 0, sizeof(acHuffTables));
2680
2681
85.8k
  dctClipInit();
2682
85.8k
}
2683
2684
85.8k
DCTStream::~DCTStream() {
2685
85.8k
  close();
2686
85.8k
  delete str;
2687
85.8k
}
2688
2689
80.2k
Stream *DCTStream::copy() {
2690
80.2k
  return new DCTStream(str->copy(), colorXform);
2691
80.2k
}
2692
2693
25.8k
void DCTStream::reset() {
2694
25.8k
  int i;
2695
2696
25.8k
  str->reset();
2697
2698
25.8k
  progressive = interleaved = gFalse;
2699
25.8k
  width = height = 0;
2700
25.8k
  numComps = 0;
2701
25.8k
  numQuantTables = 0;
2702
25.8k
  numDCHuffTables = 0;
2703
25.8k
  numACHuffTables = 0;
2704
25.8k
  gotJFIFMarker = gFalse;
2705
25.8k
  gotAdobeMarker = gFalse;
2706
25.8k
  restartInterval = 0;
2707
2708
25.8k
  if (!readHeader(gTrue)) {
2709
    // force an EOF condition
2710
18.3k
    progressive = gTrue;
2711
18.3k
    y = height;
2712
18.3k
    prepared = gTrue;
2713
18.3k
    return;
2714
18.3k
  }
2715
2716
  // compute MCU size
2717
7.57k
  if (numComps == 1) {
2718
824
    compInfo[0].hSample = compInfo[0].vSample = 1;
2719
824
  }
2720
7.57k
  mcuWidth = compInfo[0].hSample;
2721
7.57k
  mcuHeight = compInfo[0].vSample;
2722
21.6k
  for (i = 1; i < numComps; ++i) {
2723
14.0k
    if (compInfo[i].hSample > mcuWidth) {
2724
558
      mcuWidth = compInfo[i].hSample;
2725
558
    }
2726
14.0k
    if (compInfo[i].vSample > mcuHeight) {
2727
519
      mcuHeight = compInfo[i].vSample;
2728
519
    }
2729
14.0k
  }
2730
7.57k
  mcuWidth *= 8;
2731
7.57k
  mcuHeight *= 8;
2732
2733
  // figure out color transform
2734
7.57k
  if (colorXform == -1) {
2735
7.49k
    if (numComps == 3) {
2736
6.19k
      if (gotJFIFMarker) {
2737
256
  colorXform = 1;
2738
5.94k
      } else if (compInfo[0].id == 82 && compInfo[1].id == 71 &&
2739
0
     compInfo[2].id == 66) { // ASCII "RGB"
2740
0
  colorXform = 0;
2741
5.94k
      } else {
2742
5.94k
  colorXform = 1;
2743
5.94k
      }
2744
6.19k
    } else {
2745
1.29k
      colorXform = 0;
2746
1.29k
    }
2747
7.49k
  }
2748
2749
7.57k
  prepared = gFalse;
2750
7.57k
}
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
123k
void DCTStream::close() {
2775
123k
  int i;
2776
2777
618k
  for (i = 0; i < 4; ++i) {
2778
494k
    gfree(frameBuf[i]);
2779
494k
    frameBuf[i] = NULL;
2780
494k
  }
2781
123k
  gfree(rowBuf);
2782
123k
  rowBuf = NULL;
2783
123k
  FilterStream::close();
2784
123k
}
2785
2786
89.2M
int DCTStream::getChar() {
2787
89.2M
  int c;
2788
2789
89.2M
  if (!prepared) {
2790
7.31k
    prepare();
2791
7.31k
  }
2792
89.2M
  if (progressive || !interleaved) {
2793
89.2M
    if (y >= height) {
2794
78.3k
      return EOF;
2795
78.3k
    }
2796
89.1M
    c = frameBuf[comp][y * bufWidth + x];
2797
89.1M
    if (++comp == numComps) {
2798
29.7M
      comp = 0;
2799
29.7M
      if (++x == width) {
2800
52.5k
  x = 0;
2801
52.5k
  ++y;
2802
52.5k
      }
2803
29.7M
    }
2804
89.1M
  } else {
2805
52.1k
    if (rowBufPtr == rowBufEnd) {
2806
1.78k
      if (y + mcuHeight >= height) {
2807
182
  return EOF;
2808
182
      }
2809
1.59k
      y += mcuHeight;
2810
1.59k
      if (!readMCURow()) {
2811
727
  y = height;
2812
727
  return EOF;
2813
727
      }
2814
1.59k
    }
2815
51.1k
    c = *rowBufPtr++;
2816
51.1k
  }
2817
89.1M
  return c;
2818
89.2M
}
2819
2820
405k
int DCTStream::lookChar() {
2821
405k
  if (!prepared) {
2822
0
    prepare();
2823
0
  }
2824
405k
  if (progressive || !interleaved) {
2825
377k
    if (y >= height) {
2826
716
      return EOF;
2827
716
    }
2828
376k
    return frameBuf[comp][y * bufWidth + x];
2829
377k
  } else {
2830
27.7k
    if (rowBufPtr == rowBufEnd) {
2831
478
      if (y + mcuHeight >= height) {
2832
39
  return EOF;
2833
39
      }
2834
439
      if (!readMCURow()) {
2835
133
  y = height;
2836
133
  return EOF;
2837
133
      }
2838
439
    }
2839
27.5k
    return *rowBufPtr;
2840
27.7k
  }
2841
405k
}
2842
2843
4.81k
int DCTStream::getBlock(char *blk, int size) {
2844
4.81k
  int nRead, nAvail, n;
2845
2846
4.81k
  if (!prepared) {
2847
6
    prepare();
2848
6
  }
2849
4.81k
  if (y >= height) {
2850
3.35k
    return 0;
2851
3.35k
  }
2852
1.46k
  if (progressive || !interleaved) {
2853
740k
    for (nRead = 0; nRead < size; ++nRead) {
2854
740k
      blk[nRead] = (char)frameBuf[comp][y * bufWidth + x];
2855
740k
      if (++comp == numComps) {
2856
246k
  comp = 0;
2857
246k
  if (++x == width) {
2858
1.05k
    x = 0;
2859
1.05k
    ++y;
2860
1.05k
    if (y >= height) {
2861
61
      ++nRead;
2862
61
      break;
2863
61
    }
2864
1.05k
  }
2865
246k
      }
2866
740k
    }
2867
1.21k
  } else {
2868
1.21k
    nRead = 0;
2869
3.20k
    while (nRead < size) {
2870
2.25k
      if (rowBufPtr == rowBufEnd) {
2871
1.10k
  if (y + mcuHeight >= height) {
2872
5
    break;
2873
5
  }
2874
1.10k
  y += mcuHeight;
2875
1.10k
  if (!readMCURow()) {
2876
267
    y = height;
2877
267
    break;
2878
267
  }
2879
1.10k
      }
2880
1.98k
      nAvail = (int)(rowBufEnd - rowBufPtr);
2881
1.98k
      n = (nAvail < size - nRead) ? nAvail : size - nRead;
2882
1.98k
      memcpy(blk + nRead, rowBufPtr, n);
2883
1.98k
      rowBufPtr += n;
2884
1.98k
      nRead += n;
2885
1.98k
    }
2886
1.21k
  }
2887
1.46k
  return nRead;
2888
4.81k
}
2889
2890
7.31k
void DCTStream::prepare() {
2891
7.31k
  int i;
2892
2893
7.31k
  if (progressive || !interleaved) {
2894
2895
    // allocate a buffer for the whole image
2896
6.10k
    bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
2897
6.10k
    bufHeight = ((height + mcuHeight - 1) / mcuHeight) * mcuHeight;
2898
6.10k
    if (bufWidth <= 0 || bufHeight <= 0 ||
2899
5.93k
  bufWidth > INT_MAX / bufHeight / (int)sizeof(int)) {
2900
655
      error(errSyntaxError, getPos(), "Invalid image size in DCT stream");
2901
655
      y = height;
2902
655
      prepared = gTrue;
2903
655
      return;
2904
655
    }
2905
5.45k
#if USE_EXCEPTIONS
2906
5.45k
    try {
2907
5.45k
#endif
2908
21.1k
      for (i = 0; i < numComps; ++i) {
2909
15.6k
  frameBuf[i] = (int *)gmallocn(bufWidth * bufHeight, sizeof(int));
2910
15.6k
  memset(frameBuf[i], 0, bufWidth * bufHeight * sizeof(int));
2911
15.6k
      }
2912
5.45k
#if USE_EXCEPTIONS
2913
5.45k
    } 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
13.1k
    do {
2923
13.1k
      restartMarker = 0xd0;
2924
13.1k
      restart();
2925
13.1k
      readScan();
2926
13.1k
    } while (readHeader(gFalse));
2927
2928
    // decode
2929
5.45k
    decodeImage();
2930
2931
    // initialize counters
2932
5.45k
    comp = 0;
2933
5.45k
    x = 0;
2934
5.45k
    y = 0;
2935
2936
5.45k
  } else {
2937
2938
1.21k
    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
1.21k
    bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
2947
1.21k
    if (bufWidth <= 0 || bufWidth > INT_MAX / numComps / mcuHeight) {
2948
21
      error(errSyntaxError, getPos(), "Invalid image size in DCT stream");
2949
21
      y = height;
2950
21
      rowBuf = rowBufPtr = rowBufEnd = NULL;
2951
21
      prepared = gTrue;
2952
21
      return;
2953
21
    }
2954
1.19k
    rowBuf = (Guchar *)gmallocn(bufWidth, numComps * mcuHeight);
2955
1.19k
    rowBufPtr = rowBufEnd = rowBuf;
2956
2957
    // initialize counters
2958
1.19k
    y = -mcuHeight;
2959
2960
1.19k
    restartMarker = 0xd0;
2961
1.19k
    restart();
2962
1.19k
  }
2963
2964
6.64k
  prepared = gTrue;
2965
6.64k
}
2966
2967
14.7k
void DCTStream::restart() {
2968
14.7k
  int i;
2969
2970
14.7k
  inputBits = 0;
2971
14.7k
  restartCtr = restartInterval;
2972
57.8k
  for (i = 0; i < numComps; ++i) {
2973
43.1k
    compInfo[i].prevDC = 0;
2974
43.1k
  }
2975
14.7k
  eobRun = 0;
2976
14.7k
}
2977
2978
// Read one row of MCUs from a sequential JPEG stream.
2979
3.13k
GBool DCTStream::readMCURow() {
2980
3.13k
  int data1[64];
2981
3.13k
  Guchar data2[64];
2982
3.13k
  Guchar *p1, *p2;
2983
3.13k
  int pY, pCb, pCr, pR, pG, pB;
2984
3.13k
  int h, v, horiz, vert, hSub, vSub;
2985
3.13k
  int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
2986
3.13k
  int c;
2987
2988
11.6k
  for (cc = 0; cc < numComps; ++cc) {
2989
8.76k
    if (scanInfo.dcHuffTable[cc] >= numDCHuffTables ||
2990
8.55k
  scanInfo.acHuffTable[cc] >= numACHuffTables) {
2991
293
      error(errSyntaxError, getPos(),
2992
293
      "Bad DCT data: invalid Huffman table index");
2993
293
      return gFalse;
2994
293
    }
2995
8.47k
    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
8.47k
  }
3001
3002
13.2k
  for (x1 = 0; x1 < width; x1 += mcuWidth) {
3003
3004
    // deal with restart marker
3005
11.2k
    if (restartInterval > 0 && restartCtr == 0) {
3006
399
      c = readMarker();
3007
399
      if (c != restartMarker) {
3008
270
  error(errSyntaxError, getPos(),
3009
270
        "Bad DCT data: incorrect restart marker");
3010
270
  return gFalse;
3011
270
      }
3012
129
      if (++restartMarker == 0xd8)
3013
5
  restartMarker = 0xd0;
3014
129
      restart();
3015
129
    }
3016
3017
    // read one MCU
3018
39.9k
    for (cc = 0; cc < numComps; ++cc) {
3019
29.5k
      h = compInfo[cc].hSample;
3020
29.5k
      v = compInfo[cc].vSample;
3021
29.5k
      horiz = mcuWidth / h;
3022
29.5k
      vert = mcuHeight / v;
3023
29.5k
      hSub = horiz / 8;
3024
29.5k
      vSub = vert / 8;
3025
68.1k
      for (y2 = 0; y2 < mcuHeight; y2 += vert) {
3026
96.1k
  for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
3027
57.5k
    if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]],
3028
57.5k
          &acHuffTables[scanInfo.acHuffTable[cc]],
3029
57.5k
          &compInfo[cc].prevDC,
3030
57.5k
          data1)) {
3031
564
      return gFalse;
3032
564
    }
3033
56.9k
    transformDataUnit(quantTables[compInfo[cc].quantTable],
3034
56.9k
          data1, data2);
3035
56.9k
    if (hSub == 1 && vSub == 1 && x1+x2+8 <= width) {
3036
269k
      for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3037
239k
        p1 = &rowBuf[((y2+y3) * width + (x1+x2)) * numComps + cc];
3038
239k
        p1[0]          = data2[i];
3039
239k
        p1[  numComps] = data2[i+1];
3040
239k
        p1[2*numComps] = data2[i+2];
3041
239k
        p1[3*numComps] = data2[i+3];
3042
239k
        p1[4*numComps] = data2[i+4];
3043
239k
        p1[5*numComps] = data2[i+5];
3044
239k
        p1[6*numComps] = data2[i+6];
3045
239k
        p1[7*numComps] = data2[i+7];
3046
239k
      }
3047
29.9k
    } else if (hSub == 2 && vSub == 2 && x1+x2+16 <= width) {
3048
128k
      for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
3049
114k
        p1 = &rowBuf[((y2+y3) * width + (x1+x2)) * numComps + cc];
3050
114k
        p2 = p1 + width * numComps;
3051
114k
        p1[0] = p1[numComps] =
3052
114k
    p2[0] = p2[numComps] = data2[i];
3053
114k
        p1[2*numComps] = p1[3*numComps] =
3054
114k
    p2[2*numComps] = p2[3*numComps] = data2[i+1];
3055
114k
        p1[4*numComps] = p1[5*numComps] =
3056
114k
    p2[4*numComps] = p2[5*numComps] = data2[i+2];
3057
114k
        p1[6*numComps] = p1[7*numComps] =
3058
114k
    p2[6*numComps] = p2[7*numComps] = data2[i+3];
3059
114k
        p1[8*numComps] = p1[9*numComps] =
3060
114k
    p2[8*numComps] = p2[9*numComps] = data2[i+4];
3061
114k
        p1[10*numComps] = p1[11*numComps] =
3062
114k
    p2[10*numComps] = p2[11*numComps] = data2[i+5];
3063
114k
        p1[12*numComps] = p1[13*numComps] =
3064
114k
    p2[12*numComps] = p2[13*numComps] = data2[i+6];
3065
114k
        p1[14*numComps] = p1[15*numComps] =
3066
114k
    p2[14*numComps] = p2[15*numComps] = data2[i+7];
3067
114k
      }
3068
14.2k
    } else {
3069
12.7k
      p1 = &rowBuf[(y2 * width + (x1+x2)) * numComps + cc];
3070
12.7k
      i = 0;
3071
115k
      for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
3072
920k
        for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
3073
1.91M
    for (y5 = 0; y5 < vSub; ++y5) {
3074
1.21M
      for (x5 = 0; x5 < hSub && x1+x2+x4+x5 < width; ++x5) {
3075
121k
        p1[((y4+y5) * width + (x4+x5)) * numComps] = data2[i];
3076
121k
      }
3077
1.09M
    }
3078
818k
    ++i;
3079
818k
        }
3080
102k
      }
3081
12.7k
    }
3082
56.9k
  }
3083
39.1k
      }
3084
29.5k
    }
3085
10.4k
    --restartCtr;
3086
10.4k
  }
3087
3088
  // color space conversion
3089
2.01k
  if (colorXform) {
3090
    // convert YCbCr to RGB
3091
1.98k
    if (numComps == 3) {
3092
1.80M
      for (i = 0, p1 = rowBuf; i < width * mcuHeight; ++i, p1 += 3) {
3093
1.80M
  pY = p1[0];
3094
1.80M
  pCb = p1[1] - 128;
3095
1.80M
  pCr = p1[2] - 128;
3096
1.80M
  pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
3097
1.80M
  p1[0] = dctClip(pR);
3098
1.80M
  pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
3099
1.80M
  p1[1] = dctClip(pG);
3100
1.80M
  pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
3101
1.80M
  p1[2] = dctClip(pB);
3102
1.80M
      }
3103
    // convert YCbCrK to CMYK (K is passed through unchanged)
3104
1.98k
    } 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
1.98k
  }
3118
3119
2.01k
  rowBufPtr = rowBuf;
3120
2.01k
  if (y + mcuHeight <= height) {
3121
1.97k
    rowBufEnd = rowBuf + numComps * width * mcuHeight;
3122
1.97k
  } else {
3123
33
    rowBufEnd = rowBuf + numComps * width * (height - y);
3124
33
  }
3125
3126
2.01k
  return gTrue;
3127
2.84k
}
3128
3129
// Read one scan from a progressive or non-interleaved JPEG stream.
3130
13.1k
void DCTStream::readScan() {
3131
13.1k
  int data[64];
3132
13.1k
  int x1, y1, dx1, dy1, x2, y2, y3, cc, i;
3133
13.1k
  int h, v, horiz, vert, vSub;
3134
13.1k
  int *p1;
3135
13.1k
  int c;
3136
3137
50.3k
  for (cc = 0; cc < numComps; ++cc) {
3138
37.7k
    if (scanInfo.comp[cc] &&
3139
37.1k
  (scanInfo.dcHuffTable[cc] >= numDCHuffTables ||
3140
36.9k
   ((!progressive || scanInfo.lastCoeff > 0) &&
3141
36.2k
    scanInfo.acHuffTable[cc] >= numACHuffTables))) {
3142
567
      error(errSyntaxError, getPos(),
3143
567
      "Bad DCT data: invalid Huffman table index");
3144
567
      return;
3145
567
    }
3146
37.2k
    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
37.2k
  }
3152
3153
12.6k
  if (scanInfo.numComps == 1) {
3154
735
    for (cc = 0; cc < numComps; ++cc) {
3155
735
      if (scanInfo.comp[cc]) {
3156
671
  break;
3157
671
      }
3158
735
    }
3159
671
    dx1 = mcuWidth / compInfo[cc].hSample;
3160
671
    dy1 = mcuHeight / compInfo[cc].vSample;
3161
11.9k
  } else {
3162
11.9k
    dx1 = mcuWidth;
3163
11.9k
    dy1 = mcuHeight;
3164
11.9k
  }
3165
3166
59.2k
  for (y1 = 0; y1 < height; y1 += dy1) {
3167
170k
    for (x1 = 0; x1 < width; x1 += dx1) {
3168
3169
      // deal with restart marker
3170
123k
      if (restartInterval > 0 && restartCtr == 0) {
3171
727
  c = readMarker();
3172
727
  if (c != restartMarker) {
3173
531
    error(errSyntaxError, getPos(),
3174
531
    "Bad DCT data: incorrect restart marker");
3175
531
    return;
3176
531
  }
3177
196
  if (++restartMarker == 0xd8) {
3178
0
    restartMarker = 0xd0;
3179
0
  }
3180
196
  restart();
3181
196
      }
3182
3183
      // read one MCU
3184
467k
      for (cc = 0; cc < numComps; ++cc) {
3185
353k
  if (!scanInfo.comp[cc]) {
3186
32.0k
    continue;
3187
32.0k
  }
3188
3189
321k
  h = compInfo[cc].hSample;
3190
321k
  v = compInfo[cc].vSample;
3191
321k
  horiz = mcuWidth / h;
3192
321k
  vert = mcuHeight / v;
3193
321k
  vSub = vert / 8;
3194
842k
  for (y2 = 0; y2 < dy1; y2 += vert) {
3195
1.35M
    for (x2 = 0; x2 < dx1; x2 += horiz) {
3196
3197
      // pull out the current values
3198
838k
      p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
3199
7.54M
      for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3200
6.71M
        data[i] = p1[0];
3201
6.71M
        data[i+1] = p1[1];
3202
6.71M
        data[i+2] = p1[2];
3203
6.71M
        data[i+3] = p1[3];
3204
6.71M
        data[i+4] = p1[4];
3205
6.71M
        data[i+5] = p1[5];
3206
6.71M
        data[i+6] = p1[6];
3207
6.71M
        data[i+7] = p1[7];
3208
6.71M
        p1 += bufWidth * vSub;
3209
6.71M
      }
3210
3211
      // read one data unit
3212
838k
      if (progressive) {
3213
793k
        if (!readProgressiveDataUnit(
3214
793k
           &dcHuffTables[scanInfo.dcHuffTable[cc]],
3215
793k
           &acHuffTables[scanInfo.acHuffTable[cc]],
3216
793k
           &compInfo[cc].prevDC,
3217
793k
           data)) {
3218
9.32k
    return;
3219
9.32k
        }
3220
793k
      } else {
3221
45.5k
        if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]],
3222
45.5k
        &acHuffTables[scanInfo.acHuffTable[cc]],
3223
45.5k
        &compInfo[cc].prevDC,
3224
45.5k
        data)) {
3225
488
    return;
3226
488
        }
3227
45.5k
      }
3228
3229
      // add the data unit into frameBuf
3230
829k
      p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
3231
7.46M
      for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3232
6.63M
        p1[0] = data[i];
3233
6.63M
        p1[1] = data[i+1];
3234
6.63M
        p1[2] = data[i+2];
3235
6.63M
        p1[3] = data[i+3];
3236
6.63M
        p1[4] = data[i+4];
3237
6.63M
        p1[5] = data[i+5];
3238
6.63M
        p1[6] = data[i+6];
3239
6.63M
        p1[7] = data[i+7];
3240
6.63M
        p1 += bufWidth * vSub;
3241
6.63M
      }
3242
829k
    }
3243
530k
  }
3244
321k
      }
3245
113k
      --restartCtr;
3246
113k
    }
3247
56.9k
  }
3248
12.6k
}
3249
3250
// Read one data unit from a sequential JPEG stream.
3251
GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
3252
            DCTHuffTable *acHuffTable,
3253
103k
            int *prevDC, int data[64]) {
3254
103k
  int run, size, amp;
3255
103k
  int c;
3256
103k
  int i, j;
3257
3258
103k
  if ((size = readHuffSym(dcHuffTable)) == 9999) {
3259
261
    return gFalse;
3260
261
  }
3261
102k
  if (size > 0) {
3262
55.9k
    if ((amp = readAmp(size)) == 9999) {
3263
202
      return gFalse;
3264
202
    }
3265
55.9k
  } else {
3266
46.9k
    amp = 0;
3267
46.9k
  }
3268
102k
  data[0] = *prevDC += amp;
3269
6.57M
  for (i = 1; i < 64; ++i) {
3270
6.46M
    data[i] = 0;
3271
6.46M
  }
3272
102k
  i = 1;
3273
723k
  while (i < 64) {
3274
669k
    run = 0;
3275
672k
    while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30) {
3276
2.46k
      run += 0x10;
3277
2.46k
    }
3278
669k
    if (c == 9999) {
3279
255
      return gFalse;
3280
255
    }
3281
669k
    if (c == 0x00) {
3282
47.9k
      break;
3283
621k
    } else {
3284
621k
      run += (c >> 4) & 0x0f;
3285
621k
      size = c & 0x0f;
3286
621k
      amp = readAmp(size);
3287
621k
      if (amp == 9999) {
3288
334
  return gFalse;
3289
334
      }
3290
621k
      i += run;
3291
621k
      if (i < 64) {
3292
579k
  j = dctZigZag[i++];
3293
579k
  data[j] = amp;
3294
579k
      }
3295
621k
    }
3296
669k
  }
3297
102k
  return gTrue;
3298
102k
}
3299
3300
// Read one data unit from a progressive JPEG stream.
3301
GBool DCTStream::readProgressiveDataUnit(DCTHuffTable *dcHuffTable,
3302
           DCTHuffTable *acHuffTable,
3303
793k
           int *prevDC, int data[64]) {
3304
793k
  int run, size, amp, bit, c;
3305
793k
  int i, j, k;
3306
3307
  // get the DC coefficient
3308
793k
  i = scanInfo.firstCoeff;
3309
793k
  if (i == 0) {
3310
771k
    if (scanInfo.ah == 0) {
3311
8.68k
      if ((size = readHuffSym(dcHuffTable)) == 9999) {
3312
194
  return gFalse;
3313
194
      }
3314
8.49k
      if (size > 0) {
3315
8.09k
  if ((amp = readAmp(size)) == 9999) {
3316
39
    return gFalse;
3317
39
  }
3318
8.09k
      } else {
3319
396
  amp = 0;
3320
396
      }
3321
8.45k
      data[0] += (*prevDC += amp) << scanInfo.al;
3322
763k
    } else {
3323
763k
      if ((bit = readBit()) == 9999) {
3324
0
  return gFalse;
3325
0
      }
3326
763k
      if (bit) {
3327
450k
  data[0] += 1 << scanInfo.al;
3328
450k
      }
3329
763k
    }
3330
771k
    ++i;
3331
771k
  }
3332
793k
  if (scanInfo.lastCoeff == 0) {
3333
286k
    return gTrue;
3334
286k
  }
3335
3336
  // check for an EOB run
3337
506k
  if (eobRun > 0) {
3338
15.0M
    while (i <= scanInfo.lastCoeff) {
3339
14.7M
      j = dctZigZag[i++];
3340
14.7M
      if (data[j] != 0) {
3341
476k
  if ((bit = readBit()) == EOF) {
3342
464
    return gFalse;
3343
464
  }
3344
476k
  if (bit) {
3345
200k
    if (data[j] >= 0) {
3346
83.4k
      data[j] += 1 << scanInfo.al;
3347
116k
    } else {
3348
116k
      data[j] -= 1 << scanInfo.al;
3349
116k
    }
3350
200k
  }
3351
476k
      }
3352
14.7M
    }
3353
237k
    --eobRun;
3354
237k
    return gTrue;
3355
237k
  }
3356
3357
  // read the AC coefficients
3358
2.17M
  while (i <= scanInfo.lastCoeff) {
3359
2.03M
    if ((c = readHuffSym(acHuffTable)) == 9999) {
3360
2.53k
      return gFalse;
3361
2.53k
    }
3362
3363
    // ZRL
3364
2.03M
    if (c == 0xf0) {
3365
21.5k
      k = 0;
3366
364k
      while (k < 16 && i <= scanInfo.lastCoeff) {
3367
342k
  j = dctZigZag[i++];
3368
342k
  if (data[j] == 0) {
3369
329k
    ++k;
3370
329k
  } else {
3371
12.9k
    if ((bit = readBit()) == EOF) {
3372
34
      return gFalse;
3373
34
    }
3374
12.8k
    if (bit) {
3375
6.28k
      if (data[j] >= 0) {
3376
2.04k
        data[j] += 1 << scanInfo.al;
3377
4.23k
      } else {
3378
4.23k
        data[j] -= 1 << scanInfo.al;
3379
4.23k
      }
3380
6.28k
    }
3381
12.8k
  }
3382
342k
      }
3383
3384
    // EOB run
3385
2.00M
    } else if ((c & 0x0f) == 0x00) {
3386
121k
      j = c >> 4;
3387
121k
      eobRun = 0;
3388
164k
      for (k = 0; k < j; ++k) {
3389
43.4k
  if ((bit = readBit()) == EOF) {
3390
179
    return gFalse;
3391
179
  }
3392
43.2k
  eobRun = (eobRun << 1) | bit;
3393
43.2k
      }
3394
121k
      eobRun += 1 << j;
3395
6.48M
      while (i <= scanInfo.lastCoeff) {
3396
6.36M
  j = dctZigZag[i++];
3397
6.36M
  if (data[j] != 0) {
3398
152k
    if ((bit = readBit()) == EOF) {
3399
427
      return gFalse;
3400
427
    }
3401
152k
    if (bit) {
3402
64.7k
      if (data[j] >= 0) {
3403
25.1k
        data[j] += 1 << scanInfo.al;
3404
39.5k
      } else {
3405
39.5k
        data[j] -= 1 << scanInfo.al;
3406
39.5k
      }
3407
64.7k
    }
3408
152k
  }
3409
6.36M
      }
3410
120k
      --eobRun;
3411
120k
      break;
3412
3413
    // zero run and one AC coefficient
3414
1.88M
    } else {
3415
1.88M
      run = (c >> 4) & 0x0f;
3416
1.88M
      size = c & 0x0f;
3417
1.88M
      if ((amp = readAmp(size)) == 9999) {
3418
5.12k
  return gFalse;
3419
5.12k
      }
3420
1.88M
      j = 0; // make gcc happy
3421
10.0M
      for (k = 0; k <= run && i <= scanInfo.lastCoeff; ++k) {
3422
8.15M
  j = dctZigZag[i++];
3423
9.53M
  while (data[j] != 0 && i <= scanInfo.lastCoeff) {
3424
1.38M
    if ((bit = readBit()) == EOF) {
3425
332
      return gFalse;
3426
332
    }
3427
1.38M
    if (bit) {
3428
544k
      if (data[j] >= 0) {
3429
182k
        data[j] += 1 << scanInfo.al;
3430
361k
      } else {
3431
361k
        data[j] -= 1 << scanInfo.al;
3432
361k
      }
3433
544k
    }
3434
1.38M
    j = dctZigZag[i++];
3435
1.38M
  }
3436
8.15M
      }
3437
1.88M
      data[j] = amp << scanInfo.al;
3438
1.88M
    }
3439
2.03M
  }
3440
3441
260k
  return gTrue;
3442
268k
}
3443
3444
// Decode a progressive JPEG image.
3445
5.45k
void DCTStream::decodeImage() {
3446
5.45k
  int dataIn[64];
3447
5.45k
  Guchar dataOut[64];
3448
5.45k
  Gushort *quantTable;
3449
5.45k
  int pY, pCb, pCr, pR, pG, pB;
3450
5.45k
  int x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
3451
5.45k
  int h, v, horiz, vert, hSub, vSub;
3452
5.45k
  int *p0, *p1, *p2;
3453
3454
198k
  for (y1 = 0; y1 < bufHeight; y1 += mcuHeight) {
3455
704k
    for (x1 = 0; x1 < bufWidth; x1 += mcuWidth) {
3456
2.27M
      for (cc = 0; cc < numComps; ++cc) {
3457
1.76M
  quantTable = quantTables[compInfo[cc].quantTable];
3458
1.76M
  h = compInfo[cc].hSample;
3459
1.76M
  v = compInfo[cc].vSample;
3460
1.76M
  horiz = mcuWidth / h;
3461
1.76M
  vert = mcuHeight / v;
3462
1.76M
  hSub = horiz / 8;
3463
1.76M
  vSub = vert / 8;
3464
4.47M
  for (y2 = 0; y2 < mcuHeight; y2 += vert) {
3465
6.89M
    for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
3466
3467
      // pull out the coded data unit
3468
4.17M
      p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
3469
37.5M
      for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3470
33.4M
        dataIn[i]   = p1[0];
3471
33.4M
        dataIn[i+1] = p1[1];
3472
33.4M
        dataIn[i+2] = p1[2];
3473
33.4M
        dataIn[i+3] = p1[3];
3474
33.4M
        dataIn[i+4] = p1[4];
3475
33.4M
        dataIn[i+5] = p1[5];
3476
33.4M
        dataIn[i+6] = p1[6];
3477
33.4M
        dataIn[i+7] = p1[7];
3478
33.4M
        p1 += bufWidth * vSub;
3479
33.4M
      }
3480
3481
      // transform
3482
4.17M
      transformDataUnit(quantTable, dataIn, dataOut);
3483
3484
      // store back into frameBuf, doing replication for
3485
      // subsampled components
3486
4.17M
      p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
3487
4.17M
      if (hSub == 1 && vSub == 1) {
3488
24.7M
        for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3489
22.0M
    p1[0] = dataOut[i] & 0xff;
3490
22.0M
    p1[1] = dataOut[i+1] & 0xff;
3491
22.0M
    p1[2] = dataOut[i+2] & 0xff;
3492
22.0M
    p1[3] = dataOut[i+3] & 0xff;
3493
22.0M
    p1[4] = dataOut[i+4] & 0xff;
3494
22.0M
    p1[5] = dataOut[i+5] & 0xff;
3495
22.0M
    p1[6] = dataOut[i+6] & 0xff;
3496
22.0M
    p1[7] = dataOut[i+7] & 0xff;
3497
22.0M
    p1 += bufWidth;
3498
22.0M
        }
3499
2.75M
      } else if (hSub == 2 && vSub == 2) {
3500
838k
        p2 = p1 + bufWidth;
3501
7.54M
        for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
3502
6.70M
    p1[0] = p1[1] = p2[0] = p2[1] = dataOut[i] & 0xff;
3503
6.70M
    p1[2] = p1[3] = p2[2] = p2[3] = dataOut[i+1] & 0xff;
3504
6.70M
    p1[4] = p1[5] = p2[4] = p2[5] = dataOut[i+2] & 0xff;
3505
6.70M
    p1[6] = p1[7] = p2[6] = p2[7] = dataOut[i+3] & 0xff;
3506
6.70M
    p1[8] = p1[9] = p2[8] = p2[9] = dataOut[i+4] & 0xff;
3507
6.70M
    p1[10] = p1[11] = p2[10] = p2[11] = dataOut[i+5] & 0xff;
3508
6.70M
    p1[12] = p1[13] = p2[12] = p2[13] = dataOut[i+6] & 0xff;
3509
6.70M
    p1[14] = p1[15] = p2[14] = p2[15] = dataOut[i+7] & 0xff;
3510
6.70M
    p1 += bufWidth * 2;
3511
6.70M
    p2 += bufWidth * 2;
3512
6.70M
        }
3513
838k
      } else {
3514
581k
        i = 0;
3515
5.23M
        for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
3516
41.8M
    for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
3517
37.2M
      p2 = p1 + x4;
3518
149M
      for (y5 = 0; y5 < vSub; ++y5) {
3519
313M
        for (x5 = 0; x5 < hSub; ++x5) {
3520
201M
          p2[x5] = dataOut[i] & 0xff;
3521
201M
        }
3522
112M
        p2 += bufWidth;
3523
112M
      }
3524
37.2M
      ++i;
3525
37.2M
    }
3526
4.65M
    p1 += bufWidth * vSub;
3527
4.65M
        }
3528
581k
      }
3529
4.17M
    }
3530
2.71M
  }
3531
1.76M
      }
3532
3533
      // color space conversion
3534
511k
      if (colorXform) {
3535
  // convert YCbCr to RGB
3536
244k
  if (numComps == 3) {
3537
7.12M
    for (y2 = 0; y2 < mcuHeight; ++y2) {
3538
6.88M
      p0 = &frameBuf[0][(y1+y2) * bufWidth + x1];
3539
6.88M
      p1 = &frameBuf[1][(y1+y2) * bufWidth + x1];
3540
6.88M
      p2 = &frameBuf[2][(y1+y2) * bufWidth + x1];
3541
116M
      for (x2 = 0; x2 < mcuWidth; ++x2) {
3542
110M
        pY = *p0;
3543
110M
        pCb = *p1 - 128;
3544
110M
        pCr = *p2 - 128;
3545
110M
        pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
3546
110M
        *p0++ = dctClip(pR);
3547
110M
        pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr +
3548
110M
        32768) >> 16;
3549
110M
        *p1++ = dctClip(pG);
3550
110M
        pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
3551
110M
        *p2++ = dctClip(pB);
3552
110M
      }
3553
6.88M
    }
3554
  // convert YCbCrK to CMYK (K is passed through unchanged)
3555
244k
  } else if (numComps == 4) {
3556
0
    for (y2 = 0; y2 < mcuHeight; ++y2) {
3557
0
      p0 = &frameBuf[0][(y1+y2) * bufWidth + x1];
3558
0
      p1 = &frameBuf[1][(y1+y2) * bufWidth + x1];
3559
0
      p2 = &frameBuf[2][(y1+y2) * bufWidth + x1];
3560
0
      for (x2 = 0; x2 < mcuWidth; ++x2) {
3561
0
        pY = *p0;
3562
0
        pCb = *p1 - 128;
3563
0
        pCr = *p2 - 128;
3564
0
        pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
3565
0
        *p0++ = 255 - dctClip(pR);
3566
0
        pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr +
3567
0
        32768) >> 16;
3568
0
        *p1++ = 255 - dctClip(pG);
3569
0
        pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
3570
0
        *p2++ = 255 - dctClip(pB);
3571
0
      }
3572
0
    }
3573
0
  }
3574
244k
      }
3575
511k
    }
3576
193k
  }
3577
5.45k
}
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
4.23M
          int dataIn[64], Guchar dataOut[64]) {
3594
4.23M
  int v0, v1, v2, v3, v4, v5, v6, v7;
3595
4.23M
  int t0, t1, t2, t3, t4, t5, t6, t7;
3596
4.23M
  int *p, *scale;
3597
4.23M
  Gushort *q;
3598
4.23M
  int i;
3599
3600
  // dequant; inverse DCT on rows
3601
38.0M
  for (i = 0; i < 64; i += 8) {
3602
33.8M
    p = dataIn + i;
3603
33.8M
    q = quantTable + i;
3604
33.8M
    scale = idctScaleMat + i;
3605
3606
    // check for all-zero AC coefficients
3607
33.8M
    if (p[1] == 0 && p[2] == 0 && p[3] == 0 &&
3608
33.2M
  p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] == 0) {
3609
32.9M
      t0 = p[0] * q[0] * scale[0];
3610
32.9M
      if (i == 0) {
3611
4.09M
  t0 += 1 << 12;    // rounding bias
3612
4.09M
      }
3613
32.9M
      p[0] = t0;
3614
32.9M
      p[1] = t0;
3615
32.9M
      p[2] = t0;
3616
32.9M
      p[3] = t0;
3617
32.9M
      p[4] = t0;
3618
32.9M
      p[5] = t0;
3619
32.9M
      p[6] = t0;
3620
32.9M
      p[7] = t0;
3621
32.9M
      continue;
3622
32.9M
    }
3623
3624
    // stage 4
3625
901k
    v0 = p[0] * q[0] * scale[0];
3626
901k
    if (i == 0) {
3627
136k
      v0 += 1 << 12;    // rounding bias
3628
136k
    }
3629
901k
    v1 = p[4] * q[4] * scale[4];
3630
901k
    v2 = p[2] * q[2] * scale[2];
3631
901k
    v3 = p[6] * q[6] * scale[6];
3632
901k
    t0 = p[1] * q[1] * scale[1];
3633
901k
    t1 = p[7] * q[7] * scale[7];
3634
901k
    v4 = t0 - t1;
3635
901k
    v7 = t0 + t1;
3636
901k
    v5 = p[3] * q[3] * scale[3];
3637
901k
    v6 = p[5] * q[5] * scale[5];
3638
3639
    // stage 3
3640
901k
    t0 = v0 - v1;
3641
901k
    v0 = v0 + v1;
3642
901k
    v1 = t0;
3643
901k
    t0 = v2 + (v2 >> 5);
3644
901k
    t1 = t0 >> 2;
3645
901k
    t2 = t1 + (v2 >> 4);  // 41/128 * v2
3646
901k
    t3 = t0 - t1;   // 99/128 * v2
3647
901k
    t4 = v3 + (v3 >> 5);
3648
901k
    t5 = t4 >> 2;
3649
901k
    t6 = t5 + (v3 >> 4);  // 41/128 * v3
3650
901k
    t7 = t4 - t5;   // 99/128 * v3
3651
901k
    v2 = t2 - t7;
3652
901k
    v3 = t3 + t6;
3653
901k
    t0 = v4 - v6;
3654
901k
    v4 = v4 + v6;
3655
901k
    v6 = t0;
3656
901k
    t0 = v7 + v5;
3657
901k
    v5 = v7 - v5;
3658
901k
    v7 = t0;
3659
3660
    // stage 2
3661
901k
    t0 = v0 - v3;
3662
901k
    v0 = v0 + v3;
3663
901k
    v3 = t0;
3664
901k
    t0 = v1 - v2;
3665
901k
    v1 = v1 + v2;
3666
901k
    v2 = t0;
3667
901k
    t0 = (v4 >> 9) - v4;
3668
901k
    t1 = v4 >> 1;   // 1/2 * v4
3669
901k
    t2 = (t0 >> 2) - t0;  // 1533/2048 * v4
3670
901k
    t3 = (v7 >> 9) - v7;
3671
901k
    t4 = v7 >> 1;   // 1/2 * v7
3672
901k
    t5 = (t3 >> 2) - t3;  // 1533/2048 * v7
3673
901k
    v4 = t2 - t4;
3674
901k
    v7 = t1 + t5;
3675
901k
    t0 = (v5 >> 3) - (v5 >> 7);
3676
901k
    t1 = t0 - (v5 >> 11);
3677
901k
    t2 = t0 + (t1 >> 1);  // 719/4096 * v5
3678
901k
    t3 = v5 - t0;   // 113/256 * v5
3679
901k
    t4 = (v6 >> 3) - (v6 >> 7);
3680
901k
    t5 = t4 - (v6 >> 11);
3681
901k
    t6 = t4 + (t5 >> 1);  // 719/4096 * v6
3682
901k
    t7 = v6 - t4;   // 113/256 * v6
3683
901k
    v5 = t3 - t6;
3684
901k
    v6 = t2 + t7;
3685
3686
    // stage 1
3687
901k
    p[0] = v0 + v7;
3688
901k
    p[7] = v0 - v7;
3689
901k
    p[1] = v1 + v6;
3690
901k
    p[6] = v1 - v6;
3691
901k
    p[2] = v2 + v5;
3692
901k
    p[5] = v2 - v5;
3693
901k
    p[3] = v3 + v4;
3694
901k
    p[4] = v3 - v4;
3695
901k
  }
3696
3697
  // inverse DCT on columns
3698
38.0M
  for (i = 0; i < 8; ++i) {
3699
33.8M
    p = dataIn + i;
3700
3701
    // check for all-zero AC coefficients
3702
33.8M
    if (p[1*8] == 0 && p[2*8] == 0 && p[3*8] == 0 &&
3703
32.9M
  p[4*8] == 0 && p[5*8] == 0 && p[6*8] == 0 && p[7*8] == 0) {
3704
32.8M
      t0 = p[0*8];
3705
32.8M
      p[1*8] = t0;
3706
32.8M
      p[2*8] = t0;
3707
32.8M
      p[3*8] = t0;
3708
32.8M
      p[4*8] = t0;
3709
32.8M
      p[5*8] = t0;
3710
32.8M
      p[6*8] = t0;
3711
32.8M
      p[7*8] = t0;
3712
32.8M
      continue;
3713
32.8M
    }
3714
3715
    // stage 4
3716
965k
    v0 = p[0*8];
3717
965k
    v1 = p[4*8];
3718
965k
    v2 = p[2*8];
3719
965k
    v3 = p[6*8];
3720
965k
    t0 = p[1*8];
3721
965k
    t1 = p[7*8];
3722
965k
    v4 = t0 - t1;
3723
965k
    v7 = t0 + t1;
3724
965k
    v5 = p[3*8];
3725
965k
    v6 = p[5*8];
3726
3727
    // stage 3
3728
965k
    t0 = v0 - v1;
3729
965k
    v0 = v0 + v1;
3730
965k
    v1 = t0;
3731
965k
    t0 = v2 + (v2 >> 5);
3732
965k
    t1 = t0 >> 2;
3733
965k
    t2 = t1 + (v2 >> 4);  // 41/128 * v2
3734
965k
    t3 = t0 - t1;   // 99/128 * v2
3735
965k
    t4 = v3 + (v3 >> 5);
3736
965k
    t5 = t4 >> 2;
3737
965k
    t6 = t5 + (v3 >> 4);  // 41/128 * v3
3738
965k
    t7 = t4 - t5;   // 99/128 * v3
3739
965k
    v2 = t2 - t7;
3740
965k
    v3 = t3 + t6;
3741
965k
    t0 = v4 - v6;
3742
965k
    v4 = v4 + v6;
3743
965k
    v6 = t0;
3744
965k
    t0 = v7 + v5;
3745
965k
    v5 = v7 - v5;
3746
965k
    v7 = t0;
3747
3748
    // stage 2
3749
965k
    t0 = v0 - v3;
3750
965k
    v0 = v0 + v3;
3751
965k
    v3 = t0;
3752
965k
    t0 = v1 - v2;
3753
965k
    v1 = v1 + v2;
3754
965k
    v2 = t0;
3755
965k
    t0 = (v4 >> 9) - v4;
3756
965k
    t1 = v4 >> 1;   // 1/2 * v4
3757
965k
    t2 = (t0 >> 2) - t0;  // 1533/2048 * v4
3758
965k
    t3 = (v7 >> 9) - v7;
3759
965k
    t4 = v7 >> 1;   // 1/2 * v7
3760
965k
    t5 = (t3 >> 2) - t3;  // 1533/2048 * v7
3761
965k
    v4 = t2 - t4;
3762
965k
    v7 = t1 + t5;
3763
965k
    t0 = (v5 >> 3) - (v5 >> 7);
3764
965k
    t1 = t0 - (v5 >> 11);
3765
965k
    t2 = t0 + (t1 >> 1);  // 719/4096 * v5
3766
965k
    t3 = v5 - t0;   // 113/256 * v5
3767
965k
    t4 = (v6 >> 3) - (v6 >> 7);
3768
965k
    t5 = t4 - (v6 >> 11);
3769
965k
    t6 = t4 + (t5 >> 1);  // 719/4096 * v6
3770
965k
    t7 = v6 - t4;   // 113/256 * v6
3771
965k
    v5 = t3 - t6;
3772
965k
    v6 = t2 + t7;
3773
3774
    // stage 1
3775
965k
    p[0*8] = v0 + v7;
3776
965k
    p[7*8] = v0 - v7;
3777
965k
    p[1*8] = v1 + v6;
3778
965k
    p[6*8] = v1 - v6;
3779
965k
    p[2*8] = v2 + v5;
3780
965k
    p[5*8] = v2 - v5;
3781
965k
    p[3*8] = v3 + v4;
3782
965k
    p[4*8] = v3 - v4;
3783
965k
  }
3784
3785
  // convert to 8-bit integers
3786
275M
  for (i = 0; i < 64; ++i) {
3787
270M
    dataOut[i] = dctClip(128 + (dataIn[i] >> 13));
3788
270M
  }
3789
4.23M
}
3790
3791
2.81M
int DCTStream::readHuffSym(DCTHuffTable *table) {
3792
2.81M
  Gushort code;
3793
2.81M
  int bit;
3794
2.81M
  int codeBits;
3795
3796
2.81M
  code = 0;
3797
2.81M
  codeBits = 0;
3798
6.33M
  do {
3799
    // add a bit to the code
3800
6.33M
    if ((bit = readBit()) == EOF) {
3801
2.69k
      return 9999;
3802
2.69k
    }
3803
6.32M
    code = (Gushort)((code << 1) + bit);
3804
6.32M
    ++codeBits;
3805
3806
    // look up code
3807
6.32M
    if (code < table->firstCode[codeBits]) {
3808
0
      break;
3809
0
    }
3810
6.32M
    if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
3811
2.81M
      code = (Gushort)(code - table->firstCode[codeBits]);
3812
2.81M
      return table->sym[table->firstSym[codeBits] + code];
3813
2.81M
    }
3814
6.32M
  } while (codeBits < 16);
3815
3816
547
  error(errSyntaxError, getPos(), "Bad Huffman code in DCT stream");
3817
547
  return 9999;
3818
2.81M
}
3819
3820
2.57M
int DCTStream::readAmp(int size) {
3821
2.57M
  int amp, bit;
3822
2.57M
  int bits;
3823
3824
2.57M
  amp = 0;
3825
19.5M
  for (bits = 0; bits < size; ++bits) {
3826
16.9M
    if ((bit = readBit()) == EOF)
3827
5.69k
      return 9999;
3828
16.9M
    amp = (amp << 1) + bit;
3829
16.9M
  }
3830
2.56M
  if (amp < (1 << (size - 1)))
3831
1.63M
    amp -= (1 << size) - 1;
3832
2.56M
  return amp;
3833
2.57M
}
3834
3835
26.1M
int DCTStream::readBit() {
3836
26.1M
  int bit;
3837
26.1M
  int c, c2;
3838
3839
26.1M
  if (inputBits == 0) {
3840
3.39M
    if ((c = str->getChar()) == EOF)
3841
130k
      return EOF;
3842
3.26M
    if (c == 0xff) {
3843
58.7k
      do {
3844
58.7k
  c2 = str->getChar();
3845
58.7k
      } while (c2 == 0xff);
3846
27.3k
      if (c2 != 0x00) {
3847
16.6k
  error(errSyntaxError, getPos(), "Bad DCT data: missing 00 after ff");
3848
16.6k
  return EOF;
3849
16.6k
      }
3850
27.3k
    }
3851
3.24M
    inputBuf = c;
3852
3.24M
    inputBits = 8;
3853
3.24M
  }
3854
25.9M
  bit = (inputBuf >> (inputBits - 1)) & 1;
3855
25.9M
  --inputBits;
3856
25.9M
  return bit;
3857
26.1M
}
3858
3859
39.0k
GBool DCTStream::readHeader(GBool frame) {
3860
39.0k
  GBool haveSOF, doScan;
3861
39.0k
  int n, i;
3862
39.0k
  int c = 0;
3863
3864
  // read headers
3865
39.0k
  haveSOF = gFalse;
3866
39.0k
  doScan = gFalse;
3867
150k
  while (!doScan) {
3868
134k
    c = readMarker();
3869
134k
    switch (c) {
3870
5.06k
    case 0xc0:      // SOF0 (sequential)
3871
5.89k
    case 0xc1:      // SOF1 (extended sequential)
3872
5.89k
      if (!frame) {
3873
181
  error(errSyntaxError, getPos(),
3874
181
        "Invalid DCT marker in scan <{0:02x}>", c);
3875
181
  return gFalse;
3876
181
      }
3877
5.71k
      if (!readBaselineSOF()) {
3878
1.24k
  return gFalse;
3879
1.24k
      }
3880
4.46k
      haveSOF = gTrue;
3881
4.46k
      break;
3882
7.41k
    case 0xc2:      // SOF2 (progressive)
3883
7.41k
      if (!frame) {
3884
18
  error(errSyntaxError, getPos(),
3885
18
        "Invalid DCT marker in scan <{0:02x}>", c);
3886
18
  return gFalse;
3887
18
      }
3888
7.39k
      if (!readProgressiveSOF()) {
3889
834
  return gFalse;
3890
834
      }
3891
6.56k
      haveSOF = gTrue;
3892
6.56k
      break;
3893
47.7k
    case 0xc4:      // DHT
3894
47.7k
      if (!readHuffmanTables()) {
3895
277
  return gFalse;
3896
277
      }
3897
47.5k
      break;
3898
47.5k
    case 0xd8:      // SOI
3899
5.62k
      if (!frame) {
3900
73
  error(errSyntaxError, getPos(),
3901
73
        "Invalid DCT marker in scan <{0:02x}>", c);
3902
73
  return gFalse;
3903
73
      }
3904
5.54k
      break;
3905
5.54k
    case 0xd9:      // EOI
3906
791
      return gFalse;
3907
17.8k
    case 0xda:      // SOS
3908
17.8k
      if (frame && !haveSOF) {
3909
213
  error(errSyntaxError, getPos(), "Missing SOF in DCT stream");
3910
213
  return gFalse;
3911
213
      }
3912
17.6k
      if (!readScanInfo()) {
3913
2.21k
  return gFalse;
3914
2.21k
      }
3915
15.3k
      if (frame) {
3916
7.64k
  interleaved = scanInfo.numComps == numComps;
3917
7.64k
      }
3918
15.3k
      doScan = gTrue;
3919
15.3k
      break;
3920
13.6k
    case 0xdb:      // DQT
3921
13.6k
      if (!readQuantTables()) {
3922
302
  return gFalse;
3923
302
      }
3924
13.3k
      break;
3925
13.3k
    case 0xdd:      // DRI
3926
2.19k
      if (!readRestartInterval()) {
3927
301
  return gFalse;
3928
301
      }
3929
1.89k
      break;
3930
6.17k
    case 0xe0:      // APP0
3931
6.17k
      if (!frame) {
3932
240
  error(errSyntaxError, getPos(),
3933
240
        "Invalid DCT marker in scan <{0:02x}>", c);
3934
240
  return gFalse;
3935
240
      }
3936
5.93k
      if (!readJFIFMarker()) {
3937
69
  return gFalse;
3938
69
      }
3939
5.86k
      break;
3940
5.86k
    case 0xee:      // APP14
3941
596
      if (!frame) {
3942
30
  error(errSyntaxError, getPos(),
3943
30
        "Invalid DCT marker in scan <{0:02x}>", c);
3944
30
  return gFalse;
3945
30
      }
3946
566
      if (!readAdobeMarker()) {
3947
370
  return gFalse;
3948
370
      }
3949
196
      break;
3950
8.33k
    case EOF:
3951
8.33k
      error(errSyntaxError, getPos(), "Bad DCT header");
3952
8.33k
      return gFalse;
3953
18.5k
    default:
3954
      // skip APPn / COM / etc.
3955
18.5k
      if (c >= 0xe0) {
3956
10.3k
  n = read16() - 2;
3957
10.3k
  str->discardChars(n);
3958
10.3k
      } else {
3959
8.19k
  error(errSyntaxError, getPos(), "Unknown DCT marker <{0:02x}>", c);
3960
8.19k
  return gFalse;
3961
8.19k
      }
3962
10.3k
      break;
3963
134k
    }
3964
134k
  }
3965
3966
60.2k
  for (i = 0; i < numComps; ++i) {
3967
44.9k
    if (compInfo[i].quantTable >= numQuantTables) {
3968
70
      error(errSyntaxError, getPos(), "Invalid DCT quant table selector");
3969
70
      return gFalse;
3970
70
    }
3971
44.9k
  }
3972
3973
15.3k
  return gTrue;
3974
15.3k
}
3975
3976
5.71k
GBool DCTStream::readBaselineSOF() {
3977
5.71k
  int prec;
3978
5.71k
  int i;
3979
5.71k
  int c;
3980
3981
5.71k
  read16(); // length
3982
5.71k
  prec = str->getChar();
3983
5.71k
  height = read16();
3984
5.71k
  width = read16();
3985
5.71k
  numComps = str->getChar();
3986
5.71k
  if (numComps <= 0 || numComps > 4) {
3987
316
    error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
3988
316
    numComps = 0;
3989
316
    return gFalse;
3990
316
  }
3991
5.39k
  if (prec != 8) {
3992
216
    error(errSyntaxError, getPos(), "Bad DCT precision {0:d}", prec);
3993
216
    return gFalse;
3994
216
  }
3995
18.1k
  for (i = 0; i < numComps; ++i) {
3996
13.6k
    compInfo[i].id = str->getChar();
3997
13.6k
    c = str->getChar();
3998
13.6k
    compInfo[i].hSample = (c >> 4) & 0x0f;
3999
13.6k
    compInfo[i].vSample = c & 0x0f;
4000
13.6k
    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
13.6k
    if (!(compInfo[i].hSample == 1 ||
4004
4.38k
    compInfo[i].hSample == 2 ||
4005
332
    compInfo[i].hSample == 4) ||
4006
13.4k
  !(compInfo[i].vSample == 1 ||
4007
4.32k
    compInfo[i].vSample == 2 ||
4008
466
    compInfo[i].vSample == 4)) {
4009
419
      error(errSyntaxError, getPos(), "Bad DCT sampling factor");
4010
419
      return gFalse;
4011
419
    }
4012
13.2k
    if (compInfo[i].quantTable < 0 || compInfo[i].quantTable > 3) {
4013
292
      error(errSyntaxError, getPos(), "Bad DCT quant table selector");
4014
292
      return gFalse;
4015
292
    }
4016
13.2k
  }
4017
4.46k
  progressive = gFalse;
4018
4.46k
  return gTrue;
4019
5.17k
}
4020
4021
7.39k
GBool DCTStream::readProgressiveSOF() {
4022
7.39k
  int prec;
4023
7.39k
  int i;
4024
7.39k
  int c;
4025
4026
7.39k
  read16(); // length
4027
7.39k
  prec = str->getChar();
4028
7.39k
  height = read16();
4029
7.39k
  width = read16();
4030
7.39k
  numComps = str->getChar();
4031
7.39k
  if (numComps <= 0 || numComps > 4) {
4032
147
    error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
4033
147
    numComps = 0;
4034
147
    return gFalse;
4035
147
  }
4036
7.25k
  if (prec != 8) {
4037
207
    error(errSyntaxError, getPos(), "Bad DCT precision {0:d}", prec);
4038
207
    return gFalse;
4039
207
  }
4040
25.9k
  for (i = 0; i < numComps; ++i) {
4041
19.4k
    compInfo[i].id = str->getChar();
4042
19.4k
    c = str->getChar();
4043
19.4k
    compInfo[i].hSample = (c >> 4) & 0x0f;
4044
19.4k
    compInfo[i].vSample = c & 0x0f;
4045
19.4k
    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
19.4k
    if (!(compInfo[i].hSample == 1 ||
4049
7.90k
    compInfo[i].hSample == 2 ||
4050
412
    compInfo[i].hSample == 4) ||
4051
19.2k
  !(compInfo[i].vSample == 1 ||
4052
7.52k
    compInfo[i].vSample == 2 ||
4053
2.29k
    compInfo[i].vSample == 4)) {
4054
300
      error(errSyntaxError, getPos(), "Bad DCT sampling factor");
4055
300
      return gFalse;
4056
300
    }
4057
19.1k
    if (compInfo[i].quantTable < 0 || compInfo[i].quantTable > 3) {
4058
180
      error(errSyntaxError, getPos(), "Bad DCT quant table selector");
4059
180
      return gFalse;
4060
180
    }
4061
19.1k
  }
4062
6.56k
  progressive = gTrue;
4063
6.56k
  return gTrue;
4064
7.04k
}
4065
4066
17.6k
GBool DCTStream::readScanInfo() {
4067
17.6k
  int length;
4068
17.6k
  int id, c;
4069
17.6k
  int i, j;
4070
4071
17.6k
  length = read16() - 2;
4072
17.6k
  scanInfo.numComps = str->getChar();
4073
17.6k
  if (scanInfo.numComps <= 0 || scanInfo.numComps > 4) {
4074
290
    error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
4075
290
    scanInfo.numComps = 0;
4076
290
    return gFalse;
4077
290
  }
4078
17.3k
  --length;
4079
17.3k
  if (length != 2 * scanInfo.numComps + 3) {
4080
250
    error(errSyntaxError, getPos(), "Bad DCT scan info block");
4081
250
    return gFalse;
4082
250
  }
4083
64.8k
  for (j = 0; j < numComps; ++j) {
4084
47.7k
    scanInfo.comp[j] = gFalse;
4085
47.7k
  }
4086
62.6k
  for (i = 0; i < scanInfo.numComps; ++i) {
4087
46.9k
    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
46.9k
    if (id == compInfo[i].id) {
4092
44.3k
      j = i;
4093
44.3k
    } else {
4094
6.94k
      for (j = 0; j < numComps; ++j) {
4095
5.68k
  if (id == compInfo[j].id) {
4096
1.27k
    break;
4097
1.27k
  }
4098
5.68k
      }
4099
2.53k
      if (j == numComps) {
4100
1.25k
  error(errSyntaxError, getPos(),
4101
1.25k
        "Bad DCT component ID in scan info block");
4102
1.25k
  return gFalse;
4103
1.25k
      }
4104
2.53k
    }
4105
45.6k
    if (scanInfo.comp[j]) {
4106
100
      error(errSyntaxError, getPos(),
4107
100
      "Invalid DCT component ID in scan info block");
4108
100
      return gFalse;
4109
100
    }
4110
45.5k
    scanInfo.comp[j] = gTrue;
4111
45.5k
    c = str->getChar();
4112
45.5k
    scanInfo.dcHuffTable[j] = (c >> 4) & 0x0f;
4113
45.5k
    scanInfo.acHuffTable[j] = c & 0x0f;
4114
45.5k
  }
4115
15.7k
  scanInfo.firstCoeff = str->getChar();
4116
15.7k
  scanInfo.lastCoeff = str->getChar();
4117
15.7k
  if (scanInfo.firstCoeff < 0 || scanInfo.lastCoeff > 63 ||
4118
15.5k
      scanInfo.firstCoeff > scanInfo.lastCoeff) {
4119
318
    error(errSyntaxError, getPos(),
4120
318
    "Bad DCT coefficient numbers in scan info block");
4121
318
    return gFalse;
4122
318
  }
4123
15.3k
  c = str->getChar();
4124
15.3k
  scanInfo.ah = (c >> 4) & 0x0f;
4125
15.3k
  scanInfo.al = c & 0x0f;
4126
15.3k
  return gTrue;
4127
15.7k
}
4128
4129
13.6k
GBool DCTStream::readQuantTables() {
4130
13.6k
  int length, prec, i, index;
4131
4132
13.6k
  length = read16() - 2;
4133
27.6k
  while (length > 0) {
4134
14.2k
    index = str->getChar();
4135
14.2k
    prec = (index >> 4) & 0x0f;
4136
14.2k
    index &= 0x0f;
4137
14.2k
    if (prec > 1 || index >= 4) {
4138
302
      error(errSyntaxError, getPos(), "Bad DCT quantization table");
4139
302
      return gFalse;
4140
302
    }
4141
13.9k
    if (index >= numQuantTables) {
4142
12.4k
      numQuantTables = index + 1;
4143
12.4k
    }
4144
909k
    for (i = 0; i < 64; ++i) {
4145
895k
      if (prec) {
4146
9.47k
  quantTables[index][dctZigZag[i]] = (Gushort)read16();
4147
886k
      } else {
4148
886k
  quantTables[index][dctZigZag[i]] = (Gushort)str->getChar();
4149
886k
      }
4150
895k
    }
4151
13.9k
    if (prec) {
4152
148
      length -= 129;
4153
13.8k
    } else {
4154
13.8k
      length -= 65;
4155
13.8k
    }
4156
13.9k
  }
4157
13.3k
  return gTrue;
4158
13.6k
}
4159
4160
47.7k
GBool DCTStream::readHuffmanTables() {
4161
47.7k
  DCTHuffTable *tbl;
4162
47.7k
  int length;
4163
47.7k
  int index;
4164
47.7k
  Gushort code;
4165
47.7k
  Guchar sym;
4166
47.7k
  int i;
4167
47.7k
  int c;
4168
4169
47.7k
  length = read16() - 2;
4170
100k
  while (length > 0) {
4171
53.1k
    index = str->getChar();
4172
53.1k
    --length;
4173
53.1k
    if ((index & 0x0f) >= 4) {
4174
277
      error(errSyntaxError, getPos(), "Bad DCT Huffman table");
4175
277
      return gFalse;
4176
277
    }
4177
52.8k
    if (index & 0x10) {
4178
27.2k
      index &= 0x0f;
4179
27.2k
      if (index >= numACHuffTables)
4180
16.0k
  numACHuffTables = index+1;
4181
27.2k
      tbl = &acHuffTables[index];
4182
27.2k
    } else {
4183
25.5k
      index &= 0x0f;
4184
25.5k
      if (index >= numDCHuffTables)
4185
15.8k
  numDCHuffTables = index+1;
4186
25.5k
      tbl = &dcHuffTables[index];
4187
25.5k
    }
4188
52.8k
    sym = 0;
4189
52.8k
    code = 0;
4190
898k
    for (i = 1; i <= 16; ++i) {
4191
845k
      c = str->getChar();
4192
845k
      tbl->firstSym[i] = sym;
4193
845k
      tbl->firstCode[i] = code;
4194
845k
      tbl->numCodes[i] = (Gushort)c;
4195
845k
      sym = (Guchar)(sym + c);
4196
845k
      code = (Gushort)((code + c) << 1);
4197
845k
    }
4198
52.8k
    length -= 16;
4199
4.54M
    for (i = 0; i < sym; ++i)
4200
4.49M
      tbl->sym[i] = (Guchar)str->getChar();
4201
52.8k
    length -= sym;
4202
52.8k
  }
4203
47.5k
  return gTrue;
4204
47.7k
}
4205
4206
2.19k
GBool DCTStream::readRestartInterval() {
4207
2.19k
  int length;
4208
4209
2.19k
  length = read16();
4210
2.19k
  if (length != 4) {
4211
301
    error(errSyntaxError, getPos(), "Bad DCT restart interval");
4212
301
    return gFalse;
4213
301
  }
4214
1.89k
  restartInterval = read16();
4215
1.89k
  return gTrue;
4216
2.19k
}
4217
4218
5.93k
GBool DCTStream::readJFIFMarker() {
4219
5.93k
  int length, i;
4220
5.93k
  char buf[5];
4221
5.93k
  int c;
4222
4223
5.93k
  length = read16();
4224
5.93k
  length -= 2;
4225
5.93k
  if (length >= 5) {
4226
15.7k
    for (i = 0; i < 5; ++i) {
4227
13.1k
      if ((c = str->getChar()) == EOF) {
4228
0
  error(errSyntaxError, getPos(), "Bad DCT APP0 marker");
4229
0
  return gFalse;
4230
0
      }
4231
13.1k
      buf[i] = (char)c;
4232
13.1k
    }
4233
2.62k
    length -= 5;
4234
2.62k
    if (!memcmp(buf, "JFIF\0", 5)) {
4235
281
      gotJFIFMarker = gTrue;
4236
281
    }
4237
2.62k
  }
4238
726k
  while (length > 0) {
4239
720k
    if (str->getChar() == EOF) {
4240
69
      error(errSyntaxError, getPos(), "Bad DCT APP0 marker");
4241
69
      return gFalse;
4242
69
    }
4243
720k
    --length;
4244
720k
  }
4245
5.86k
  return gTrue;
4246
5.93k
}
4247
4248
566
GBool DCTStream::readAdobeMarker() {
4249
566
  int length, i;
4250
566
  char buf[12];
4251
566
  int c;
4252
4253
566
  length = read16();
4254
566
  if (length < 14) {
4255
60
    goto err;
4256
60
  }
4257
6.48k
  for (i = 0; i < 12; ++i) {
4258
6.00k
    if ((c = str->getChar()) == EOF) {
4259
27
      goto err;
4260
27
    }
4261
5.97k
    buf[i] = (char)c;
4262
5.97k
  }
4263
479
  if (!strncmp(buf, "Adobe", 5)) {
4264
87
    colorXform = buf[11];
4265
87
    gotAdobeMarker = gTrue;
4266
87
  }
4267
4.72M
  for (i = 14; i < length; ++i) {
4268
4.72M
    if (str->getChar() == EOF) {
4269
283
      goto err;
4270
283
    }
4271
4.72M
  }
4272
196
  return gTrue;
4273
4274
370
 err:
4275
370
  error(errSyntaxError, getPos(), "Bad DCT Adobe APP14 marker");
4276
370
  return gFalse;
4277
479
}
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
135k
int DCTStream::readMarker() {
4291
135k
  int c;
4292
4293
142k
  do {
4294
89.7M
    do {
4295
89.7M
      c = str->getChar();
4296
89.7M
    } while (c != 0xff && c != EOF);
4297
233k
    do {
4298
233k
      c = str->getChar();
4299
233k
    } while (c == 0xff);
4300
142k
  } while (c == 0x00);
4301
135k
  return c;
4302
135k
}
4303
4304
148k
int DCTStream::read16() {
4305
148k
  int c1, c2;
4306
4307
148k
  if ((c1 = str->getChar()) == EOF)
4308
1.23k
    return EOF;
4309
147k
  if ((c2 = str->getChar()) == EOF)
4310
747
    return EOF;
4311
146k
  return (c1 << 8) + c2;
4312
147k
}
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
511k
    FilterStream(strA) {
4975
511k
  if (predictor != 1) {
4976
10.3k
    pred = new StreamPredictor(this, predictor, columns, colors, bits);
4977
10.3k
    if (!pred->isOk()) {
4978
2.29k
      delete pred;
4979
2.29k
      pred = NULL;
4980
2.29k
    }
4981
501k
  } else {
4982
501k
    pred = NULL;
4983
501k
  }
4984
511k
  litCodeTab.codes = NULL;
4985
511k
  distCodeTab.codes = NULL;
4986
511k
  memset(buf, 0, flateWindow);
4987
511k
  checkForDecompressionBombs = gTrue;
4988
511k
}
4989
4990
511k
FlateStream::~FlateStream() {
4991
511k
  if (litCodeTab.codes != fixedLitCodeTab.codes) {
4992
496k
    gfree(litCodeTab.codes);
4993
496k
  }
4994
511k
  if (distCodeTab.codes != fixedDistCodeTab.codes) {
4995
496k
    gfree(distCodeTab.codes);
4996
496k
  }
4997
511k
  if (pred) {
4998
8.02k
    delete pred;
4999
8.02k
  }
5000
511k
  delete str;
5001
511k
}
5002
5003
408k
Stream *FlateStream::copy() {
5004
408k
  if (pred) {
5005
4.86k
    return new FlateStream(str->copy(), pred->getPredictor(),
5006
4.86k
         pred->getWidth(), pred->getNComps(),
5007
4.86k
         pred->getNBits());
5008
403k
  } else {
5009
403k
    return new FlateStream(str->copy(), 1, 0, 0, 0);
5010
403k
  }
5011
408k
}
5012
5013
10.2k
void FlateStream::disableDecompressionBombChecking() {
5014
10.2k
  checkForDecompressionBombs = gFalse;
5015
10.2k
  FilterStream::disableDecompressionBombChecking();
5016
10.2k
}
5017
5018
126k
void FlateStream::reset() {
5019
126k
  int cmf, flg;
5020
5021
126k
  index = 0;
5022
126k
  remain = 0;
5023
126k
  codeBuf = 0;
5024
126k
  codeSize = 0;
5025
126k
  compressedBlock = gFalse;
5026
126k
  endOfBlock = gTrue;
5027
126k
  eof = gTrue;
5028
5029
126k
  str->reset();
5030
126k
  if (pred) {
5031
1.47k
    pred->reset();
5032
1.47k
  }
5033
5034
  // read header
5035
  //~ need to look at window size?
5036
126k
  endOfBlock = eof = gTrue;
5037
126k
  cmf = str->getChar();
5038
126k
  flg = str->getChar();
5039
126k
  totalIn = 2;
5040
126k
  totalOut = 0;
5041
126k
  if (cmf == EOF || flg == EOF)
5042
1
    return;
5043
126k
  if ((cmf & 0x0f) != 0x08) {
5044
410
    error(errSyntaxError, getPos(),
5045
410
    "Unknown compression method in flate stream");
5046
410
    return;
5047
410
  }
5048
126k
  if ((((cmf << 8) + flg) % 31) != 0) {
5049
619
    error(errSyntaxError, getPos(), "Bad FCHECK in flate stream");
5050
619
    return;
5051
619
  }
5052
125k
  if (flg & 0x20) {
5053
211
    error(errSyntaxError, getPos(), "FDICT bit set in flate stream");
5054
211
    return;
5055
211
  }
5056
5057
125k
  eof = gFalse;
5058
125k
}
5059
5060
460M
int FlateStream::getChar() {
5061
460M
  int c;
5062
5063
460M
  if (pred) {
5064
4.58M
    return pred->getChar();
5065
4.58M
  }
5066
494M
  while (remain == 0) {
5067
39.2M
    if (endOfBlock && eof)
5068
310k
      return EOF;
5069
38.9M
    readSome();
5070
38.9M
  }
5071
455M
  c = buf[index];
5072
455M
  index = (index + 1) & flateMask;
5073
455M
  --remain;
5074
455M
  return c;
5075
455M
}
5076
5077
111M
int FlateStream::lookChar() {
5078
111M
  int c;
5079
5080
111M
  if (pred) {
5081
4.48M
    return pred->lookChar();
5082
4.48M
  }
5083
124M
  while (remain == 0) {
5084
17.5M
    if (endOfBlock && eof)
5085
29.0k
      return EOF;
5086
17.4M
    readSome();
5087
17.4M
  }
5088
107M
  c = buf[index];
5089
107M
  return c;
5090
107M
}
5091
5092
2.60M
int FlateStream::getRawChar() {
5093
2.60M
  int c;
5094
5095
2.63M
  while (remain == 0) {
5096
40.4k
    if (endOfBlock && eof)
5097
11.3k
      return EOF;
5098
29.0k
    readSome();
5099
29.0k
  }
5100
2.59M
  c = buf[index];
5101
2.59M
  index = (index + 1) & flateMask;
5102
2.59M
  --remain;
5103
2.59M
  return c;
5104
2.60M
}
5105
5106
2.17M
int FlateStream::getBlock(char *blk, int size) {
5107
2.17M
  int n, k;
5108
5109
2.17M
  if (pred) {
5110
39.4k
    return pred->getBlock(blk, size);
5111
39.4k
  }
5112
5113
2.13M
  n = 0;
5114
69.6M
  while (n < size) {
5115
69.3M
    if (remain == 0) {
5116
69.0M
      if (endOfBlock && eof) {
5117
1.81M
  break;
5118
1.81M
      }
5119
67.2M
      readSome();
5120
67.2M
    }
5121
67.5M
    k = remain;
5122
67.5M
    if (size - n < k) {
5123
267k
      k = size - n;
5124
267k
    }
5125
67.5M
    if (flateWindow - index < k) {
5126
54
      k = flateWindow - index;
5127
54
    }
5128
67.5M
    memcpy(blk + n, buf + index, k);
5129
67.5M
    n += k;
5130
67.5M
    index = (index + k) & flateMask;
5131
67.5M
    remain -= k;
5132
67.5M
  }
5133
2.13M
  return n;
5134
2.17M
}
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
123M
void FlateStream::readSome() {
5155
123M
  int code1, code2;
5156
123M
  int len, dist;
5157
123M
  int src, dest, n1, n2, n3, i, j, k;
5158
123M
  int c;
5159
5160
123M
  if (endOfBlock) {
5161
161k
    if (!startBlock())
5162
19.1k
      return;
5163
161k
  }
5164
5165
123M
  if (compressedBlock) {
5166
123M
    if ((code1 = getHuffmanCodeWord(&litCodeTab)) == EOF)
5167
9.38k
      goto err;
5168
123M
    if (code1 < 256) {
5169
88.1M
      buf[index] = (Guchar)code1;
5170
88.1M
      remain = 1;
5171
88.1M
    } else if (code1 == 256) {
5172
70.6k
      endOfBlock = gTrue;
5173
70.6k
      remain = 0;
5174
35.4M
    } else {
5175
35.4M
      code1 -= 257;
5176
35.4M
      code2 = lengthDecode[code1].bits;
5177
35.4M
      if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
5178
921
  goto err;
5179
35.4M
      len = lengthDecode[code1].first + code2;
5180
35.4M
      if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF)
5181
8.59k
  goto err;
5182
35.4M
      code2 = distDecode[code1].bits;
5183
35.4M
      if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
5184
6.10k
  goto err;
5185
35.4M
      dist = distDecode[code1].first + code2;
5186
35.4M
      dest = index;
5187
35.4M
      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
35.4M
      if (dest + len <= flateWindow) {
5195
35.4M
  if (src + len <= flateWindow) {
5196
708M
    for (k = 0; k < len; ++k) {
5197
673M
      buf[dest + k] = buf[src + k];
5198
673M
    }
5199
35.4M
  } else {
5200
22.2k
    n1 = flateWindow - src;
5201
22.2k
    n2 = len - n1;
5202
658k
    for (k = 0; k < n1; ++k) {
5203
636k
      buf[dest + k] = buf[src + k];
5204
636k
    }
5205
22.2k
    dest = dest + n1;
5206
22.2k
    src = 0;
5207
914k
    for (k = 0; k < n2; ++k) {
5208
892k
      buf[dest + k] = buf[src + k];
5209
892k
    }
5210
22.2k
  }
5211
35.4M
      } else {
5212
10.8k
  if (src + len <= flateWindow) {
5213
6.06k
    n1 = flateWindow - dest;
5214
6.06k
    n2 = len - n1;
5215
279k
    for (k = 0; k < n1; ++k) {
5216
273k
      buf[dest + k] = buf[src + k];
5217
273k
    }
5218
6.06k
    dest = 0;
5219
6.06k
    src = src + n1;
5220
283k
    for (k = 0; k < n2; ++k) {
5221
277k
      buf[dest + k] = buf[src + k];
5222
277k
    }
5223
6.06k
  } else if (src < dest) {
5224
4.19k
    n1 = flateWindow - dest;
5225
4.19k
    n2 = dest - src;
5226
4.19k
    n3 = len - n1 - n2;
5227
509k
    for (k = 0; k < n1; ++k) {
5228
504k
      buf[dest + k] = buf[src + k];
5229
504k
    }
5230
4.19k
    dest = 0;
5231
4.19k
    src = src + n1;
5232
48.9k
    for (k = 0; k < n2; ++k) {
5233
44.7k
      buf[dest + k] = buf[src + k];
5234
44.7k
    }
5235
4.19k
    dest = n2;
5236
4.19k
    src = 0;
5237
460k
    for (k = 0; k < n3; ++k) {
5238
456k
      buf[dest + k] = buf[src + k];
5239
456k
    }
5240
4.19k
  } else {
5241
550
    n1 = flateWindow - src;
5242
550
    n2 = src - dest;
5243
550
    n3 = len - n1 - n2;
5244
62.5k
    for (k = 0; k < n1; ++k) {
5245
62.0k
      buf[dest + k] = buf[src + k];
5246
62.0k
    }
5247
550
    dest = dest + n1;
5248
550
    src = 0;
5249
49.5k
    for (k = 0; k < n2; ++k) {
5250
48.9k
      buf[dest + k] = buf[src + k];
5251
48.9k
    }
5252
550
    dest = 0;
5253
550
    src = n2;
5254
31.2k
    for (k = 0; k < n3; ++k) {
5255
30.6k
      buf[dest + k] = buf[src + k];
5256
30.6k
    }
5257
550
  }
5258
10.8k
      }
5259
35.4M
      remain = len;
5260
35.4M
    }
5261
5262
123M
  } else {
5263
5.43k
    len = (blockLen < flateWindow) ? blockLen : flateWindow;
5264
7.97M
    for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) {
5265
7.96M
      if ((c = str->getChar()) == EOF) {
5266
1.72k
  endOfBlock = eof = gTrue;
5267
1.72k
  break;
5268
1.72k
      }
5269
7.96M
      buf[j] = (Guchar)c;
5270
7.96M
    }
5271
5.43k
    remain = i;
5272
5.43k
    blockLen -= len;
5273
5.43k
    if (blockLen == 0)
5274
3.71k
      endOfBlock = gTrue;
5275
5.43k
    totalIn += remain;
5276
5.43k
  }
5277
123M
  totalOut += remain;
5278
5279
  // check for a 'decompression bomb'
5280
123M
  if (checkForDecompressionBombs &&
5281
123M
      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
123M
  return;
5289
5290
25.0k
err:
5291
25.0k
  error(errSyntaxError, getPos(), "Unexpected end of file in flate stream");
5292
25.0k
  endOfBlock = eof = gTrue;
5293
25.0k
  remain = 0;
5294
25.0k
}
5295
5296
161k
GBool FlateStream::startBlock() {
5297
161k
  int blockHdr;
5298
161k
  int c;
5299
161k
  int check;
5300
5301
  // free the code tables from the previous block
5302
161k
  if (litCodeTab.codes != fixedLitCodeTab.codes) {
5303
144k
    gfree(litCodeTab.codes);
5304
144k
  }
5305
161k
  litCodeTab.codes = NULL;
5306
161k
  if (distCodeTab.codes != fixedDistCodeTab.codes) {
5307
144k
    gfree(distCodeTab.codes);
5308
144k
  }
5309
161k
  distCodeTab.codes = NULL;
5310
5311
  // read block header
5312
161k
  blockHdr = getCodeWord(3);
5313
161k
  if (blockHdr & 1)
5314
70.9k
    eof = gTrue;
5315
161k
  blockHdr >>= 1;
5316
5317
  // uncompressed block
5318
161k
  if (blockHdr == 0) {
5319
12.4k
    compressedBlock = gFalse;
5320
12.4k
    if ((c = str->getChar()) == EOF)
5321
0
      goto err;
5322
12.4k
    blockLen = c & 0xff;
5323
12.4k
    if ((c = str->getChar()) == EOF)
5324
39
      goto err;
5325
12.3k
    blockLen |= (c & 0xff) << 8;
5326
12.3k
    if ((c = str->getChar()) == EOF)
5327
4
      goto err;
5328
12.3k
    check = c & 0xff;
5329
12.3k
    if ((c = str->getChar()) == EOF)
5330
0
      goto err;
5331
12.3k
    check |= (c & 0xff) << 8;
5332
12.3k
    if (check != (~blockLen & 0xffff))
5333
6.92k
      goto err;
5334
5.43k
    codeBuf = 0;
5335
5.43k
    codeSize = 0;
5336
5.43k
    totalIn += 4;
5337
5338
  // compressed block with fixed codes
5339
149k
  } else if (blockHdr == 1) {
5340
32.0k
    compressedBlock = gTrue;
5341
32.0k
    loadFixedCodes();
5342
5343
  // compressed block with dynamic codes
5344
117k
  } else if (blockHdr == 2) {
5345
116k
    compressedBlock = gTrue;
5346
116k
    if (!readDynamicCodes()) {
5347
11.0k
      goto err;
5348
11.0k
    }
5349
5350
  // unknown block type
5351
116k
  } else {
5352
1.19k
    goto err;
5353
1.19k
  }
5354
5355
142k
  endOfBlock = gFalse;
5356
142k
  return gTrue;
5357
5358
19.1k
err:
5359
19.1k
  error(errSyntaxError, getPos(), "Bad block header in flate stream");
5360
19.1k
  endOfBlock = eof = gTrue;
5361
19.1k
  return gFalse;
5362
161k
}
5363
5364
32.0k
void FlateStream::loadFixedCodes() {
5365
32.0k
  litCodeTab.codes = fixedLitCodeTab.codes;
5366
32.0k
  litCodeTab.maxLen = fixedLitCodeTab.maxLen;
5367
32.0k
  distCodeTab.codes = fixedDistCodeTab.codes;
5368
32.0k
  distCodeTab.maxLen = fixedDistCodeTab.maxLen;
5369
32.0k
}
5370
5371
116k
GBool FlateStream::readDynamicCodes() {
5372
116k
  int numCodeLenCodes;
5373
116k
  int numLitCodes;
5374
116k
  int numDistCodes;
5375
116k
  int codeLenCodeLengths[flateMaxCodeLenCodes];
5376
116k
  FlateHuffmanTab codeLenCodeTab;
5377
116k
  int len, repeat, code;
5378
116k
  int i;
5379
5380
116k
  codeLenCodeTab.codes = NULL;
5381
5382
  // read lengths
5383
116k
  if ((numLitCodes = getCodeWord(5)) == EOF) {
5384
15
    goto err;
5385
15
  }
5386
116k
  numLitCodes += 257;
5387
116k
  if ((numDistCodes = getCodeWord(5)) == EOF) {
5388
0
    goto err;
5389
0
  }
5390
116k
  numDistCodes += 1;
5391
116k
  if ((numCodeLenCodes = getCodeWord(4)) == EOF) {
5392
12
    goto err;
5393
12
  }
5394
116k
  numCodeLenCodes += 4;
5395
116k
  if (numLitCodes > flateMaxLitCodes ||
5396
116k
      numDistCodes > flateMaxDistCodes ||
5397
115k
      numCodeLenCodes > flateMaxCodeLenCodes) {
5398
78
    goto err;
5399
78
  }
5400
5401
  // build the code length code table
5402
2.31M
  for (i = 0; i < flateMaxCodeLenCodes; ++i) {
5403
2.20M
    codeLenCodeLengths[i] = 0;
5404
2.20M
  }
5405
1.91M
  for (i = 0; i < numCodeLenCodes; ++i) {
5406
1.79M
    if ((codeLenCodeLengths[codeLenCodeMap[i]] = getCodeWord(3)) == -1) {
5407
8
      goto err;
5408
8
    }
5409
1.79M
  }
5410
115k
  compHuffmanCodes(codeLenCodeLengths, flateMaxCodeLenCodes, &codeLenCodeTab);
5411
5412
  // build the literal and distance code tables
5413
115k
  len = 0;
5414
115k
  repeat = 0;
5415
115k
  i = 0;
5416
19.7M
  while (i < numLitCodes + numDistCodes) {
5417
19.6M
    if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF) {
5418
2.36k
      goto err;
5419
2.36k
    }
5420
19.6M
    if (code == 16) {
5421
976k
      if ((repeat = getCodeWord(2)) == EOF) {
5422
16
  goto err;
5423
16
      }
5424
976k
      repeat += 3;
5425
976k
      if (i + repeat > numLitCodes + numDistCodes) {
5426
991
  goto err;
5427
991
      }
5428
5.37M
      for (; repeat > 0; --repeat) {
5429
4.39M
  codeLengths[i++] = len;
5430
4.39M
      }
5431
18.6M
    } else if (code == 17) {
5432
525k
      if ((repeat = getCodeWord(3)) == EOF) {
5433
56
  goto err;
5434
56
      }
5435
525k
      repeat += 3;
5436
525k
      if (i + repeat > numLitCodes + numDistCodes) {
5437
5.43k
  goto err;
5438
5.43k
      }
5439
519k
      len = 0;
5440
3.24M
      for (; repeat > 0; --repeat) {
5441
2.72M
  codeLengths[i++] = 0;
5442
2.72M
      }
5443
18.1M
    } else if (code == 18) {
5444
163k
      if ((repeat = getCodeWord(7)) == EOF) {
5445
90
  goto err;
5446
90
      }
5447
163k
      repeat += 11;
5448
163k
      if (i + repeat > numLitCodes + numDistCodes) {
5449
1.95k
  goto err;
5450
1.95k
      }
5451
161k
      len = 0;
5452
8.88M
      for (; repeat > 0; --repeat) {
5453
8.71M
  codeLengths[i++] = 0;
5454
8.71M
      }
5455
17.9M
    } else {
5456
17.9M
      codeLengths[i++] = len = code;
5457
17.9M
    }
5458
19.6M
  }
5459
105k
  compHuffmanCodes(codeLengths, numLitCodes, &litCodeTab);
5460
105k
  compHuffmanCodes(codeLengths + numLitCodes, numDistCodes, &distCodeTab);
5461
5462
105k
  gfree(codeLenCodeTab.codes);
5463
105k
  return gTrue;
5464
5465
11.0k
err:
5466
11.0k
  error(errSyntaxError, getPos(), "Bad dynamic code table in flate stream");
5467
11.0k
  gfree(codeLenCodeTab.codes);
5468
11.0k
  return gFalse;
5469
115k
}
5470
5471
// Convert an array <lengths> of <n> lengths, in value order, into a
5472
// Huffman code lookup table.
5473
326k
void FlateStream::compHuffmanCodes(int *lengths, int n, FlateHuffmanTab *tab) {
5474
326k
  int tabSize, len, code, code2, skip, val, i, t;
5475
5476
  // find max code length
5477
326k
  tab->maxLen = 0;
5478
33.9M
  for (val = 0; val < n; ++val) {
5479
33.6M
    if (lengths[val] > tab->maxLen) {
5480
805k
      tab->maxLen = lengths[val];
5481
805k
    }
5482
33.6M
  }
5483
5484
  // allocate the table
5485
326k
  tabSize = 1 << tab->maxLen;
5486
326k
  tab->codes = (FlateCode *)gmallocn(tabSize, sizeof(FlateCode));
5487
5488
  // clear the table
5489
502M
  for (i = 0; i < tabSize; ++i) {
5490
501M
    tab->codes[i].len = 0;
5491
501M
    tab->codes[i].val = 0;
5492
501M
  }
5493
5494
  // build the table
5495
326k
  for (len = 1, code = 0, skip = 2;
5496
3.02M
       len <= tab->maxLen;
5497
2.70M
       ++len, code <<= 1, skip <<= 1) {
5498
349M
    for (val = 0; val < n; ++val) {
5499
346M
      if (lengths[val] == len) {
5500
5501
  // bit-reverse the code
5502
21.4M
  code2 = 0;
5503
21.4M
  t = code;
5504
188M
  for (i = 0; i < len; ++i) {
5505
167M
    code2 = (code2 << 1) | (t & 1);
5506
167M
    t >>= 1;
5507
167M
  }
5508
5509
  // fill in the table entries
5510
959M
  for (i = code2; i < tabSize; i += skip) {
5511
938M
    tab->codes[i].len = (Gushort)len;
5512
938M
    tab->codes[i].val = (Gushort)val;
5513
938M
  }
5514
5515
21.4M
  ++code;
5516
21.4M
      }
5517
346M
    }
5518
2.70M
  }
5519
326k
}
5520
5521
178M
int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) {
5522
178M
  FlateCode *code;
5523
178M
  int c;
5524
5525
327M
  while (codeSize < tab->maxLen) {
5526
148M
    if ((c = str->getChar()) == EOF) {
5527
23.9k
      break;
5528
23.9k
    }
5529
148M
    codeBuf |= (c & 0xff) << codeSize;
5530
148M
    codeSize += 8;
5531
148M
    ++totalIn;
5532
148M
  }
5533
178M
  code = &tab->codes[codeBuf & ((1 << tab->maxLen) - 1)];
5534
178M
  if (codeSize == 0 || codeSize < code->len || code->len == 0) {
5535
20.3k
    return EOF;
5536
20.3k
  }
5537
178M
  codeBuf >>= code->len;
5538
178M
  codeSize -= code->len;
5539
178M
  return (int)code->val;
5540
178M
}
5541
5542
48.6M
int FlateStream::getCodeWord(int bits) {
5543
48.6M
  int c;
5544
5545
59.7M
  while (codeSize < bits) {
5546
11.0M
    if ((c = str->getChar()) == EOF)
5547
7.25k
      return EOF;
5548
11.0M
    codeBuf |= (c & 0xff) << codeSize;
5549
11.0M
    codeSize += 8;
5550
11.0M
    ++totalIn;
5551
11.0M
  }
5552
48.6M
  c = codeBuf & ((1 << bits) - 1);
5553
48.6M
  codeBuf >>= bits;
5554
48.6M
  codeSize -= bits;
5555
48.6M
  return c;
5556
48.6M
}
5557
5558
//------------------------------------------------------------------------
5559
// EOFStream
5560
//------------------------------------------------------------------------
5561
5562
EOFStream::EOFStream(Stream *strA):
5563
20.4k
    FilterStream(strA) {
5564
20.4k
}
5565
5566
20.4k
EOFStream::~EOFStream() {
5567
20.4k
  delete str;
5568
20.4k
}
5569
5570
14.1k
Stream *EOFStream::copy() {
5571
14.1k
  return new EOFStream(str->copy());
5572
14.1k
}
5573
5574
//------------------------------------------------------------------------
5575
// BufStream
5576
//------------------------------------------------------------------------
5577
5578
110k
BufStream::BufStream(Stream *strA, int bufSizeA): FilterStream(strA) {
5579
110k
  bufSize = bufSizeA;
5580
110k
  buf = (int *)gmallocn(bufSize, sizeof(int));
5581
110k
}
5582
5583
110k
BufStream::~BufStream() {
5584
110k
  gfree(buf);
5585
110k
  delete str;
5586
110k
}
5587
5588
0
Stream *BufStream::copy() {
5589
0
  return new BufStream(str->copy(), bufSize);
5590
0
}
5591
5592
36.0k
void BufStream::reset() {
5593
36.0k
  int i;
5594
5595
36.0k
  str->reset();
5596
144k
  for (i = 0; i < bufSize; ++i) {
5597
108k
    buf[i] = str->getChar();
5598
108k
  }
5599
36.0k
}
5600
5601
43.2M
int BufStream::getChar() {
5602
43.2M
  int c, i;
5603
5604
43.2M
  c = buf[0];
5605
129M
  for (i = 1; i < bufSize; ++i) {
5606
86.5M
    buf[i-1] = buf[i];
5607
86.5M
  }
5608
43.2M
  buf[bufSize - 1] = str->getChar();
5609
43.2M
  return c;
5610
43.2M
}
5611
5612
35.7k
int BufStream::lookChar() {
5613
35.7k
  return buf[0];
5614
35.7k
}
5615
5616
650k
int BufStream::lookChar(int idx) {
5617
650k
  return buf[idx];
5618
650k
}
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
}