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