~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/poppler/poppler/Stream.cc

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

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