Coverage Report

Created: 2023-09-25 06:41

/src/xpdf-4.04/xpdf/Stream.cc
Line
Count
Source (jump to first uncovered line)
1
//========================================================================
2
//
3
// Stream.cc
4
//
5
// Copyright 1996-2003 Glyph & Cog, LLC
6
//
7
//========================================================================
8
9
#include <aconf.h>
10
11
#ifdef USE_GCC_PRAGMAS
12
#pragma implementation
13
#endif
14
15
#include <stdio.h>
16
#include <stdlib.h>
17
#include <stddef.h>
18
#include <limits.h>
19
#ifdef _WIN32
20
#include <io.h>
21
#else
22
#include <unistd.h>
23
#endif
24
#include <string.h>
25
#include <ctype.h>
26
#include "gmem.h"
27
#include "gmempp.h"
28
#include "gfile.h"
29
#if MULTITHREADED
30
#include "GMutex.h"
31
#endif
32
#include "config.h"
33
#include "Error.h"
34
#include "Object.h"
35
#include "Lexer.h"
36
#include "GfxState.h"
37
#include "Stream.h"
38
#include "JBIG2Stream.h"
39
#include "JPXStream.h"
40
#include "Stream-CCITT.h"
41
42
#ifdef __DJGPP__
43
static GBool setDJSYSFLAGS = gFalse;
44
#endif
45
46
#ifdef VMS
47
#ifdef __GNUC__
48
#define SEEK_SET 0
49
#define SEEK_CUR 1
50
#define SEEK_END 2
51
#endif
52
#endif
53
54
//------------------------------------------------------------------------
55
56
// An LZW/Flate decompression bomb is detected if the output size
57
// exceeds decompressionBombSizeThreshold and the decompression ratio
58
// exceeds decompressionBombRatioThreshold.
59
1.97M
#define decompressionBombSizeThreshold 50000000
60
0
#define decompressionBombRatioThreshold 200
61
62
//------------------------------------------------------------------------
63
// Stream (base class)
64
//------------------------------------------------------------------------
65
66
501k
Stream::Stream() {
67
501k
}
68
69
501k
Stream::~Stream() {
70
501k
}
71
72
0
void Stream::close() {
73
0
}
74
75
0
int Stream::getRawChar() {
76
0
  error(errInternal, -1, "Called getRawChar() on non-predictor stream");
77
0
  return EOF;
78
0
}
79
80
20.8k
int Stream::getBlock(char *buf, int size) {
81
20.8k
  int n, c;
82
83
20.8k
  n = 0;
84
47.0M
  while (n < size) {
85
47.0M
    if ((c = getChar()) == EOF) {
86
10.4k
      break;
87
10.4k
    }
88
47.0M
    buf[n++] = (char)c;
89
47.0M
  }
90
20.8k
  return n;
91
20.8k
}
92
93
0
char *Stream::getLine(char *buf, int size) {
94
0
  int i;
95
0
  int c;
96
97
0
  if (lookChar() == EOF || size < 0)
98
0
    return NULL;
99
0
  for (i = 0; i < size - 1; ++i) {
100
0
    c = getChar();
101
0
    if (c == EOF || c == '\n')
102
0
      break;
103
0
    if (c == '\r') {
104
0
      if ((c = lookChar()) == '\n')
105
0
  getChar();
106
0
      break;
107
0
    }
108
0
    buf[i] = (char)c;
109
0
  }
110
0
  buf[i] = '\0';
111
0
  return buf;
112
0
}
113
114
24.2k
Guint Stream::discardChars(Guint n) {
115
24.2k
  char buf[4096];
116
24.2k
  Guint count, i, j;
117
118
24.2k
  count = 0;
119
61.8k
  while (count < n) {
120
48.1k
    if ((i = n - count) > sizeof(buf)) {
121
34.4k
      i = (Guint)sizeof(buf);
122
34.4k
    }
123
48.1k
    j = (Guint)getBlock(buf, (int)i);
124
48.1k
    count += j;
125
48.1k
    if (j != i) {
126
10.5k
      break;
127
10.5k
    }
128
48.1k
  }
129
24.2k
  return count;
130
24.2k
}
131
132
GString *Stream::getPSFilter(int psLevel, const char *indent,
133
0
           GBool okToReadStream) {
134
0
  return new GString();
135
0
}
136
137
2.76k
Stream *Stream::addFilters(Object *dict, int recursion) {
138
2.76k
  Object obj, obj2;
139
2.76k
  Object params, params2;
140
2.76k
  Stream *str;
141
2.76k
  int i;
142
143
2.76k
  str = this;
144
2.76k
  dict->dictLookup("Filter", &obj, recursion);
145
2.76k
  if (obj.isNull()) {
146
13
    obj.free();
147
13
    dict->dictLookup("F", &obj, recursion);
148
13
  }
149
2.76k
  dict->dictLookup("DecodeParms", &params, recursion);
150
2.76k
  if (params.isNull()) {
151
2.75k
    params.free();
152
2.75k
    dict->dictLookup("DP", &params, recursion);
153
2.75k
  }
154
2.76k
  if (obj.isName()) {
155
2.74k
    str = makeFilter(obj.getName(), str, &params, recursion);
156
2.74k
  } else if (obj.isArray()) {
157
143k
    for (i = 0; i < obj.arrayGetLength(); ++i) {
158
143k
      obj.arrayGet(i, &obj2, recursion);
159
143k
      if (params.isArray() && i < params.arrayGetLength())
160
0
  params.arrayGet(i, &params2, recursion);
161
143k
      else
162
143k
  params2.initNull();
163
143k
      if (obj2.isName()) {
164
2.90k
  str = makeFilter(obj2.getName(), str, &params2, recursion);
165
140k
      } else {
166
140k
  error(errSyntaxError, getPos(), "Bad filter name");
167
140k
  str = new EOFStream(str);
168
140k
      }
169
143k
      obj2.free();
170
143k
      params2.free();
171
143k
    }
172
10
  } else if (!obj.isNull()) {
173
0
    error(errSyntaxError, getPos(), "Bad 'Filter' attribute in stream");
174
0
  }
175
2.76k
  obj.free();
176
2.76k
  params.free();
177
178
2.76k
  return str;
179
2.76k
}
180
181
Stream *Stream::makeFilter(char *name, Stream *str, Object *params,
182
5.64k
         int recursion) {
183
5.64k
  int pred;     // parameters
184
5.64k
  int colors;
185
5.64k
  int bits;
186
5.64k
  int early;
187
5.64k
  int encoding;
188
5.64k
  GBool endOfLine, byteAlign, endOfBlock, black;
189
5.64k
  int columns, rows;
190
5.64k
  int colorXform;
191
5.64k
  Object globals, obj;
192
193
5.64k
  if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) {
194
10
    str = new ASCIIHexStream(str);
195
5.63k
  } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) {
196
0
    str = new ASCII85Stream(str);
197
5.63k
  } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) {
198
4
    pred = 1;
199
4
    columns = 1;
200
4
    colors = 1;
201
4
    bits = 8;
202
4
    early = 1;
203
4
    if (params->isDict()) {
204
0
      params->dictLookup("Predictor", &obj, recursion);
205
0
      if (obj.isInt())
206
0
  pred = obj.getInt();
207
0
      obj.free();
208
0
      params->dictLookup("Columns", &obj, recursion);
209
0
      if (obj.isInt())
210
0
  columns = obj.getInt();
211
0
      obj.free();
212
0
      params->dictLookup("Colors", &obj, recursion);
213
0
      if (obj.isInt())
214
0
  colors = obj.getInt();
215
0
      obj.free();
216
0
      params->dictLookup("BitsPerComponent", &obj, recursion);
217
0
      if (obj.isInt())
218
0
  bits = obj.getInt();
219
0
      obj.free();
220
0
      params->dictLookup("EarlyChange", &obj, recursion);
221
0
      if (obj.isInt())
222
0
  early = obj.getInt();
223
0
      obj.free();
224
0
    }
225
4
    str = new LZWStream(str, pred, columns, colors, bits, early);
226
5.63k
  } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) {
227
5
    str = new RunLengthStream(str);
228
5.62k
  } else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) {
229
1
    encoding = 0;
230
1
    endOfLine = gFalse;
231
1
    byteAlign = gFalse;
232
1
    columns = 1728;
233
1
    rows = 0;
234
1
    endOfBlock = gTrue;
235
1
    black = gFalse;
236
1
    if (params->isDict()) {
237
1
      params->dictLookup("K", &obj, recursion);
238
1
      if (obj.isInt()) {
239
1
  encoding = obj.getInt();
240
1
      }
241
1
      obj.free();
242
1
      params->dictLookup("EndOfLine", &obj, recursion);
243
1
      if (obj.isBool()) {
244
0
  endOfLine = obj.getBool();
245
0
      }
246
1
      obj.free();
247
1
      params->dictLookup("EncodedByteAlign", &obj, recursion);
248
1
      if (obj.isBool()) {
249
0
  byteAlign = obj.getBool();
250
0
      }
251
1
      obj.free();
252
1
      params->dictLookup("Columns", &obj, recursion);
253
1
      if (obj.isInt()) {
254
0
  columns = obj.getInt();
255
0
      }
256
1
      obj.free();
257
1
      params->dictLookup("Rows", &obj, recursion);
258
1
      if (obj.isInt()) {
259
0
  rows = obj.getInt();
260
0
      }
261
1
      obj.free();
262
1
      params->dictLookup("EndOfBlock", &obj, recursion);
263
1
      if (obj.isBool()) {
264
1
  endOfBlock = obj.getBool();
265
1
      }
266
1
      obj.free();
267
1
      params->dictLookup("BlackIs1", &obj, recursion);
268
1
      if (obj.isBool()) {
269
0
  black = obj.getBool();
270
0
      }
271
1
      obj.free();
272
1
    }
273
1
    str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign,
274
1
           columns, rows, endOfBlock, black);
275
5.62k
  } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) {
276
23
    colorXform = -1;
277
23
    if (params->isDict()) {
278
0
      if (params->dictLookup("ColorTransform", &obj, recursion)->isInt()) {
279
0
  colorXform = obj.getInt();
280
0
      }
281
0
      obj.free();
282
0
    }
283
23
    str = new DCTStream(str, colorXform);
284
5.60k
  } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) {
285
2.26k
    pred = 1;
286
2.26k
    columns = 1;
287
2.26k
    colors = 1;
288
2.26k
    bits = 8;
289
2.26k
    if (params->isDict()) {
290
2
      params->dictLookup("Predictor", &obj, recursion);
291
2
      if (obj.isInt())
292
2
  pred = obj.getInt();
293
2
      obj.free();
294
2
      params->dictLookup("Columns", &obj, recursion);
295
2
      if (obj.isInt())
296
2
  columns = obj.getInt();
297
2
      obj.free();
298
2
      params->dictLookup("Colors", &obj, recursion);
299
2
      if (obj.isInt())
300
0
  colors = obj.getInt();
301
2
      obj.free();
302
2
      params->dictLookup("BitsPerComponent", &obj, recursion);
303
2
      if (obj.isInt())
304
0
  bits = obj.getInt();
305
2
      obj.free();
306
2
    }
307
2.26k
    str = new FlateStream(str, pred, columns, colors, bits);
308
3.33k
  } else if (!strcmp(name, "JBIG2Decode")) {
309
445
    if (params->isDict()) {
310
0
      params->dictLookup("JBIG2Globals", &globals, recursion);
311
0
    }
312
445
    str = new JBIG2Stream(str, &globals);
313
445
    globals.free();
314
2.89k
  } else if (!strcmp(name, "JPXDecode")) {
315
9
    str = new JPXStream(str);
316
2.88k
  } else if (!strcmp(name, "Crypt")) {
317
    // this is handled in Parser::makeStream()
318
2.88k
  } else {
319
2.88k
    error(errSyntaxError, getPos(), "Unknown filter '{0:s}'", name);
320
2.88k
    str = new EOFStream(str);
321
2.88k
  }
322
5.64k
  return str;
323
5.64k
}
324
325
//------------------------------------------------------------------------
326
// BaseStream
327
//------------------------------------------------------------------------
328
329
162k
BaseStream::BaseStream(Object *dictA) {
330
162k
  dict = *dictA;
331
162k
}
332
333
162k
BaseStream::~BaseStream() {
334
162k
  dict.free();
335
162k
}
336
337
//------------------------------------------------------------------------
338
// FilterStream
339
//------------------------------------------------------------------------
340
341
338k
FilterStream::FilterStream(Stream *strA) {
342
338k
  str = strA;
343
338k
}
344
345
FilterStream::~FilterStream() {
346
}
347
348
172k
void FilterStream::close() {
349
172k
  str->close();
350
172k
}
351
352
0
void FilterStream::setPos(GFileOffset pos, int dir) {
353
0
  error(errInternal, -1, "Called setPos() on FilterStream");
354
0
}
355
356
//------------------------------------------------------------------------
357
// ImageStream
358
//------------------------------------------------------------------------
359
360
0
ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) {
361
0
  int imgLineSize;
362
363
0
  str = strA;
364
0
  width = widthA;
365
0
  nComps = nCompsA;
366
0
  nBits = nBitsA;
367
368
0
  nVals = width * nComps;
369
0
  inputLineSize = (nVals * nBits + 7) >> 3;
370
0
  if (width > INT_MAX / nComps ||
371
0
      nVals > (INT_MAX - 7) / nBits) {
372
    // force a call to gmallocn(-1,...), which will throw an exception
373
0
    inputLineSize = -1;
374
0
  }
375
0
  inputLine = (char *)gmallocn(inputLineSize, sizeof(char));
376
0
  if (nBits == 8) {
377
0
    imgLine = (Guchar *)inputLine;
378
0
  } else {
379
0
    if (nBits == 1) {
380
0
      imgLineSize = (nVals + 7) & ~7;
381
0
    } else {
382
0
      imgLineSize = nVals;
383
0
    }
384
0
    imgLine = (Guchar *)gmallocn(imgLineSize, sizeof(Guchar));
385
0
  }
386
0
  imgIdx = nVals;
387
0
}
388
389
0
ImageStream::~ImageStream() {
390
0
  if (imgLine != (Guchar *)inputLine) {
391
0
    gfree(imgLine);
392
0
  }
393
0
  gfree(inputLine);
394
0
}
395
396
0
void ImageStream::reset() {
397
0
  str->disableDecompressionBombChecking();
398
0
  str->reset();
399
0
}
400
401
0
void ImageStream::close() {
402
0
  str->close();
403
0
}
404
405
0
GBool ImageStream::getPixel(Guchar *pix) {
406
0
  int i;
407
408
0
  if (imgIdx >= nVals) {
409
0
    if (!getLine()) {
410
0
      return gFalse;
411
0
    }
412
0
    imgIdx = 0;
413
0
  }
414
0
  for (i = 0; i < nComps; ++i) {
415
0
    pix[i] = imgLine[imgIdx++];
416
0
  }
417
0
  return gTrue;
418
0
}
419
420
0
Guchar *ImageStream::getLine() {
421
0
  Gulong buf, bitMask;
422
0
  int bits;
423
0
  int c;
424
0
  int i;
425
0
  char *p;
426
427
0
  if (str->getBlock(inputLine, inputLineSize) != inputLineSize) {
428
0
    return NULL;
429
0
  }
430
0
  if (nBits == 1) {
431
0
    p = inputLine;
432
0
    for (i = 0; i < nVals; i += 8) {
433
0
      c = *p++;
434
0
      imgLine[i+0] = (Guchar)((c >> 7) & 1);
435
0
      imgLine[i+1] = (Guchar)((c >> 6) & 1);
436
0
      imgLine[i+2] = (Guchar)((c >> 5) & 1);
437
0
      imgLine[i+3] = (Guchar)((c >> 4) & 1);
438
0
      imgLine[i+4] = (Guchar)((c >> 3) & 1);
439
0
      imgLine[i+5] = (Guchar)((c >> 2) & 1);
440
0
      imgLine[i+6] = (Guchar)((c >> 1) & 1);
441
0
      imgLine[i+7] = (Guchar)(c & 1);
442
0
    }
443
0
  } else if (nBits == 8) {
444
    // special case: imgLine == inputLine
445
0
  } else if (nBits == 16) {
446
0
    for (i = 0; i < nVals; ++i) {
447
0
      imgLine[i] = (Guchar)inputLine[2*i];
448
0
    }
449
0
  } else {
450
0
    bitMask = (1 << nBits) - 1;
451
0
    buf = 0;
452
0
    bits = 0;
453
0
    p = inputLine;
454
0
    for (i = 0; i < nVals; ++i) {
455
0
      if (bits < nBits) {
456
0
  buf = (buf << 8) | (*p++ & 0xff);
457
0
  bits += 8;
458
0
      }
459
0
      imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask);
460
0
      bits -= nBits;
461
0
    }
462
0
  }
463
0
  return imgLine;
464
0
}
465
466
0
void ImageStream::skipLine() {
467
0
  str->getBlock(inputLine, inputLineSize);
468
0
}
469
470
471
//------------------------------------------------------------------------
472
// StreamPredictor
473
//------------------------------------------------------------------------
474
475
StreamPredictor::StreamPredictor(Stream *strA, int predictorA,
476
4
         int widthA, int nCompsA, int nBitsA) {
477
4
  str = strA;
478
4
  predictor = predictorA;
479
4
  width = widthA;
480
4
  nComps = nCompsA;
481
4
  nBits = nBitsA;
482
4
  predLine = NULL;
483
4
  ok = gFalse;
484
485
4
  nVals = width * nComps;
486
4
  pixBytes = (nComps * nBits + 7) >> 3;
487
4
  rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes;
488
4
  if (width <= 0 || nComps <= 0 || nBits <= 0 ||
489
4
      nComps > gfxColorMaxComps ||
490
4
      nBits > 16 ||
491
4
      width >= INT_MAX / nComps ||      // check for overflow in nVals 
492
4
      nVals >= (INT_MAX - 7) / nBits) { // check for overflow in rowBytes
493
0
    return;
494
0
  }
495
4
  predLine = (Guchar *)gmalloc(rowBytes);
496
497
4
  reset();
498
499
4
  ok = gTrue;
500
4
}
501
502
4
StreamPredictor::~StreamPredictor() {
503
4
  gfree(predLine);
504
4
}
505
506
4
void StreamPredictor::reset() {
507
4
  memset(predLine, 0, rowBytes);
508
4
  predIdx = rowBytes;
509
4
}
510
511
0
int StreamPredictor::lookChar() {
512
0
  if (predIdx >= rowBytes) {
513
0
    if (!getNextLine()) {
514
0
      return EOF;
515
0
    }
516
0
  }
517
0
  return predLine[predIdx];
518
0
}
519
520
0
int StreamPredictor::getChar() {
521
0
  if (predIdx >= rowBytes) {
522
0
    if (!getNextLine()) {
523
0
      return EOF;
524
0
    }
525
0
  }
526
0
  return predLine[predIdx++];
527
0
}
528
529
0
int StreamPredictor::getBlock(char *blk, int size) {
530
0
  int n, m;
531
532
0
  n = 0;
533
0
  while (n < size) {
534
0
    if (predIdx >= rowBytes) {
535
0
      if (!getNextLine()) {
536
0
  break;
537
0
      }
538
0
    }
539
0
    m = rowBytes - predIdx;
540
0
    if (m > size - n) {
541
0
      m = size - n;
542
0
    }
543
0
    memcpy(blk + n, predLine + predIdx, m);
544
0
    predIdx += m;
545
0
    n += m;
546
0
  }
547
0
  return n;
548
0
}
549
550
0
GBool StreamPredictor::getNextLine() {
551
0
  int curPred;
552
0
  Guchar upLeftBuf[gfxColorMaxComps * 2 + 1];
553
0
  int left, up, upLeft, p, pa, pb, pc;
554
0
  int c;
555
0
  Gulong inBuf, outBuf, bitMask;
556
0
  int inBits, outBits;
557
0
  int i, j, k, kk;
558
559
  // get PNG optimum predictor number
560
0
  if (predictor >= 10) {
561
0
    if ((curPred = str->getRawChar()) == EOF) {
562
0
      return gFalse;
563
0
    }
564
0
    curPred += 10;
565
0
  } else {
566
0
    curPred = predictor;
567
0
  }
568
569
  // read the raw line, apply PNG (byte) predictor
570
0
  memset(upLeftBuf, 0, pixBytes + 1);
571
0
  for (i = pixBytes; i < rowBytes; ++i) {
572
0
    for (j = pixBytes; j > 0; --j) {
573
0
      upLeftBuf[j] = upLeftBuf[j-1];
574
0
    }
575
0
    upLeftBuf[0] = predLine[i];
576
0
    if ((c = str->getRawChar()) == EOF) {
577
0
      if (i > pixBytes) {
578
  // this ought to return false, but some (broken) PDF files
579
  // contain truncated image data, and Adobe apparently reads the
580
  // last partial line
581
0
  break;
582
0
      }
583
0
      return gFalse;
584
0
    }
585
0
    switch (curPred) {
586
0
    case 11:      // PNG sub
587
0
      predLine[i] = (Guchar)(predLine[i - pixBytes] + c);
588
0
      break;
589
0
    case 12:      // PNG up
590
0
      predLine[i] = (Guchar)(predLine[i] + c);
591
0
      break;
592
0
    case 13:      // PNG average
593
0
      predLine[i] = (Guchar)(((predLine[i - pixBytes] + predLine[i]) >> 1) + c);
594
0
      break;
595
0
    case 14:      // PNG Paeth
596
0
      left = predLine[i - pixBytes];
597
0
      up = predLine[i];
598
0
      upLeft = upLeftBuf[pixBytes];
599
0
      p = left + up - upLeft;
600
0
      if ((pa = p - left) < 0)
601
0
  pa = -pa;
602
0
      if ((pb = p - up) < 0)
603
0
  pb = -pb;
604
0
      if ((pc = p - upLeft) < 0)
605
0
  pc = -pc;
606
0
      if (pa <= pb && pa <= pc)
607
0
  predLine[i] = (Guchar)(left + c);
608
0
      else if (pb <= pc)
609
0
  predLine[i] = (Guchar)(up + c);
610
0
      else
611
0
  predLine[i] = (Guchar)(upLeft + c);
612
0
      break;
613
0
    case 10:      // PNG none
614
0
    default:      // no predictor or TIFF predictor
615
0
      predLine[i] = (Guchar)c;
616
0
      break;
617
0
    }
618
0
  }
619
620
  // apply TIFF (component) predictor
621
0
  if (predictor == 2) {
622
0
    if (nBits == 8) {
623
0
      for (i = pixBytes; i < rowBytes; ++i) {
624
0
  predLine[i] = (Guchar)(predLine[i] + predLine[i - nComps]);
625
0
      }
626
0
    } else if (nBits == 16) {
627
0
      for (i = pixBytes; i < rowBytes; i += 2) {
628
0
  c = ((predLine[i] + predLine[i - 2*nComps]) << 8) +
629
0
      predLine[i + 1] + predLine[i + 1 - 2*nComps];
630
0
  predLine[i] = (Guchar)(c >> 8);
631
0
  predLine[i+1] = (Guchar)(c & 0xff);
632
0
      }
633
0
    } else {
634
0
      memset(upLeftBuf, 0, nComps);
635
0
      bitMask = (1 << nBits) - 1;
636
0
      inBuf = outBuf = 0;
637
0
      inBits = outBits = 0;
638
0
      j = k = pixBytes;
639
0
      for (i = 0; i < width; ++i) {
640
0
  for (kk = 0; kk < nComps; ++kk) {
641
0
    if (inBits < nBits) {
642
0
      inBuf = (inBuf << 8) | (predLine[j++] & 0xff);
643
0
      inBits += 8;
644
0
    }
645
0
    upLeftBuf[kk] = (Guchar)((upLeftBuf[kk] +
646
0
            (inBuf >> (inBits - nBits))) & bitMask);
647
0
    inBits -= nBits;
648
0
    outBuf = (outBuf << nBits) | upLeftBuf[kk];
649
0
    outBits += nBits;
650
0
    if (outBits >= 8) {
651
0
      predLine[k++] = (Guchar)(outBuf >> (outBits - 8));
652
0
      outBits -= 8;
653
0
    }
654
0
  }
655
0
      }
656
0
      if (outBits > 0) {
657
0
  predLine[k++] = (Guchar)((outBuf << (8 - outBits)) +
658
0
         (inBuf & ((1 << (8 - outBits)) - 1)));
659
0
      }
660
0
    }
661
0
  }
662
663
  // reset to start of line
664
0
  predIdx = pixBytes;
665
666
0
  return gTrue;
667
0
}
668
669
//------------------------------------------------------------------------
670
// SharedFile
671
//------------------------------------------------------------------------
672
673
class SharedFile {
674
public:
675
676
  SharedFile(FILE *fA);
677
  SharedFile *copy();
678
  void free();
679
  int readBlock(char *buf, GFileOffset pos, int size);
680
  GFileOffset getSize();
681
682
private:
683
684
  ~SharedFile();
685
686
  FILE *f;
687
  int refCnt;
688
#if MULTITHREADED
689
  GMutex mutex;
690
#endif
691
};
692
693
0
SharedFile::SharedFile(FILE *fA) {
694
0
  f = fA;
695
0
  refCnt = 1;
696
0
#if MULTITHREADED
697
0
  gInitMutex(&mutex);
698
0
#endif
699
0
}
700
701
0
SharedFile::~SharedFile() {
702
0
#if MULTITHREADED
703
0
  gDestroyMutex(&mutex);
704
0
#endif
705
0
}
706
707
0
SharedFile *SharedFile::copy() {
708
0
#if MULTITHREADED
709
0
  gLockMutex(&mutex);
710
0
#endif
711
0
  ++refCnt;
712
0
#if MULTITHREADED
713
0
  gUnlockMutex(&mutex);
714
0
#endif
715
0
  return this;
716
0
}
717
718
0
void SharedFile::free() {
719
0
  int newCount;
720
721
0
#if MULTITHREADED
722
0
  gLockMutex(&mutex);
723
0
#endif
724
0
  newCount = --refCnt;
725
0
#if MULTITHREADED
726
0
  gUnlockMutex(&mutex);
727
0
#endif
728
0
  if (newCount == 0) {
729
0
    delete this;
730
0
  }
731
0
}
732
733
0
int SharedFile::readBlock(char *buf, GFileOffset pos, int size) {
734
0
  int n;
735
736
0
#if MULTITHREADED
737
0
  gLockMutex(&mutex);
738
0
#endif
739
0
  gfseek(f, pos, SEEK_SET);
740
0
  n = (int)fread(buf, 1, size, f);
741
0
#if MULTITHREADED
742
0
  gUnlockMutex(&mutex);
743
0
#endif
744
0
  return n;
745
0
}
746
747
0
GFileOffset SharedFile::getSize() {
748
0
  GFileOffset size;
749
750
0
#if MULTITHREADED
751
0
  gLockMutex(&mutex);
752
0
#endif
753
0
  gfseek(f, 0, SEEK_END);
754
0
  size = gftell(f);
755
0
#if MULTITHREADED
756
0
  gUnlockMutex(&mutex);
757
0
#endif
758
0
  return size;
759
0
}
760
761
//------------------------------------------------------------------------
762
// FileStream
763
//------------------------------------------------------------------------
764
765
FileStream::FileStream(FILE *fA, GFileOffset startA, GBool limitedA,
766
           GFileOffset lengthA, Object *dictA):
