source: trunk/poppler/mypoppler/poppler/Stream.cc @ 257

Last change on this file since 257 was 257, checked in by Eugene Romanenko, 13 years ago

PDF plugin: Poppler library updated to version 0.10.0

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