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