767
0
    BaseStream(dictA) {
768
0
  f = new SharedFile(fA);
769
0
  start = startA;
770
0
  limited = limitedA;
771
0
  length = lengthA;
772
0
  bufPtr = bufEnd = buf;
773
0
  bufPos = start;
774
0
}
775
776
FileStream::FileStream(SharedFile *fA, GFileOffset startA, GBool limitedA,
777
           GFileOffset lengthA, Object *dictA):
778
0
    BaseStream(dictA) {
779
0
  f = fA->copy();
780
0
  start = startA;
781
0
  limited = limitedA;
782
0
  length = lengthA;
783
0
  bufPtr = bufEnd = buf;
784
0
  bufPos = start;
785
0
}
786
787
0
FileStream::~FileStream() {
788
0
  f->free();
789
0
}
790
791
0
Stream *FileStream::copy() {
792
0
  Object dictA;
793
794
0
  dict.copy(&dictA);
795
0
  return new FileStream(f, start, limited, length, &dictA);
796
0
}
797
798
Stream *FileStream::makeSubStream(GFileOffset startA, GBool limitedA,
799
0
          GFileOffset lengthA, Object *dictA) {
800
0
  return new FileStream(f, startA, limitedA, lengthA, dictA);
801
0
}
802
803
0
void FileStream::reset() {
804
0
  bufPtr = bufEnd = buf;
805
0
  bufPos = start;
806
0
}
807
808
0
int FileStream::getBlock(char *blk, int size) {
809
0
  int n, m;
810
811
0
  n = 0;
812
0
  while (n < size) {
813
0
    if (bufPtr >= bufEnd) {
814
0
      if (!fillBuf()) {
815
0
  break;
816
0
      }
817
0
    }
818
0
    m = (int)(bufEnd - bufPtr);
819
0
    if (m > size - n) {
820
0
      m = size - n;
821
0
    }
822
0
    memcpy(blk + n, bufPtr, m);
823
0
    bufPtr += m;
824
0
    n += m;
825
0
  }
826
0
  return n;
827
0
}
828
829
0
GBool FileStream::fillBuf() {
830
0
  int n;
831
832
0
  bufPos += (int)(bufEnd - buf);
833
0
  bufPtr = bufEnd = buf;
834
0
  if (limited && bufPos >= start + length) {
835
0
    return gFalse;
836
0
  }
837
0
  if (limited && bufPos + fileStreamBufSize > start + length) {
838
0
    n = (int)(start + length - bufPos);
839
0
  } else {
840
0
    n = fileStreamBufSize;
841
0
  }
842
0
  n = f->readBlock(buf, bufPos, n);
843
0
  bufEnd = buf + n;
844
0
  if (bufPtr >= bufEnd) {
845
0
    return gFalse;
846
0
  }
847
0
  return gTrue;
848
0
}
849
850
0
void FileStream::setPos(GFileOffset pos, int dir) {
851
0
  GFileOffset size;
852
853
0
  if (dir >= 0) {
854
0
    bufPos = pos;
855
0
  } else {
856
0
    size = f->getSize();
857
0
    if (pos <= size) {
858
0
      bufPos = size - pos;
859
0
    } else {
860
0
      bufPos = 0;
861
0
    }
862
0
  }
863
0
  bufPtr = bufEnd = buf;
864
0
}
865
866
0
void FileStream::moveStart(int delta) {
867
0
  start += delta;
868
0
  bufPtr = bufEnd = buf;
869
0
  bufPos = start;
870
0
}
871
872
//------------------------------------------------------------------------
873
// MemStream
874
//------------------------------------------------------------------------
875
876
MemStream::MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA):
877
162k
    BaseStream(dictA) {
878
162k
  buf = bufA;
879
162k
  start = startA;
880
162k
  length = lengthA;
881
162k
  bufEnd = buf + start + length;
882
162k
  bufPtr = buf + start;
883
162k
  needFree = gFalse;
884
162k
}
885
886
162k
MemStream::~MemStream() {
887
162k
  if (needFree) {
888
0
    gfree(buf);
889
0
  }
890
162k
}
891
892
141k
Stream *MemStream::copy() {
893
141k
  Object dictA;
894
895
141k
  dict.copy(&dictA);
896
141k
  return new MemStream(buf, start, length, &dictA);
897
141k
}
898
899
Stream *MemStream::makeSubStream(GFileOffset startA, GBool limited,
900
20.9k
         GFileOffset lengthA, Object *dictA) {
901
20.9k
  MemStream *subStr;
902
20.9k
  Guint newStart, newLength;
903
904
20.9k
  if (startA < start) {
905
0
    newStart = start;
906
20.9k
  } else if (startA > start + length) {
907
0
    newStart = start + (int)length;
908
20.9k
  } else {
909
20.9k
    newStart = (int)startA;
910
20.9k
  }
911
20.9k
  if (!limited || newStart + lengthA > start + length) {
912
17.7k
    newLength = start + length - newStart;
913
17.7k
  } else {
914
3.19k
    newLength = (Guint)lengthA;
915
3.19k
  }
916
20.9k
  subStr = new MemStream(buf, newStart, newLength, dictA);
917
20.9k
  return subStr;
918
20.9k
}
919
920
57.4k
void MemStream::reset() {
921
57.4k
  bufPtr = buf + start;
922
57.4k
}
923
924
176k
void MemStream::close() {
925
176k
}
926
927
21.5k
int MemStream::getBlock(char *blk, int size) {
928
21.5k
  int n;
929
930
21.5k
  if (size <= 0) {
931
0
    return 0;
932
0
  }
933
21.5k
  if (bufEnd - bufPtr < size) {
934
36
    n = (int)(bufEnd - bufPtr);
935
21.5k
  } else {
936
21.5k
    n = size;
937
21.5k
  }
938
21.5k
  memcpy(blk, bufPtr, n);
939
21.5k
  bufPtr += n;
940
21.5k
  return n;
941
21.5k
}
942
943
2.79k
void MemStream::setPos(GFileOffset pos, int dir) {
944
2.79k
  Guint i;
945
946
2.79k
  if (dir >= 0) {
947
2.76k
    i = (Guint)pos;
948
2.76k
  } else {
949
36
    if (pos > start + length) {
950
0
      i = 0;
951
36
    } else {
952
36
      i = (Guint)(start + length - pos);
953
36
    }
954
36
  }
955
2.79k
  if (i < start) {
956
0
    i = start;
957
2.79k
  } else if (i > start + length) {
958
10
    i = start + length;
959
10
  }
960
2.79k
  bufPtr = buf + i;
961
2.79k
}
962
963
6
void MemStream::moveStart(int delta) {
964
6
  start += delta;
965
6
  length -= delta;
966
6
  bufPtr = buf + start;
967
6
}
968
969
//------------------------------------------------------------------------
970
// EmbedStream
971
//------------------------------------------------------------------------
972
973
EmbedStream::EmbedStream(Stream *strA, Object *dictA,
974
       GBool limitedA, GFileOffset lengthA):
975
0
    BaseStream(dictA) {
976
0
  str = strA;
977
0
  limited = limitedA;
978
0
  length = lengthA;
979
0
}
980
981
EmbedStream::~EmbedStream() {
982
}
983
984
0
Stream *EmbedStream::copy() {
985
0
  Object dictA;
986
987
0
  dict.copy(&dictA);
988
0
  return new EmbedStream(str, &dictA, limited, length);
989
0
}
990
991
Stream *EmbedStream::makeSubStream(GFileOffset start, GBool limitedA,
992
0
           GFileOffset lengthA, Object *dictA) {
993
0
  error(errInternal, -1, "Called makeSubStream() on EmbedStream");
994
0
  return NULL;
995
0
}
996
997
0
int EmbedStream::getChar() {
998
0
  if (limited && !length) {
999
0
    return EOF;
1000
0
  }
1001
0
  --length;
1002
0
  return str->getChar();
1003
0
}
1004
1005
0
int EmbedStream::lookChar() {
1006
0
  if (limited && !length) {
1007
0
    return EOF;
1008
0
  }
1009
0
  return str->lookChar();
1010
0
}
1011
1012
0
int EmbedStream::getBlock(char *blk, int size) {
1013
0
  if (size <= 0) {
1014
0
    return 0;
1015
0
  }
1016
0
  if (limited && length < (Guint)size) {
1017
0
    size = (int)length;
1018
0
  }
1019
0
  length -= size;
1020
0
  return str->getBlock(blk, size);
1021
0
}
1022
1023
0
void EmbedStream::setPos(GFileOffset pos, int dir) {
1024
0
  error(errInternal, -1, "Called setPos() on EmbedStream");
1025
0
}
1026
1027
0
GFileOffset EmbedStream::getStart() {
1028
0
  error(errInternal, -1, "Called getStart() on EmbedStream");
1029
0
  return 0;
1030
0
}
1031
1032
0
void EmbedStream::moveStart(int delta) {
1033
0
  error(errInternal, -1, "Called moveStart() on EmbedStream");
1034
0
}
1035
1036
//------------------------------------------------------------------------
1037
// ASCIIHexStream
1038
//------------------------------------------------------------------------
1039
1040
ASCIIHexStream::ASCIIHexStream(Stream *strA):
1041
172
    FilterStream(strA) {
1042
172
  buf = EOF;
1043
172
  eof = gFalse;
1044
172
}
1045
1046
172
ASCIIHexStream::~ASCIIHexStream() {
1047
172
  delete str;
1048
172
}
1049
1050
162
Stream *ASCIIHexStream::copy() {
1051
162
  return new ASCIIHexStream(str->copy());
1052
162
}
1053
1054
54
void ASCIIHexStream::reset() {
1055
54
  str->reset();
1056
54
  buf = EOF;
1057
54
  eof = gFalse;
1058
54
}
1059
1060
3.82k
int ASCIIHexStream::lookChar() {
1061
3.82k
  int c1, c2, x;
1062
1063
3.82k
  if (buf != EOF)
1064
330
    return buf;
1065
3.49k
  if (eof) {
1066
128
    buf = EOF;
1067
128
    return EOF;
1068
128
  }
1069
4.38k
  do {
1070
4.38k
    c1 = str->getChar();
1071
4.38k
  } while (isspace(c1));
1072
3.36k
  if (c1 == '>') {
1073
8
    eof = gTrue;
1074
8
    buf = EOF;
1075
8
    return buf;
1076
8
  }
1077
3.52k
  do {
1078
3.52k
    c2 = str->getChar();
1079
3.52k
  } while (isspace(c2));
1080
3.35k
  if (c2 == '>') {
1081
0
    eof = gTrue;
1082
0
    c2 = '0';
1083
0
  }
1084
3.35k
  if (c1 >= '0' && c1 <= '9') {
1085
82
    x = (c1 - '0') << 4;
1086
3.27k
  } else if (c1 >= 'A' && c1 <= 'F') {
1087
62
    x = (c1 - 'A' + 10) << 4;
1088
3.21k
  } else if (c1 >= 'a' && c1 <= 'f') {
1089
144
    x = (c1 - 'a' + 10) << 4;
1090
3.06k
  } else if (c1 == EOF) {
1091
24
    eof = gTrue;
1092
24
    x = 0;
1093
3.04k
  } else {
1094
3.04k
    error(errSyntaxError, getPos(),
1095
3.04k
    "Illegal character <{0:02x}> in ASCIIHex stream", c1);
1096
3.04k
    x = 0;
1097
3.04k
  }
1098
3.35k
  if (c2 >= '0' && c2 <= '9') {
1099
194
    x += c2 - '0';
1100
3.16k
  } else if (c2 >= 'A' && c2 <= 'F') {
1101
60
    x += c2 - 'A' + 10;
1102
3.10k
  } else if (c2 >= 'a' && c2 <= 'f') {
1103
114
    x += c2 - 'a' + 10;
1104
2.98k
  } else if (c2 == EOF) {
1105
24
    eof = gTrue;
1106
24
    x = 0;
1107
2.96k
  } else {
1108
2.96k
    error(errSyntaxError, getPos(),
1109
2.96k
    "Illegal character <{0:02x}> in ASCIIHex stream", c2);
1110
2.96k
  }
1111
3.35k
  buf = x & 0xff;
1112
3.35k
  return buf;
1113
3.36k
}
1114
1115
GString *ASCIIHexStream::getPSFilter(int psLevel, const char *indent,
1116
0
             GBool okToReadStream) {
1117
0
  GString *s;
1118
1119
0
  if (psLevel < 2) {
1120
0
    return NULL;
1121
0
  }
1122
0
  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
1123
0
    return NULL;
1124
0
  }
1125
0
  s->append(indent)->append("/ASCIIHexDecode filter\n");
1126
0
  return s;
1127
0
}
1128
1129
0
GBool ASCIIHexStream::isBinary(GBool last) {
1130
0
  return str->isBinary(gFalse);
1131
0
}
1132
1133
//------------------------------------------------------------------------
1134
// ASCII85Stream
1135
//------------------------------------------------------------------------
1136
1137
ASCII85Stream::ASCII85Stream(Stream *strA):
1138
0
    FilterStream(strA) {
1139
0
  index = n = 0;
1140
0
  eof = gFalse;
1141
0
}
1142
1143
0
ASCII85Stream::~ASCII85Stream() {
1144
0
  delete str;
1145
0
}
1146
1147
0
Stream *ASCII85Stream::copy() {
1148
0
  return new ASCII85Stream(str->copy());
1149
0
}
1150
1151
0
void ASCII85Stream::reset() {
1152
0
  str->reset();
1153
0
  index = n = 0;
1154
0
  eof = gFalse;
1155
0
}
1156
1157
0
int ASCII85Stream::lookChar() {
1158
0
  int k;
1159
0
  Gulong t;
1160
1161
0
  if (index >= n) {
1162
0
    if (eof)
1163
0
      return EOF;
1164
0
    index = 0;
1165
0
    do {
1166
0
      c[0] = str->getChar();
1167
0
    } while (Lexer::isSpace(c[0]));
1168
0
    if (c[0] == '~' || c[0] == EOF) {
1169
0
      eof = gTrue;
1170
0
      n = 0;
1171
0
      return EOF;
1172
0
    } else if (c[0] == 'z') {
1173
0
      b[0] = b[1] = b[2] = b[3] = 0;
1174
0
      n = 4;
1175
0
    } else {
1176
0
      for (k = 1; k < 5; ++k) {
1177
0
  do {
1178
0
    c[k] = str->getChar();
1179
0
  } while (Lexer::isSpace(c[k]));
1180
0
  if (c[k] == '~' || c[k] == EOF)
1181
0
    break;
1182
0
      }
1183
0
      n = k - 1;
1184
0
      if (k < 5 && (c[k] == '~' || c[k] == EOF)) {
1185
0
  for (++k; k < 5; ++k)
1186
0
    c[k] = 0x21 + 84;
1187
0
  eof = gTrue;
1188
0
      }
1189
0
      t = 0;
1190
0
      for (k = 0; k < 5; ++k)
1191
0
  t = t * 85 + (c[k] - 0x21);
1192
0
      for (k = 3; k >= 0; --k) {
1193
0
  b[k] = (int)(t & 0xff);
1194
0
  t >>= 8;
1195
0
      }
1196
0
    }
1197
0
  }
1198
0
  return b[index];
1199
0
}
1200
1201
GString *ASCII85Stream::getPSFilter(int psLevel, const char *indent,
1202
0
            GBool okToReadStream) {
1203
0
  GString *s;
1204
1205
0
  if (psLevel < 2) {
1206
0
    return NULL;
1207
0
  }
1208
0
  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
1209
0
    return NULL;
1210
0
  }
1211
0
  s->append(indent)->append("/ASCII85Decode filter\n");
1212
0
  return s;
1213
0
}
1214
1215
0
GBool ASCII85Stream::isBinary(GBool last) {
1216
0
  return str->isBinary(gFalse);
1217
0
}
1218
1219
//------------------------------------------------------------------------
1220
// LZWStream
1221
//------------------------------------------------------------------------
1222
1223
LZWStream::LZWStream(Stream *strA, int predictor, int columns, int colors,
1224
         int bits, int earlyA):
1225
478
    FilterStream(strA) {
1226
478
  if (predictor != 1) {
1227
0
    pred = new StreamPredictor(this, predictor, columns, colors, bits);
1228
0
    if (!pred->isOk()) {
1229
0
      delete pred;
1230
0
      pred = NULL;
1231
0
    }
1232
478
  } else {
1233
478
    pred = NULL;
1234
478
  }
1235
478
  early = earlyA;
1236
478
  eof = gFalse;
1237
478
  inputBits = 0;
1238
478
  clearTable();
1239
478
  checkForDecompressionBombs = gTrue;
1240
478
}
1241
1242
478
LZWStream::~LZWStream() {
1243
478
  if (pred) {
1244
0
    delete pred;
1245
0
  }
1246
478
  delete str;
1247
478
}
1248
1249
474
Stream *LZWStream::copy() {
1250
474
  if (pred) {
1251
0
    return new LZWStream(str->copy(), pred->getPredictor(),
1252
0
       pred->getWidth(), pred->getNComps(),
1253
0
       pred->getNBits(), early);
1254
474
  } else {
1255
474
    return new LZWStream(str->copy(), 1, 0, 0, 0, early);
1256
474
  }
1257
474
}
1258
1259
0
void LZWStream::disableDecompressionBombChecking() {
1260
0
  checkForDecompressionBombs = gFalse;
1261
0
  FilterStream::disableDecompressionBombChecking();
1262
0
}
1263
1264
158
int LZWStream::getChar() {
1265
158
  if (pred) {
1266
0
    return pred->getChar();
1267
0
  }
1268
158
  if (eof) {
1269
0
    return EOF;
1270
0
  }
1271
158
  if (seqIndex >= seqLength) {
1272
158
    if (!processNextCode()) {
1273
158
      return EOF;
1274
158
    }
1275
158
  }
1276
0
  return seqBuf[seqIndex++];
1277
158
}
1278
1279
0
int LZWStream::lookChar() {
1280
0
  if (pred) {
1281
0
    return pred->lookChar();
1282
0
  }
1283
0
  if (eof) {
1284
0
    return EOF;
1285
0
  }
1286
0
  if (seqIndex >= seqLength) {
1287
0
    if (!processNextCode()) {
1288
0
      return EOF;
1289
0
    }
1290
0
  }
1291
0
  return seqBuf[seqIndex];
1292
0
}
1293
1294
0
int LZWStream::getRawChar() {
1295
0
  if (eof) {
1296
0
    return EOF;
1297
0
  }
1298
0
  if (seqIndex >= seqLength) {
1299
0
    if (!processNextCode()) {
1300
0
      return EOF;
1301
0
    }
1302
0
  }
1303
0
  return seqBuf[seqIndex++];
1304
0
}
1305
1306
0
int LZWStream::getBlock(char *blk, int size) {
1307
0
  int n, m;
1308
1309
0
  if (pred) {
1310
0
    return pred->getBlock(blk, size);
1311
0
  }
1312
0
  if (eof) {
1313
0
    return 0;
1314
0
  }
1315
0
  n = 0;
1316
0
  while (n < size) {
1317
0
    if (seqIndex >= seqLength) {
1318
0
      if (!processNextCode()) {
1319
0
  break;
1320
0
      }
1321
0
    }
1322
0
    m = seqLength - seqIndex;
1323
0
    if (m > size - n) {
1324
0
      m = size - n;
1325
0
    }
1326
0
    memcpy(blk + n, seqBuf + seqIndex, m);
1327
0
    seqIndex += m;
1328
0
    n += m;
1329
0
  }
1330
0
  return n;
1331
0
}
1332
1333
158
void LZWStream::reset() {
1334
158
  str->reset();
1335
158
  if (pred) {
1336
0
    pred->reset();
1337
0
  }
1338
158
  eof = gFalse;
1339
158
  inputBits = 0;
1340
158
  clearTable();
1341
158
  totalIn = totalOut = 0;
1342
158
}
1343
1344
158
GBool LZWStream::processNextCode() {
1345
158
  int code;
1346
158
  int nextLength;
1347
158
  int i, j;
1348
1349
  // check for EOF
1350
158
  if (eof) {
1351
0
    return gFalse;
1352
0
  }
1353
1354
  // check for eod and clear-table codes
1355
158
 start:
1356
158
  code = getCode();
1357
158
  if (code == EOF || code == 257) {
1358
158
    eof = gTrue;
1359
158
    return gFalse;
1360
158
  }
1361
0
  if (code == 256) {
1362
0
    clearTable();
1363
0
    goto start;
1364
0
  }
1365
0
  if (nextCode >= 4097) {
1366
0
    error(errSyntaxError, getPos(),
1367
0
    "Bad LZW stream - expected clear-table code");
1368
0
    clearTable();
1369
0
  }
1370
1371
  // process the next code
1372
0
  nextLength = seqLength + 1;
1373
0
  if (code < 256) {
1374
0
    seqBuf[0] = (Guchar)code;
1375
0
    seqLength = 1;
1376
0
  } else if (code < nextCode) {
1377
0
    seqLength = table[code].length;
1378
0
    for (i = seqLength - 1, j = code; i > 0; --i) {
1379
0
      seqBuf[i] = table[j].tail;
1380
0
      j = table[j].head;
1381
0
    }
1382
0
    seqBuf[0] = (Guchar)j;
1383
0
  } else if (code == nextCode) {
1384
0
    seqBuf[seqLength] = (Guchar)newChar;
1385
0
    ++seqLength;
1386
0
  } else {
1387
0
    error(errSyntaxError, getPos(), "Bad LZW stream - unexpected code");
1388
0
    eof = gTrue;
1389
0
    return gFalse;
1390
0
  }
1391
0
  newChar = seqBuf[0];
1392
0
  if (first) {
1393
0
    first = gFalse;
1394
0
  } else {
1395
0
    table[nextCode].length = nextLength;
1396
0
    table[nextCode].head = prevCode;
1397
0
    table[nextCode].tail = (Guchar)newChar;
1398
0
    ++nextCode;
1399
0
    if (nextCode + early == 512)
1400
0
      nextBits = 10;
1401
0
    else if (nextCode + early == 1024)
1402
0
      nextBits = 11;
1403
0
    else if (nextCode + early == 2048)
1404
0
      nextBits = 12;
1405
0
  }
1406
0
  prevCode = code;
1407
0
  totalOut += seqLength;
1408
1409
  // check for a 'decompression bomb'
1410
0
  if (checkForDecompressionBombs &&
1411
0
      totalOut > decompressionBombSizeThreshold &&
1412
0
      totalIn < totalOut / decompressionBombRatioThreshold) {
1413
0
    error(errSyntaxError, getPos(), "Decompression bomb in LZW stream");
1414
0
    eof = gTrue;
1415
0
    return gFalse;
1416
0
  }
1417
1418
  // reset buffer
1419
0
  seqIndex = 0;
1420
1421
0
  return gTrue;
1422
0
}
1423
1424
636
void LZWStream::clearTable() {
1425
636
  nextCode = 258;
1426
636
  nextBits = 9;
1427
636
  seqIndex = seqLength = 0;
1428
636
  first = gTrue;
1429
636
}
1430
1431
158
int LZWStream::getCode() {
1432
158
  int c;
1433
158
  int code;
1434
1435
158
  while (inputBits < nextBits) {
1436
158
    if ((c = str->getChar()) == EOF)
1437
158
      return EOF;
1438
0
    inputBuf = (inputBuf << 8) | (c & 0xff);
1439
0
    inputBits += 8;
1440
0
    ++totalIn;
1441
0
  }
1442
0
  code = (inputBuf >> (inputBits - nextBits)) & ((1 << nextBits) - 1);
1443
0
  inputBits -= nextBits;
1444
0
  return code;
1445
158
}
1446
1447
GString *LZWStream::getPSFilter(int psLevel, const char *indent,
1448
0
        GBool okToReadStream) {
1449
0
  GString *s;
1450
1451
0
  if (psLevel < 2 || pred) {
1452
0
    return NULL;
1453
0
  }
1454
0
  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
1455
0
    return NULL;
1456
0
  }
