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