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