1457
0
  s->append(indent)->append("<< ");
1458
0
  if (!early) {
1459
0
    s->append("/EarlyChange 0 ");
1460
0
  }
1461
0
  s->append(">> /LZWDecode filter\n");
1462
0
  return s;
1463
0
}
1464
1465
0
GBool LZWStream::isBinary(GBool last) {
1466
0
  return str->isBinary(gTrue);
1467
0
}
1468
1469
//------------------------------------------------------------------------
1470
// RunLengthStream
1471
//------------------------------------------------------------------------
1472
1473
RunLengthStream::RunLengthStream(Stream *strA):
1474
77
    FilterStream(strA) {
1475
77
  bufPtr = bufEnd = buf;
1476
77
  eof = gFalse;
1477
77
}
1478
1479
77
RunLengthStream::~RunLengthStream() {
1480
77
  delete str;
1481
77
}
1482
1483
72
Stream *RunLengthStream::copy() {
1484
72
  return new RunLengthStream(str->copy());
1485
72
}
1486
1487
24
void RunLengthStream::reset() {
1488
24
  str->reset();
1489
24
  bufPtr = bufEnd = buf;
1490
24
  eof = gFalse;
1491
24
}
1492
1493
0
int RunLengthStream::getBlock(char *blk, int size) {
1494
0
  int n, m;
1495
1496
0
  n = 0;
1497
0
  while (n < size) {
1498
0
    if (bufPtr >= bufEnd) {
1499
0
      if (!fillBuf()) {
1500
0
  break;
1501
0
      }
1502
0
    }
1503
0
    m = (int)(bufEnd - bufPtr);
1504
0
    if (m > size - n) {
1505
0
      m = size - n;
1506
0
    }
1507
0
    memcpy(blk + n, bufPtr, m);
1508
0
    bufPtr += m;
1509
0
    n += m;
1510
0
  }
1511
0
  return n;
1512
0
}
1513
1514
GString *RunLengthStream::getPSFilter(int psLevel, const char *indent,
1515
0
              GBool okToReadStream) {
1516
0
  GString *s;
1517
1518
0
  if (psLevel < 2) {
1519
0
    return NULL;
1520
0
  }
1521
0
  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
1522
0
    return NULL;
1523
0
  }
1524
0
  s->append(indent)->append("/RunLengthDecode filter\n");
1525
0
  return s;
1526
0
}
1527
1528
0
GBool RunLengthStream::isBinary(GBool last) {
1529
0
  return str->isBinary(gTrue);
1530
0
}
1531
1532
536
GBool RunLengthStream::fillBuf() {
1533
536
  int c;
1534
536
  int n, i;
1535
1536
536
  if (eof)
1537
16
    return gFalse;
1538
520
  c = str->getChar();
1539
520
  if (c == 0x80 || c == EOF) {
1540
16
    eof = gTrue;
1541
16
    return gFalse;
1542
16
  }
1543
504
  if (c < 0x80) {
1544
448
    n = c + 1;
1545
6.37k
    for (i = 0; i < n; ++i)
1546
5.92k
      buf[i] = (char)str->getChar();
1547
448
  } else {
1548
56
    n = 0x101 - c;
1549
56
    c = str->getChar();
1550
3.91k
    for (i = 0; i < n; ++i)
1551
3.85k
      buf[i] = (char)c;
1552
56
  }
1553
504
  bufPtr = buf;
1554
504
  bufEnd = buf + n;
1555
504
  return gTrue;
1556
520
}
1557
1558
//------------------------------------------------------------------------
1559
// CCITTFaxStream
1560
//------------------------------------------------------------------------
1561
1562
CCITTFaxStream::CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA,
1563
             GBool byteAlignA, int columnsA, int rowsA,
1564
             GBool endOfBlockA, GBool blackA):
1565
7
    FilterStream(strA) {
1566
7
  encoding = encodingA;
1567
7
  endOfLine = endOfLineA;
1568
7
  byteAlign = byteAlignA;
1569
7
  columns = columnsA;
1570
7
  if (columns < 1) {
1571
0
    columns = 1;
1572
7
  } else if (columns > INT_MAX - 3) {
1573
0
    columns = INT_MAX - 3;
1574
0
  }
1575
7
  rows = rowsA;
1576
7
  endOfBlock = endOfBlockA;
1577
7
  black = blackA;
1578
7
  blackXOR = black ? 0xff : 0x00;
1579
  // 0 <= codingLine[0] < codingLine[1] < ... < codingLine[n] = columns
1580
  // ---> max codingLine size = columns + 1
1581
  // refLine has two extra guard entries at the end
1582
  // ---> max refLine size = columns + 3
1583
7
  codingLine = (int *)gmallocn(columns + 1, sizeof(int));
1584
7
  refLine = (int *)gmallocn(columns + 3, sizeof(int));
1585
1586
7
  eof = gFalse;
1587
7
  row = 0;
1588
7
  nextLine2D = encoding < 0;
1589
7
  inputBits = 0;
1590
7
  codingLine[0] = columns;
1591
7
  nextCol = columns;
1592
7
  a0i = 0;
1593
7
  err = gFalse;
1594
7
  nErrors = 0;
1595
7
}
1596
1597
7
CCITTFaxStream::~CCITTFaxStream() {
1598
7
  delete str;
1599
7
  gfree(refLine);
1600
7
  gfree(codingLine);
1601
7
}
1602
1603
6
Stream *CCITTFaxStream::copy() {
1604
6
  return new CCITTFaxStream(str->copy(), encoding, endOfLine,
1605
6
          byteAlign, columns, rows, endOfBlock, black);
1606
6
}
1607
1608
2
void CCITTFaxStream::reset() {
1609
2
  int code1;
1610
1611
2
  str->reset();
1612
2
  eof = gFalse;
1613
2
  row = 0;
1614
2
  nextLine2D = encoding < 0;
1615
2
  inputBits = 0;
1616
2
  codingLine[0] = columns;
1617
2
  nextCol = columns;
1618
2
  a0i = 0;
1619
1620
  // skip any initial zero bits and end-of-line marker, and get the 2D
1621
  // encoding tag
1622
2
  while ((code1 = lookBits(12)) == 0) {
1623
0
    eatBits(1);
1624
0
  }
1625
2
  if (code1 == 0x001) {
1626
0
    eatBits(12);
1627
0
    endOfLine = gTrue;
1628
0
  }
1629
2
  if (encoding > 0) {
1630
2
    nextLine2D = !lookBits(1);
1631
2
    eatBits(1);
1632
2
  }
1633
2
}
1634
1635
186k
int CCITTFaxStream::getChar() {
1636
186k
  int c, bitsNeeded, bitsAvail, bitsUsed;
1637
1638
186k
  if (nextCol >= columns) {
1639
534
    if (eof) {
1640
0
      return EOF;
1641
0
    }
1642
534
    if (!readRow()) {
1643
2
      return EOF;
1644
2
    }
1645
534
  }
1646
186k
  bitsAvail = codingLine[a0i] - nextCol;
1647
186k
  if (bitsAvail > 8) {
1648
178k
    c = (a0i & 1) ? 0x00 : 0xff;
1649
178k
  } else {
1650
8.56k
    c = 0;
1651
8.56k
    bitsNeeded = 8;
1652
19.9k
    do {
1653
19.9k
      bitsUsed = (bitsAvail < bitsNeeded) ? bitsAvail : bitsNeeded;
1654
19.9k
      c <<= bitsUsed;
1655
19.9k
      if (!(a0i & 1)) {
1656
11.2k
  c |= 0xff >> (8 - bitsUsed);
1657
11.2k
      }
1658
19.9k
      bitsAvail -= bitsUsed;
1659
19.9k
      bitsNeeded -= bitsUsed;
1660
19.9k
      if (bitsAvail == 0) {
1661
13.9k
  if (codingLine[a0i] >= columns) {
1662
864
    c <<= bitsNeeded;
1663
864
    break;
1664
864
  }
1665
13.0k
  ++a0i;
1666
13.0k
  bitsAvail = codingLine[a0i] - codingLine[a0i - 1];
1667
13.0k
      }
1668
19.9k
    } while (bitsNeeded > 0);
1669
8.56k
  }
1670
0
  nextCol += 8;
1671
186k
  c ^= blackXOR;
1672
186k
  return c;
1673
186k
}
1674
1675
70.9k
int CCITTFaxStream::lookChar() {
1676
70.9k
  int c, bitsNeeded, bitsAvail, bitsUsed, i;
1677
1678
70.9k
  if (nextCol >= columns) {
1679
332
    if (eof) {
1680
0
      return EOF;
1681
0
    }
1682
332
    if (!readRow()) {
1683
0
      return EOF;
1684
0
    }
1685
332
  }
1686
70.9k
  bitsAvail = codingLine[a0i] - nextCol;
1687
70.9k
  if (bitsAvail >= 8) {
1688
67.4k
    c = (a0i & 1) ? 0x00 : 0xff;
1689
67.4k
  } else {
1690
3.47k
    i = a0i;
1691
3.47k
    c = 0;
1692
3.47k
    bitsNeeded = 8;
1693
8.93k
    do {
1694
8.93k
      bitsUsed = (bitsAvail < bitsNeeded) ? bitsAvail : bitsNeeded;
1695
8.93k
      c <<= bitsUsed;
1696
8.93k
      if (!(i & 1)) {
1697
5.01k
  c |= 0xff >> (8 - bitsUsed);
1698
5.01k
      }
1699
8.93k
      bitsAvail -= bitsUsed;
1700
8.93k
      bitsNeeded -= bitsUsed;
1701
8.93k
      if (bitsAvail == 0) {
1702
5.99k
  if (codingLine[i] >= columns) {
1703
56
    c <<= bitsNeeded;
1704
56
    break;
1705
56
  }
1706
5.93k
  ++i;
1707
5.93k
  bitsAvail = codingLine[i] - codingLine[i - 1];
1708
5.93k
      }
1709
8.93k
    } while (bitsNeeded > 0);
1710
3.47k
  }
1711
0
  c ^= blackXOR;
1712
70.9k
  return c;
1713
70.9k
}
1714
1715
0
int CCITTFaxStream::getBlock(char *blk, int size) {
1716
0
  int bytesRead, bitsAvail, bitsNeeded, bitsUsed, byte, c;
1717
1718
0
  bytesRead = 0;
1719
0
  while (bytesRead < size) {
1720
0
    if (nextCol >= columns) {
1721
0
      if (eof) {
1722
0
  break;
1723
0
      }
1724
0
      if (!readRow()) {
1725
0
  break;
1726
0
      }
1727
0
    }
1728
0
    bitsAvail = codingLine[a0i] - nextCol;
1729
0
    byte = (a0i & 1) ? 0x00 : 0xff;
1730
0
    if (bitsAvail > 8) {
1731
0
      c = byte;
1732
0
      bitsAvail -= 8;
1733
0
    } else {
1734
0
      c = 0;
1735
0
      bitsNeeded = 8;
1736
0
      do {
1737
0
  bitsUsed = (bitsAvail < bitsNeeded) ? bitsAvail : bitsNeeded;
1738
0
  c <<= bitsUsed;
1739
0
  c |= byte >> (8 - bitsUsed);
1740
0
  bitsAvail -= bitsUsed;
1741
0
  bitsNeeded -= bitsUsed;
1742
0
  if (bitsAvail == 0) {
1743
0
    if (codingLine[a0i] >= columns) {
1744
0
      c <<= bitsNeeded;
1745
0
      break;
1746
0
    }
1747
0
    ++a0i;
1748
0
    bitsAvail = codingLine[a0i] - codingLine[a0i - 1];
1749
0
    byte ^= 0xff;
1750
0
  }
1751
0
      } while (bitsNeeded > 0);
1752
0
    }
1753
0
    nextCol += 8;
1754
0
    blk[bytesRead++] = (char)(c ^ blackXOR);
1755
0
  }
1756
0
  return bytesRead;
1757
0
}
1758
1759
13.8k
inline void CCITTFaxStream::addPixels(int a1, int blackPixels) {
1760
13.8k
  if (a1 > codingLine[a0i]) {
1761
13.7k
    if (a1 > columns) {
1762
444
      error(errSyntaxError, getPos(),
1763
444
      "CCITTFax row is wrong length ({0:d})", a1);
1764
444
      err = gTrue;
1765
444
      ++nErrors;
1766
444
      a1 = columns;
1767
444
    }
1768
13.7k
    if ((a0i & 1) ^ blackPixels) {
1769
12.6k
      ++a0i;
1770
12.6k
    }
1771
13.7k
    codingLine[a0i] = a1;
1772
13.7k
  }
1773
13.8k
}
1774
1775
692
inline void CCITTFaxStream::addPixelsNeg(int a1, int blackPixels) {
1776
692
  if (a1 > codingLine[a0i]) {
1777
600
    if (a1 > columns) {
1778
0
      error(errSyntaxError, getPos(),
1779
0
      "CCITTFax row is wrong length ({0:d})", a1);
1780
0
      err = gTrue;
1781
0
      ++nErrors;
1782
0
      a1 = columns;
1783
0
    }
1784
600
    if ((a0i & 1) ^ blackPixels) {
1785
414
      ++a0i;
1786
414
    }
1787
600
    codingLine[a0i] = a1;
1788
600
  } else if (a1 < codingLine[a0i]) {
1789
14
    if (a1 < 0) {
1790
0
      error(errSyntaxError, getPos(), "Invalid CCITTFax code");
1791
0
      err = gTrue;
1792
0
      ++nErrors;
1793
0
      a1 = 0;
1794
0
    }
1795
14
    while (a0i > 0 && a1 <= codingLine[a0i - 1]) {
1796
0
      --a0i;
1797
0
    }
1798
14
    codingLine[a0i] = a1;
1799
14
  }
1800
692
}
1801
1802
866
GBool CCITTFaxStream::readRow() {
1803
866
  int code1, code2, code3;
1804
866
  int b1i, blackPixels, i;
1805
866
  GBool gotEOL;
1806
1807
  // if at eof just return EOF
1808
866
  if (eof) {
1809
0
    return gFalse;
1810
0
  }
1811
1812
866
  err = gFalse;
1813
1814
  // 2-D encoding
1815
866
  if (nextLine2D) {
1816
6.94k
    for (i = 0; codingLine[i] < columns; ++i) {
1817
6.41k
      refLine[i] = codingLine[i];
1818
6.41k
    }
1819
532
    refLine[i++] = columns;
1820
532
    refLine[i++] = columns;
1821
532
    refLine[i] = columns;
1822
532
    codingLine[0] = 0;
1823
532
    a0i = 0;
1824
532
    b1i = 0;
1825
532
    blackPixels = 0;
1826
    // invariant:
1827
    // refLine[b1i-1] <= codingLine[a0i] < refLine[b1i] < refLine[b1i+1]
1828
    //                                                             <= columns
1829
    // exception at left edge:
1830
    //   codingLine[a0i = 0] = refLine[b1i = 0] = 0 is possible
1831
    // exception at right edge:
1832
    //   refLine[b1i] = refLine[b1i+1] = columns is possible
1833
4.00k
    while (codingLine[a0i] < columns) {
1834
3.46k
      code1 = getTwoDimCode();
1835
3.46k
      switch (code1) {
1836
216
      case twoDimPass:
1837
216
  addPixels(refLine[b1i + 1], blackPixels);
1838
216
  if (refLine[b1i + 1] < columns) {
1839
170
    b1i += 2;
1840
170
  }
1841
216
  break;
1842
286
      case twoDimHoriz:
1843
286
  code1 = code2 = 0;
1844
286
  if (blackPixels) {
1845
136
    do {
1846
136
      code1 += code3 = getBlackCode();
1847
136
    } while (code3 >= 64);
1848
170
    do {
1849
170
      code2 += code3 = getWhiteCode();
1850
170
    } while (code3 >= 64);
1851
156
  } else {
1852
186
    do {
1853
186
      code1 += code3 = getWhiteCode();
1854
186
    } while (code3 >= 64);
1855
158
    do {
1856
158
      code2 += code3 = getBlackCode();
1857
158
    } while (code3 >= 64);
1858
156
  }
1859
286
  addPixels(codingLine[a0i] + code1, blackPixels);
1860
286
  if (codingLine[a0i] < columns) {
1861
270
    addPixels(codingLine[a0i] + code2, blackPixels ^ 1);
1862
270
  }
1863
1.11k
  while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1864
826
    b1i += 2;
1865
826
  }
1866
286
  break;
1867
84
      case twoDimVertR3:
1868
84
  addPixels(refLine[b1i] + 3, blackPixels);
1869
84
  blackPixels ^= 1;
1870
84
  if (codingLine[a0i] < columns) {
1871
40
    ++b1i;
1872
60
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1873
20
      b1i += 2;
1874
20
    }
1875
40
  }
1876
84
  break;
1877
32
      case twoDimVertR2:
1878
32
  addPixels(refLine[b1i] + 2, blackPixels);
1879
32
  blackPixels ^= 1;
1880
32
  if (codingLine[a0i] < columns) {
1881
30
    ++b1i;
1882
34
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1883
4
      b1i += 2;
1884
4
    }
1885
30
  }
1886
32
  break;
1887
372
      case twoDimVertR1:
1888
372
  addPixels(refLine[b1i] + 1, blackPixels);
1889
372
  blackPixels ^= 1;
1890
372
  if (codingLine[a0i] < columns) {
1891
320
    ++b1i;
1892
348
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1893
28
      b1i += 2;
1894
28
    }
1895
320
  }
1896
372
  break;
1897
1.66k
      case twoDimVert0:
1898
1.66k
  addPixels(refLine[b1i], blackPixels);
1899
1.66k
  blackPixels ^= 1;
1900
1.66k
  if (codingLine[a0i] < columns) {
1901
1.41k
    ++b1i;
1902
1.41k
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1903
0
      b1i += 2;
1904
0
    }
1905
1.41k
  }
1906
1.66k
  break;
1907
78
      case twoDimVertL3:
1908
78
  addPixelsNeg(refLine[b1i] - 3, blackPixels);
1909
78
  blackPixels ^= 1;
1910
78
  if (codingLine[a0i] < columns) {
1911
78
    if (b1i > 0) {
1912
26
      --b1i;
1913
52
    } else {
1914
52
      ++b1i;
1915
52
    }
1916
100
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1917
22
      b1i += 2;
1918
22
    }
1919
78
  }
1920
78
  break;
1921
48
      case twoDimVertL2:
1922
48
  addPixelsNeg(refLine[b1i] - 2, blackPixels);
1923
48
  blackPixels ^= 1;
1924
48
  if (codingLine[a0i] < columns) {
1925
48
    if (b1i > 0) {
1926
42
      --b1i;
1927
42
    } else {
1928
6
      ++b1i;
1929
6
    }
1930
80
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1931
32
      b1i += 2;
1932
32
    }
1933
48
  }
1934
48
  break;
1935
566
      case twoDimVertL1:
1936
566
  addPixelsNeg(refLine[b1i] - 1, blackPixels);
1937
566
  blackPixels ^= 1;
1938
566
  if (codingLine[a0i] < columns) {
1939
566
    if (b1i > 0) {
1940
498
      --b1i;
1941
498
    } else {
1942
68
      ++b1i;
1943
68
    }
1944
1.05k
    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1945
490
      b1i += 2;
1946
490
    }
1947
566
  }
1948
566
  break;
1949
124
      case EOF:
1950
124
  addPixels(columns, 0);
1951
124
  err = gTrue;
1952
124
  break;
1953
0
      default:
1954
0
  error(errSyntaxError, getPos(),
1955
0
        "Bad 2D code {0:04x} in CCITTFax stream", code1);
1956
0
  addPixels(columns, 0);
1957
0
  err = gTrue;
1958
0
  ++nErrors;
1959
0
  break;
1960
3.46k
      }
1961
3.46k
    }
1962
1963
  // 1-D encoding
1964
532
  } else {
1965
334
    codingLine[0] = 0;
1966
334
    a0i = 0;
1967
334
    blackPixels = 0;
1968
11.1k
    while (codingLine[a0i] < columns) {
1969
10.7k
      code1 = 0;
1970
10.7k
      if (blackPixels) {
1971
5.45k
  do {
1972
5.45k
    code1 += code3 = getBlackCode();
1973
5.45k
  } while (code3 >= 64);
1974
5.49k
      } else {
1975
6.17k
  do {
1976
6.17k
    code1 += code3 = getWhiteCode();
1977
6.17k
  } while (code3 >= 64);
1978
5.49k
      }
1979
10.7k
      addPixels(codingLine[a0i] + code1, blackPixels);
1980
10.7k
      blackPixels ^= 1;
1981
10.7k
    }
1982
334
  }
1983
1984
  // check for end-of-line marker, skipping over any extra zero bits
