Coverage Report

Created: 2025-08-26 06:28

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