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

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 16 years ago

First import

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