1985
  // (if EncodedByteAlign is true and EndOfLine is false, there can
1986
  // be "false" EOL markers -- i.e., if the last n unused bits in
1987
  // row i are set to zero, and the first 11-n bits in row i+1
1988
  // happen to be zero -- so we don't look for EOL markers in this
1989
  // case)
1990
866
  gotEOL = gFalse;
1991
866
  if (!endOfBlock && row == rows - 1) {
1992
0
    eof = gTrue;
1993
866
  } else if (endOfLine || !byteAlign) {
1994
866
    code1 = lookBits(12);
1995
866
    if (endOfLine) {
1996
0
      while (code1 != EOF && code1 != 0x001) {
1997
0
  eatBits(1);
1998
0
  code1 = lookBits(12);
1999
0
      }
2000
866
    } else {
2001
2.06k
      while (code1 == 0) {
2002
1.20k
  eatBits(1);
2003
1.20k
  code1 = lookBits(12);
2004
1.20k
      }
2005
866
    }
2006
866
    if (code1 == 0x001) {
2007
52
      eatBits(12);
2008
52
      gotEOL = gTrue;
2009
52
    }
2010
866
  }
2011
2012
  // byte-align the row
2013
  // (Adobe apparently doesn't do byte alignment after EOL markers
2014
  // -- I've seen CCITT image data streams in two different formats,
2015
  // both with the byteAlign flag set:
2016
  //   1. xx:x0:01:yy:yy
2017
  //   2. xx:00:1y:yy:yy
2018
  // where xx is the previous line, yy is the next line, and colons
2019
  // separate bytes.)
2020
866
  if (byteAlign && !gotEOL) {
2021
0
    inputBits &= ~7;
2022
0
  }
2023
2024
  // check for end of stream
2025
866
  if (lookBits(1) == EOF) {
2026
0
    eof = gTrue;
2027
0
  }
2028
2029
  // get 2D encoding tag
2030
866
  if (!eof && encoding > 0) {
2031
866
    nextLine2D = !lookBits(1);
2032
866
    eatBits(1);
2033
866
  }
2034
2035
  // check for end-of-block marker
2036
866
  if (endOfBlock && !endOfLine && byteAlign) {
2037
    // in this case, we didn't check for an EOL code above, so we
2038
    // need to check here
2039
0
    code1 = lookBits(24);
2040
0
    if (code1 == 0x001001) {
2041
0
      eatBits(12);
2042
0
      gotEOL = gTrue;
2043
0
    }
2044
0
  }
2045
866
  if (endOfBlock && gotEOL) {
2046
0
    code1 = lookBits(12);
2047
0
    if (code1 == 0x001) {
2048
0
      eatBits(12);
2049
0
      if (encoding > 0) {
2050
0
  lookBits(1);
2051
0
  eatBits(1);
2052
0
      }
2053
0
      if (encoding > 0) {
2054
0
  for (i = 0; i < 4; ++i) {
2055
0
    code1 = lookBits(12);
2056
0
    if (code1 != 0x001) {
2057
0
      error(errSyntaxError, getPos(),
2058
0
      "Bad RTC code in CCITTFax stream");
2059
0
      ++nErrors;
2060
0
    }
2061
0
    eatBits(12);
2062
0
    if (encoding > 0) {
2063
0
      lookBits(1);
2064
0
      eatBits(1);
2065
0
    }
2066
0
  }
2067
0
      }
2068
0
      eof = gTrue;
2069
0
    }
2070
2071
  // look for an end-of-line marker after an error -- we only do
2072
  // this if we know the stream contains end-of-line markers because
2073
  // the "just plow on" technique tends to work better otherwise
2074
866
  } else if (err && endOfLine) {
2075
0
    while (1) {
2076
0
      code1 = lookBits(13);
2077
0
      if (code1 == EOF) {
2078
0
  eof = gTrue;
2079
0
  return gFalse;
2080
0
      }
2081
0
      if ((code1 >> 1) == 0x001) {
2082
0
  break;
2083
0
      }
2084
0
      eatBits(1);
2085
0
    }
2086
0
    eatBits(12); 
2087
0
    if (encoding > 0) {
2088
0
      eatBits(1);
2089
0
      nextLine2D = !(code1 & 1);
2090
0
    }
2091
0
  }
2092
2093
  // corrupt CCITTFax streams can generate huge data expansion -- we
2094
  // avoid that case by aborting decode after 1000 errors
2095
866
  if (nErrors > 1000) {
2096
2
    error(errSyntaxError, getPos(), "Too many errors in CCITTFaxStream - aborting decode");
2097
2
    eof = gTrue;
2098
2
    return gFalse;
2099
2
  }
2100
2101
  // set up for output
2102
864
  nextCol = 0;
2103
864
  a0i = (codingLine[0] > 0) ? 0 : 1;
2104
2105
864
  ++row;
2106
2107
864
  return gTrue;
2108
866
}
2109
2110
3.46k
short CCITTFaxStream::getTwoDimCode() {
2111
3.46k
  int code;
2112
3.46k
  CCITTCode *p;
2113
3.46k
  int n;
2114
2115
3.46k
  code = 0; // make gcc happy
2116
3.46k
  if (endOfBlock) {
2117
0
    if ((code = lookBits(7)) != EOF) {
2118
0
      p = &twoDimTab1[code];
2119
0
      if (p->bits > 0) {
2120
0
  eatBits(p->bits);
2121
0
  return p->n;
2122
0
      }
2123
0
    }
2124
3.46k
  } else {
2125
8.80k
    for (n = 1; n <= 7; ++n) {
2126
8.68k
      if ((code = lookBits(n)) == EOF) {
2127
0
  break;
2128
0
      }
2129
8.68k
      if (n < 7) {
2130
8.39k
  code <<= 7 - n;
2131
8.39k
      }
2132
8.68k
      p = &twoDimTab1[code];
2133
8.68k
      if (p->bits == n) {
2134
3.34k
  eatBits(n);
2135
3.34k
  return p->n;
2136
3.34k
      }
2137
8.68k
    }
2138
3.46k
  }
2139
124
  error(errSyntaxError, getPos(),
2140
124
  "Bad two dim code ({0:04x}) in CCITTFax stream", code);
2141
124
  ++nErrors;
2142
124
  return EOF;
2143
3.46k
}
2144
2145
6.53k
short CCITTFaxStream::getWhiteCode() {
2146
6.53k
  short code;
2147
6.53k
  CCITTCode *p;
2148
6.53k
  int n;
2149
2150
6.53k
  code = 0; // make gcc happy
2151
6.53k
  if (endOfBlock) {
2152
0
    code = lookBits(12);
2153
0
    if (code == EOF) {
2154
0
      return 1;
2155
0
    }
2156
0
    if ((code >> 5) == 0) {
2157
0
      p = &whiteTab1[code];
2158
0
    } else {
2159
0
      p = &whiteTab2[code >> 3];
2160
0
    }
2161
0
    if (p->bits > 0) {
2162
0
      eatBits(p->bits);
2163
0
      return p->n;
2164
0
    }
2165
6.53k
  } else {
2166
39.5k
    for (n = 1; n <= 9; ++n) {
2167
38.7k
      code = lookBits(n);
2168
38.7k
      if (code == EOF) {
2169
0
  return 1;
2170
0
      }
2171
38.7k
      if (n < 9) {
2172
37.7k
  code = (short)(code << (9 - n));
2173
37.7k
      }
2174
38.7k
      p = &whiteTab2[code];
2175
38.7k
      if (p->bits == n) {
2176
5.69k
  eatBits(n);
2177
5.69k
  return p->n;
2178
5.69k
      }
2179
38.7k
    }
2180
2.42k
    for (n = 11; n <= 12; ++n) {
2181
1.67k
      code = lookBits(n);
2182
1.67k
      if (code == EOF) {
2183
0
  return 1;
2184
0
      }
2185
1.67k
      if (n < 12) {
2186
842
  code = (short)(code << (12 - n));
2187
842
      }
2188
1.67k
      p = &whiteTab1[code];
2189
1.67k
      if (p->bits == n) {
2190
90
  eatBits(n);
2191
90
  return p->n;
2192
90
      }
2193
1.67k
    }
2194
842
  }
2195
752
  error(errSyntaxError, getPos(),
2196
752
  "Bad white code ({0:04x}) in CCITTFax stream", code);
2197
752
  ++nErrors;
2198
  // eat a bit and return a positive number so that the caller doesn't
2199
  // go into an infinite loop
2200
752
  eatBits(1);
2201
752
  return 1;
2202
6.53k
}
2203
2204
5.75k
short CCITTFaxStream::getBlackCode() {
2205
5.75k
  short code;
2206
5.75k
  CCITTCode *p;
2207
5.75k
  int n;
2208
2209
5.75k
  code = 0; // make gcc happy
2210
5.75k
  if (endOfBlock) {
2211
0
    code = lookBits(13);
2212
0
    if (code == EOF) {
2213
0
      return 1;
2214
0
    }
2215
0
    if ((code >> 7) == 0) {
2216
0
      p = &blackTab1[code];
2217
0
    } else if ((code >> 9) == 0 && (code >> 7) != 0) {
2218
0
      p = &blackTab2[(code >> 1) - 64];
2219
0
    } else {
2220
0
      p = &blackTab3[code >> 7];
2221
0
    }
2222
0
    if (p->bits > 0) {
2223
0
      eatBits(p->bits);
2224
0
      return p->n;
2225
0
    }
2226
5.75k
  } else {
2227
14.7k
    for (n = 2; n <= 6; ++n) {
2228
13.6k
      code = lookBits(n);
2229
13.6k
      if (code == EOF) {
2230
0
  return 1;
2231
0
      }
2232
13.6k
      if (n < 6) {
2233
12.3k
  code = (short)(code << (6 - n));
2234
12.3k
      }
2235
13.6k
      p = &blackTab3[code];
2236
13.6k
      if (p->bits == n) {
2237
4.59k
  eatBits(n);
2238
4.59k
  return p->n;
2239
4.59k
      }
2240
13.6k
    }
2241
7.25k
    for (n = 7; n <= 12; ++n) {
2242
6.28k
      code = lookBits(n);
2243
6.28k
      if (code == EOF) {
2244
0
  return 1;
2245
0
      }
2246
6.28k
      if (n < 12) {
2247
5.28k
  code = (short)(code << (12 - n));
2248
5.28k
      }
2249
6.28k
      if (code >= 64) {
2250
480
  p = &blackTab2[code - 64];
2251
480
  if (p->bits == n) {
2252
186
    eatBits(n);
2253
186
    return p->n;
2254
186
  }
2255
480
      }
2256
6.28k
    }
2257
4.29k
    for (n = 10; n <= 13; ++n) {
2258
3.58k
      code = lookBits(n);
2259
3.58k
      if (code == EOF) {
2260
0
  return 1;
2261
0
      }
2262
3.58k
      if (n < 13) {
2263
2.86k
  code = (short)(code << (13 - n));
2264
2.86k
      }
2265
3.58k
      p = &blackTab1[code];
2266
3.58k
      if (p->bits == n) {
2267
262
  eatBits(n);
2268
262
  return p->n;
2269
262
      }
2270
3.58k
    }
2271
968
  }
2272
706
  error(errSyntaxError, getPos(),
2273
706
  "Bad black code ({0:04x}) in CCITTFax stream", code);
2274
706
  ++nErrors;
2275
  // eat a bit and return a positive number so that the caller doesn't
2276
  // go into an infinite loop
2277
706
  eatBits(1);
2278
706
  return 1;
2279
5.75k
}
2280
2281
76.3k
short CCITTFaxStream::lookBits(int n) {
2282
76.3k
  int c;
2283
2284
84.0k
  while (inputBits < n) {
2285
7.66k
    if ((c = str->getChar()) == EOF) {
2286
0
      if (inputBits == 0) {
2287
0
  return EOF;
2288
0
      }
2289
      // near the end of the stream, the caller may ask for more bits
2290
      // than are available, but there may still be a valid code in
2291
      // however many bits are available -- we need to return correct
2292
      // data in this case
2293
0
      return (short)((inputBuf << (n - inputBits)) & (0xffffffff >> (32 - n)));
2294
0
    }
2295
7.66k
    inputBuf = (inputBuf << 8) + c;
2296
7.66k
    inputBits += 8;
2297
7.66k
  }
2298
76.3k
  return (short)((inputBuf >> (inputBits - n)) & (0xffffffff >> (32 - n)));
2299
76.3k
}
2300
2301
GString *CCITTFaxStream::getPSFilter(int psLevel, const char *indent,
2302
0
             GBool okToReadStream) {
2303
0
  GString *s;
2304
2305
0
  if (psLevel < 2) {
2306
0
    return NULL;
2307
0
  }
2308
0
  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
2309
0
    return NULL;
2310
0
  }
2311
0
  s->append(indent)->append("<< ");
2312
0
  if (encoding != 0) {
2313
0
    s->appendf("/K {0:d} ", encoding);
2314
0
  }
2315
0
  if (endOfLine) {
2316
0
    s->append("/EndOfLine true ");
2317
0
  }
2318
0
  if (byteAlign) {
2319
0
    s->append("/EncodedByteAlign true ");
2320
0
  }
2321
0
  s->appendf("/Columns {0:d} ", columns);
2322
0
  if (rows != 0) {
2323
0
    s->appendf("/Rows {0:d} ", rows);
2324
0
  }
2325
0
  if (!endOfBlock) {
2326
0
    s->append("/EndOfBlock false ");
2327
0
  }
2328
0
  if (black) {
2329
0
    s->append("/BlackIs1 true ");
2330
0
  }
2331
0
  s->append(">> /CCITTFaxDecode filter\n");
2332
0
  return s;
