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