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