2333
0
}
2334
2335
0
GBool CCITTFaxStream::isBinary(GBool last) {
2336
0
  return str->isBinary(gTrue);
2337
0
}
2338
2339
//------------------------------------------------------------------------
2340
// DCTStream
2341
//------------------------------------------------------------------------
2342
2343
#if HAVE_JPEGLIB
2344
2345
DCTStream::DCTStream(Stream *strA, GBool colorXformA):
2346
    FilterStream(strA) {
2347
  colorXform = colorXformA;
2348
  lineBuf = NULL;
2349
  inlineImage = str->isEmbedStream();
2350
}
2351
2352
DCTStream::~DCTStream() {
2353
  delete str;
2354
}
2355
2356
Stream *DCTStream::copy() {
2357
  return new DCTStream(str->copy(), colorXform);
2358
}
2359
2360
void DCTStream::reset() {
2361
  int i;
2362
2363
  lineBuf = NULL;
2364
  error = gFalse;
2365
2366
  str->reset();
2367
2368
  // initialize the libjpeg decompression object
2369
  decomp.err = jpeg_std_error(&errorMgr.err);
2370
  errorMgr.err.error_exit = &errorExit;
2371
  errorMgr.err.output_message = &errorMessage;
2372
  if (setjmp(errorMgr.setjmpBuf)) {
2373
    error = gTrue;
2374
    return;
2375
  }
2376
  jpeg_create_decompress(&decomp);
2377
2378
  // set up the data source manager
2379
  sourceMgr.src.next_input_byte = NULL;
2380
  sourceMgr.src.bytes_in_buffer = 0;
2381
  sourceMgr.src.init_source = &initSourceCbk;
2382
  sourceMgr.src.fill_input_buffer = &fillInputBufferCbk;
2383
  sourceMgr.src.skip_input_data = &skipInputDataCbk;
2384
  sourceMgr.src.resync_to_restart = &jpeg_resync_to_restart;
2385
  sourceMgr.src.term_source = &termSourceCbk;
2386
  sourceMgr.str = this;
2387
  decomp.src = &sourceMgr.src;
2388
2389
  // read the header
2390
  jpeg_read_header(&decomp, TRUE);
2391
  jpeg_calc_output_dimensions(&decomp);
2392
2393
  // set up the color transform
2394
  if (!decomp.saw_Adobe_marker && colorXform >= 0) {
2395
    if (decomp.num_components == 3) {
2396
      decomp.jpeg_color_space = colorXform ? JCS_YCbCr : JCS_RGB;
2397
      decomp.out_color_space = JCS_RGB;
2398
      decomp.out_color_components = 3;
2399
    } else if (decomp.num_components == 4) {
2400
      decomp.jpeg_color_space = colorXform ? JCS_YCCK : JCS_CMYK;
2401
      decomp.out_color_space = JCS_CMYK;
2402
      decomp.out_color_components = 4;
2403
    }
2404
  }
2405
2406
  // allocate a line buffer
2407
  if ((lineBufHeight = decomp.rec_outbuf_height) > 4) {
2408
    lineBufHeight = 4;
2409
  }
2410
  lineBuf = (char *)gmallocn(lineBufHeight * decomp.out_color_components,
2411
           decomp.output_width);
2412
  for (i = 0; i < lineBufHeight; ++i) {
2413
    lineBufRows[i] = lineBuf +
2414
                     i * decomp.out_color_components * decomp.output_width;
2415
  }
2416
  bufPtr = bufEnd = lineBuf;
2417
2418
  // start up the decompression process
2419
  jpeg_start_decompress(&decomp);
2420
}
2421
2422
GBool DCTStream::checkSequentialInterleaved() {
2423
  //~ this is unimplemented
2424
  return gTrue;
2425
}
2426
2427
void DCTStream::close() {
2428
  // we don't call jpeg_finish_decompress() here because it will report
2429
  // an error if the full image wasn't read
2430
  if (setjmp(errorMgr.setjmpBuf)) {
2431
    goto skip;
2432
  }
2433
  jpeg_destroy_decompress(&decomp);
2434
 skip:
2435
  gfree(lineBuf);
2436
  FilterStream::close();
2437
}
2438
2439
int DCTStream::getChar() {
2440
  if (error) {
2441
    return EOF;
2442
  }
2443
  if (bufPtr == bufEnd) {
2444
    if (!fillBuf()) {
2445
      return EOF;
2446
    }
2447
  }
2448
  return *bufPtr++ & 0xff;
2449
}
2450
2451
int DCTStream::lookChar() {
2452
  if (error) {
2453
    return EOF;
2454
  }
2455
  if (bufPtr == bufEnd) {
2456
    if (!fillBuf()) {
2457
      return EOF;
2458
    }
2459
  }
2460
  return *bufPtr & 0xff;
2461
}
2462
2463
int DCTStream::getBlock(char *blk, int size) {
2464
  int nRead, nAvail, n;
2465
2466
  if (error) {
2467
    return 0;
2468
  }
2469
  nRead = 0;
2470
  while (nRead < size) {
2471
    if (bufPtr == bufEnd) {
2472
      if (!fillBuf()) {
2473
  break;
2474
      }
2475
    }
2476
    nAvail = bufEnd - bufPtr;
2477
    n = (nAvail < size - nRead) ? nAvail : size - nRead;
2478
    memcpy(blk + nRead, bufPtr, n);
2479
    bufPtr += n;
2480
    nRead += n;
2481
  }
2482
  return nRead;
2483
}
2484
2485
GBool DCTStream::fillBuf() {
2486
  int nLines;
2487
2488
  if (setjmp(errorMgr.setjmpBuf)) {
2489
    error = gTrue;
2490
    return gFalse;
2491
  }
2492
  nLines = jpeg_read_scanlines(&decomp, (JSAMPARRAY)lineBufRows,
2493
             lineBufHeight);
2494
  bufPtr = lineBuf;
2495
  bufEnd = lineBuf +
2496
           nLines * decomp.out_color_components * decomp.output_width;
2497
  return nLines > 0;
2498
}
2499
2500
void DCTStream::errorExit(j_common_ptr d) {
2501
  DCTErrorMgr *errMgr = (DCTErrorMgr *)d->err;
2502
  longjmp(errMgr->setjmpBuf, 1);
2503
}
2504
2505
void DCTStream::errorMessage(j_common_ptr d) {
2506
#if 0 // for debugging
2507
  char buf[JMSG_LENGTH_MAX];
2508
2509
  (*d->err->format_message)(d, buf);
2510
  fprintf(stderr, "%s\n", buf);
2511
#endif
2512
}
2513
2514
void DCTStream::initSourceCbk(j_decompress_ptr d) {
2515
  DCTSourceMgr *sourceMgr = (DCTSourceMgr *)d->src;
2516
2517
  sourceMgr->src.next_input_byte = NULL;
2518
  sourceMgr->src.bytes_in_buffer = 0;
2519
}
2520
2521
boolean DCTStream::fillInputBufferCbk(j_decompress_ptr d) {
2522
  DCTSourceMgr *sourceMgr = (DCTSourceMgr *)d->src;
2523
  int c, n;
2524
2525
  // for inline images, we need to read one byte at a time so we don't
2526
  // read past the end of the input data
2527
  if (sourceMgr->str->inlineImage) {
2528
    c = sourceMgr->str->str->getChar();
2529
    if (c == EOF) {
2530
      sourceMgr->buf[0] = (char)0xff;
2531
      sourceMgr->buf[1] = (char)JPEG_EOI;
2532
      sourceMgr->src.bytes_in_buffer = 2;
2533
    } else {
2534
      sourceMgr->buf[0] = (char)c;
2535
      sourceMgr->src.bytes_in_buffer = 1;
2536
    }
2537
  } else {
2538
    n = sourceMgr->str->str->getBlock(sourceMgr->buf, dctStreamBufSize);
2539
    if (n > 0) {
2540
      sourceMgr->src.bytes_in_buffer = (size_t)n;
2541
    } else {
2542
      sourceMgr->buf[0] = (char)0xff;
2543
      sourceMgr->buf[1] = (char)JPEG_EOI;
2544
      sourceMgr->src.bytes_in_buffer = 2;
2545
    }
2546
  }
2547
  sourceMgr->src.next_input_byte = (JOCTET *)sourceMgr->buf;
2548
  return TRUE;
2549
}
2550
2551
void DCTStream::skipInputDataCbk(j_decompress_ptr d, long numBytes) {
2552
  DCTSourceMgr *sourceMgr = (DCTSourceMgr *)d->src;
2553
2554
  if (numBytes > 0) {
2555
    if ((long)sourceMgr->src.bytes_in_buffer < numBytes) {
2556
      sourceMgr->str->str->discardChars(
2557
       (Guint)(numBytes - sourceMgr->src.bytes_in_buffer));
2558
      sourceMgr->src.bytes_in_buffer = 0;
2559
    } else {
2560
      sourceMgr->src.bytes_in_buffer -= numBytes;
2561
      sourceMgr->src.next_input_byte += numBytes;
2562
    }
2563
  }
2564
}
2565
2566
void DCTStream::termSourceCbk(j_decompress_ptr d) {
2567
}
2568
2569
#else // HAVE_JPEGLIB
2570
2571
#define idctScaleA 1024
2572
#define idctScaleB 1138
2573
#define idctScaleC 1730
2574
#define idctScaleD 1609
2575
#define idctScaleE 1264
2576
#define idctScaleF 1922
2577
#define idctScaleG 1788
2578
#define idctScaleH 2923
2579
#define idctScaleI 2718
2580
#define idctScaleJ 2528
2581
2582
static int idctScaleMat[64] = {
2583
  idctScaleA, idctScaleB, idctScaleC, idctScaleD, idctScaleA, idctScaleD, idctScaleC, idctScaleB,
2584
  idctScaleB, idctScaleE, idctScaleF, idctScaleG, idctScaleB, idctScaleG, idctScaleF, idctScaleE,
2585
  idctScaleC, idctScaleF, idctScaleH, idctScaleI, idctScaleC, idctScaleI, idctScaleH, idctScaleF,
2586
  idctScaleD, idctScaleG, idctScaleI, idctScaleJ, idctScaleD, idctScaleJ, idctScaleI, idctScaleG,
2587
  idctScaleA, idctScaleB, idctScaleC, idctScaleD, idctScaleA, idctScaleD, idctScaleC, idctScaleB,
2588
  idctScaleD, idctScaleG, idctScaleI, idctScaleJ, idctScaleD, idctScaleJ, idctScaleI, idctScaleG,
2589
  idctScaleC, idctScaleF, idctScaleH, idctScaleI, idctScaleC, idctScaleI, idctScaleH, idctScaleF,
2590
  idctScaleB, idctScaleE, idctScaleF, idctScaleG, idctScaleB, idctScaleG, idctScaleF, idctScaleE
2591
};
2592
2593
// color conversion parameters (16.16 fixed point format)
2594
0
#define dctCrToR   91881  //  1.4020
2595
0
#define dctCbToG  -22553  // -0.3441363
2596
0
#define dctCrToG  -46802  // -0.71413636
2597
0
#define dctCbToB  116130  //  1.772
2598
2599
// The dctClip function clips signed integers to the [0,255] range.
2600
// To handle valid DCT inputs, this must support an input range of at
2601
// least [-256,511].  Invalid DCT inputs (e.g., from damaged PDF
2602
// files) can result in arbitrary values, so we want to mask those
2603
// out.  We round the input range size up to a power of 2 (so we can
2604
// use a bit mask), which gives us an input range of [-384,639].  The
2605
// end result is:
2606
//     input       output
2607
//     ----------  ------
2608
//     <-384       X        invalid inputs -> output is "don't care"
2609
//     -384..-257  0        invalid inputs, clipped
2610
//     -256..-1    0        valid inputs, need to be clipped
2611
//     0..255      0..255
2612
//     256..511    255      valid inputs, need to be clipped
2613
//     512..639    255      invalid inputs, clipped
2614
//     >=512       X        invalid inputs -> output is "don't care"
2615
2616
1.02k
#define dctClipOffset  384
2617
0
#define dctClipMask   1023
2618
static Guchar dctClipData[1024];
2619
2620
47
static inline void dctClipInit() {
2621
47
  static int initDone = 0;
2622
47
  int i;
2623
47
  if (!initDone) {
2624
385
    for (i = -384; i < 0; ++i) {
2625
384
      dctClipData[dctClipOffset + i] = 0;
2626
384
    }
2627
257
    for (i = 0; i < 256; ++i) {
2628
256
      dctClipData[dctClipOffset + i] = (Guchar)i;
2629
256
    }
2630
384
    for (i = 256; i < 639; ++i) {
2631
383
      dctClipData[dctClipOffset + i] = 255;
2632
383
    }
2633
1
    initDone = 1;
2634
1
  }
2635
47
}
2636
2637
0
static inline Guchar dctClip(int x) {
2638
0
  return dctClipData[(dctClipOffset + x) & dctClipMask];
2639
0
}
2640
2641
// zig zag decode map
2642
static int dctZigZag[64] = {
2643
   0,
2644
   1,  8,
2645
  16,  9,  2,
2646
   3, 10, 17, 24,
2647
  32, 25, 18, 11, 4,
2648
   5, 12, 19, 26, 33, 40,
2649
  48, 41, 34, 27, 20, 13,  6,
2650
   7, 14, 21, 28, 35, 42, 49, 56,
2651
  57, 50, 43, 36, 29, 22, 15,
2652
  23, 30, 37, 44, 51, 58,
2653
  59, 52, 45, 38, 31,
2654
  39, 46, 53, 60,
2655
  61, 54, 47,
2656
  55, 62,
2657
  63
2658
};
2659
2660
DCTStream::DCTStream(Stream *strA, GBool colorXformA):
2661
47
    FilterStream(strA) {
2662
47
  int i;
2663
2664
47
  prepared = gFalse;
2665
47
  colorXform = colorXformA;
2666
47
  progressive = interleaved = gFalse;
2667
47
  width = height = 0;
2668
47
  mcuWidth = mcuHeight = 0;
2669
47
  numComps = 0;
2670
47
  comp = 0;
2671
47
  x = y = 0;
2672
235
  for (i = 0; i < 4; ++i) {
2673
188
    frameBuf[i] = NULL;
2674
188
  }
2675
47
  rowBuf = NULL;
2676
47
  memset(dcHuffTables, 0, sizeof(dcHuffTables));
2677
47
  memset(acHuffTables, 0, sizeof(acHuffTables));
2678
2679
47
  dctClipInit();
2680
47
}
2681
2682
47
DCTStream::~DCTStream() {
2683
47
  close();
2684
47
  delete str;
2685
47
}
2686
2687
24
Stream *DCTStream::copy() {
2688
24
  return new DCTStream(str->copy(), colorXform);
2689
24
}
2690
2691
0
void DCTStream::reset() {
2692
0
  int i;
2693
2694
0
  str->reset();
2695
2696
0
  progressive = interleaved = gFalse;
2697
0
  width = height = 0;
2698
0
  numComps = 0;
2699
0
  numQuantTables = 0;
2700
0
  numDCHuffTables = 0;
2701
0
  numACHuffTables = 0;
2702
0
  gotJFIFMarker = gFalse;
2703
0
  gotAdobeMarker = gFalse;
2704
0
  restartInterval = 0;
2705
2706
0
  if (!readHeader(gTrue)) {
2707
    // force an EOF condition
2708
0
    progressive = gTrue;
2709
0
    y = height;
2710
0
    prepared = gTrue;
2711
0
    return;
2712
0
  }
2713
2714
  // compute MCU size
2715
0
  if (numComps == 1) {
2716
0
    compInfo[0].hSample = compInfo[0].vSample = 1;
2717
0
  }
2718
0
  mcuWidth = compInfo[0].hSample;
2719
0
  mcuHeight = compInfo[0].vSample;
2720
0
  for (i = 1; i < numComps; ++i) {
2721
0
    if (compInfo[i].hSample > mcuWidth) {
2722
0
      mcuWidth = compInfo[i].hSample;
2723
0
    }
2724
0
    if (compInfo[i].vSample > mcuHeight) {
2725
0
      mcuHeight = compInfo[i].vSample;
2726
0
    }
2727
0
  }
2728
0
  mcuWidth *= 8;
2729
0
  mcuHeight *= 8;
2730
2731
  // figure out color transform
2732
0
  if (colorXform == -1) {
2733
0
    if (numComps == 3) {
2734
0
      if (gotJFIFMarker) {
2735
0
  colorXform = 1;
2736
0
      } else if (compInfo[0].id == 82 && compInfo[1].id == 71 &&
2737
0
     compInfo[2].id == 66) { // ASCII "RGB"
2738
0
  colorXform = 0;
2739
0
      } else {
2740
0
  colorXform = 1;
2741
0
      }
2742
0
    } else {
2743
0
      colorXform = 0;
2744
0
    }
2745
0
  }
2746
2747
0
  prepared = gFalse;
2748
0
}
2749
2750
0
GBool DCTStream::checkSequentialInterleaved() {
2751
0
  GBool headerOk;
2752
2753
0
  str->reset();
2754
2755
0
  progressive = interleaved = gFalse;
2756
0
  width = height = 0;
2757
0
  numComps = 0;
2758
0
  numQuantTables = 0;
2759
0
  numDCHuffTables = 0;
2760
0
  numACHuffTables = 0;
2761
0
  gotJFIFMarker = gFalse;
2762
0
  gotAdobeMarker = gFalse;
2763
0
  restartInterval = 0;
2764
2765
0
  headerOk = readHeader(gTrue);
2766
2767
0
  FilterStream::close();
2768
2769
0
  return headerOk && !progressive && interleaved;
2770
0
}
2771
2772
47
void DCTStream::close() {
2773
47
  int i;
2774
2775
235
  for (i = 0; i < 4; ++i) {
2776
188
    gfree(frameBuf[i]);
2777
188
    frameBuf[i] = NULL;
2778
188
  }
2779
47
  gfree(rowBuf);
2780
47
  rowBuf = NULL;
2781
47
  FilterStream::close();
2782
47
}
2783
2784
0
int DCTStream::getChar() {
2785
0
  int c;
2786
2787
0
  if (!prepared) {
2788
0
    prepare();
2789
0
  }
2790
0
  if (progressive || !interleaved) {
2791
0
    if (y >= height) {
2792
0
      return EOF;
2793
0
    }
2794
0
    c = frameBuf[comp][y * bufWidth + x];
2795
0
    if (++comp == numComps) {
2796
0
      comp = 0;
2797
0
      if (++x == width) {
2798
0
  x = 0;
2799
0
  ++y;
2800
0
      }
2801
0
    }
2802
0
  } else {
2803
0
    if (rowBufPtr == rowBufEnd) {
2804
0
      if (y + mcuHeight >= height) {
2805
0
  return EOF;
2806
0
      }
2807
0
      y += mcuHeight;
2808
0
      if (!readMCURow()) {
2809
0
  y = height;
2810
0
  return EOF;
2811
0
      }
2812
0
    }
2813
0
    c = *rowBufPtr++;
2814
0
  }
2815
0
  return c;
2816
0
}
2817
2818
0
int DCTStream::lookChar() {
2819
0
  if (!prepared) {
2820
0
    prepare();
2821
0
  }
2822
0
  if (progressive || !interleaved) {
2823
0
    if (y >= height) {
2824
0
      return EOF;
2825
0
    }
2826
0
    return frameBuf[comp][y * bufWidth + x];
2827
0
  } else {
2828
0
    if (rowBufPtr == rowBufEnd) {
2829
0
      if (y + mcuHeight >= height) {
2830
0
  return EOF;
2831
0
      }
2832
0
      if (!readMCURow()) {
2833
0
  y = height;
2834
0
  return EOF;
2835
0
      }
2836
0
    }
2837
0
    return *rowBufPtr;
2838
0
  }
2839
0
}
2840
2841
0
int DCTStream::getBlock(char *blk, int size) {
2842
0
  int nRead, nAvail, n;
2843
2844
0
  if (!prepared) {
2845
0
    prepare();
2846
0
  }
2847
0
  if (progressive || !interleaved) {
2848
0
    if (y >= height) {
2849
0
      return 0;
2850
0
    }
2851
0
    for (nRead = 0; nRead < size; ++nRead) {
2852
0
      blk[nRead] = (char)frameBuf[comp][y * bufWidth + x];
2853
0
      if (++comp == numComps) {
2854
0
  comp = 0;
2855
0
  if (++x == width) {
2856
0
    x = 0;
2857
0
    ++y;
2858
0
    if (y >= height) {
2859
0
      ++nRead;
2860
0
      break;
2861
0
    }
2862
0
  }
2863
0
      }
2864
0
    }
2865
0
  } else {
2866
0
    nRead = 0;
2867
0
    while (nRead < size) {
2868
0
      if (rowBufPtr == rowBufEnd) {
2869
0
  if (y + mcuHeight >= height) {
2870
0
    break;
2871
0
  }
2872
0
  y += mcuHeight;
2873
0
  if (!readMCURow()) {
2874
0
    y = height;
2875
0
    break;
2876
0
  }
2877
0
      }
2878
0
      nAvail = (int)(rowBufEnd - rowBufPtr);
2879
0
      n = (nAvail < size - nRead) ? nAvail : size - nRead;
2880
0
      memcpy(blk + nRead, rowBufPtr, n);
2881
0
      rowBufPtr += n;
2882
0
      nRead += n;
2883
0
    }
2884
0
  }
2885
0
  return nRead;
2886
0
}
2887
2888
0
void DCTStream::prepare() {
2889
0
  int i;
2890
2891
0
  if (progressive || !interleaved) {
2892
2893
    // allocate a buffer for the whole image
2894
0
    bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
2895
0
    bufHeight = ((height + mcuHeight - 1) / mcuHeight) * mcuHeight;
2896
0
    if (bufWidth <= 0 || bufHeight <= 0 ||
2897
0
  bufWidth > INT_MAX / bufWidth / (int)sizeof(int)) {
2898
0
      error(errSyntaxError, getPos(), "Invalid image size in DCT stream");
2899
0
      y = height;
2900
0
      prepared = gTrue;
2901
0
      return;
2902
0
    }
2903
0
#if USE_EXCEPTIONS
2904
0
    try {
2905
0
#endif
2906
0
      for (i = 0; i < numComps; ++i) {
2907
0
  frameBuf[i] = (int *)gmallocn(bufWidth * bufHeight, sizeof(int));
2908
0
  memset(frameBuf[i], 0, bufWidth * bufHeight * sizeof(int));
2909
0
      }
2910
0
#if USE_EXCEPTIONS
2911
0
    } catch (GMemException) {
2912
0
      error(errSyntaxError, getPos(), "Out of memory in DCT stream");
2913
0
      y = height;
2914
0
      prepared = gTrue;
2915
0
      return;
2916
0
    }
2917
0
#endif
2918
2919
    // read the image data
2920
0
    do {
2921
0
      restartMarker = 0xd0;
2922
0
      restart();
2923
0
      readScan();
2924
0
    } while (readHeader(gFalse));
2925
2926
    // decode
2927
0
    decodeImage();
2928
2929
    // initialize counters
2930
0
    comp = 0;
2931
0
    x = 0;
2932
0
    y = 0;
2933
2934
0
  } else {
2935
2936
0
    if (scanInfo.numComps != numComps) {
2937
0
      error(errSyntaxError, getPos(), "Invalid scan in sequential DCT stream");
2938
0
      y = height;
2939
0
      prepared = gTrue;
2940
0
      return;
2941
0
    }
2942
2943
    // allocate a buffer for one row of MCUs
2944
0
    bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
2945
0
    rowBuf = (Guchar *)gmallocn(numComps * mcuHeight, bufWidth);
2946
0
    rowBufPtr = rowBufEnd = rowBuf;
2947
2948
    // initialize counters
2949
0
    y = -mcuHeight;
2950
2951
0
    restartMarker = 0xd0;
2952
0
    restart();
2953
0
  }
2954
2955
0
  prepared = gTrue;
2956
0
}
2957
2958
0
void DCTStream::restart() {
2959
0
  int i;
2960
2961
0
  inputBits = 0;
2962
0
  restartCtr = restartInterval;
2963
0
  for (i = 0; i < numComps; ++i) {
2964
0
    compInfo[i].prevDC = 0;
2965
0
  }
2966
0
  eobRun = 0;
2967
0
}
2968
2969
// Read one row of MCUs from a sequential JPEG stream.
2970
0
GBool DCTStream::readMCURow() {
2971
0
  int data1[64];
2972
0
  Guchar data2[64];
2973
0
  Guchar *p1, *p2;
2974
0
  int pY, pCb, pCr, pR, pG, pB;
2975
0
  int h, v, horiz, vert, hSub, vSub;
2976
0
  int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
2977
0
  int c;
2978
2979
0
  for (cc = 0; cc < numComps; ++cc) {
2980
0
    if (scanInfo.dcHuffTable[cc] >= numDCHuffTables ||
2981
0
  scanInfo.acHuffTable[cc] >= numACHuffTables) {
2982
0
      error(errSyntaxError, getPos(),
2983
0
      "Bad DCT data: invalid Huffman table index");
2984
0
      return gFalse;
2985
0
    }
2986
0
    if (compInfo[cc].quantTable > numQuantTables) {
2987
0
      error(errSyntaxError, getPos(),
2988
0
      "Bad DCT data: invalid quant table index");
2989
0
      return gFalse;
2990
0
    }
2991
0
  }
2992
2993
0
  for (x1 = 0; x1 < width; x1 += mcuWidth) {
2994
2995
    // deal with restart marker
2996
0
    if (restartInterval > 0 && restartCtr == 0) {
2997
0
      c = readMarker();
2998
0
      if (c != restartMarker) {
2999
0
  error(errSyntaxError, getPos(),
3000
0
        "Bad DCT data: incorrect restart marker");
3001
0
  return gFalse;
3002
0
      }
3003
0
      if (++restartMarker == 0xd8)
3004
0
  restartMarker = 0xd0;
3005
0
      restart();
3006
0
    }
3007
3008
    // read one MCU
3009
0
    for (cc = 0; cc < numComps; ++cc) {
3010
0
      h = compInfo[cc].hSample;
3011
0
      v = compInfo[cc].vSample;
3012
0
      horiz = mcuWidth / h;
3013
0
      vert = mcuHeight / v;
3014
0
      hSub = horiz / 8;
3015
0
      vSub = vert / 8;
3016
0
      for (y2 = 0; y2 < mcuHeight; y2 += vert) {
3017
0
  for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
3018
0
    if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]],
3019
0
          &acHuffTables[scanInfo.acHuffTable[cc]],
3020
0
          &compInfo[cc].prevDC,
3021
0
          data1)) {
3022
0
      return gFalse;
3023
0
    }
3024
0
    transformDataUnit(quantTables[compInfo[cc].quantTable],
3025
0
          data1, data2);
3026
0
    if (hSub == 1 && vSub == 1 && x1+x2+8 <= width) {
3027
0
      for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3028
0
        p1 = &rowBuf[((y2+y3) * width + (x1+x2)) * numComps + cc];
3029
0
        p1[0]          = data2[i];
3030
0
        p1[  numComps] = data2[i+1];
3031
0
        p1[2*numComps] = data2[i+2];
3032
0
        p1[3*numComps] = data2[i+3];
3033
0
        p1[4*numComps] = data2[i+4];
3034
0
        p1[5*numComps] = data2[i+5];
3035
0
        p1[6*numComps] = data2[i+6];
3036
0
        p1[7*numComps] = data2[i+7];
3037
0
      }
3038
0
    } else if (hSub == 2 && vSub == 2 && x1+x2+16 <= width) {
3039
0
      for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
3040
0
        p1 = &rowBuf[((y2+y3) * width + (x1+x2)) * numComps + cc];
3041
0
        p2 = p1 + width * numComps;
3042
0
        p1[0] = p1[numComps] =
3043
0
    p2[0] = p2[numComps] = data2[i];
3044
0
        p1[2*numComps] = p1[3*numComps] =
3045
0
    p2[2*numComps] = p2[3*numComps] = data2[i+1];
3046
0
        p1[4*numComps] = p1[5*numComps] =
3047
0
    p2[4*numComps] = p2[5*numComps] = data2[i+2];
3048
0
        p1[6*numComps] = p1[7*numComps] =
3049
0
    p2[6*numComps] = p2[7*numComps] = data2[i+3];
3050
0
        p1[8*numComps] = p1[9*numComps] =
3051
0
    p2[8*numComps] = p2[9*numComps] = data2[i+4];
3052
0
        p1[10*numComps] = p1[11*numComps] =
3053
0
    p2[10*numComps] = p2[11*numComps] = data2[i+5];
3054
0
        p1[12*numComps] = p1[13*numComps] =
3055
0
    p2[12*numComps] = p2[13*numComps] = data2[i+6];
3056
0
        p1[14*numComps] = p1[15*numComps] =
3057
0
    p2[14*numComps] = p2[15*numComps] = data2[i+7];
3058
0
      }
3059
0
    } else {
3060
0
      p1 = &rowBuf[(y2 * width + (x1+x2)) * numComps + cc];
3061
0
      i = 0;
3062
0
      for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
3063
0
        for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
3064
0
    for (y5 = 0; y5 < vSub; ++y5) {
3065
0
      for (x5 = 0; x5 < hSub && x1+x2+x4+x5 < width; ++x5) {
3066
0
        p1[((y4+y5) * width + (x4+x5)) * numComps] = data2[i];
3067
0
      }
3068
0
    }
3069
0
    ++i;
3070
0
        }
3071
0
      }
3072
0
    }
3073
0
  }
3074
0
      }
3075
0
    }
3076
0
    --restartCtr;
3077
0
  }
3078
3079
  // color space conversion
3080
0
  if (colorXform) {
3081
    // convert YCbCr to RGB
3082
0
    if (numComps == 3) {
3083
0
      for (i = 0, p1 = rowBuf; i < width * mcuHeight; ++i, p1 += 3) {
3084
0
  pY = p1[0];
3085
0
  pCb = p1[1] - 128;
3086
0
  pCr = p1[2] - 128;
3087
0
  pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
3088
0
  p1[0] = dctClip(pR);
3089
0
  pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
3090
0
  p1[1] = dctClip(pG);
3091
0
  pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
3092
0
  p1[2] = dctClip(pB);
3093
0
      }
3094
    // convert YCbCrK to CMYK (K is passed through unchanged)
3095
0
    } else if (numComps == 4) {
3096
0
      for (i = 0, p1 = rowBuf; i < width * mcuHeight; ++i, p1 += 4) {
3097
0
  pY = p1[0];
3098
0
  pCb = p1[1] - 128;
3099
0
  pCr = p1[2] - 128;
3100
0
  pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
3101
0
  p1[0] = (Guchar)(255 - dctClip(pR));
3102
0
  pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
3103
0
  p1[1] = (Guchar)(255 - dctClip(pG));
3104
0
  pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
3105
0
  p1[2] = (Guchar)(255 - dctClip(pB));
3106
0
      }
3107
0
    }
3108
0
  }
3109
3110
0
  rowBufPtr = rowBuf;
3111
0
  if (y + mcuHeight <= height) {
3112
0
    rowBufEnd = rowBuf + numComps * width * mcuHeight;
3113
0
  } else {
3114
0
    rowBufEnd = rowBuf + numComps * width * (height - y);
3115
0
  }
3116
3117
0
  return gTrue;
3118
0
}
3119
3120
// Read one scan from a progressive or non-interleaved JPEG stream.
3121
0
void DCTStream::readScan() {
3122
0
  int data[64];
3123
0
  int x1, y1, dx1, dy1, x2, y2, y3, cc, i;
3124
0
  int h, v, horiz, vert, vSub;
3125
0
  int *p1;
3126
0
  int c;
3127
3128
0
  for (cc = 0; cc < numComps; ++cc) {
3129
0
    if (scanInfo.comp[cc] &&
3130
0
  (scanInfo.dcHuffTable[cc] >= numDCHuffTables ||
3131
0
   ((!progressive || scanInfo.lastCoeff > 0) &&
3132
0
    scanInfo.acHuffTable[cc] >= numACHuffTables))) {
3133
0
      error(errSyntaxError, getPos(),
3134
0
      "Bad DCT data: invalid Huffman table index");
3135
0
      return;
3136
0
    }
3137
0
    if (compInfo[cc].quantTable > numQuantTables) {
3138
0
      error(errSyntaxError, getPos(),
3139
0
      "Bad DCT data: invalid quant table index");
3140
0
      return;
3141
0
    }
3142
0
  }
3143
3144
0
  if (scanInfo.numComps == 1) {
3145
0
    for (cc = 0; cc < numComps; ++cc) {
3146
0
      if (scanInfo.comp[cc]) {
3147
0
  break;
3148
0
      }
3149
0
    }
3150
0
    dx1 = mcuWidth / compInfo[cc].hSample;
3151
0
    dy1 = mcuHeight / compInfo[cc].vSample;
3152
0
  } else {
3153
0
    dx1 = mcuWidth;
3154
0
    dy1 = mcuHeight;
3155
0
  }
3156
3157
0
  for (y1 = 0; y1 < height; y1 += dy1) {
3158
0
    for (x1 = 0; x1 < width; x1 += dx1) {
3159
3160
      // deal with restart marker
3161
0
      if (restartInterval > 0 && restartCtr == 0) {
3162
0
  c = readMarker();
3163
0
  if (c != restartMarker) {
3164
0
    error(errSyntaxError, getPos(),
3165
0
    "Bad DCT data: incorrect restart marker");
3166
0
    return;
3167
0
  }
3168
0
  if (++restartMarker == 0xd8) {
3169
0
    restartMarker = 0xd0;
3170
0
  }
3171
0
  restart();
3172
0
      }
3173
3174
      // read one MCU
3175
0
      for (cc = 0; cc < numComps; ++cc) {
3176
0
  if (!scanInfo.comp[cc]) {
3177
0
    continue;
3178
0
  }
3179
3180
0
  h = compInfo[cc].hSample;
3181
0
  v = compInfo[cc].vSample;
3182
0
  horiz = mcuWidth / h;
3183
0
  vert = mcuHeight / v;
3184
0
  vSub = vert / 8;
3185
0
  for (y2 = 0; y2 < dy1; y2 += vert) {
3186
0
    for (x2 = 0; x2 < dx1; x2 += horiz) {
3187
3188
      // pull out the current values
3189
0
      p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
3190
0
      for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3191
0
        data[i] = p1[0];
3192
0
        data[i+1] = p1[1];
3193
0
        data[i+2] = p1[2];
3194
0
        data[i+3] = p1[3];
3195
0
        data[i+4] = p1[4];
3196
0
        data[i+5] = p1[5];
3197
0
        data[i+6] = p1[6];
3198
0
        data[i+7] = p1[7];
3199
0
        p1 += bufWidth * vSub;
3200
0
      }
3201
3202
      // read one data unit
3203
0
      if (progressive) {
3204
0
        if (!readProgressiveDataUnit(
3205
0
           &dcHuffTables[scanInfo.dcHuffTable[cc]],
3206
0
           &acHuffTables[scanInfo.acHuffTable[cc]],
3207
0
           &compInfo[cc].prevDC,
3208
0
           data)) {
3209
0
    return;
3210
0
        }
3211
0
      } else {
3212
0
        if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]],
3213
0
        &acHuffTables[scanInfo.acHuffTable[cc]],
3214
0
        &compInfo[cc].prevDC,
3215
0
        data)) {
3216
0
    return;
3217
0
        }
3218
0
      }
3219
3220
      // add the data unit into frameBuf
3221
0
      p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
3222
0
      for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3223
0
        p1[0] = data[i];
3224
0
        p1[1] = data[i+1];
3225
0
        p1[2] = data[i+2];
3226
0
        p1[3] = data[i+3];
3227
0
        p1[4] = data[i+4];
3228
0
        p1[5] = data[i+5];
3229
0
        p1[6] = data[i+6];
3230
0
        p1[7] = data[i+7];
3231
0
        p1 += bufWidth * vSub;
3232
0
      }
