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