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