3233
0
    }
3234
0
  }
3235
0
      }
3236
0
      --restartCtr;
3237
0
    }
3238
0
  }
3239
0
}
3240
3241
// Read one data unit from a sequential JPEG stream.
3242
GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
3243
            DCTHuffTable *acHuffTable,
3244
0
            int *prevDC, int data[64]) {
3245
0
  int run, size, amp;
3246
0
  int c;
3247
0
  int i, j;
3248
3249
0
  if ((size = readHuffSym(dcHuffTable)) == 9999) {
3250
0
    return gFalse;
3251
0
  }
3252
0
  if (size > 0) {
3253
0
    if ((amp = readAmp(size)) == 9999) {
3254
0
      return gFalse;
3255
0
    }
3256
0
  } else {
3257
0
    amp = 0;
3258
0
  }
3259
0
  data[0] = *prevDC += amp;
3260
0
  for (i = 1; i < 64; ++i) {
3261
0
    data[i] = 0;
3262
0
  }
3263
0
  i = 1;
3264
0
  while (i < 64) {
3265
0
    run = 0;
3266
0
    while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30) {
3267
0
      run += 0x10;
3268
0
    }
3269
0
    if (c == 9999) {
3270
0
      return gFalse;
3271
0
    }
3272
0
    if (c == 0x00) {
3273
0
      break;
3274
0
    } else {
3275
0
      run += (c >> 4) & 0x0f;
3276
0
      size = c & 0x0f;
3277
0
      amp = readAmp(size);
3278
0
      if (amp == 9999) {
3279
0
  return gFalse;
3280
0
      }
3281
0
      i += run;
3282
0
      if (i < 64) {
3283
0
  j = dctZigZag[i++];
3284
0
  data[j] = amp;
3285
0
      }
3286
0
    }
3287
0
  }
3288
0
  return gTrue;
3289
0
}
3290
3291
// Read one data unit from a progressive JPEG stream.
3292
GBool DCTStream::readProgressiveDataUnit(DCTHuffTable *dcHuffTable,
3293
           DCTHuffTable *acHuffTable,
3294
0
           int *prevDC, int data[64]) {
3295
0
  int run, size, amp, bit, c;
3296
0
  int i, j, k;
3297
3298
  // get the DC coefficient
3299
0
  i = scanInfo.firstCoeff;
3300
0
  if (i == 0) {
3301
0
    if (scanInfo.ah == 0) {
3302
0
      if ((size = readHuffSym(dcHuffTable)) == 9999) {
3303
0
  return gFalse;
3304
0
      }
3305
0
      if (size > 0) {
3306
0
  if ((amp = readAmp(size)) == 9999) {
3307
0
    return gFalse;
3308
0
  }
3309
0
      } else {
3310
0
  amp = 0;
3311
0
      }
3312
0
      data[0] += (*prevDC += amp) << scanInfo.al;
3313
0
    } else {
3314
0
      if ((bit = readBit()) == 9999) {
3315
0
  return gFalse;
3316
0
      }
3317
0
      if (bit) {
3318
0
  data[0] += 1 << scanInfo.al;
3319
0
      }
3320
0
    }
3321
0
    ++i;
3322
0
  }
3323
0
  if (scanInfo.lastCoeff == 0) {
3324
0
    return gTrue;
3325
0
  }
3326
3327
  // check for an EOB run
3328
0
  if (eobRun > 0) {
3329
0
    while (i <= scanInfo.lastCoeff) {
3330
0
      j = dctZigZag[i++];
3331
0
      if (data[j] != 0) {
3332
0
  if ((bit = readBit()) == EOF) {
3333
0
    return gFalse;
3334
0
  }
3335
0
  if (bit) {
3336
0
    if (data[j] >= 0) {
3337
0
      data[j] += 1 << scanInfo.al;
3338
0
    } else {
3339
0
      data[j] -= 1 << scanInfo.al;
3340
0
    }
3341
0
  }
3342
0
      }
3343
0
    }
3344
0
    --eobRun;
3345
0
    return gTrue;
3346
0
  }
3347
3348
  // read the AC coefficients
3349
0
  while (i <= scanInfo.lastCoeff) {
3350
0
    if ((c = readHuffSym(acHuffTable)) == 9999) {
3351
0
      return gFalse;
3352
0
    }
3353
3354
    // ZRL
3355
0
    if (c == 0xf0) {
3356
0
      k = 0;
3357
0
      while (k < 16 && i <= scanInfo.lastCoeff) {
3358
0
  j = dctZigZag[i++];
3359
0
  if (data[j] == 0) {
3360
0
    ++k;
3361
0
  } else {
3362
0
    if ((bit = readBit()) == EOF) {
3363
0
      return gFalse;
3364
0
    }
3365
0
    if (bit) {
3366
0
      if (data[j] >= 0) {
3367
0
        data[j] += 1 << scanInfo.al;
3368
0
      } else {
3369
0
        data[j] -= 1 << scanInfo.al;
3370
0
      }
3371
0
    }
3372
0
  }
3373
0
      }
3374
3375
    // EOB run
3376
0
    } else if ((c & 0x0f) == 0x00) {
3377
0
      j = c >> 4;
3378
0
      eobRun = 0;
3379
0
      for (k = 0; k < j; ++k) {
3380
0
  if ((bit = readBit()) == EOF) {
3381
0
    return gFalse;
3382
0
  }
3383
0
  eobRun = (eobRun << 1) | bit;
3384
0
      }
3385
0
      eobRun += 1 << j;
3386
0
      while (i <= scanInfo.lastCoeff) {
3387
0
  j = dctZigZag[i++];
3388
0
  if (data[j] != 0) {
3389
0
    if ((bit = readBit()) == EOF) {
3390
0
      return gFalse;
3391
0
    }
3392
0
    if (bit) {
3393
0
      if (data[j] >= 0) {
3394
0
        data[j] += 1 << scanInfo.al;
3395
0
      } else {
3396
0
        data[j] -= 1 << scanInfo.al;
3397
0
      }
3398
0
    }
3399
0
  }
3400
0
      }
3401
0
      --eobRun;
3402
0
      break;
3403
3404
    // zero run and one AC coefficient
3405
0
    } else {
3406
0
      run = (c >> 4) & 0x0f;
3407
0
      size = c & 0x0f;
3408
0
      if ((amp = readAmp(size)) == 9999) {
3409
0
  return gFalse;
3410
0
      }
3411
0
      j = 0; // make gcc happy
3412
0
      for (k = 0; k <= run && i <= scanInfo.lastCoeff; ++k) {
3413
0
  j = dctZigZag[i++];
3414
0
  while (data[j] != 0 && i <= scanInfo.lastCoeff) {
3415
0
    if ((bit = readBit()) == EOF) {
3416
0
      return gFalse;
3417
0
    }
3418
0
    if (bit) {
3419
0
      if (data[j] >= 0) {
3420
0
        data[j] += 1 << scanInfo.al;
3421
0
      } else {
3422
0
        data[j] -= 1 << scanInfo.al;
3423
0
      }
3424
0
    }
3425
0
    j = dctZigZag[i++];
3426
0
  }
3427
0
      }
3428
0
      data[j] = amp << scanInfo.al;
3429
0
    }
3430
0
  }
3431
3432
0
  return gTrue;
3433
0
}
3434
3435
// Decode a progressive JPEG image.
3436
0
void DCTStream::decodeImage() {
3437
0
  int dataIn[64];
3438
0
  Guchar dataOut[64];
3439
0
  Gushort *quantTable;
3440
0
  int pY, pCb, pCr, pR, pG, pB;
3441
0
  int x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
3442
0
  int h, v, horiz, vert, hSub, vSub;
3443
0
  int *p0, *p1, *p2;
3444
3445
0
  for (y1 = 0; y1 < bufHeight; y1 += mcuHeight) {
3446
0
    for (x1 = 0; x1 < bufWidth; x1 += mcuWidth) {
3447
0
      for (cc = 0; cc < numComps; ++cc) {
3448
0
  quantTable = quantTables[compInfo[cc].quantTable];
3449
0
  h = compInfo[cc].hSample;
3450
0
  v = compInfo[cc].vSample;
3451
0
  horiz = mcuWidth / h;
3452
0
  vert = mcuHeight / v;
3453
0
  hSub = horiz / 8;
3454
0
  vSub = vert / 8;
3455
0
  for (y2 = 0; y2 < mcuHeight; y2 += vert) {
3456
0
    for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
3457
3458
      // pull out the coded data unit
3459
0
      p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
3460
0
      for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3461
0
        dataIn[i]   = p1[0];
3462
0
        dataIn[i+1] = p1[1];
3463
0
        dataIn[i+2] = p1[2];
3464
0
        dataIn[i+3] = p1[3];
3465
0
        dataIn[i+4] = p1[4];
3466
0
        dataIn[i+5] = p1[5];
3467
0
        dataIn[i+6] = p1[6];
3468
0
        dataIn[i+7] = p1[7];
3469
0
        p1 += bufWidth * vSub;
3470
0
      }
3471
3472
      // transform
3473
0
      transformDataUnit(quantTable, dataIn, dataOut);
3474
3475
      // store back into frameBuf, doing replication for
3476
      // subsampled components
3477
0
      p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
3478
0
      if (hSub == 1 && vSub == 1) {
3479
0
        for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
3480
0
    p1[0] = dataOut[i] & 0xff;
3481
0
    p1[1] = dataOut[i+1] & 0xff;
3482
0
    p1[2] = dataOut[i+2] & 0xff;
3483
0
    p1[3] = dataOut[i+3] & 0xff;
3484
0
    p1[4] = dataOut[i+4] & 0xff;
3485
0
    p1[5] = dataOut[i+5] & 0xff;
3486
0
    p1[6] = dataOut[i+6] & 0xff;
3487
0
    p1[7] = dataOut[i+7] & 0xff;
3488
0
    p1 += bufWidth;
3489
0
        }
3490
0
      } else if (hSub == 2 && vSub == 2) {
3491
0
        p2 = p1 + bufWidth;
3492
0
        for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
3493
0
    p1[0] = p1[1] = p2[0] = p2[1] = dataOut[i] & 0xff;
3494
0
    p1[2] = p1[3] = p2[2] = p2[3] = dataOut[i+1] & 0xff;
3495
0
    p1[4] = p1[5] = p2[4] = p2[5] = dataOut[i+2] & 0xff;
3496
0
    p1[6] = p1[7] = p2[6] = p2[7] = dataOut[i+3] & 0xff;
3497
0
    p1[8] = p1[9] = p2[8] = p2[9] = dataOut[i+4] & 0xff;
3498
0
    p1[10] = p1[11] = p2[10] = p2[11] = dataOut[i+5] & 0xff;
3499
0
    p1[12] = p1[13] = p2[12] = p2[13] = dataOut[i+6] & 0xff;
3500
0
    p1[14] = p1[15] = p2[14] = p2[15] = dataOut[i+7] & 0xff;
3501
0
    p1 += bufWidth * 2;
3502
0
    p2 += bufWidth * 2;
3503
0
        }
3504
0
      } else {
3505
0
        i = 0;
3506
0
        for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
3507
0
    for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
3508
0
      p2 = p1 + x4;
3509
0
      for (y5 = 0; y5 < vSub; ++y5) {
3510
0
        for (x5 = 0; x5 < hSub; ++x5) {
3511
0
          p2[x5] = dataOut[i] & 0xff;
3512
0
        }
3513
0
        p2 += bufWidth;
3514
0
      }
3515
0
      ++i;
3516
0
    }
3517
0
    p1 += bufWidth * vSub;
3518
0
        }
3519
0
      }
3520
0
    }
3521
0
  }
3522
0
      }
3523
3524
      // color space conversion
3525
0
      if (colorXform) {
3526
  // convert YCbCr to RGB
3527
0
  if (numComps == 3) {
3528
0
    for (y2 = 0; y2 < mcuHeight; ++y2) {
3529
0
      p0 = &frameBuf[0][(y1+y2) * bufWidth + x1];
3530
0
      p1 = &frameBuf[1][(y1+y2) * bufWidth + x1];
3531
0
      p2 = &frameBuf[2][(y1+y2) * bufWidth + x1];
3532
0
      for (x2 = 0; x2 < mcuWidth; ++x2) {
3533
0
        pY = *p0;
3534
0
        pCb = *p1 - 128;
3535
0
        pCr = *p2 - 128;
3536
0
        pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
3537
0
        *p0++ = dctClip(pR);
3538
0
        pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr +
3539
0
        32768) >> 16;
3540
0
        *p1++ = dctClip(pG);
3541
0
        pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
3542
0
        *p2++ = dctClip(pB);
3543
0
      }
3544
0
    }
3545
  // convert YCbCrK to CMYK (K is passed through unchanged)
3546
0
  } else if (numComps == 4) {
3547
0
    for (y2 = 0; y2 < mcuHeight; ++y2) {
3548
0
      p0 = &frameBuf[0][(y1+y2) * bufWidth + x1];
3549
0
      p1 = &frameBuf[1][(y1+y2) * bufWidth + x1];
3550
0
      p2 = &frameBuf[2][(y1+y2) * bufWidth + x1];
3551
0
      for (x2 = 0; x2 < mcuWidth; ++x2) {
3552
0
        pY = *p0;
3553
0
        pCb = *p1 - 128;
3554
0
        pCr = *p2 - 128;
3555
0
        pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
3556
0
        *p0++ = 255 - dctClip(pR);
3557
0
        pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr +
3558
0
        32768) >> 16;
3559
0
        *p1++ = 255 - dctClip(pG);
3560
0
        pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
3561
0
        *p2++ = 255 - dctClip(pB);
3562
0
      }
3563
0
    }
3564
0
  }
3565
0
      }
3566
0
    }
3567
0
  }
3568
0
}
3569
3570
// Transform one data unit -- this performs the dequantization and
3571
// IDCT steps.  This IDCT algorithm is taken from:
3572
//   Y. A. Reznik, A. T. Hinds, L. Yu, Z. Ni, and C-X. Zhang,
3573
//   "Efficient fixed-point approximations of the 8x8 inverse discrete
3574
//   cosine transform" (invited paper), Proc. SPIE Vol. 6696, Sep. 24,
3575
//   2007.
3576
// which is based on:
3577
//   Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,
3578
//   "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
3579
//   IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
3580
//   988-991.
3581
// The stage numbers mentioned in the comments refer to Figure 1 in the
3582
// Loeffler paper.
3583
void DCTStream::transformDataUnit(Gushort *quantTable,
3584
0
          int dataIn[64], Guchar dataOut[64]) {
3585
0
  int v0, v1, v2, v3, v4, v5, v6, v7;
3586
0
  int t0, t1, t2, t3, t4, t5, t6, t7;
3587
0
  int *p, *scale;
3588
0
  Gushort *q;
3589
0
  int i;
3590
3591
  // dequant; inverse DCT on rows
3592
0
  for (i = 0; i < 64; i += 8) {
3593
0
    p = dataIn + i;
3594
0
    q = quantTable + i;
3595
0
    scale = idctScaleMat + i;
3596
3597
    // check for all-zero AC coefficients
3598
0
    if (p[1] == 0 && p[2] == 0 && p[3] == 0 &&
3599
0
  p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] == 0) {
3600
0
      t0 = p[0] * q[0] * scale[0];
3601
0
      if (i == 0) {
3602
0
  t0 += 1 << 12;    // rounding bias
3603
0
      }
3604
0
      p[0] = t0;
3605
0
      p[1] = t0;
3606
0
      p[2] = t0;
3607
0
      p[3] = t0;
3608
0
      p[4] = t0;
3609
0
      p[5] = t0;
3610
0
      p[6] = t0;
3611
0
      p[7] = t0;
3612
0
      continue;
3613
0
    }
3614
3615
    // stage 4
3616
0
    v0 = p[0] * q[0] * scale[0];
3617
0
    if (i == 0) {
3618
0
      v0 += 1 << 12;    // rounding bias
3619
0
    }
3620
0
    v1 = p[4] * q[4] * scale[4];
3621
0
    v2 = p[2] * q[2] * scale[2];
3622
0
    v3 = p[6] * q[6] * scale[6];
3623
0
    t0 = p[1] * q[1] * scale[1];
3624
0
    t1 = p[7] * q[7] * scale[7];
3625
0
    v4 = t0 - t1;
3626
0
    v7 = t0 + t1;
3627
0
    v5 = p[3] * q[3] * scale[3];
3628
0
    v6 = p[5] * q[5] * scale[5];
3629
3630
    // stage 3
3631
0
    t0 = v0 - v1;
3632
0
    v0 = v0 + v1;
3633
0
    v1 = t0;
3634
0
    t0 = v2 + (v2 >> 5);
3635
0
    t1 = t0 >> 2;
3636
0
    t2 = t1 + (v2 >> 4);  // 41/128 * v2
3637
0
    t3 = t0 - t1;   // 99/128 * v2
3638
0
    t4 = v3 + (v3 >> 5);
3639
0
    t5 = t4 >> 2;
3640
0
    t6 = t5 + (v3 >> 4);  // 41/128 * v3
3641
0
    t7 = t4 - t5;   // 99/128 * v3
3642
0
    v2 = t2 - t7;
3643
0
    v3 = t3 + t6;
3644
0
    t0 = v4 - v6;
3645
0
    v4 = v4 + v6;
3646
0
    v6 = t0;
3647
0
    t0 = v7 + v5;
3648
0
    v5 = v7 - v5;
3649
0
    v7 = t0;
3650
3651
    // stage 2
3652
0
    t0 = v0 - v3;
3653
0
    v0 = v0 + v3;
3654
0
    v3 = t0;
3655
0
    t0 = v1 - v2;
3656
0
    v1 = v1 + v2;
3657
0
    v2 = t0;
3658
0
    t0 = (v4 >> 9) - v4;
3659
0
    t1 = v4 >> 1;   // 1/2 * v4
3660
0
    t2 = (t0 >> 2) - t0;  // 1533/2048 * v4
3661
0
    t3 = (v7 >> 9) - v7;
3662
0
    t4 = v7 >> 1;   // 1/2 * v7
3663
0
    t5 = (t3 >> 2) - t3;  // 1533/2048 * v7
3664
0
    v4 = t2 - t4;
3665
0
    v7 = t1 + t5;
3666
0
    t0 = (v5 >> 3) - (v5 >> 7);
3667
0
    t1 = t0 - (v5 >> 11);
3668
0
    t2 = t0 + (t1 >> 1);  // 719/4096 * v5
3669
0
    t3 = v5 - t0;   // 113/256 * v5
3670
0
    t4 = (v6 >> 3) - (v6 >> 7);
3671
0
    t5 = t4 - (v6 >> 11);
3672
0
    t6 = t4 + (t5 >> 1);  // 719/4096 * v6
3673
0
    t7 = v6 - t4;   // 113/256 * v6
3674
0
    v5 = t3 - t6;
3675
0
    v6 = t2 + t7;
3676
3677
    // stage 1
3678
0
    p[0] = v0 + v7;
3679
0
    p[7] = v0 - v7;
3680
0
    p[1] = v1 + v6;
3681
0
    p[6] = v1 - v6;
3682
0
    p[2] = v2 + v5;
3683
0
    p[5] = v2 - v5;
3684
0
    p[3] = v3 + v4;
3685
0
    p[4] = v3 - v4;
3686
0
  }
3687
3688
  // inverse DCT on columns
3689
0
  for (i = 0; i < 8; ++i) {
3690
0
    p = dataIn + i;
3691
3692
    // check for all-zero AC coefficients
3693
0
    if (p[1*8] == 0 && p[2*8] == 0 && p[3*8] == 0 &&
3694
0
  p[4*8] == 0 && p[5*8] == 0 && p[6*8] == 0 && p[7*8] == 0) {
3695
0
      t0 = p[0*8];
3696
0
      p[1*8] = t0;
3697
0
      p[2*8] = t0;
3698
0
      p[3*8] = t0;
3699
0
      p[4*8] = t0;
3700
0
      p[5*8] = t0;
3701
0
      p[6*8] = t0;
3702
0
      p[7*8] = t0;
3703
0
      continue;
3704
0
    }
3705
3706
    // stage 4
3707
0
    v0 = p[0*8];
3708
0
    v1 = p[4*8];
3709
0
    v2 = p[2*8];
3710
0
    v3 = p[6*8];
3711
0
    t0 = p[1*8];
3712
0
    t1 = p[7*8];
3713
0
    v4 = t0 - t1;
3714
0
    v7 = t0 + t1;
3715
0
    v5 = p[3*8];
3716
0
    v6 = p[5*8];
3717
3718
    // stage 3
3719
0
    t0 = v0 - v1;
3720
0
    v0 = v0 + v1;
3721
0
    v1 = t0;
3722
0
    t0 = v2 + (v2 >> 5);
3723
0
    t1 = t0 >> 2;
3724
0
    t2 = t1 + (v2 >> 4);  // 41/128 * v2
3725
0
    t3 = t0 - t1;   // 99/128 * v2
3726
0
    t4 = v3 + (v3 >> 5);
3727
0
    t5 = t4 >> 2;
3728
0
    t6 = t5 + (v3 >> 4);  // 41/128 * v3
3729
0
    t7 = t4 - t5;   // 99/128 * v3
3730
0
    v2 = t2 - t7;
3731
0
    v3 = t3 + t6;
3732
0
    t0 = v4 - v6;
3733
0
    v4 = v4 + v6;
3734
0
    v6 = t0;
3735
0
    t0 = v7 + v5;
3736
0
    v5 = v7 - v5;
3737
0
    v7 = t0;
3738
3739
    // stage 2
3740
0
    t0 = v0 - v3;
3741
0
    v0 = v0 + v3;
3742
0
    v3 = t0;
3743
0
    t0 = v1 - v2;
3744
0
    v1 = v1 + v2;
3745
0
    v2 = t0;
3746
0
    t0 = (v4 >> 9) - v4;
3747
0
    t1 = v4 >> 1;   // 1/2 * v4
3748
0
    t2 = (t0 >> 2) - t0;  // 1533/2048 * v4
3749
0
    t3 = (v7 >> 9) - v7;
3750
0
    t4 = v7 >> 1;   // 1/2 * v7
3751
0
    t5 = (t3 >> 2) - t3;  // 1533/2048 * v7
3752
0
    v4 = t2 - t4;
3753
0
    v7 = t1 + t5;
3754
0
    t0 = (v5 >> 3) - (v5 >> 7);
3755
0
    t1 = t0 - (v5 >> 11);
3756
0
    t2 = t0 + (t1 >> 1);  // 719/4096 * v5
3757
0
    t3 = v5 - t0;   // 113/256 * v5
3758
0
    t4 = (v6 >> 3) - (v6 >> 7);
3759
0
    t5 = t4 - (v6 >> 11);
3760
0
    t6 = t4 + (t5 >> 1);  // 719/4096 * v6
3761
0
    t7 = v6 - t4;   // 113/256 * v6
3762
0
    v5 = t3 - t6;
3763
0
    v6 = t2 + t7;
3764
3765
    // stage 1
3766
0
    p[0*8] = v0 + v7;
3767
0
    p[7*8] = v0 - v7;
3768
0
    p[1*8] = v1 + v6;
3769
0
    p[6*8] = v1 - v6;
3770
0
    p[2*8] = v2 + v5;
3771
0
    p[5*8] = v2 - v5;
3772
0
    p[3*8] = v3 + v4;
3773
0
    p[4*8] = v3 - v4;
3774
0
  }
