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