Coverage Report

Created: 2026-06-22 07:14

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