3775
3776
  // convert to 8-bit integers
3777
0
  for (i = 0; i < 64; ++i) {
3778
0
    dataOut[i] = dctClip(128 + (dataIn[i] >> 13));
3779
0
  }
3780
0
}
3781
3782
0
int DCTStream::readHuffSym(DCTHuffTable *table) {
3783
0
  Gushort code;
3784
0
  int bit;
3785
0
  int codeBits;
3786
3787
0
  code = 0;
3788
0
  codeBits = 0;
3789
0
  do {
3790
    // add a bit to the code
3791
0
    if ((bit = readBit()) == EOF) {
3792
0
      return 9999;
3793
0
    }
3794
0
    code = (Gushort)((code << 1) + bit);
3795
0
    ++codeBits;
3796
3797
    // look up code
3798
0
    if (code < table->firstCode[codeBits]) {
3799
0
      break;
3800
0
    }
3801
0
    if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
3802
0
      code = (Gushort)(code - table->firstCode[codeBits]);
3803
0
      return table->sym[table->firstSym[codeBits] + code];
3804
0
    }
3805
0
  } while (codeBits < 16);
3806
3807
0
  error(errSyntaxError, getPos(), "Bad Huffman code in DCT stream");
3808
0
  return 9999;
3809
0
}
3810
3811
0
int DCTStream::readAmp(int size) {
3812
0
  int amp, bit;
3813
0
  int bits;
3814
3815
0
  amp = 0;
3816
0
  for (bits = 0; bits < size; ++bits) {
3817
0
    if ((bit = readBit()) == EOF)
3818
0
      return 9999;
3819
0
    amp = (amp << 1) + bit;
3820
0
  }
3821
0
  if (amp < (1 << (size - 1)))
3822
0
    amp -= (1 << size) - 1;
3823
0
  return amp;
3824
0
}
3825
3826
0
int DCTStream::readBit() {
3827
0
  int bit;
3828
0
  int c, c2;
3829
3830
0
  if (inputBits == 0) {
3831
0
    if ((c = str->getChar()) == EOF)
3832
0
      return EOF;
3833
0
    if (c == 0xff) {
3834
0
      do {
3835
0
  c2 = str->getChar();
3836
0
      } while (c2 == 0xff);
3837
0
      if (c2 != 0x00) {
3838
0
  error(errSyntaxError, getPos(), "Bad DCT data: missing 00 after ff");
3839
0
  return EOF;
3840
0
      }
3841
0
    }
3842
0
    inputBuf = c;
3843
0
    inputBits = 8;
3844
0
  }
3845
0
  bit = (inputBuf >> (inputBits - 1)) & 1;
3846
0
  --inputBits;
3847
0
  return bit;
3848
0
}
3849
3850
0
GBool DCTStream::readHeader(GBool frame) {
3851
0
  GBool doScan;
3852
0
  int n, i;
3853
0
  int c = 0;
3854
3855
  // read headers
3856
0
  doScan = gFalse;
3857
0
  while (!doScan) {
3858
0
    c = readMarker();
3859
0
    switch (c) {
3860
0
    case 0xc0:      // SOF0 (sequential)
3861
0
    case 0xc1:      // SOF1 (extended sequential)
3862
0
      if (!frame) {
3863
0
  error(errSyntaxError, getPos(),
3864
0
        "Invalid DCT marker in scan <{0:02x}>", c);
3865
0
  return gFalse;
3866
0
      }
3867
0
      if (!readBaselineSOF()) {
3868
0
  return gFalse;
3869
0
      }
3870
0
      break;
3871
0
    case 0xc2:      // SOF2 (progressive)
3872
0
      if (!frame) {
3873
0
  error(errSyntaxError, getPos(),
3874
0
        "Invalid DCT marker in scan <{0:02x}>", c);
3875
0
  return gFalse;
3876
0
      }
3877
0
      if (!readProgressiveSOF()) {
3878
0
  return gFalse;
3879
0
      }
3880
0
      break;
3881
0
    case 0xc4:      // DHT
3882
0
      if (!readHuffmanTables()) {
3883
0
  return gFalse;
3884
0
      }
3885
0
      break;
3886
0
    case 0xd8:      // SOI
3887
0
      if (!frame) {
3888
0
  error(errSyntaxError, getPos(),
3889
0
        "Invalid DCT marker in scan <{0:02x}>", c);
3890
0
  return gFalse;
3891
0
      }
3892
0
      break;
3893
0
    case 0xd9:      // EOI
3894
0
      return gFalse;
3895
0
    case 0xda:      // SOS
3896
0
      if (!readScanInfo()) {
3897
0
  return gFalse;
3898
0
      }
3899
0
      if (frame) {
3900
0
  interleaved = scanInfo.numComps == numComps;
3901
0
      }
3902
0
      doScan = gTrue;
3903
0
      break;
3904
0
    case 0xdb:      // DQT
3905
0
      if (!readQuantTables()) {
3906
0
  return gFalse;
3907
0
      }
3908
0
      break;
3909
0
    case 0xdd:      // DRI
3910
0
      if (!readRestartInterval()) {
3911
0
  return gFalse;
3912
0
      }
3913
0
      break;
3914
0
    case 0xe0:      // APP0
3915
0
      if (!frame) {
3916
0
  error(errSyntaxError, getPos(),
3917
0
        "Invalid DCT marker in scan <{0:02x}>", c);
3918
0
  return gFalse;
3919
0
      }
3920
0
      if (!readJFIFMarker()) {
3921
0
  return gFalse;
3922
0
      }
3923
0
      break;
3924
0
    case 0xee:      // APP14
3925
0
      if (!frame) {
3926
0
  error(errSyntaxError, getPos(),
3927
0
        "Invalid DCT marker in scan <{0:02x}>", c);
3928
0
  return gFalse;
3929
0
      }
3930
0
      if (!readAdobeMarker()) {
3931
0
  return gFalse;
3932
0
      }
3933
0
      break;
3934
0
    case EOF:
3935
0
      error(errSyntaxError, getPos(), "Bad DCT header");
3936
0
      return gFalse;
3937
0
    default:
3938
      // skip APPn / COM / etc.
3939
0
      if (c >= 0xe0) {
3940
0
  n = read16() - 2;
3941
0
  str->discardChars(n);
3942
0
      } else {
3943
0
  error(errSyntaxError, getPos(), "Unknown DCT marker <{0:02x}>", c);
3944
0
  return gFalse;
3945
0
      }
3946
0
      break;
3947
0
    }
3948
0
  }
3949
3950
0
  for (i = 0; i < numComps; ++i) {
3951
0
    if (compInfo[i].quantTable >= numQuantTables) {
3952
0
      error(errSyntaxError, getPos(), "Invalid DCT quant table selector");
3953
0
      return gFalse;
3954
0
    }
3955
0
  }
3956
3957
0
  return gTrue;
3958
0
}
3959
3960
0
GBool DCTStream::readBaselineSOF() {
3961
0
  int prec;
3962
0
  int i;
3963
0
  int c;
3964
3965
0
  read16(); // length
3966
0
  prec = str->getChar();
3967
0
  height = read16();
3968
0
  width = read16();
3969
0
  numComps = str->getChar();
3970
0
  if (numComps <= 0 || numComps > 4) {
3971
0
    error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
3972
0
    numComps = 0;
3973
0
    return gFalse;
3974
0
  }
3975
0
  if (prec != 8) {
3976
0
    error(errSyntaxError, getPos(), "Bad DCT precision {0:d}", prec);
3977
0
    return gFalse;
3978
0
  }
3979
0
  for (i = 0; i < numComps; ++i) {
3980
0
    compInfo[i].id = str->getChar();
3981
0
    c = str->getChar();
3982
0
    compInfo[i].hSample = (c >> 4) & 0x0f;
3983
0
    compInfo[i].vSample = c & 0x0f;
3984
0
    compInfo[i].quantTable = str->getChar();
3985
    // a sampling factor of 3 is allowed by the spec, but requires
3986
    // messy upsampling, and appears not to be used in practice
3987
0
    if (!(compInfo[i].hSample == 1 ||
3988
0
    compInfo[i].hSample == 2 ||
3989
0
    compInfo[i].hSample == 4) ||
3990
0
  !(compInfo[i].vSample == 1 ||
3991
0
    compInfo[i].vSample == 2 ||
3992
0
    compInfo[i].vSample == 4)) {
3993
0
      error(errSyntaxError, getPos(), "Bad DCT sampling factor");
3994
0
      return gFalse;
3995
0
    }
3996
0
    if (compInfo[i].quantTable < 0 || compInfo[i].quantTable > 3) {
3997
0
      error(errSyntaxError, getPos(), "Bad DCT quant table selector");
3998
0
      return gFalse;
3999
0
    }
4000
0
  }
4001
0
  progressive = gFalse;
4002
0
  return gTrue;
4003
0
}
4004
4005
0
GBool DCTStream::readProgressiveSOF() {
4006
0
  int prec;
4007
0
  int i;
4008
0
  int c;
4009
4010
0
  read16(); // length
4011
0
  prec = str->getChar();
4012
0
  height = read16();
4013
0
  width = read16();
4014
0
  numComps = str->getChar();
4015
0
  if (numComps <= 0 || numComps > 4) {
4016
0
    error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
4017
0
    numComps = 0;
4018
0
    return gFalse;
4019
0
  }
4020
0
  if (prec != 8) {
4021
0
    error(errSyntaxError, getPos(), "Bad DCT precision {0:d}", prec);
4022
0
    return gFalse;
4023
0
  }
4024
0
  for (i = 0; i < numComps; ++i) {
4025
0
    compInfo[i].id = str->getChar();
4026
0
    c = str->getChar();
4027
0
    compInfo[i].hSample = (c >> 4) & 0x0f;
4028
0
    compInfo[i].vSample = c & 0x0f;
4029
0
    compInfo[i].quantTable = str->getChar();
4030
    // a sampling factor of 3 is allowed by the spec, but requires
4031
    // messy upsampling, and appears not to be used in practice
4032
0
    if (!(compInfo[i].hSample == 1 ||
4033
0
    compInfo[i].hSample == 2 ||
4034
0
    compInfo[i].hSample == 4) ||
4035
0
  !(compInfo[i].vSample == 1 ||
4036
0
    compInfo[i].vSample == 2 ||
4037
0
    compInfo[i].vSample == 4)) {
4038
0
      error(errSyntaxError, getPos(), "Bad DCT sampling factor");
4039
0
      return gFalse;
4040
0
    }
4041
0
    if (compInfo[i].quantTable < 0 || compInfo[i].quantTable > 3) {
4042
0
      error(errSyntaxError, getPos(), "Bad DCT quant table selector");
4043
0
      return gFalse;
4044
0
    }
4045
0
  }
4046
0
  progressive = gTrue;
4047
0
  return gTrue;
4048
0
}
4049
4050
0
GBool DCTStream::readScanInfo() {
4051
0
  int length;
4052
0
  int id, c;
4053
0
  int i, j;
4054
4055
0
  length = read16() - 2;
4056
0
  scanInfo.numComps = str->getChar();
4057
0
  if (scanInfo.numComps <= 0 || scanInfo.numComps > 4) {
4058
0
    error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
4059
0
    scanInfo.numComps = 0;
4060
0
    return gFalse;
4061
0
  }
4062
0
  --length;
4063
0
  if (length != 2 * scanInfo.numComps + 3) {
4064
0
    error(errSyntaxError, getPos(), "Bad DCT scan info block");
4065
0
    return gFalse;
4066
0
  }
4067
0
  for (j = 0; j < numComps; ++j) {
4068
0
    scanInfo.comp[j] = gFalse;
4069
0
  }
4070
0
  for (i = 0; i < scanInfo.numComps; ++i) {
4071
0
    id = str->getChar();
4072
    // some (broken) DCT streams reuse ID numbers, but at least they
4073
    // keep the components in order, so we check compInfo[i] first to
4074
    // work around the problem
4075
0
    if (id == compInfo[i].id) {
4076
0
      j = i;
4077
0
    } else {
4078
0
      for (j = 0; j < numComps; ++j) {
4079
0
  if (id == compInfo[j].id) {
4080
0
    break;
4081
0
  }
4082
0
      }
4083
0
      if (j == numComps) {
4084
0
  error(errSyntaxError, getPos(),
4085
0
        "Bad DCT component ID in scan info block");
4086
0
  return gFalse;
4087
0
      }
4088
0
    }
4089
0
    if (scanInfo.comp[j]) {
4090
0
      error(errSyntaxError, getPos(),
4091
0
      "Invalid DCT component ID in scan info block");
4092
0
      return gFalse;
4093
0
    }
4094
0
    scanInfo.comp[j] = gTrue;
4095
0
    c = str->getChar();
4096
0
    scanInfo.dcHuffTable[j] = (c >> 4) & 0x0f;
4097
0
    scanInfo.acHuffTable[j] = c & 0x0f;
4098
0
  }
4099
0
  scanInfo.firstCoeff = str->getChar();
4100
0
  scanInfo.lastCoeff = str->getChar();
4101
0
  if (scanInfo.firstCoeff < 0 || scanInfo.lastCoeff > 63 ||
4102
0
      scanInfo.firstCoeff > scanInfo.lastCoeff) {
4103
0
    error(errSyntaxError, getPos(),
4104
0
    "Bad DCT coefficient numbers in scan info block");
4105
0
    return gFalse;
4106
0
  }
4107
0
  c = str->getChar();
4108
0
  scanInfo.ah = (c >> 4) & 0x0f;
4109
0
  scanInfo.al = c & 0x0f;
4110
0
  return gTrue;
4111
0
}
4112
4113
0
GBool DCTStream::readQuantTables() {
4114
0
  int length, prec, i, index;
4115
4116
0
  length = read16() - 2;
4117
0
  while (length > 0) {
4118
0
    index = str->getChar();
4119
0
    prec = (index >> 4) & 0x0f;
4120
0
    index &= 0x0f;
4121
0
    if (prec > 1 || index >= 4) {
4122
0
      error(errSyntaxError, getPos(), "Bad DCT quantization table");
4123
0
      return gFalse;
4124
0
    }
4125
0
    if (index >= numQuantTables) {
4126
0
      numQuantTables = index + 1;
4127
0
    }
4128
0
    for (i = 0; i < 64; ++i) {
4129
0
      if (prec) {
4130
0
  quantTables[index][dctZigZag[i]] = (Gushort)read16();
4131
0
      } else {
4132
0
  quantTables[index][dctZigZag[i]] = (Gushort)str->getChar();
4133
0
      }
4134
0
    }
4135
0
    if (prec) {
4136
0
      length -= 129;
4137
0
    } else {
4138
0
      length -= 65;
4139
0
    }
4140
0
  }
4141
0
  return gTrue;
4142
0
}
4143
4144
0
GBool DCTStream::readHuffmanTables() {
4145
0
  DCTHuffTable *tbl;
4146
0
  int length;
4147
0
  int index;
4148
0
  Gushort code;
4149
0
  Guchar sym;
4150
0
  int i;
4151
0
  int c;
4152
4153
0
  length = read16() - 2;
4154
0
  while (length > 0) {
4155
0
    index = str->getChar();
4156
0
    --length;
4157
0
    if ((index & 0x0f) >= 4) {
4158
0
      error(errSyntaxError, getPos(), "Bad DCT Huffman table");
4159
0
      return gFalse;
4160
0
    }
4161
0
    if (index & 0x10) {
4162
0
      index &= 0x0f;
4163
0
      if (index >= numACHuffTables)
4164
0
  numACHuffTables = index+1;
4165
0
      tbl = &acHuffTables[index];
4166
0
    } else {
4167
0
      index &= 0x0f;
4168
0
      if (index >= numDCHuffTables)
4169
0
  numDCHuffTables = index+1;
4170
0
      tbl = &dcHuffTables[index];
4171
0
    }
4172
0
    sym = 0;
4173
0
    code = 0;
4174
0
    for (i = 1; i <= 16; ++i) {
4175
0
      c = str->getChar();
4176
0
      tbl->firstSym[i] = sym;
4177
0
      tbl->firstCode[i] = code;
4178
0
      tbl->numCodes[i] = (Gushort)c;
4179
0
      sym = (Guchar)(sym + c);
4180
0
      code = (Gushort)((code + c) << 1);
4181
0
    }
4182
0
    length -= 16;
4183
0
    for (i = 0; i < sym; ++i)
4184
0
      tbl->sym[i] = (Guchar)str->getChar();
4185
0
    length -= sym;
4186
0
  }
4187
0
  return gTrue;
4188
0
}
4189
4190
0
GBool DCTStream::readRestartInterval() {
4191
0
  int length;
4192
4193
0
  length = read16();
4194
0
  if (length != 4) {
4195
0
    error(errSyntaxError, getPos(), "Bad DCT restart interval");
4196
0
    return gFalse;
4197
0
  }
4198
0
  restartInterval = read16();
4199
0
  return gTrue;
4200
0
}
4201
4202
0
GBool DCTStream::readJFIFMarker() {
4203
0
  int length, i;
4204
0
  char buf[5];
4205
0
  int c;
4206
4207
0
  length = read16();
4208
0
  length -= 2;
4209
0
  if (length >= 5) {
4210
0
    for (i = 0; i < 5; ++i) {
4211
0
      if ((c = str->getChar()) == EOF) {
4212
0
  error(errSyntaxError, getPos(), "Bad DCT APP0 marker");
4213
0
  return gFalse;
4214
0
      }
4215
0
      buf[i] = (char)c;
4216
0
    }
4217
0
    length -= 5;
4218
0
    if (!memcmp(buf, "JFIF\0", 5)) {
4219
0
      gotJFIFMarker = gTrue;
4220
0
    }
4221
0
  }
4222
0
  while (length > 0) {
4223
0
    if (str->getChar() == EOF) {
4224
0
      error(errSyntaxError, getPos(), "Bad DCT APP0 marker");
4225
0
      return gFalse;
4226
0
    }
4227
0
    --length;
4228
0
  }
4229
0
  return gTrue;
4230
0
}
4231
4232
0
GBool DCTStream::readAdobeMarker() {
4233
0
  int length, i;
4234
0
  char buf[12];
4235
0
  int c;
4236
4237
0
  length = read16();
4238
0
  if (length < 14) {
4239
0
    goto err;
4240
0
  }
4241
0
  for (i = 0; i < 12; ++i) {
4242
0
    if ((c = str->getChar()) == EOF) {
4243
0
      goto err;
4244
0
    }
4245
0
    buf[i] = (char)c;
4246
0
  }
4247
0
  if (!strncmp(buf, "Adobe", 5)) {
4248
0
    colorXform = buf[11];
4249
0
    gotAdobeMarker = gTrue;
4250
0
  }
4251
0
  for (i = 14; i < length; ++i) {
4252
0
    if (str->getChar() == EOF) {
4253
0
      goto err;
4254
0
    }
4255
0
  }
4256
0
  return gTrue;
4257
4258
0
 err:
4259
0
  error(errSyntaxError, getPos(), "Bad DCT Adobe APP14 marker");
4260
0
  return gFalse;
4261
0
}
4262
4263
0
GBool DCTStream::readTrailer() {
4264
0
  int c;
4265
4266
0
  c = readMarker();
4267
0
  if (c != 0xd9) {   // EOI
4268
0
    error(errSyntaxError, getPos(), "Bad DCT trailer");
4269
0
    return gFalse;
4270
0
  }
4271
0
  return gTrue;
4272
0
}
4273
4274
0
int DCTStream::readMarker() {
4275
0
  int c;
4276
4277
0
  do {
4278
0
    do {
4279
0
      c = str->getChar();
4280
0
    } while (c != 0xff && c != EOF);
4281
0
    do {
4282
0
      c = str->getChar();
4283
0
    } while (c == 0xff);
4284
0
  } while (c == 0x00);
4285
0
  return c;
4286
0
}
4287
4288
0
int DCTStream::read16() {
4289
0
  int c1, c2;
4290
4291
0
  if ((c1 = str->getChar()) == EOF)
4292
0
    return EOF;
4293
0
  if ((c2 = str->getChar()) == EOF)
4294
0
    return EOF;
4295
0
  return (c1 << 8) + c2;
4296
0
}
4297
4298
#endif // HAVE_JPEGLIB
4299
4300
GString *DCTStream::getPSFilter(int psLevel, const char *indent,
4301
0
        GBool okToReadStream) {
4302
0
  GString *s;
4303
4304
0
  if (psLevel < 2) {
4305
0
    return NULL;
4306
0
  }
4307
0
  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
4308
0
    return NULL;
4309
0
  }
4310
0
  if (okToReadStream && !checkSequentialInterleaved()) {
4311
    // PostScript does not allow progressive or interleaved JPEG
4312
0
    delete s;
4313
0
    return NULL;
4314
0
  }
4315
0
  s->append(indent)->append("<< >> /DCTDecode filter\n");
4316
0
  return s;
