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