Coverage Report

Created: 2026-10-17 07:09

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