4317
0
}
4318
4319
0
GBool DCTStream::isBinary(GBool last) {
4320
0
  return str->isBinary(gTrue);
4321
0
}
4322
4323
//------------------------------------------------------------------------
4324
// FlateStream
4325
//------------------------------------------------------------------------
4326
4327
int FlateStream::codeLenCodeMap[flateMaxCodeLenCodes] = {
4328
  16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
4329
};
4330
4331
FlateDecode FlateStream::lengthDecode[flateMaxLitCodes-257] = {
4332
  {0,   3},
4333
  {0,   4},
4334
  {0,   5},
4335
  {0,   6},
4336
  {0,   7},
4337
  {0,   8},
4338
  {0,   9},
4339
  {0,  10},
4340
  {1,  11},
4341
  {1,  13},
4342
  {1,  15},
4343
  {1,  17},
4344
  {2,  19},
4345
  {2,  23},
4346
  {2,  27},
4347
  {2,  31},
4348
  {3,  35},
4349
  {3,  43},
4350
  {3,  51},
4351
  {3,  59},
4352
  {4,  67},
4353
  {4,  83},
4354
  {4,  99},
4355
  {4, 115},
4356
  {5, 131},
4357
  {5, 163},
4358
  {5, 195},
4359
  {5, 227},
4360
  {0, 258},
4361
  {0, 258},
4362
  {0, 258}
4363
};
4364
4365
FlateDecode FlateStream::distDecode[flateMaxDistCodes] = {
4366
  { 0,     1},
4367
  { 0,     2},
4368
  { 0,     3},
4369
  { 0,     4},
4370
  { 1,     5},
4371
  { 1,     7},
4372
  { 2,     9},
4373
  { 2,    13},
4374
  { 3,    17},
4375
  { 3,    25},
4376
  { 4,    33},
4377
  { 4,    49},
4378
  { 5,    65},
4379
  { 5,    97},
4380
  { 6,   129},
4381
  { 6,   193},
4382
  { 7,   257},
4383
  { 7,   385},
4384
  { 8,   513},
4385
  { 8,   769},
4386
  { 9,  1025},
4387
  { 9,  1537},
4388
  {10,  2049},
4389
  {10,  3073},
4390
  {11,  4097},
4391
  {11,  6145},
4392
  {12,  8193},
4393
  {12, 12289},
4394
  {13, 16385},
4395
  {13, 24577}
4396
};
4397
4398
static FlateCode flateFixedLitCodeTabCodes[512] = {
4399
  {7, 0x0100},
4400
  {8, 0x0050},
4401
  {8, 0x0010},
4402
  {8, 0x0118},
4403
  {7, 0x0110},
4404
  {8, 0x0070},
4405
  {8, 0x0030},
4406
  {9, 0x00c0},
4407
  {7, 0x0108},
4408
  {8, 0x0060},
4409
  {8, 0x0020},
4410
  {9, 0x00a0},
4411
  {8, 0x0000},
4412
  {8, 0x0080},
4413
  {8, 0x0040},
4414
  {9, 0x00e0},
4415
  {7, 0x0104},
4416
  {8, 0x0058},
4417
  {8, 0x0018},
4418
  {9, 0x0090},
4419
  {7, 0x0114},
4420
  {8, 0x0078},
4421
  {8, 0x0038},
4422
  {9, 0x00d0},
4423
  {7, 0x010c},
4424
  {8, 0x0068},
4425
  {8, 0x0028},
4426
  {9, 0x00b0},
4427
  {8, 0x0008},
4428
  {8, 0x0088},
4429
  {8, 0x0048},
4430
  {9, 0x00f0},
4431
  {7, 0x0102},
4432
  {8, 0x0054},
4433
  {8, 0x0014},
4434
  {8, 0x011c},
4435
  {7, 0x0112},
4436
  {8, 0x0074},
4437
  {8, 0x0034},
4438
  {9, 0x00c8},
4439
  {7, 0x010a},
4440
  {8, 0x0064},
4441
  {8, 0x0024},
4442
  {9, 0x00a8},
4443
  {8, 0x0004},
4444
  {8, 0x0084},
4445
  {8, 0x0044},
4446
  {9, 0x00e8},
4447
  {7, 0x0106},
4448
  {8, 0x005c},
4449
  {8, 0x001c},
4450
  {9, 0x0098},
4451
  {7, 0x0116},
4452
  {8, 0x007c},
4453
  {8, 0x003c},
4454
  {9, 0x00d8},
4455
  {7, 0x010e},
4456
  {8, 0x006c},
4457
  {8, 0x002c},
4458
  {9, 0x00b8},
4459
  {8, 0x000c},
4460
  {8, 0x008c},
4461
  {8, 0x004c},
4462
  {9, 0x00f8},
4463
  {7, 0x0101},
4464
  {8, 0x0052},
4465
  {8, 0x0012},
4466
  {8, 0x011a},
4467
  {7, 0x0111},
4468
  {8, 0x0072},
4469
  {8, 0x0032},
4470
  {9, 0x00c4},
4471
  {7, 0x0109},
4472
  {8, 0x0062},
4473
  {8, 0x0022},
4474
  {9, 0x00a4},
4475
  {8, 0x0002},
4476
  {8, 0x0082},
4477
  {8, 0x0042},
4478
  {9, 0x00e4},
4479
  {7, 0x0105},
4480
  {8, 0x005a},
4481
  {8, 0x001a},
4482
  {9, 0x0094},
4483
  {7, 0x0115},
4484
  {8, 0x007a},
4485
  {8, 0x003a},
4486
  {9, 0x00d4},
4487
  {7, 0x010d},
4488
  {8, 0x006a},
4489
  {8, 0x002a},
4490
  {9, 0x00b4},
4491
  {8, 0x000a},
4492
  {8, 0x008a},
4493
  {8, 0x004a},
4494
  {9, 0x00f4},
4495
  {7, 0x0103},
4496
  {8, 0x0056},
4497
  {8, 0x0016},
4498
  {8, 0x011e},
4499
  {7, 0x0113},
4500
  {8, 0x0076},
4501
  {8, 0x0036},
4502
  {9, 0x00cc},
4503
  {7, 0x010b},
4504
  {8, 0x0066},
4505
  {8, 0x0026},
4506
  {9, 0x00ac},
4507
  {8, 0x0006},
4508
  {8, 0x0086},
4509
  {8, 0x0046},
4510
  {9, 0x00ec},
4511
  {7, 0x0107},
4512
  {8, 0x005e},
4513
  {8, 0x001e},
4514
  {9, 0x009c},
4515
  {7, 0x0117},
4516
  {8, 0x007e},
4517
  {8, 0x003e},
4518
  {9, 0x00dc},
4519
  {7, 0x010f},
4520
  {8, 0x006e},
4521
  {8, 0x002e},
4522
  {9, 0x00bc},
4523
  {8, 0x000e},
4524
  {8, 0x008e},
4525
  {8, 0x004e},
4526
  {9, 0x00fc},
4527
  {7, 0x0100},
4528
  {8, 0x0051},
4529
  {8, 0x0011},
4530
  {8, 0x0119},
4531
  {7, 0x0110},
4532
  {8, 0x0071},
4533
  {8, 0x0031},
4534
  {9, 0x00c2},
4535
  {7, 0x0108},
4536
  {8, 0x0061},
4537
  {8, 0x0021},
4538
  {9, 0x00a2},
4539
  {8, 0x0001},
4540
  {8, 0x0081},
4541
  {8, 0x0041},
4542
  {9, 0x00e2},
4543
  {7, 0x0104},
4544
  {8, 0x0059},
4545
  {8, 0x0019},
4546
  {9, 0x0092},
4547
  {7, 0x0114},
4548
  {8, 0x0079},
4549
  {8, 0x0039},
4550
  {9, 0x00d2},
4551
  {7, 0x010c},
4552
  {8, 0x0069},
4553
  {8, 0x0029},
4554
  {9, 0x00b2},
4555
  {8, 0x0009},
4556
  {8, 0x0089},
4557
  {8, 0x0049},
4558
  {9, 0x00f2},
4559
  {7, 0x0102},
4560
  {8, 0x0055},
4561
  {8, 0x0015},
4562
  {8, 0x011d},
4563
  {7, 0x0112},
4564
  {8, 0x0075},
4565
  {8, 0x0035},
4566
  {9, 0x00ca},
4567
  {7, 0x010a},
4568
  {8, 0x0065},
4569
  {8, 0x0025},
4570
  {9, 0x00aa},
4571
  {8, 0x0005},
4572
  {8, 0x0085},
4573
  {8, 0x0045},
4574
  {9, 0x00ea},
4575
  {7, 0x0106},
4576
  {8, 0x005d},
4577
  {8, 0x001d},
4578
  {9, 0x009a},
4579
  {7, 0x0116},
4580
  {8, 0x007d},
4581
  {8, 0x003d},
4582
  {9, 0x00da},
4583
  {7, 0x010e},
4584
  {8, 0x006d},
4585
  {8, 0x002d},
4586
  {9, 0x00ba},
4587
  {8, 0x000d},
4588
  {8, 0x008d},
4589
  {8, 0x004d},
4590
  {9, 0x00fa},
4591
  {7, 0x0101},
4592
  {8, 0x0053},
4593
  {8, 0x0013},
4594
  {8, 0x011b},
4595
  {7, 0x0111},
4596
  {8, 0x0073},
4597
  {8, 0x0033},
4598
  {9, 0x00c6},
4599
  {7, 0x0109},
4600
  {8, 0x0063},
4601
  {8, 0x0023},
4602
  {9, 0x00a6},
4603
  {8, 0x0003},
4604
  {8, 0x0083},
4605
  {8, 0x0043},
4606
  {9, 0x00e6},
4607
  {7, 0x0105},
4608
  {8, 0x005b},
4609
  {8, 0x001b},
4610
  {9, 0x0096},
4611
  {7, 0x0115},
4612
  {8, 0x007b},
4613
  {8, 0x003b},
4614
  {9, 0x00d6},
4615
  {7, 0x010d},
4616
  {8, 0x006b},
4617
  {8, 0x002b},
4618
  {9, 0x00b6},
4619
  {8, 0x000b},
4620
  {8, 0x008b},
4621
  {8, 0x004b},
4622
  {9, 0x00f6},
4623
  {7, 0x0103},
4624
  {8, 0x0057},
4625
  {8, 0x0017},
4626
  {8, 0x011f},
4627
  {7, 0x0113},
4628
  {8, 0x0077},
4629
  {8, 0x0037},
4630
  {9, 0x00ce},
4631
  {7, 0x010b},
4632
  {8, 0x0067},
4633
  {8, 0x0027},
4634
  {9, 0x00ae},
4635
  {8, 0x0007},
4636
  {8, 0x0087},
4637
  {8, 0x0047},
4638
  {9, 0x00ee},
4639
  {7, 0x0107},
4640
  {8, 0x005f},
4641
  {8, 0x001f},
4642
  {9, 0x009e},
4643
  {7, 0x0117},
4644
  {8, 0x007f},
4645
  {8, 0x003f},
4646
  {9, 0x00de},
4647
  {7, 0x010f},
4648
  {8, 0x006f},
4649
  {8, 0x002f},
4650
  {9, 0x00be},
4651
  {8, 0x000f},
4652
  {8, 0x008f},
4653
  {8, 0x004f},
4654
  {9, 0x00fe},
4655
  {7, 0x0100},
4656
  {8, 0x0050},
4657
  {8, 0x0010},
4658
  {8, 0x0118},
4659
  {7, 0x0110},
4660
  {8, 0x0070},
4661
  {8, 0x0030},
4662
  {9, 0x00c1},
4663
  {7, 0x0108},
4664
  {8, 0x0060},
4665
  {8, 0x0020},
4666
  {9, 0x00a1},
4667
  {8, 0x0000},
4668
  {8, 0x0080},
4669
  {8, 0x0040},
4670
  {9, 0x00e1},
4671
  {7, 0x0104},
4672
  {8, 0x0058},
4673
  {8, 0x0018},
4674
  {9, 0x0091},
4675
  {7, 0x0114},
4676
  {8, 0x0078},
4677
  {8, 0x0038},
4678
  {9, 0x00d1},
4679
  {7, 0x010c},
4680
  {8, 0x0068},
4681
  {8, 0x0028},
4682
  {9, 0x00b1},
4683
  {8, 0x0008},
4684
  {8, 0x0088},
4685
  {8, 0x0048},
4686
  {9, 0x00f1},
4687
  {7, 0x0102},
4688
  {8, 0x0054},
4689
  {8, 0x0014},
4690
  {8, 0x011c},
4691
  {7, 0x0112},
4692
  {8, 0x0074},
4693
  {8, 0x0034},
4694
  {9, 0x00c9},
4695
  {7, 0x010a},
4696
  {8, 0x0064},
4697
  {8, 0x0024},
4698
  {9, 0x00a9},
4699
  {8, 0x0004},
4700
  {8, 0x0084},
4701
  {8, 0x0044},
4702
  {9, 0x00e9},
4703
  {7, 0x0106},
4704
  {8, 0x005c},
4705
  {8, 0x001c},
4706
  {9, 0x0099},
4707
  {7, 0x0116},
4708
  {8, 0x007c},
4709
  {8, 0x003c},
4710
  {9, 0x00d9},
4711
  {7, 0x010e},
4712
  {8, 0x006c},
4713
  {8, 0x002c},
4714
  {9, 0x00b9},
4715
  {8, 0x000c},
4716
  {8, 0x008c},
4717
  {8, 0x004c},
4718
  {9, 0x00f9},
4719
  {7, 0x0101},
4720
  {8, 0x0052},
4721
  {8, 0x0012},
4722
  {8, 0x011a},
4723
  {7, 0x0111},
4724
  {8, 0x0072},
4725
  {8, 0x0032},
4726
  {9, 0x00c5},
4727
  {7, 0x0109},
4728
  {8, 0x0062},
4729
  {8, 0x0022},
4730
  {9, 0x00a5},
4731
  {8, 0x0002},
4732
  {8, 0x0082},
4733
  {8, 0x0042},
4734
  {9, 0x00e5},
4735
  {7, 0x0105},
4736
  {8, 0x005a},
4737
  {8, 0x001a},
4738
  {9, 0x0095},
4739
  {7, 0x0115},
4740
  {8, 0x007a},
4741
  {8, 0x003a},
4742
  {9, 0x00d5},
4743
  {7, 0x010d},
4744
  {8, 0x006a},
4745
  {8, 0x002a},
4746
  {9, 0x00b5},
4747
  {8, 0x000a},
4748
  {8, 0x008a},
4749
  {8, 0x004a},
4750
  {9, 0x00f5},
4751
  {7, 0x0103},
4752
  {8, 0x0056},
4753
  {8, 0x0016},
4754
  {8, 0x011e},
4755
  {7, 0x0113},
4756
  {8, 0x0076},
4757
  {8, 0x0036},
4758
  {9, 0x00cd},
4759
  {7, 0x010b},
4760
  {8, 0x0066},
4761
  {8, 0x0026},
4762
  {9, 0x00ad},
4763
  {8, 0x0006},
4764
  {8, 0x0086},
4765
  {8, 0x0046},
4766
  {9, 0x00ed},
4767
  {7, 0x0107},
4768
  {8, 0x005e},
4769
  {8, 0x001e},
4770
  {9, 0x009d},
4771
  {7, 0x0117},
4772
  {8, 0x007e},
4773
  {8, 0x003e},
4774
  {9, 0x00dd},
4775
  {7, 0x010f},
4776
  {8, 0x006e},
4777
  {8, 0x002e},
4778
  {9, 0x00bd},
4779
  {8, 0x000e},
4780
  {8, 0x008e},
4781
  {8, 0x004e},
4782
  {9, 0x00fd},
4783
  {7, 0x0100},
4784
  {8, 0x0051},
4785
  {8, 0x0011},
4786
  {8, 0x0119},
4787
  {7, 0x0110},
4788
  {8, 0x0071},
4789
  {8, 0x0031},
4790
  {9, 0x00c3},
4791
  {7, 0x0108},
4792
  {8, 0x0061},
4793
  {8, 0x0021},
4794
  {9, 0x00a3},
4795
  {8, 0x0001},
4796
  {8, 0x0081},
4797
  {8, 0x0041},
4798
  {9, 0x00e3},
4799
  {7, 0x0104},
4800
  {8, 0x0059},
4801
  {8, 0x0019},
4802
  {9, 0x0093},
4803
  {7, 0x0114},
4804
  {8, 0x0079},
4805
  {8, 0x0039},
4806
  {9, 0x00d3},
4807
  {7, 0x010c},
4808
  {8, 0x0069},
4809
  {8, 0x0029},
4810
  {9, 0x00b3},
4811
  {8, 0x0009},
4812
  {8, 0x0089},
4813
  {8, 0x0049},
4814
  {9, 0x00f3},
4815
  {7, 0x0102},
4816
  {8, 0x0055},
4817
  {8, 0x0015},
4818
  {8, 0x011d},
4819
  {7, 0x0112},
4820
  {8, 0x0075},
4821
  {8, 0x0035},
4822
  {9, 0x00cb},
4823
  {7, 0x010a},
4824
  {8, 0x0065},
4825
  {8, 0x0025},
4826
  {9, 0x00ab},
4827
  {8, 0x0005},
4828
  {8, 0x0085},
4829
  {8, 0x0045},
4830
  {9, 0x00eb},
4831
  {7, 0x0106},
4832
  {8, 0x005d},
4833
  {8, 0x001d},
4834
  {9, 0x009b},
4835
  {7, 0x0116},
4836
  {8, 0x007d},
4837
  {8, 0x003d},
4838
  {9, 0x00db},
4839
  {7, 0x010e},
4840
  {8, 0x006d},
4841
  {8, 0x002d},
4842
  {9, 0x00bb},
4843
  {8, 0x000d},
4844
  {8, 0x008d},
4845
  {8, 0x004d},
4846
  {9, 0x00fb},
4847
  {7, 0x0101},
4848
  {8, 0x0053},
4849
  {8, 0x0013},
4850
  {8, 0x011b},
4851
  {7, 0x0111},
4852
  {8, 0x0073},
4853
  {8, 0x0033},
4854
  {9, 0x00c7},
4855
  {7, 0x0109},
4856
  {8, 0x0063},
4857
  {8, 0x0023},
4858
  {9, 0x00a7},
4859
  {8, 0x0003},
4860
  {8, 0x0083},
4861
  {8, 0x0043},
4862
  {9, 0x00e7},
4863
  {7, 0x0105},
4864
  {8, 0x005b},
4865
  {8, 0x001b},
4866
  {9, 0x0097},
4867
  {7, 0x0115},
4868
  {8, 0x007b},
4869
  {8, 0x003b},
4870
  {9, 0x00d7},
4871
  {7, 0x010d},
4872
  {8, 0x006b},
4873
  {8, 0x002b},
4874
  {9, 0x00b7},
4875
  {8, 0x000b},
4876
  {8, 0x008b},
4877
  {8, 0x004b},
4878
  {9, 0x00f7},
4879
  {7, 0x0103},
4880
  {8, 0x0057},
4881
  {8, 0x0017},
4882
  {8, 0x011f},
4883
  {7, 0x0113},
4884
  {8, 0x0077},
4885
  {8, 0x0037},
4886
  {9, 0x00cf},
4887
  {7, 0x010b},
4888
  {8, 0x0067},
4889
  {8, 0x0027},
4890
  {9, 0x00af},
4891
  {8, 0x0007},
4892
  {8, 0x0087},
4893
  {8, 0x0047},
4894
  {9, 0x00ef},
4895
  {7, 0x0107},
4896
  {8, 0x005f},
4897
  {8, 0x001f},
4898
  {9, 0x009f},
4899
  {7, 0x0117},
4900
  {8, 0x007f},
4901
  {8, 0x003f},
4902
  {9, 0x00df},
4903
  {7, 0x010f},
4904
  {8, 0x006f},
4905
  {8, 0x002f},
4906
  {9, 0x00bf},
4907
  {8, 0x000f},
4908
  {8, 0x008f},
4909
  {8, 0x004f},
4910
  {9, 0x00ff}
4911
};
4912
4913
FlateHuffmanTab FlateStream::fixedLitCodeTab = {
4914
  flateFixedLitCodeTabCodes, 9
4915
};
4916
4917
static FlateCode flateFixedDistCodeTabCodes[32] = {
4918
  {5, 0x0000},
4919
  {5, 0x0010},
4920
  {5, 0x0008},
4921
  {5, 0x0018},
4922
  {5, 0x0004},
4923
  {5, 0x0014},
4924
  {5, 0x000c},
4925
  {5, 0x001c},
4926
  {5, 0x0002},
4927
  {5, 0x0012},
4928
  {5, 0x000a},
4929
  {5, 0x001a},
4930
  {5, 0x0006},
4931
  {5, 0x0016},
4932
  {5, 0x000e},
4933
  {0, 0x0000},
4934
  {5, 0x0001},
4935
  {5, 0x0011},
4936
  {5, 0x0009},
4937
  {5, 0x0019},
4938
  {5, 0x0005},
4939
  {5, 0x0015},
4940
  {5, 0x000d},
4941
  {5, 0x001d},
4942
  {5, 0x0003},
4943
  {5, 0x0013},
4944
  {5, 0x000b},
4945
  {5, 0x001b},
4946
  {5, 0x0007},
4947
  {5, 0x0017},
4948
  {5, 0x000f},
4949
  {0, 0x0000}
4950
};
4951
4952
FlateHuffmanTab FlateStream::fixedDistCodeTab = {
4953
  flateFixedDistCodeTabCodes, 5
4954
};
4955
4956
FlateStream::FlateStream(Stream *strA, int predictor, int columns,
4957
       int colors, int bits):
4958
5.13k
    FilterStream(strA) {
4959
5.13k
  if (predictor != 1) {
4960
4
    pred = new StreamPredictor(this, predictor, columns, colors, bits);
4961
4
    if (!pred->isOk()) {
4962
0
      delete pred;
4963
0
      pred = NULL;
4964
0
    }
4965
5.13k
  } else {
4966
5.13k
    pred = NULL;
4967
5.13k
  }
4968
5.13k
  litCodeTab.codes = NULL;
4969
5.13k
  distCodeTab.codes = NULL;
4970
5.13k
  memset(buf, 0, flateWindow);
4971
5.13k
  checkForDecompressionBombs = gTrue;
4972
5.13k
}
4973
4974
5.13k
FlateStream::~FlateStream() {
4975
5.13k
  if (litCodeTab.codes != fixedLitCodeTab.codes) {
4976
5.10k
    gfree(litCodeTab.codes);
4977
5.10k
  }
4978
5.13k
  if (distCodeTab.codes != fixedDistCodeTab.codes) {
4979
5.10k
    gfree(distCodeTab.codes);
4980
5.10k
  }
4981
5.13k
  if (pred) {
4982
4
    delete pred;
4983
4
  }
4984
5.13k
  delete str;
4985
5.13k
}
4986
4987
2.87k
Stream *FlateStream::copy() {
4988
2.87k
  if (pred) {
4989
2
    return new FlateStream(str->copy(), pred->getPredictor(),
4990
2
         pred->getWidth(), pred->getNComps(),
4991
2
         pred->getNBits());
4992
2.86k
  } else {
4993
2.86k
    return new FlateStream(str->copy(), 1, 0, 0, 0);
4994
2.86k
  }
4995
2.87k
}
4996
4997
0
void FlateStream::disableDecompressionBombChecking() {
4998
0
  checkForDecompressionBombs = gFalse;
4999
0
  FilterStream::disableDecompressionBombChecking();
5000
0
}
5001
5002
193
void FlateStream::reset() {
5003
193
  int cmf, flg;
5004
5005
193
  index = 0;
5006
193
  remain = 0;
5007
193
  codeBuf = 0;
5008
193
  codeSize = 0;
5009
193
  compressedBlock = gFalse;
5010
193
  endOfBlock = gTrue;
5011
193
  eof = gTrue;
5012
5013
193
  str->reset();
5014
193
  if (pred) {
5015
0
    pred->reset();
5016
0
  }
5017
5018
  // read header
5019
  //~ need to look at window size?
5020
193
  endOfBlock = eof = gTrue;
5021
193
  cmf = str->getChar();
5022
193
  flg = str->getChar();
5023
193
  totalIn = 2;
5024
193
  totalOut = 0;
5025
193
  if (cmf == EOF || flg == EOF)
5026
0
    return;
5027
193
  if ((cmf & 0x0f) != 0x08) {
5028
0
    error(errSyntaxError, getPos(),
5029
0
    "Unknown compression method in flate stream");
5030
0
    return;
5031
0
  }
5032
193
  if ((((cmf << 8) + flg) % 31) != 0) {
5033
0
    error(errSyntaxError, getPos(), "Bad FCHECK in flate stream");
5034
0
    return;
5035
0
  }
5036
193
  if (flg & 0x20) {
5037
0
    error(errSyntaxError, getPos(), "FDICT bit set in flate stream");
5038
0
    return;
5039
0
  }
5040
5041
193
  eof = gFalse;
5042
193
}
5043
5044
4.07k
int FlateStream::getChar() {
5045
4.07k
  int c;
5046
5047
4.07k
  if (pred) {
5048
0
    return pred->getChar();
5049
0
  }
5050
6.20k
  while (remain == 0) {
5051
2.13k
    if (endOfBlock && eof)
5052
0
      return EOF;
5053
2.13k
    readSome();
5054
2.13k
  }
5055
4.07k
  c = buf[index];
5056
4.07k
  index = (index + 1) & flateMask;
5057
4.07k
  --remain;
5058
4.07k
  return c;
5059
4.07k
}
5060
5061
1.66k
int FlateStream::lookChar() {
5062
1.66k
  int c;
5063
5064
1.66k
  if (pred) {
5065
0
    return pred->lookChar();
5066
0
  }
5067
2.63k
  while (remain == 0) {
5068
972
    if (endOfBlock && eof)
5069
0
      return EOF;
5070
972
    readSome();
5071
972
  }
5072
1.66k
  c = buf[index];
5073
1.66k
  return c;
5074
1.66k
}
5075
5076
0
int FlateStream::getRawChar() {
5077
0
  int c;
5078
5079
0
  while (remain == 0) {
5080
0
    if (endOfBlock && eof)
5081