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 #include <limits.h>
19 #ifndef _WIN32
20 #include <unistd.h>
21 #endif
22 #include <string.h>
23 #include <ctype.h>
24 #include "gmem.h"
25 #include "gfile.h"
26 #include "config.h"
27 #include "Error.h"
28 #include "Object.h"
29 #include "Lexer.h"
30 #include "GfxState.h"
31 #include "Stream.h"
32 #include "JBIG2Stream.h"
33 #include "JPXStream.h"
34 #include "Stream-CCITT.h"
35 
36 #ifdef __DJGPP__
37 static GBool setDJSYSFLAGS = gFalse;
38 #endif
39 
40 #ifdef VMS
41 #ifdef __GNUC__
42 #define SEEK_SET 0
43 #define SEEK_CUR 1
44 #define SEEK_END 2
45 #endif
46 #endif
47 
48 //------------------------------------------------------------------------
49 // Stream (base class)
50 //------------------------------------------------------------------------
51 
Stream()52 Stream::Stream() {
53   ref = 1;
54 }
55 
~Stream()56 Stream::~Stream() {
57 }
58 
close()59 void Stream::close() {
60 }
61 
getRawChar()62 int Stream::getRawChar() {
63   error(errInternal, -1, "Called getRawChar() on non-predictor stream");
64   return EOF;
65 }
66 
getBlock(char * buf,int size)67 int Stream::getBlock(char *buf, int size) {
68   int n, c;
69 
70   n = 0;
71   while (n < size) {
72     if ((c = getChar()) == EOF) {
73       break;
74     }
75     buf[n++] = (char)c;
76   }
77   return n;
78 }
79 
getLine(char * buf,int size)80 char *Stream::getLine(char *buf, int size) {
81   int i;
82   int c;
83 
84   if (lookChar() == EOF || size < 0)
85     return NULL;
86   for (i = 0; i < size - 1; ++i) {
87     c = getChar();
88     if (c == EOF || c == '\n')
89       break;
90     if (c == '\r') {
91       if ((c = lookChar()) == '\n')
92 	getChar();
93       break;
94     }
95     buf[i] = c;
96   }
97   buf[i] = '\0';
98   return buf;
99 }
100 
discardChars(Guint n)101 Guint Stream::discardChars(Guint n) {
102   char buf[4096];
103   Guint count, i, j;
104 
105   count = 0;
106   while (count < n) {
107     if ((i = n - count) > sizeof(buf)) {
108       i = (Guint)sizeof(buf);
109     }
110     j = (Guint)getBlock(buf, (int)i);
111     count += j;
112     if (j != i) {
113       break;
114     }
115   }
116   return count;
117 }
118 
getPSFilter(int psLevel,const char * indent)119 GString *Stream::getPSFilter(int psLevel, const char *indent) {
120   return new GString();
121 }
122 
addFilters(Object * dict,int recursion)123 Stream *Stream::addFilters(Object *dict, int recursion) {
124   Object obj, obj2;
125   Object params, params2;
126   Stream *str;
127   int i;
128 
129   str = this;
130   dict->dictLookup("Filter", &obj);
131   if (obj.isNull()) {
132     obj.free();
133     dict->dictLookup("F", &obj);
134   }
135   dict->dictLookup("DecodeParms", &params);
136   if (params.isNull()) {
137     params.free();
138     dict->dictLookup("DP", &params);
139   }
140   if (obj.isName()) {
141     str = makeFilter(obj.getName(), str, &params, recursion);
142   } else if (obj.isArray()) {
143     for (i = 0; i < obj.arrayGetLength(); ++i) {
144       obj.arrayGet(i, &obj2);
145       if (params.isArray())
146 	params.arrayGet(i, &params2);
147       else
148 	params2.initNull();
149       if (obj2.isName()) {
150 	str = makeFilter(obj2.getName(), str, &params2, recursion);
151       } else {
152 	error(errSyntaxError, getPos(), "Bad filter name");
153 	str = new EOFStream(str);
154       }
155       obj2.free();
156       params2.free();
157     }
158   } else if (!obj.isNull()) {
159     error(errSyntaxError, getPos(), "Bad 'Filter' attribute in stream");
160   }
161   obj.free();
162   params.free();
163 
164   return str;
165 }
166 
makeFilter(char * name,Stream * str,Object * params,int recursion)167 Stream *Stream::makeFilter(char *name, Stream *str, Object *params,
168 			   int recursion) {
169   int pred;			// parameters
170   int colors;
171   int bits;
172   int early;
173   int encoding;
174   GBool endOfLine, byteAlign, endOfBlock, black;
175   int columns, rows;
176   int colorXform;
177   Object globals, obj;
178 
179   if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) {
180     str = new ASCIIHexStream(str);
181   } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) {
182     str = new ASCII85Stream(str);
183   } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) {
184     pred = 1;
185     columns = 1;
186     colors = 1;
187     bits = 8;
188     early = 1;
189     if (params->isDict()) {
190       params->dictLookup("Predictor", &obj, recursion);
191       if (obj.isInt())
192 	pred = obj.getInt();
193       obj.free();
194       params->dictLookup("Columns", &obj, recursion);
195       if (obj.isInt())
196 	columns = obj.getInt();
197       obj.free();
198       params->dictLookup("Colors", &obj, recursion);
199       if (obj.isInt())
200 	colors = obj.getInt();
201       obj.free();
202       params->dictLookup("BitsPerComponent", &obj, recursion);
203       if (obj.isInt())
204 	bits = obj.getInt();
205       obj.free();
206       params->dictLookup("EarlyChange", &obj, recursion);
207       if (obj.isInt())
208 	early = obj.getInt();
209       obj.free();
210     }
211     str = new LZWStream(str, pred, columns, colors, bits, early);
212   } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) {
213     str = new RunLengthStream(str);
214   } else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) {
215     encoding = 0;
216     endOfLine = gFalse;
217     byteAlign = gFalse;
218     columns = 1728;
219     rows = 0;
220     endOfBlock = gTrue;
221     black = gFalse;
222     if (params->isDict()) {
223       params->dictLookup("K", &obj, recursion);
224       if (obj.isInt()) {
225 	encoding = obj.getInt();
226       }
227       obj.free();
228       params->dictLookup("EndOfLine", &obj, recursion);
229       if (obj.isBool()) {
230 	endOfLine = obj.getBool();
231       }
232       obj.free();
233       params->dictLookup("EncodedByteAlign", &obj, recursion);
234       if (obj.isBool()) {
235 	byteAlign = obj.getBool();
236       }
237       obj.free();
238       params->dictLookup("Columns", &obj, recursion);
239       if (obj.isInt()) {
240 	columns = obj.getInt();
241       }
242       obj.free();
243       params->dictLookup("Rows", &obj, recursion);
244       if (obj.isInt()) {
245 	rows = obj.getInt();
246       }
247       obj.free();
248       params->dictLookup("EndOfBlock", &obj, recursion);
249       if (obj.isBool()) {
250 	endOfBlock = obj.getBool();
251       }
252       obj.free();
253       params->dictLookup("BlackIs1", &obj, recursion);
254       if (obj.isBool()) {
255 	black = obj.getBool();
256       }
257       obj.free();
258     }
259     str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign,
260 			     columns, rows, endOfBlock, black);
261   } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) {
262     colorXform = -1;
263     if (params->isDict()) {
264       if (params->dictLookup("ColorTransform", &obj, recursion)->isInt()) {
265 	colorXform = obj.getInt();
266       }
267       obj.free();
268     }
269     str = new DCTStream(str, colorXform);
270   } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) {
271     pred = 1;
272     columns = 1;
273     colors = 1;
274     bits = 8;
275     if (params->isDict()) {
276       params->dictLookup("Predictor", &obj, recursion);
277       if (obj.isInt())
278 	pred = obj.getInt();
279       obj.free();
280       params->dictLookup("Columns", &obj, recursion);
281       if (obj.isInt())
282 	columns = obj.getInt();
283       obj.free();
284       params->dictLookup("Colors", &obj, recursion);
285       if (obj.isInt())
286 	colors = obj.getInt();
287       obj.free();
288       params->dictLookup("BitsPerComponent", &obj, recursion);
289       if (obj.isInt())
290 	bits = obj.getInt();
291       obj.free();
292     }
293     str = new FlateStream(str, pred, columns, colors, bits);
294   } else if (!strcmp(name, "JBIG2Decode")) {
295     if (params->isDict()) {
296       params->dictLookup("JBIG2Globals", &globals, recursion);
297     }
298     str = new JBIG2Stream(str, &globals);
299     globals.free();
300   } else if (!strcmp(name, "JPXDecode")) {
301     str = new JPXStream(str);
302   } else {
303     error(errSyntaxError, getPos(), "Unknown filter '{0:s}'", name);
304     str = new EOFStream(str);
305   }
306   return str;
307 }
308 
309 //------------------------------------------------------------------------
310 // BaseStream
311 //------------------------------------------------------------------------
312 
BaseStream(Object * dictA)313 BaseStream::BaseStream(Object *dictA) {
314   dict = *dictA;
315 }
316 
~BaseStream()317 BaseStream::~BaseStream() {
318   dict.free();
319 }
320 
321 //------------------------------------------------------------------------
322 // FilterStream
323 //------------------------------------------------------------------------
324 
FilterStream(Stream * strA)325 FilterStream::FilterStream(Stream *strA) {
326   str = strA;
327 }
328 
~FilterStream()329 FilterStream::~FilterStream() {
330 }
331 
close()332 void FilterStream::close() {
333   str->close();
334 }
335 
setPos(GFileOffset pos,int dir)336 void FilterStream::setPos(GFileOffset pos, int dir) {
337   error(errInternal, -1, "Called setPos() on FilterStream");
338 }
339 
340 //------------------------------------------------------------------------
341 // ImageStream
342 //------------------------------------------------------------------------
343 
ImageStream(Stream * strA,int widthA,int nCompsA,int nBitsA)344 ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) {
345   int imgLineSize;
346 
347   str = strA;
348   width = widthA;
349   nComps = nCompsA;
350   nBits = nBitsA;
351 
352   nVals = width * nComps;
353   inputLineSize = (nVals * nBits + 7) >> 3;
354   if (nVals > INT_MAX / nBits - 7) {
355     // force a call to gmallocn(-1,...), which will throw an exception
356     inputLineSize = -1;
357   }
358   inputLine = (char *)gmallocn(inputLineSize, sizeof(char));
359   if (nBits == 8) {
360     imgLine = (Guchar *)inputLine;
361   } else {
362     if (nBits == 1) {
363       imgLineSize = (nVals + 7) & ~7;
364     } else {
365       imgLineSize = nVals;
366     }
367     if (width > INT_MAX / nComps) {
368       // force a call to gmallocn(-1,...), which will throw an exception
369       imgLineSize = -1;
370     }
371     imgLine = (Guchar *)gmallocn(imgLineSize, sizeof(Guchar));
372   }
373   imgIdx = nVals;
374 }
375 
~ImageStream()376 ImageStream::~ImageStream() {
377   if (imgLine != (Guchar *)inputLine) {
378     gfree(imgLine);
379   }
380   gfree(inputLine);
381 }
382 
reset()383 void ImageStream::reset() {
384   str->reset();
385 }
386 
close()387 void ImageStream::close() {
388   str->close();
389 }
390 
getPixel(Guchar * pix)391 GBool ImageStream::getPixel(Guchar *pix) {
392   int i;
393 
394   if (imgIdx >= nVals) {
395     if (!getLine()) {
396       return gFalse;
397     }
398     imgIdx = 0;
399   }
400   for (i = 0; i < nComps; ++i) {
401     pix[i] = imgLine[imgIdx++];
402   }
403   return gTrue;
404 }
405 
getLine()406 Guchar *ImageStream::getLine() {
407   Gulong buf, bitMask;
408   int bits;
409   int c;
410   int i;
411   char *p;
412 
413   if (str->getBlock(inputLine, inputLineSize) != inputLineSize) {
414     return NULL;
415   }
416   if (nBits == 1) {
417     p = inputLine;
418     for (i = 0; i < nVals; i += 8) {
419       c = *p++;
420       imgLine[i+0] = (Guchar)((c >> 7) & 1);
421       imgLine[i+1] = (Guchar)((c >> 6) & 1);
422       imgLine[i+2] = (Guchar)((c >> 5) & 1);
423       imgLine[i+3] = (Guchar)((c >> 4) & 1);
424       imgLine[i+4] = (Guchar)((c >> 3) & 1);
425       imgLine[i+5] = (Guchar)((c >> 2) & 1);
426       imgLine[i+6] = (Guchar)((c >> 1) & 1);
427       imgLine[i+7] = (Guchar)(c & 1);
428     }
429   } else if (nBits == 8) {
430     // special case: imgLine == inputLine
431   } else if (nBits == 16) {
432     for (i = 0; i < nVals; ++i) {
433       imgLine[i] = (Guchar)inputLine[2*i];
434     }
435   } else {
436     bitMask = (1 << nBits) - 1;
437     buf = 0;
438     bits = 0;
439     p = inputLine;
440     for (i = 0; i < nVals; ++i) {
441       if (bits < nBits) {
442 	buf = (buf << 8) | (*p++ & 0xff);
443 	bits += 8;
444       }
445       imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask);
446       bits -= nBits;
447     }
448   }
449   return imgLine;
450 }
451 
skipLine()452 void ImageStream::skipLine() {
453   str->getBlock(inputLine, inputLineSize);
454 }
455 
456 //------------------------------------------------------------------------
457 // StreamPredictor
458 //------------------------------------------------------------------------
459 
StreamPredictor(Stream * strA,int predictorA,int widthA,int nCompsA,int nBitsA)460 StreamPredictor::StreamPredictor(Stream *strA, int predictorA,
461 				 int widthA, int nCompsA, int nBitsA) {
462   str = strA;
463   predictor = predictorA;
464   width = widthA;
465   nComps = nCompsA;
466   nBits = nBitsA;
467   predLine = NULL;
468   ok = gFalse;
469 
470   nVals = width * nComps;
471   pixBytes = (nComps * nBits + 7) >> 3;
472   rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes;
473   if (width <= 0 || nComps <= 0 || nBits <= 0 ||
474       nComps > gfxColorMaxComps ||
475       nBits > 16 ||
476       width >= INT_MAX / nComps ||      // check for overflow in nVals
477       nVals >= (INT_MAX - 7) / nBits) { // check for overflow in rowBytes
478     return;
479   }
480   predLine = (Guchar *)gmalloc(rowBytes);
481 
482   reset();
483 
484   ok = gTrue;
485 }
486 
~StreamPredictor()487 StreamPredictor::~StreamPredictor() {
488   gfree(predLine);
489 }
490 
reset()491 void StreamPredictor::reset() {
492   memset(predLine, 0, rowBytes);
493   predIdx = rowBytes;
494 }
495 
lookChar()496 int StreamPredictor::lookChar() {
497   if (predIdx >= rowBytes) {
498     if (!getNextLine()) {
499       return EOF;
500     }
501   }
502   return predLine[predIdx];
503 }
504 
getChar()505 int StreamPredictor::getChar() {
506   if (predIdx >= rowBytes) {
507     if (!getNextLine()) {
508       return EOF;
509     }
510   }
511   return predLine[predIdx++];
512 }
513 
getBlock(char * blk,int size)514 int StreamPredictor::getBlock(char *blk, int size) {
515   int n, m;
516 
517   n = 0;
518   while (n < size) {
519     if (predIdx >= rowBytes) {
520       if (!getNextLine()) {
521 	break;
522       }
523     }
524     m = rowBytes - predIdx;
525     if (m > size - n) {
526       m = size - n;
527     }
528     memcpy(blk + n, predLine + predIdx, m);
529     predIdx += m;
530     n += m;
531   }
532   return n;
533 }
534 
getNextLine()535 GBool StreamPredictor::getNextLine() {
536   int curPred;
537   Guchar upLeftBuf[gfxColorMaxComps * 2 + 1];
538   int left, up, upLeft, p, pa, pb, pc;
539   int c;
540   Gulong inBuf, outBuf, bitMask;
541   int inBits, outBits;
542   int i, j, k, kk;
543 
544   // get PNG optimum predictor number
545   if (predictor >= 10) {
546     if ((curPred = str->getRawChar()) == EOF) {
547       return gFalse;
548     }
549     curPred += 10;
550   } else {
551     curPred = predictor;
552   }
553 
554   // read the raw line, apply PNG (byte) predictor
555   memset(upLeftBuf, 0, pixBytes + 1);
556   for (i = pixBytes; i < rowBytes; ++i) {
557     for (j = pixBytes; j > 0; --j) {
558       upLeftBuf[j] = upLeftBuf[j-1];
559     }
560     upLeftBuf[0] = predLine[i];
561     if ((c = str->getRawChar()) == EOF) {
562       if (i > pixBytes) {
563 	// this ought to return false, but some (broken) PDF files
564 	// contain truncated image data, and Adobe apparently reads the
565 	// last partial line
566 	break;
567       }
568       return gFalse;
569     }
570     switch (curPred) {
571     case 11:			// PNG sub
572       predLine[i] = predLine[i - pixBytes] + (Guchar)c;
573       break;
574     case 12:			// PNG up
575       predLine[i] = predLine[i] + (Guchar)c;
576       break;
577     case 13:			// PNG average
578       predLine[i] = ((predLine[i - pixBytes] + predLine[i]) >> 1) +
579 	            (Guchar)c;
580       break;
581     case 14:			// PNG Paeth
582       left = predLine[i - pixBytes];
583       up = predLine[i];
584       upLeft = upLeftBuf[pixBytes];
585       p = left + up - upLeft;
586       if ((pa = p - left) < 0)
587 	pa = -pa;
588       if ((pb = p - up) < 0)
589 	pb = -pb;
590       if ((pc = p - upLeft) < 0)
591 	pc = -pc;
592       if (pa <= pb && pa <= pc)
593 	predLine[i] = left + (Guchar)c;
594       else if (pb <= pc)
595 	predLine[i] = up + (Guchar)c;
596       else
597 	predLine[i] = upLeft + (Guchar)c;
598       break;
599     case 10:			// PNG none
600     default:			// no predictor or TIFF predictor
601       predLine[i] = (Guchar)c;
602       break;
603     }
604   }
605 
606   // apply TIFF (component) predictor
607   if (predictor == 2) {
608     if (nBits == 8) {
609       for (i = pixBytes; i < rowBytes; ++i) {
610 	predLine[i] += predLine[i - nComps];
611       }
612     } else if (nBits == 16) {
613       for (i = pixBytes; i < rowBytes; i += 2) {
614 	c = ((predLine[i] + predLine[i - 2*nComps]) << 8) +
615 	    predLine[i + 1] + predLine[i + 1 - 2*nComps];
616 	predLine[i] = (Guchar)(c >> 8);
617 	predLine[i+1] = (Guchar)(c & 0xff);
618       }
619     } else {
620       memset(upLeftBuf, 0, nComps);
621       bitMask = (1 << nBits) - 1;
622       inBuf = outBuf = 0;
623       inBits = outBits = 0;
624       j = k = pixBytes;
625       for (i = 0; i < width; ++i) {
626 	for (kk = 0; kk < nComps; ++kk) {
627 	  if (inBits < nBits) {
628 	    inBuf = (inBuf << 8) | (predLine[j++] & 0xff);
629 	    inBits += 8;
630 	  }
631 	  upLeftBuf[kk] = (Guchar)((upLeftBuf[kk] +
632 				    (inBuf >> (inBits - nBits))) & bitMask);
633 	  inBits -= nBits;
634 	  outBuf = (outBuf << nBits) | upLeftBuf[kk];
635 	  outBits += nBits;
636 	  if (outBits >= 8) {
637 	    predLine[k++] = (Guchar)(outBuf >> (outBits - 8));
638 	    outBits -= 8;
639 	  }
640 	}
641       }
642       if (outBits > 0) {
643 	predLine[k++] = (Guchar)((outBuf << (8 - outBits)) +
644 				 (inBuf & ((1 << (8 - outBits)) - 1)));
645       }
646     }
647   }
648 
649   // reset to start of line
650   predIdx = pixBytes;
651 
652   return gTrue;
653 }
654 
655 //------------------------------------------------------------------------
656 // FileStream
657 //------------------------------------------------------------------------
658 
FileStream(FILE * fA,GFileOffset startA,GBool limitedA,GFileOffset lengthA,Object * dictA)659 FileStream::FileStream(FILE *fA, GFileOffset startA, GBool limitedA,
660 		       GFileOffset lengthA, Object *dictA):
661     BaseStream(dictA) {
662   f = fA;
663   start = startA;
664   limited = limitedA;
665   length = lengthA;
666   bufPtr = bufEnd = buf;
667   bufPos = start;
668   savePos = 0;
669   saved = gFalse;
670 }
671 
~FileStream()672 FileStream::~FileStream() {
673   close();
674 }
675 
makeSubStream(GFileOffset startA,GBool limitedA,GFileOffset lengthA,Object * dictA)676 Stream *FileStream::makeSubStream(GFileOffset startA, GBool limitedA,
677 				  GFileOffset lengthA, Object *dictA) {
678   return new FileStream(f, startA, limitedA, lengthA, dictA);
679 }
680 
reset()681 void FileStream::reset() {
682   savePos = gftell(f);
683   gfseek(f, start, SEEK_SET);
684   saved = gTrue;
685   bufPtr = bufEnd = buf;
686   bufPos = start;
687 }
688 
close()689 void FileStream::close() {
690   if (saved) {
691     gfseek(f, savePos, SEEK_SET);
692     saved = gFalse;
693   }
694 }
695 
getBlock(char * blk,int size)696 int FileStream::getBlock(char *blk, int size) {
697   int n, m;
698 
699   n = 0;
700   while (n < size) {
701     if (bufPtr >= bufEnd) {
702       if (!fillBuf()) {
703 	break;
704       }
705     }
706     m = (int)(bufEnd - bufPtr);
707     if (m > size - n) {
708       m = size - n;
709     }
710     memcpy(blk + n, bufPtr, m);
711     bufPtr += m;
712     n += m;
713   }
714   return n;
715 }
716 
fillBuf()717 GBool FileStream::fillBuf() {
718   int n;
719 
720   bufPos += (int)(bufEnd - buf);
721   bufPtr = bufEnd = buf;
722   if (limited && bufPos >= start + length) {
723     return gFalse;
724   }
725   if (limited && bufPos + fileStreamBufSize > start + length) {
726     n = (int)(start + length - bufPos);
727   } else {
728     n = fileStreamBufSize;
729   }
730   n = (int)fread(buf, 1, n, f);
731   bufEnd = buf + n;
732   if (bufPtr >= bufEnd) {
733     return gFalse;
734   }
735   return gTrue;
736 }
737 
setPos(GFileOffset pos,int dir)738 void FileStream::setPos(GFileOffset pos, int dir) {
739   GFileOffset size;
740 
741   if (dir >= 0) {
742     gfseek(f, pos, SEEK_SET);
743     bufPos = pos;
744   } else {
745     gfseek(f, 0, SEEK_END);
746     size = gftell(f);
747     if (pos > size) {
748       pos = size;
749     }
750     gfseek(f, -pos, SEEK_END);
751     bufPos = gftell(f);
752   }
753   bufPtr = bufEnd = buf;
754 }
755 
moveStart(int delta)756 void FileStream::moveStart(int delta) {
757   start += delta;
758   bufPtr = bufEnd = buf;
759   bufPos = start;
760 }
761 
762 //------------------------------------------------------------------------
763 // MemStream
764 //------------------------------------------------------------------------
765 
MemStream(char * bufA,Guint startA,Guint lengthA,Object * dictA)766 MemStream::MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA):
767     BaseStream(dictA) {
768   buf = bufA;
769   start = startA;
770   length = lengthA;
771   bufEnd = buf + start + length;
772   bufPtr = buf + start;
773   needFree = gFalse;
774 }
775 
~MemStream()776 MemStream::~MemStream() {
777   if (needFree) {
778     gfree(buf);
779   }
780 }
781 
makeSubStream(GFileOffset startA,GBool limited,GFileOffset lengthA,Object * dictA)782 Stream *MemStream::makeSubStream(GFileOffset startA, GBool limited,
783 				 GFileOffset lengthA, Object *dictA) {
784   MemStream *subStr;
785   Guint newStart, newLength;
786 
787   if (startA < start) {
788     newStart = start;
789   } else if (startA > start + length) {
790     newStart = start + (int)length;
791   } else {
792     newStart = (int)startA;
793   }
794   if (!limited || newStart + lengthA > start + length) {
795     newLength = start + length - newStart;
796   } else {
797     newLength = (Guint)lengthA;
798   }
799   subStr = new MemStream(buf, newStart, newLength, dictA);
800   return subStr;
801 }
802 
reset()803 void MemStream::reset() {
804   bufPtr = buf + start;
805 }
806 
close()807 void MemStream::close() {
808 }
809 
getBlock(char * blk,int size)810 int MemStream::getBlock(char *blk, int size) {
811   int n;
812 
813   if (size <= 0) {
814     return 0;
815   }
816   if (bufEnd - bufPtr < size) {
817     n = (int)(bufEnd - bufPtr);
818   } else {
819     n = size;
820   }
821   memcpy(blk, bufPtr, n);
822   bufPtr += n;
823   return n;
824 }
825 
setPos(GFileOffset pos,int dir)826 void MemStream::setPos(GFileOffset pos, int dir) {
827   Guint i;
828 
829   if (dir >= 0) {
830     i = (Guint)pos;
831   } else {
832     i = (Guint)(start + length - pos);
833   }
834   if (i < start) {
835     i = start;
836   } else if (i > start + length) {
837     i = start + length;
838   }
839   bufPtr = buf + i;
840 }
841 
moveStart(int delta)842 void MemStream::moveStart(int delta) {
843   start += delta;
844   length -= delta;
845   bufPtr = buf + start;
846 }
847 
848 //------------------------------------------------------------------------
849 // EmbedStream
850 //------------------------------------------------------------------------
851 
EmbedStream(Stream * strA,Object * dictA,GBool limitedA,GFileOffset lengthA)852 EmbedStream::EmbedStream(Stream *strA, Object *dictA,
853 			 GBool limitedA, GFileOffset lengthA):
854     BaseStream(dictA) {
855   str = strA;
856   limited = limitedA;
857   length = lengthA;
858 }
859 
~EmbedStream()860 EmbedStream::~EmbedStream() {
861 }
862 
makeSubStream(GFileOffset start,GBool limitedA,GFileOffset lengthA,Object * dictA)863 Stream *EmbedStream::makeSubStream(GFileOffset start, GBool limitedA,
864 				   GFileOffset lengthA, Object *dictA) {
865   error(errInternal, -1, "Called makeSubStream() on EmbedStream");
866   return NULL;
867 }
868 
getChar()869 int EmbedStream::getChar() {
870   if (limited && !length) {
871     return EOF;
872   }
873   --length;
874   return str->getChar();
875 }
876 
lookChar()877 int EmbedStream::lookChar() {
878   if (limited && !length) {
879     return EOF;
880   }
881   return str->lookChar();
882 }
883 
getBlock(char * blk,int size)884 int EmbedStream::getBlock(char *blk, int size) {
885   if (size <= 0) {
886     return 0;
887   }
888   if (limited && length < (Guint)size) {
889     size = (int)length;
890   }
891   return str->getBlock(blk, size);
892 }
893 
setPos(GFileOffset pos,int dir)894 void EmbedStream::setPos(GFileOffset pos, int dir) {
895   error(errInternal, -1, "Called setPos() on EmbedStream");
896 }
897 
getStart()898 GFileOffset EmbedStream::getStart() {
899   error(errInternal, -1, "Called getStart() on EmbedStream");
900   return 0;
901 }
902 
moveStart(int delta)903 void EmbedStream::moveStart(int delta) {
904   error(errInternal, -1, "Called moveStart() on EmbedStream");
905 }
906 
907 //------------------------------------------------------------------------
908 // ASCIIHexStream
909 //------------------------------------------------------------------------
910 
ASCIIHexStream(Stream * strA)911 ASCIIHexStream::ASCIIHexStream(Stream *strA):
912     FilterStream(strA) {
913   buf = EOF;
914   eof = gFalse;
915 }
916 
~ASCIIHexStream()917 ASCIIHexStream::~ASCIIHexStream() {
918   delete str;
919 }
920 
reset()921 void ASCIIHexStream::reset() {
922   str->reset();
923   buf = EOF;
924   eof = gFalse;
925 }
926 
lookChar()927 int ASCIIHexStream::lookChar() {
928   int c1, c2, x;
929 
930   if (buf != EOF)
931     return buf;
932   if (eof) {
933     buf = EOF;
934     return EOF;
935   }
936   do {
937     c1 = str->getChar();
938   } while (isspace(c1));
939   if (c1 == '>') {
940     eof = gTrue;
941     buf = EOF;
942     return buf;
943   }
944   do {
945     c2 = str->getChar();
946   } while (isspace(c2));
947   if (c2 == '>') {
948     eof = gTrue;
949     c2 = '0';
950   }
951   if (c1 >= '0' && c1 <= '9') {
952     x = (c1 - '0') << 4;
953   } else if (c1 >= 'A' && c1 <= 'F') {
954     x = (c1 - 'A' + 10) << 4;
955   } else if (c1 >= 'a' && c1 <= 'f') {
956     x = (c1 - 'a' + 10) << 4;
957   } else if (c1 == EOF) {
958     eof = gTrue;
959     x = 0;
960   } else {
961     error(errSyntaxError, getPos(),
962 	  "Illegal character <{0:02x}> in ASCIIHex stream", c1);
963     x = 0;
964   }
965   if (c2 >= '0' && c2 <= '9') {
966     x += c2 - '0';
967   } else if (c2 >= 'A' && c2 <= 'F') {
968     x += c2 - 'A' + 10;
969   } else if (c2 >= 'a' && c2 <= 'f') {
970     x += c2 - 'a' + 10;
971   } else if (c2 == EOF) {
972     eof = gTrue;
973     x = 0;
974   } else {
975     error(errSyntaxError, getPos(),
976 	  "Illegal character <{0:02x}> in ASCIIHex stream", c2);
977   }
978   buf = x & 0xff;
979   return buf;
980 }
981 
getPSFilter(int psLevel,const char * indent)982 GString *ASCIIHexStream::getPSFilter(int psLevel, const char *indent) {
983   GString *s;
984 
985   if (psLevel < 2) {
986     return NULL;
987   }
988   if (!(s = str->getPSFilter(psLevel, indent))) {
989     return NULL;
990   }
991   s->append(indent)->append("/ASCIIHexDecode filter\n");
992   return s;
993 }
994 
isBinary(GBool last)995 GBool ASCIIHexStream::isBinary(GBool last) {
996   return str->isBinary(gFalse);
997 }
998 
999 //------------------------------------------------------------------------
1000 // ASCII85Stream
1001 //------------------------------------------------------------------------
1002 
ASCII85Stream(Stream * strA)1003 ASCII85Stream::ASCII85Stream(Stream *strA):
1004     FilterStream(strA) {
1005   index = n = 0;
1006   eof = gFalse;
1007 }
1008 
~ASCII85Stream()1009 ASCII85Stream::~ASCII85Stream() {
1010   delete str;
1011 }
1012 
reset()1013 void ASCII85Stream::reset() {
1014   str->reset();
1015   index = n = 0;
1016   eof = gFalse;
1017 }
1018 
lookChar()1019 int ASCII85Stream::lookChar() {
1020   int k;
1021   Gulong t;
1022 
1023   if (index >= n) {
1024     if (eof)
1025       return EOF;
1026     index = 0;
1027     do {
1028       c[0] = str->getChar();
1029     } while (Lexer::isSpace(c[0]));
1030     if (c[0] == '~' || c[0] == EOF) {
1031       eof = gTrue;
1032       n = 0;
1033       return EOF;
1034     } else if (c[0] == 'z') {
1035       b[0] = b[1] = b[2] = b[3] = 0;
1036       n = 4;
1037     } else {
1038       for (k = 1; k < 5; ++k) {
1039 	do {
1040 	  c[k] = str->getChar();
1041 	} while (Lexer::isSpace(c[k]));
1042 	if (c[k] == '~' || c[k] == EOF)
1043 	  break;
1044       }
1045       n = k - 1;
1046       if (k < 5 && (c[k] == '~' || c[k] == EOF)) {
1047 	for (++k; k < 5; ++k)
1048 	  c[k] = 0x21 + 84;
1049 	eof = gTrue;
1050       }
1051       t = 0;
1052       for (k = 0; k < 5; ++k)
1053 	t = t * 85 + (c[k] - 0x21);
1054       for (k = 3; k >= 0; --k) {
1055 	b[k] = (int)(t & 0xff);
1056 	t >>= 8;
1057       }
1058     }
1059   }
1060   return b[index];
1061 }
1062 
getPSFilter(int psLevel,const char * indent)1063 GString *ASCII85Stream::getPSFilter(int psLevel, const char *indent) {
1064   GString *s;
1065 
1066   if (psLevel < 2) {
1067     return NULL;
1068   }
1069   if (!(s = str->getPSFilter(psLevel, indent))) {
1070     return NULL;
1071   }
1072   s->append(indent)->append("/ASCII85Decode filter\n");
1073   return s;
1074 }
1075 
isBinary(GBool last)1076 GBool ASCII85Stream::isBinary(GBool last) {
1077   return str->isBinary(gFalse);
1078 }
1079 
1080 //------------------------------------------------------------------------
1081 // LZWStream
1082 //------------------------------------------------------------------------
1083 
LZWStream(Stream * strA,int predictor,int columns,int colors,int bits,int earlyA)1084 LZWStream::LZWStream(Stream *strA, int predictor, int columns, int colors,
1085 		     int bits, int earlyA):
1086     FilterStream(strA) {
1087   if (predictor != 1) {
1088     pred = new StreamPredictor(this, predictor, columns, colors, bits);
1089     if (!pred->isOk()) {
1090       delete pred;
1091       pred = NULL;
1092     }
1093   } else {
1094     pred = NULL;
1095   }
1096   early = earlyA;
1097   eof = gFalse;
1098   inputBits = 0;
1099   clearTable();
1100 }
1101 
~LZWStream()1102 LZWStream::~LZWStream() {
1103   if (pred) {
1104     delete pred;
1105   }
1106   delete str;
1107 }
1108 
getChar()1109 int LZWStream::getChar() {
1110   if (pred) {
1111     return pred->getChar();
1112   }
1113   if (eof) {
1114     return EOF;
1115   }
1116   if (seqIndex >= seqLength) {
1117     if (!processNextCode()) {
1118       return EOF;
1119     }
1120   }
1121   return seqBuf[seqIndex++];
1122 }
1123 
lookChar()1124 int LZWStream::lookChar() {
1125   if (pred) {
1126     return pred->lookChar();
1127   }
1128   if (eof) {
1129     return EOF;
1130   }
1131   if (seqIndex >= seqLength) {
1132     if (!processNextCode()) {
1133       return EOF;
1134     }
1135   }
1136   return seqBuf[seqIndex];
1137 }
1138 
getRawChar()1139 int LZWStream::getRawChar() {
1140   if (eof) {
1141     return EOF;
1142   }
1143   if (seqIndex >= seqLength) {
1144     if (!processNextCode()) {
1145       return EOF;
1146     }
1147   }
1148   return seqBuf[seqIndex++];
1149 }
1150 
getBlock(char * blk,int size)1151 int LZWStream::getBlock(char *blk, int size) {
1152   int n, m;
1153 
1154   if (pred) {
1155     return pred->getBlock(blk, size);
1156   }
1157   if (eof) {
1158     return 0;
1159   }
1160   n = 0;
1161   while (n < size) {
1162     if (seqIndex >= seqLength) {
1163       if (!processNextCode()) {
1164 	break;
1165       }
1166     }
1167     m = seqLength - seqIndex;
1168     if (m > size - n) {
1169       m = size - n;
1170     }
1171     memcpy(blk + n, seqBuf + seqIndex, m);
1172     seqIndex += m;
1173     n += m;
1174   }
1175   return n;
1176 }
1177 
reset()1178 void LZWStream::reset() {
1179   str->reset();
1180   if (pred) {
1181     pred->reset();
1182   }
1183   eof = gFalse;
1184   inputBits = 0;
1185   clearTable();
1186 }
1187 
processNextCode()1188 GBool LZWStream::processNextCode() {
1189   int code;
1190   int nextLength;
1191   int i, j;
1192 
1193   // check for EOF
1194   if (eof) {
1195     return gFalse;
1196   }
1197 
1198   // check for eod and clear-table codes
1199  start:
1200   code = getCode();
1201   if (code == EOF || code == 257) {
1202     eof = gTrue;
1203     return gFalse;
1204   }
1205   if (code == 256) {
1206     clearTable();
1207     goto start;
1208   }
1209   if (nextCode >= 4097) {
1210     error(errSyntaxError, getPos(),
1211 	  "Bad LZW stream - expected clear-table code");
1212     clearTable();
1213   }
1214 
1215   // process the next code
1216   nextLength = seqLength + 1;
1217   if (code < 256) {
1218     seqBuf[0] = code;
1219     seqLength = 1;
1220   } else if (code < nextCode) {
1221     seqLength = table[code].length;
1222     for (i = seqLength - 1, j = code; i > 0; --i) {
1223       seqBuf[i] = table[j].tail;
1224       j = table[j].head;
1225     }
1226     seqBuf[0] = j;
1227   } else if (code == nextCode) {
1228     seqBuf[seqLength] = newChar;
1229     ++seqLength;
1230   } else {
1231     error(errSyntaxError, getPos(), "Bad LZW stream - unexpected code");
1232     eof = gTrue;
1233     return gFalse;
1234   }
1235   newChar = seqBuf[0];
1236   if (first) {
1237     first = gFalse;
1238   } else {
1239     table[nextCode].length = nextLength;
1240     table[nextCode].head = prevCode;
1241     table[nextCode].tail = newChar;
1242     ++nextCode;
1243     if (nextCode + early == 512)
1244       nextBits = 10;
1245     else if (nextCode + early == 1024)
1246       nextBits = 11;
1247     else if (nextCode + early == 2048)
1248       nextBits = 12;
1249   }
1250   prevCode = code;
1251 
1252   // reset buffer
1253   seqIndex = 0;
1254 
1255   return gTrue;
1256 }
1257 
clearTable()1258 void LZWStream::clearTable() {
1259   nextCode = 258;
1260   nextBits = 9;
1261   seqIndex = seqLength = 0;
1262   first = gTrue;
1263 }
1264 
getCode()1265 int LZWStream::getCode() {
1266   int c;
1267   int code;
1268 
1269   while (inputBits < nextBits) {
1270     if ((c = str->getChar()) == EOF)
1271       return EOF;
1272     inputBuf = (inputBuf << 8) | (c & 0xff);
1273     inputBits += 8;
1274   }
1275   code = (inputBuf >> (inputBits - nextBits)) & ((1 << nextBits) - 1);
1276   inputBits -= nextBits;
1277   return code;
1278 }
1279 
getPSFilter(int psLevel,const char * indent)1280 GString *LZWStream::getPSFilter(int psLevel, const char *indent) {
1281   GString *s;
1282 
1283   if (psLevel < 2 || pred) {
1284     return NULL;
1285   }
1286   if (!(s = str->getPSFilter(psLevel, indent))) {
1287     return NULL;
1288   }
1289   s->append(indent)->append("<< ");
1290   if (!early) {
1291     s->append("/EarlyChange 0 ");
1292   }
1293   s->append(">> /LZWDecode filter\n");
1294   return s;
1295 }
1296 
isBinary(GBool last)1297 GBool LZWStream::isBinary(GBool last) {
1298   return str->isBinary(gTrue);
1299 }
1300 
1301 //------------------------------------------------------------------------
1302 // RunLengthStream
1303 //------------------------------------------------------------------------
1304 
RunLengthStream(Stream * strA)1305 RunLengthStream::RunLengthStream(Stream *strA):
1306     FilterStream(strA) {
1307   bufPtr = bufEnd = buf;
1308   eof = gFalse;
1309 }
1310 
~RunLengthStream()1311 RunLengthStream::~RunLengthStream() {
1312   delete str;
1313 }
1314 
reset()1315 void RunLengthStream::reset() {
1316   str->reset();
1317   bufPtr = bufEnd = buf;
1318   eof = gFalse;
1319 }
1320 
getBlock(char * blk,int size)1321 int RunLengthStream::getBlock(char *blk, int size) {
1322   int n, m;
1323 
1324   n = 0;
1325   while (n < size) {
1326     if (bufPtr >= bufEnd) {
1327       if (!fillBuf()) {
1328 	break;
1329       }
1330     }
1331     m = (int)(bufEnd - bufPtr);
1332     if (m > size - n) {
1333       m = size - n;
1334     }
1335     memcpy(blk + n, bufPtr, m);
1336     bufPtr += m;
1337     n += m;
1338   }
1339   return n;
1340 }
1341 
getPSFilter(int psLevel,const char * indent)1342 GString *RunLengthStream::getPSFilter(int psLevel, const char *indent) {
1343   GString *s;
1344 
1345   if (psLevel < 2) {
1346     return NULL;
1347   }
1348   if (!(s = str->getPSFilter(psLevel, indent))) {
1349     return NULL;
1350   }
1351   s->append(indent)->append("/RunLengthDecode filter\n");
1352   return s;
1353 }
1354 
isBinary(GBool last)1355 GBool RunLengthStream::isBinary(GBool last) {
1356   return str->isBinary(gTrue);
1357 }
1358 
fillBuf()1359 GBool RunLengthStream::fillBuf() {
1360   int c;
1361   int n, i;
1362 
1363   if (eof)
1364     return gFalse;
1365   c = str->getChar();
1366   if (c == 0x80 || c == EOF) {
1367     eof = gTrue;
1368     return gFalse;
1369   }
1370   if (c < 0x80) {
1371     n = c + 1;
1372     for (i = 0; i < n; ++i)
1373       buf[i] = (char)str->getChar();
1374   } else {
1375     n = 0x101 - c;
1376     c = str->getChar();
1377     for (i = 0; i < n; ++i)
1378       buf[i] = (char)c;
1379   }
1380   bufPtr = buf;
1381   bufEnd = buf + n;
1382   return gTrue;
1383 }
1384 
1385 //------------------------------------------------------------------------
1386 // CCITTFaxStream
1387 //------------------------------------------------------------------------
1388 
CCITTFaxStream(Stream * strA,int encodingA,GBool endOfLineA,GBool byteAlignA,int columnsA,int rowsA,GBool endOfBlockA,GBool blackA)1389 CCITTFaxStream::CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA,
1390 			       GBool byteAlignA, int columnsA, int rowsA,
1391 			       GBool endOfBlockA, GBool blackA):
1392     FilterStream(strA) {
1393   encoding = encodingA;
1394   endOfLine = endOfLineA;
1395   byteAlign = byteAlignA;
1396   columns = columnsA;
1397   if (columns < 1) {
1398     columns = 1;
1399   } else if (columns > INT_MAX - 2) {
1400     columns = INT_MAX - 2;
1401   }
1402   rows = rowsA;
1403   endOfBlock = endOfBlockA;
1404   black = blackA;
1405   // 0 <= codingLine[0] < codingLine[1] < ... < codingLine[n] = columns
1406   // ---> max codingLine size = columns + 1
1407   // refLine has one extra guard entry at the end
1408   // ---> max refLine size = columns + 2
1409   codingLine = (int *)gmallocn(columns + 1, sizeof(int));
1410   refLine = (int *)gmallocn(columns + 2, sizeof(int));
1411 
1412   eof = gFalse;
1413   row = 0;
1414   nextLine2D = encoding < 0;
1415   inputBits = 0;
1416   codingLine[0] = columns;
1417   a0i = 0;
1418   outputBits = 0;
1419 
1420   buf = EOF;
1421 }
1422 
~CCITTFaxStream()1423 CCITTFaxStream::~CCITTFaxStream() {
1424   delete str;
1425   gfree(refLine);
1426   gfree(codingLine);
1427 }
1428 
reset()1429 void CCITTFaxStream::reset() {
1430   int code1;
1431 
1432   str->reset();
1433   eof = gFalse;
1434   row = 0;
1435   nextLine2D = encoding < 0;
1436   inputBits = 0;
1437   codingLine[0] = columns;
1438   a0i = 0;
1439   outputBits = 0;
1440   buf = EOF;
1441 
1442   // skip any initial zero bits and end-of-line marker, and get the 2D
1443   // encoding tag
1444   while ((code1 = lookBits(12)) == 0) {
1445     eatBits(1);
1446   }
1447   if (code1 == 0x001) {
1448     eatBits(12);
1449     endOfLine = gTrue;
1450   }
1451   if (encoding > 0) {
1452     nextLine2D = !lookBits(1);
1453     eatBits(1);
1454   }
1455 }
1456 
addPixels(int a1,int blackPixels)1457 inline void CCITTFaxStream::addPixels(int a1, int blackPixels) {
1458   if (a1 > codingLine[a0i]) {
1459     if (a1 > columns) {
1460       error(errSyntaxError, getPos(),
1461 	    "CCITTFax row is wrong length ({0:d})", a1);
1462       err = gTrue;
1463       a1 = columns;
1464     }
1465     if ((a0i & 1) ^ blackPixels) {
1466       ++a0i;
1467     }
1468     codingLine[a0i] = a1;
1469   }
1470 }
1471 
addPixelsNeg(int a1,int blackPixels)1472 inline void CCITTFaxStream::addPixelsNeg(int a1, int blackPixels) {
1473   if (a1 > codingLine[a0i]) {
1474     if (a1 > columns) {
1475       error(errSyntaxError, getPos(),
1476 	    "CCITTFax row is wrong length ({0:d})", a1);
1477       err = gTrue;
1478       a1 = columns;
1479     }
1480     if ((a0i & 1) ^ blackPixels) {
1481       ++a0i;
1482     }
1483     codingLine[a0i] = a1;
1484   } else if (a1 < codingLine[a0i]) {
1485     if (a1 < 0) {
1486       error(errSyntaxError, getPos(), "Invalid CCITTFax code");
1487       err = gTrue;
1488       a1 = 0;
1489     }
1490     while (a0i > 0 && a1 <= codingLine[a0i - 1]) {
1491       --a0i;
1492     }
1493     codingLine[a0i] = a1;
1494   }
1495 }
1496 
lookChar()1497 int CCITTFaxStream::lookChar() {
1498   int code1, code2, code3;
1499   int b1i, blackPixels, i, bits;
1500   GBool gotEOL;
1501 
1502   if (buf != EOF) {
1503     return buf;
1504   }
1505 
1506   // read the next row
1507   if (outputBits == 0) {
1508 
1509     // if at eof just return EOF
1510     if (eof) {
1511       return EOF;
1512     }
1513 
1514     err = gFalse;
1515 
1516     // 2-D encoding
1517     if (nextLine2D) {
1518       for (i = 0; codingLine[i] < columns; ++i) {
1519 	refLine[i] = codingLine[i];
1520       }
1521       refLine[i++] = columns;
1522       refLine[i] = columns;
1523       codingLine[0] = 0;
1524       a0i = 0;
1525       b1i = 0;
1526       blackPixels = 0;
1527       // invariant:
1528       // refLine[b1i-1] <= codingLine[a0i] < refLine[b1i] < refLine[b1i+1]
1529       //                                                             <= columns
1530       // exception at left edge:
1531       //   codingLine[a0i = 0] = refLine[b1i = 0] = 0 is possible
1532       // exception at right edge:
1533       //   refLine[b1i] = refLine[b1i+1] = columns is possible
1534       while (codingLine[a0i] < columns) {
1535 	code1 = getTwoDimCode();
1536 	switch (code1) {
1537 	case twoDimPass:
1538 	  addPixels(refLine[b1i + 1], blackPixels);
1539 	  if (refLine[b1i + 1] < columns) {
1540 	    b1i += 2;
1541 	  }
1542 	  break;
1543 	case twoDimHoriz:
1544 	  code1 = code2 = 0;
1545 	  if (blackPixels) {
1546 	    do {
1547 	      code1 += code3 = getBlackCode();
1548 	    } while (code3 >= 64);
1549 	    do {
1550 	      code2 += code3 = getWhiteCode();
1551 	    } while (code3 >= 64);
1552 	  } else {
1553 	    do {
1554 	      code1 += code3 = getWhiteCode();
1555 	    } while (code3 >= 64);
1556 	    do {
1557 	      code2 += code3 = getBlackCode();
1558 	    } while (code3 >= 64);
1559 	  }
1560 	  addPixels(codingLine[a0i] + code1, blackPixels);
1561 	  if (codingLine[a0i] < columns) {
1562 	    addPixels(codingLine[a0i] + code2, blackPixels ^ 1);
1563 	  }
1564 	  while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1565 	    b1i += 2;
1566 	  }
1567 	  break;
1568 	case twoDimVertR3:
1569 	  addPixels(refLine[b1i] + 3, blackPixels);
1570 	  blackPixels ^= 1;
1571 	  if (codingLine[a0i] < columns) {
1572 	    ++b1i;
1573 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1574 	      b1i += 2;
1575 	    }
1576 	  }
1577 	  break;
1578 	case twoDimVertR2:
1579 	  addPixels(refLine[b1i] + 2, blackPixels);
1580 	  blackPixels ^= 1;
1581 	  if (codingLine[a0i] < columns) {
1582 	    ++b1i;
1583 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1584 	      b1i += 2;
1585 	    }
1586 	  }
1587 	  break;
1588 	case twoDimVertR1:
1589 	  addPixels(refLine[b1i] + 1, blackPixels);
1590 	  blackPixels ^= 1;
1591 	  if (codingLine[a0i] < columns) {
1592 	    ++b1i;
1593 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1594 	      b1i += 2;
1595 	    }
1596 	  }
1597 	  break;
1598 	case twoDimVert0:
1599 	  addPixels(refLine[b1i], blackPixels);
1600 	  blackPixels ^= 1;
1601 	  if (codingLine[a0i] < columns) {
1602 	    ++b1i;
1603 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1604 	      b1i += 2;
1605 	    }
1606 	  }
1607 	  break;
1608 	case twoDimVertL3:
1609 	  addPixelsNeg(refLine[b1i] - 3, blackPixels);
1610 	  blackPixels ^= 1;
1611 	  if (codingLine[a0i] < columns) {
1612 	    if (b1i > 0) {
1613 	      --b1i;
1614 	    } else {
1615 	      ++b1i;
1616 	    }
1617 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1618 	      b1i += 2;
1619 	    }
1620 	  }
1621 	  break;
1622 	case twoDimVertL2:
1623 	  addPixelsNeg(refLine[b1i] - 2, blackPixels);
1624 	  blackPixels ^= 1;
1625 	  if (codingLine[a0i] < columns) {
1626 	    if (b1i > 0) {
1627 	      --b1i;
1628 	    } else {
1629 	      ++b1i;
1630 	    }
1631 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1632 	      b1i += 2;
1633 	    }
1634 	  }
1635 	  break;
1636 	case twoDimVertL1:
1637 	  addPixelsNeg(refLine[b1i] - 1, blackPixels);
1638 	  blackPixels ^= 1;
1639 	  if (codingLine[a0i] < columns) {
1640 	    if (b1i > 0) {
1641 	      --b1i;
1642 	    } else {
1643 	      ++b1i;
1644 	    }
1645 	    while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
1646 	      b1i += 2;
1647 	    }
1648 	  }
1649 	  break;
1650 	case EOF:
1651 	  addPixels(columns, 0);
1652 	  eof = gTrue;
1653 	  break;
1654 	default:
1655 	  error(errSyntaxError, getPos(),
1656 		"Bad 2D code {0:04x} in CCITTFax stream", code1);
1657 	  addPixels(columns, 0);
1658 	  err = gTrue;
1659 	  break;
1660 	}
1661       }
1662 
1663     // 1-D encoding
1664     } else {
1665       codingLine[0] = 0;
1666       a0i = 0;
1667       blackPixels = 0;
1668       while (codingLine[a0i] < columns) {
1669 	code1 = 0;
1670 	if (blackPixels) {
1671 	  do {
1672 	    code1 += code3 = getBlackCode();
1673 	  } while (code3 >= 64);
1674 	} else {
1675 	  do {
1676 	    code1 += code3 = getWhiteCode();
1677 	  } while (code3 >= 64);
1678 	}
1679 	addPixels(codingLine[a0i] + code1, blackPixels);
1680 	blackPixels ^= 1;
1681       }
1682     }
1683 
1684     // check for end-of-line marker, skipping over any extra zero bits
1685     // (if EncodedByteAlign is true and EndOfLine is false, there can
1686     // be "false" EOL markers -- i.e., if the last n unused bits in
1687     // row i are set to zero, and the first 11-n bits in row i+1
1688     // happen to be zero -- so we don't look for EOL markers in this
1689     // case)
1690     gotEOL = gFalse;
1691     if (!endOfBlock && row == rows - 1) {
1692       eof = gTrue;
1693     } else if (endOfLine || !byteAlign) {
1694       code1 = lookBits(12);
1695       if (endOfLine) {
1696 	while (code1 != EOF && code1 != 0x001) {
1697 	  eatBits(1);
1698 	  code1 = lookBits(12);
1699 	}
1700       } else {
1701 	while (code1 == 0) {
1702 	  eatBits(1);
1703 	  code1 = lookBits(12);
1704 	}
1705       }
1706       if (code1 == 0x001) {
1707 	eatBits(12);
1708 	gotEOL = gTrue;
1709       }
1710     }
1711 
1712     // byte-align the row
1713     // (Adobe apparently doesn't do byte alignment after EOL markers
1714     // -- I've seen CCITT image data streams in two different formats,
1715     // both with the byteAlign flag set:
1716     //   1. xx:x0:01:yy:yy
1717     //   2. xx:00:1y:yy:yy
1718     // where xx is the previous line, yy is the next line, and colons
1719     // separate bytes.)
1720     if (byteAlign && !gotEOL) {
1721       inputBits &= ~7;
1722     }
1723 
1724     // check for end of stream
1725     if (lookBits(1) == EOF) {
1726       eof = gTrue;
1727     }
1728 
1729     // get 2D encoding tag
1730     if (!eof && encoding > 0) {
1731       nextLine2D = !lookBits(1);
1732       eatBits(1);
1733     }
1734 
1735     // check for end-of-block marker
1736     if (endOfBlock && !endOfLine && byteAlign) {
1737       // in this case, we didn't check for an EOL code above, so we
1738       // need to check here
1739       code1 = lookBits(24);
1740       if (code1 == 0x001001) {
1741 	eatBits(12);
1742 	gotEOL = gTrue;
1743       }
1744     }
1745     if (endOfBlock && gotEOL) {
1746       code1 = lookBits(12);
1747       if (code1 == 0x001) {
1748 	eatBits(12);
1749 	if (encoding > 0) {
1750 	  lookBits(1);
1751 	  eatBits(1);
1752 	}
1753 	if (encoding >= 0) {
1754 	  for (i = 0; i < 4; ++i) {
1755 	    code1 = lookBits(12);
1756 	    if (code1 != 0x001) {
1757 	      error(errSyntaxError, getPos(),
1758 		    "Bad RTC code in CCITTFax stream");
1759 	    }
1760 	    eatBits(12);
1761 	    if (encoding > 0) {
1762 	      lookBits(1);
1763 	      eatBits(1);
1764 	    }
1765 	  }
1766 	}
1767 	eof = gTrue;
1768       }
1769 
1770     // look for an end-of-line marker after an error -- we only do
1771     // this if we know the stream contains end-of-line markers because
1772     // the "just plow on" technique tends to work better otherwise
1773     } else if (err && endOfLine) {
1774       while (1) {
1775 	code1 = lookBits(13);
1776 	if (code1 == EOF) {
1777 	  eof = gTrue;
1778 	  return EOF;
1779 	}
1780 	if ((code1 >> 1) == 0x001) {
1781 	  break;
1782 	}
1783 	eatBits(1);
1784       }
1785       eatBits(12);
1786       if (encoding > 0) {
1787 	eatBits(1);
1788 	nextLine2D = !(code1 & 1);
1789       }
1790     }
1791 
1792     // set up for output
1793     if (codingLine[0] > 0) {
1794       outputBits = codingLine[a0i = 0];
1795     } else {
1796       outputBits = codingLine[a0i = 1];
1797     }
1798 
1799     ++row;
1800   }
1801 
1802   // get a byte
1803   if (outputBits >= 8) {
1804     buf = (a0i & 1) ? 0x00 : 0xff;
1805     outputBits -= 8;
1806     if (outputBits == 0 && codingLine[a0i] < columns) {
1807       ++a0i;
1808       outputBits = codingLine[a0i] - codingLine[a0i - 1];
1809     }
1810   } else {
1811     bits = 8;
1812     buf = 0;
1813     do {
1814       if (outputBits > bits) {
1815 	buf <<= bits;
1816 	if (!(a0i & 1)) {
1817 	  buf |= 0xff >> (8 - bits);
1818 	}
1819 	outputBits -= bits;
1820 	bits = 0;
1821       } else {
1822 	buf <<= outputBits;
1823 	if (!(a0i & 1)) {
1824 	  buf |= 0xff >> (8 - outputBits);
1825 	}
1826 	bits -= outputBits;
1827 	outputBits = 0;
1828 	if (codingLine[a0i] < columns) {
1829 	  ++a0i;
1830 	  outputBits = codingLine[a0i] - codingLine[a0i - 1];
1831 	} else if (bits > 0) {
1832 	  buf <<= bits;
1833 	  bits = 0;
1834 	}
1835       }
1836     } while (bits);
1837   }
1838   if (black) {
1839     buf ^= 0xff;
1840   }
1841   return buf;
1842 }
1843 
getTwoDimCode()1844 short CCITTFaxStream::getTwoDimCode() {
1845   int code;
1846   CCITTCode *p;
1847   int n;
1848 
1849   code = 0; // make gcc happy
1850   if (endOfBlock) {
1851     if ((code = lookBits(7)) != EOF) {
1852       p = &twoDimTab1[code];
1853       if (p->bits > 0) {
1854 	eatBits(p->bits);
1855 	return p->n;
1856       }
1857     }
1858   } else {
1859     for (n = 1; n <= 7; ++n) {
1860       if ((code = lookBits(n)) == EOF) {
1861 	break;
1862       }
1863       if (n < 7) {
1864 	code <<= 7 - n;
1865       }
1866       p = &twoDimTab1[code];
1867       if (p->bits == n) {
1868 	eatBits(n);
1869 	return p->n;
1870       }
1871     }
1872   }
1873   error(errSyntaxError, getPos(),
1874 	"Bad two dim code ({0:04x}) in CCITTFax stream", code);
1875   return EOF;
1876 }
1877 
getWhiteCode()1878 short CCITTFaxStream::getWhiteCode() {
1879   short code;
1880   CCITTCode *p;
1881   int n;
1882 
1883   code = 0; // make gcc happy
1884   if (endOfBlock) {
1885     code = lookBits(12);
1886     if (code == EOF) {
1887       return 1;
1888     }
1889     if ((code >> 5) == 0) {
1890       p = &whiteTab1[code];
1891     } else {
1892       p = &whiteTab2[code >> 3];
1893     }
1894     if (p->bits > 0) {
1895       eatBits(p->bits);
1896       return p->n;
1897     }
1898   } else {
1899     for (n = 1; n <= 9; ++n) {
1900       code = lookBits(n);
1901       if (code == EOF) {
1902 	return 1;
1903       }
1904       if (n < 9) {
1905 	code <<= 9 - n;
1906       }
1907       p = &whiteTab2[code];
1908       if (p->bits == n) {
1909 	eatBits(n);
1910 	return p->n;
1911       }
1912     }
1913     for (n = 11; n <= 12; ++n) {
1914       code = lookBits(n);
1915       if (code == EOF) {
1916 	return 1;
1917       }
1918       if (n < 12) {
1919 	code <<= 12 - n;
1920       }
1921       p = &whiteTab1[code];
1922       if (p->bits == n) {
1923 	eatBits(n);
1924 	return p->n;
1925       }
1926     }
1927   }
1928   error(errSyntaxError, getPos(),
1929 	"Bad white code ({0:04x}) in CCITTFax stream", code);
1930   // eat a bit and return a positive number so that the caller doesn't
1931   // go into an infinite loop
1932   eatBits(1);
1933   return 1;
1934 }
1935 
getBlackCode()1936 short CCITTFaxStream::getBlackCode() {
1937   short code;
1938   CCITTCode *p;
1939   int n;
1940 
1941   code = 0; // make gcc happy
1942   if (endOfBlock) {
1943     code = lookBits(13);
1944     if (code == EOF) {
1945       return 1;
1946     }
1947     if ((code >> 7) == 0) {
1948       p = &blackTab1[code];
1949     } else if ((code >> 9) == 0 && (code >> 7) != 0) {
1950       p = &blackTab2[(code >> 1) - 64];
1951     } else {
1952       p = &blackTab3[code >> 7];
1953     }
1954     if (p->bits > 0) {
1955       eatBits(p->bits);
1956       return p->n;
1957     }
1958   } else {
1959     for (n = 2; n <= 6; ++n) {
1960       code = lookBits(n);
1961       if (code == EOF) {
1962 	return 1;
1963       }
1964       if (n < 6) {
1965 	code <<= 6 - n;
1966       }
1967       p = &blackTab3[code];
1968       if (p->bits == n) {
1969 	eatBits(n);
1970 	return p->n;
1971       }
1972     }
1973     for (n = 7; n <= 12; ++n) {
1974       code = lookBits(n);
1975       if (code == EOF) {
1976 	return 1;
1977       }
1978       if (n < 12) {
1979 	code <<= 12 - n;
1980       }
1981       if (code >= 64) {
1982 	p = &blackTab2[code - 64];
1983 	if (p->bits == n) {
1984 	  eatBits(n);
1985 	  return p->n;
1986 	}
1987       }
1988     }
1989     for (n = 10; n <= 13; ++n) {
1990       code = lookBits(n);
1991       if (code == EOF) {
1992 	return 1;
1993       }
1994       if (n < 13) {
1995 	code <<= 13 - n;
1996       }
1997       p = &blackTab1[code];
1998       if (p->bits == n) {
1999 	eatBits(n);
2000 	return p->n;
2001       }
2002     }
2003   }
2004   error(errSyntaxError, getPos(),
2005 	"Bad black code ({0:04x}) in CCITTFax stream", code);
2006   // eat a bit and return a positive number so that the caller doesn't
2007   // go into an infinite loop
2008   eatBits(1);
2009   return 1;
2010 }
2011 
lookBits(int n)2012 short CCITTFaxStream::lookBits(int n) {
2013   int c;
2014 
2015   while (inputBits < n) {
2016     if ((c = str->getChar()) == EOF) {
2017       if (inputBits == 0) {
2018 	return EOF;
2019       }
2020       // near the end of the stream, the caller may ask for more bits
2021       // than are available, but there may still be a valid code in
2022       // however many bits are available -- we need to return correct
2023       // data in this case
2024       return (inputBuf << (n - inputBits)) & (0xffffffff >> (32 - n));
2025     }
2026     inputBuf = (inputBuf << 8) + c;
2027     inputBits += 8;
2028   }
2029   return (inputBuf >> (inputBits - n)) & (0xffffffff >> (32 - n));
2030 }
2031 
getPSFilter(int psLevel,const char * indent)2032 GString *CCITTFaxStream::getPSFilter(int psLevel, const char *indent) {
2033   GString *s;
2034   char s1[50];
2035 
2036   if (psLevel < 2) {
2037     return NULL;
2038   }
2039   if (!(s = str->getPSFilter(psLevel, indent))) {
2040     return NULL;
2041   }
2042   s->append(indent)->append("<< ");
2043   if (encoding != 0) {
2044     sprintf(s1, "/K %d ", encoding);
2045     s->append(s1);
2046   }
2047   if (endOfLine) {
2048     s->append("/EndOfLine true ");
2049   }
2050   if (byteAlign) {
2051     s->append("/EncodedByteAlign true ");
2052   }
2053   sprintf(s1, "/Columns %d ", columns);
2054   s->append(s1);
2055   if (rows != 0) {
2056     sprintf(s1, "/Rows %d ", rows);
2057     s->append(s1);
2058   }
2059   if (!endOfBlock) {
2060     s->append("/EndOfBlock false ");
2061   }
2062   if (black) {
2063     s->append("/BlackIs1 true ");
2064   }
2065   s->append(">> /CCITTFaxDecode filter\n");
2066   return s;
2067 }
2068 
isBinary(GBool last)2069 GBool CCITTFaxStream::isBinary(GBool last) {
2070   return str->isBinary(gTrue);
2071 }
2072 
2073 //------------------------------------------------------------------------
2074 // DCTStream
2075 //------------------------------------------------------------------------
2076 
2077 // IDCT constants (20.12 fixed point format)
2078 #define dctSqrt2          5793	// sqrt(2)
2079 #define dctSqrt2Cos6      2217	// sqrt(2) * cos(6*pi/16)
2080 #define dctSqrt2Cos6PSin6 7568	// sqrt(2) * (cos(6*pi/16) + sin(6*pi/16))
2081 #define dctSqrt2Sin6MCos6 3135	// sqrt(2) * (sin(6*pi/16) - cos(6*pi/16))
2082 #define dctCos3           3406	// cos(3*pi/16)
2083 #define dctCos3PSin3      5681	// cos(3*pi/16) + sin(3*pi/16)
2084 #define dctSin3MCos3     -1130	// sin(3*pi/16) - cos(3*pi/16)
2085 #define dctCos1           4017	// cos(pi/16)
2086 #define dctCos1PSin1      4816	// cos(pi/16) + sin(pi/16)
2087 #define dctSin1MCos1     -3218	// sin(pi/16) - cos(pi/16)
2088 
2089 // color conversion parameters (16.16 fixed point format)
2090 #define dctCrToR   91881	//  1.4020
2091 #define dctCbToG  -22553	// -0.3441363
2092 #define dctCrToG  -46802	// -0.71413636
2093 #define dctCbToB  116130	//  1.772
2094 
2095 // The dctClip function clips signed integers to the [0,255] range.
2096 // To handle valid DCT inputs, this must support an input range of at
2097 // least [-256,511].  Invalid DCT inputs (e.g., from damaged PDF
2098 // files) can result in arbitrary values, so we want to mask those
2099 // out.  We round the input range size up to a power of 2 (so we can
2100 // use a bit mask), which gives us an input range of [-384,639].  The
2101 // end result is:
2102 //     input       output
2103 //     ----------  ------
2104 //     <-384       X        invalid inputs -> output is "don't care"
2105 //     -384..-257  0        invalid inputs, clipped
2106 //     -256..-1    0        valid inputs, need to be clipped
2107 //     0..255      0..255
2108 //     256..511    255      valid inputs, need to be clipped
2109 //     512..639    255      invalid inputs, clipped
2110 //     >=512       X        invalid inputs -> output is "don't care"
2111 
2112 #define dctClipOffset  384
2113 #define dctClipMask   1023
2114 static Guchar dctClipData[1024];
2115 
dctClipInit()2116 static inline void dctClipInit() {
2117   static int initDone = 0;
2118   int i;
2119   if (!initDone) {
2120     for (i = -384; i < 0; ++i) {
2121       dctClipData[dctClipOffset + i] = 0;
2122     }
2123     for (i = 0; i < 256; ++i) {
2124       dctClipData[dctClipOffset + i] = i;
2125     }
2126     for (i = 256; i < 639; ++i) {
2127       dctClipData[dctClipOffset + i] = 255;
2128     }
2129     initDone = 1;
2130   }
2131 }
2132 
dctClip(int x)2133 static inline int dctClip(int x) {
2134   return dctClipData[(dctClipOffset + x) & dctClipMask];
2135 }
2136 
2137 // zig zag decode map
2138 static int dctZigZag[64] = {
2139    0,
2140    1,  8,
2141   16,  9,  2,
2142    3, 10, 17, 24,
2143   32, 25, 18, 11, 4,
2144    5, 12, 19, 26, 33, 40,
2145   48, 41, 34, 27, 20, 13,  6,
2146    7, 14, 21, 28, 35, 42, 49, 56,
2147   57, 50, 43, 36, 29, 22, 15,
2148   23, 30, 37, 44, 51, 58,
2149   59, 52, 45, 38, 31,
2150   39, 46, 53, 60,
2151   61, 54, 47,
2152   55, 62,
2153   63
2154 };
2155 
DCTStream(Stream * strA,GBool colorXformA)2156 DCTStream::DCTStream(Stream *strA, GBool colorXformA):
2157     FilterStream(strA) {
2158   int i;
2159 
2160   colorXform = colorXformA;
2161   progressive = interleaved = gFalse;
2162   width = height = 0;
2163   mcuWidth = mcuHeight = 0;
2164   numComps = 0;
2165   comp = 0;
2166   x = y = 0;
2167   for (i = 0; i < 4; ++i) {
2168     frameBuf[i] = NULL;
2169   }
2170   rowBuf = NULL;
2171   memset(dcHuffTables, 0, sizeof(dcHuffTables));
2172   memset(acHuffTables, 0, sizeof(acHuffTables));
2173 
2174   dctClipInit();
2175 }
2176 
~DCTStream()2177 DCTStream::~DCTStream() {
2178   close();
2179   delete str;
2180 }
2181 
reset()2182 void DCTStream::reset() {
2183   int i;
2184 
2185   str->reset();
2186 
2187   progressive = interleaved = gFalse;
2188   width = height = 0;
2189   numComps = 0;
2190   numQuantTables = 0;
2191   numDCHuffTables = 0;
2192   numACHuffTables = 0;
2193   gotJFIFMarker = gFalse;
2194   gotAdobeMarker = gFalse;
2195   restartInterval = 0;
2196 
2197   if (!readHeader()) {
2198     // force an EOF condition
2199     progressive = gTrue;
2200     y = height;
2201     return;
2202   }
2203 
2204   // compute MCU size
2205   if (numComps == 1) {
2206     compInfo[0].hSample = compInfo[0].vSample = 1;
2207   }
2208   mcuWidth = compInfo[0].hSample;
2209   mcuHeight = compInfo[0].vSample;
2210   for (i = 1; i < numComps; ++i) {
2211     if (compInfo[i].hSample > mcuWidth) {
2212       mcuWidth = compInfo[i].hSample;
2213     }
2214     if (compInfo[i].vSample > mcuHeight) {
2215       mcuHeight = compInfo[i].vSample;
2216     }
2217   }
2218   mcuWidth *= 8;
2219   mcuHeight *= 8;
2220 
2221   // figure out color transform
2222   if (colorXform == -1) {
2223     if (numComps == 3) {
2224       if (gotJFIFMarker) {
2225 	colorXform = 1;
2226       } else if (compInfo[0].id == 82 && compInfo[1].id == 71 &&
2227 		 compInfo[2].id == 66) { // ASCII "RGB"
2228 	colorXform = 0;
2229       } else {
2230 	colorXform = 1;
2231       }
2232     } else {
2233       colorXform = 0;
2234     }
2235   }
2236 
2237   if (progressive || !interleaved) {
2238 
2239     // allocate a buffer for the whole image
2240     bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
2241     bufHeight = ((height + mcuHeight - 1) / mcuHeight) * mcuHeight;
2242     if (bufWidth <= 0 || bufHeight <= 0 ||
2243 	bufWidth > INT_MAX / bufWidth / (int)sizeof(int)) {
2244       error(errSyntaxError, getPos(), "Invalid image size in DCT stream");
2245       y = height;
2246       return;
2247     }
2248     for (i = 0; i < numComps; ++i) {
2249       frameBuf[i] = (int *)gmallocn(bufWidth * bufHeight, sizeof(int));
2250       memset(frameBuf[i], 0, bufWidth * bufHeight * sizeof(int));
2251     }
2252 
2253     // read the image data
2254     do {
2255       restartMarker = 0xd0;
2256       restart();
2257       readScan();
2258     } while (readHeader());
2259 
2260     // decode
2261     decodeImage();
2262 
2263     // initialize counters
2264     comp = 0;
2265     x = 0;
2266     y = 0;
2267 
2268   } else {
2269 
2270     // allocate a buffer for one row of MCUs
2271     bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
2272     rowBuf = (Guchar *)gmallocn(numComps * mcuHeight, bufWidth);
2273     rowBufPtr = rowBufEnd = rowBuf;
2274 
2275     // initialize counters
2276     y = -mcuHeight;
2277 
2278     restartMarker = 0xd0;
2279     restart();
2280   }
2281 }
2282 
close()2283 void DCTStream::close() {
2284   int i;
2285 
2286   for (i = 0; i < 4; ++i) {
2287     gfree(frameBuf[i]);
2288     frameBuf[i] = NULL;
2289   }
2290   gfree(rowBuf);
2291   rowBuf = NULL;
2292   FilterStream::close();
2293 }
2294 
getChar()2295 int DCTStream::getChar() {
2296   int c;
2297 
2298   if (progressive || !interleaved) {
2299     if (y >= height) {
2300       return EOF;
2301     }
2302     c = frameBuf[comp][y * bufWidth + x];
2303     if (++comp == numComps) {
2304       comp = 0;
2305       if (++x == width) {
2306 	x = 0;
2307 	++y;
2308       }
2309     }
2310   } else {
2311     if (rowBufPtr == rowBufEnd) {
2312       if (y + mcuHeight >= height) {
2313 	return EOF;
2314       }
2315       y += mcuHeight;
2316       if (!readMCURow()) {
2317 	y = height;
2318 	return EOF;
2319       }
2320     }
2321     c = *rowBufPtr++;
2322   }
2323   return c;
2324 }
2325 
lookChar()2326 int DCTStream::lookChar() {
2327   if (progressive || !interleaved) {
2328     if (y >= height) {
2329       return EOF;
2330     }
2331     return frameBuf[comp][y * bufWidth + x];
2332   } else {
2333     if (rowBufPtr == rowBufEnd) {
2334       if (y + mcuHeight >= height) {
2335 	return EOF;
2336       }
2337       if (!readMCURow()) {
2338 	y = height;
2339 	return EOF;
2340       }
2341     }
2342     return *rowBufPtr;
2343   }
2344 }
2345 
restart()2346 void DCTStream::restart() {
2347   int i;
2348 
2349   inputBits = 0;
2350   restartCtr = restartInterval;
2351   for (i = 0; i < numComps; ++i) {
2352     compInfo[i].prevDC = 0;
2353   }
2354   eobRun = 0;
2355 }
2356 
2357 // Read one row of MCUs from a sequential JPEG stream.
readMCURow()2358 GBool DCTStream::readMCURow() {
2359   int data1[64];
2360   Guchar data2[64];
2361   Guchar *p1, *p2;
2362   int pY, pCb, pCr, pR, pG, pB;
2363   int h, v, horiz, vert, hSub, vSub;
2364   int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
2365   int c;
2366 
2367   for (x1 = 0; x1 < width; x1 += mcuWidth) {
2368 
2369     // deal with restart marker
2370     if (restartInterval > 0 && restartCtr == 0) {
2371       c = readMarker();
2372       if (c != restartMarker) {
2373 	error(errSyntaxError, getPos(),
2374 	      "Bad DCT data: incorrect restart marker");
2375 	return gFalse;
2376       }
2377       if (++restartMarker == 0xd8)
2378 	restartMarker = 0xd0;
2379       restart();
2380     }
2381 
2382     // read one MCU
2383     for (cc = 0; cc < numComps; ++cc) {
2384       h = compInfo[cc].hSample;
2385       v = compInfo[cc].vSample;
2386       horiz = mcuWidth / h;
2387       vert = mcuHeight / v;
2388       hSub = horiz / 8;
2389       vSub = vert / 8;
2390       for (y2 = 0; y2 < mcuHeight; y2 += vert) {
2391 	for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
2392 	  if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]],
2393 			    &acHuffTables[scanInfo.acHuffTable[cc]],
2394 			    &compInfo[cc].prevDC,
2395 			    data1)) {
2396 	    return gFalse;
2397 	  }
2398 	  transformDataUnit(quantTables[compInfo[cc].quantTable],
2399 			    data1, data2);
2400 	  if (hSub == 1 && vSub == 1 && x1+x2+8 <= width) {
2401 	    for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2402 	      p1 = &rowBuf[((y2+y3) * width + (x1+x2)) * numComps + cc];
2403 	      p1[0]          = data2[i];
2404 	      p1[  numComps] = data2[i+1];
2405 	      p1[2*numComps] = data2[i+2];
2406 	      p1[3*numComps] = data2[i+3];
2407 	      p1[4*numComps] = data2[i+4];
2408 	      p1[5*numComps] = data2[i+5];
2409 	      p1[6*numComps] = data2[i+6];
2410 	      p1[7*numComps] = data2[i+7];
2411 	    }
2412 	  } else if (hSub == 2 && vSub == 2 && x1+x2+16 <= width) {
2413 	    for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
2414 	      p1 = &rowBuf[((y2+y3) * width + (x1+x2)) * numComps + cc];
2415 	      p2 = p1 + width * numComps;
2416 	      p1[0] = p1[numComps] =
2417 		p2[0] = p2[numComps] = data2[i];
2418 	      p1[2*numComps] = p1[3*numComps] =
2419 		p2[2*numComps] = p2[3*numComps] = data2[i+1];
2420 	      p1[4*numComps] = p1[5*numComps] =
2421 		p2[4*numComps] = p2[5*numComps] = data2[i+2];
2422 	      p1[6*numComps] = p1[7*numComps] =
2423 		p2[6*numComps] = p2[7*numComps] = data2[i+3];
2424 	      p1[8*numComps] = p1[9*numComps] =
2425 		p2[8*numComps] = p2[9*numComps] = data2[i+4];
2426 	      p1[10*numComps] = p1[11*numComps] =
2427 		p2[10*numComps] = p2[11*numComps] = data2[i+5];
2428 	      p1[12*numComps] = p1[13*numComps] =
2429 		p2[12*numComps] = p2[13*numComps] = data2[i+6];
2430 	      p1[14*numComps] = p1[15*numComps] =
2431 		p2[14*numComps] = p2[15*numComps] = data2[i+7];
2432 	    }
2433 	  } else {
2434 	    p1 = &rowBuf[(y2 * width + (x1+x2)) * numComps + cc];
2435 	    i = 0;
2436 	    for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
2437 	      for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
2438 		for (y5 = 0; y5 < vSub; ++y5) {
2439 		  for (x5 = 0; x5 < hSub && x1+x2+x4+x5 < width; ++x5) {
2440 		    p1[((y4+y5) * width + (x4+x5)) * numComps] = data2[i];
2441 		  }
2442 		}
2443 		++i;
2444 	      }
2445 	    }
2446 	  }
2447 	}
2448       }
2449     }
2450     --restartCtr;
2451   }
2452 
2453   // color space conversion
2454   if (colorXform) {
2455     // convert YCbCr to RGB
2456     if (numComps == 3) {
2457       for (i = 0, p1 = rowBuf; i < width * mcuHeight; ++i, p1 += 3) {
2458 	pY = p1[0];
2459 	pCb = p1[1] - 128;
2460 	pCr = p1[2] - 128;
2461 	pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2462 	p1[0] = dctClip(pR);
2463 	pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
2464 	p1[1] = dctClip(pG);
2465 	pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2466 	p1[2] = dctClip(pB);
2467       }
2468     // convert YCbCrK to CMYK (K is passed through unchanged)
2469     } else if (numComps == 4) {
2470       for (i = 0, p1 = rowBuf; i < width * mcuHeight; ++i, p1 += 4) {
2471 	pY = p1[0];
2472 	pCb = p1[1] - 128;
2473 	pCr = p1[2] - 128;
2474 	pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2475 	p1[0] = 255 - dctClip(pR);
2476 	pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
2477 	p1[1] = 255 - dctClip(pG);
2478 	pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2479 	p1[2] = 255 - dctClip(pB);
2480       }
2481     }
2482   }
2483 
2484   rowBufPtr = rowBuf;
2485   if (y + mcuHeight <= height) {
2486     rowBufEnd = rowBuf + numComps * width * mcuHeight;
2487   } else {
2488     rowBufEnd = rowBuf + numComps * width * (height - y);
2489   }
2490 
2491   return gTrue;
2492 }
2493 
2494 // Read one scan from a progressive or non-interleaved JPEG stream.
readScan()2495 void DCTStream::readScan() {
2496   int data[64];
2497   int x1, y1, dx1, dy1, x2, y2, y3, cc, i;
2498   int h, v, horiz, vert, vSub;
2499   int *p1;
2500   int c;
2501 
2502   if (scanInfo.numComps == 1) {
2503     for (cc = 0; cc < numComps; ++cc) {
2504       if (scanInfo.comp[cc]) {
2505 	break;
2506       }
2507     }
2508     dx1 = mcuWidth / compInfo[cc].hSample;
2509     dy1 = mcuHeight / compInfo[cc].vSample;
2510   } else {
2511     dx1 = mcuWidth;
2512     dy1 = mcuHeight;
2513   }
2514 
2515   for (y1 = 0; y1 < height; y1 += dy1) {
2516     for (x1 = 0; x1 < width; x1 += dx1) {
2517 
2518       // deal with restart marker
2519       if (restartInterval > 0 && restartCtr == 0) {
2520 	c = readMarker();
2521 	if (c != restartMarker) {
2522 	  error(errSyntaxError, getPos(),
2523 		"Bad DCT data: incorrect restart marker");
2524 	  return;
2525 	}
2526 	if (++restartMarker == 0xd8) {
2527 	  restartMarker = 0xd0;
2528 	}
2529 	restart();
2530       }
2531 
2532       // read one MCU
2533       for (cc = 0; cc < numComps; ++cc) {
2534 	if (!scanInfo.comp[cc]) {
2535 	  continue;
2536 	}
2537 
2538 	h = compInfo[cc].hSample;
2539 	v = compInfo[cc].vSample;
2540 	horiz = mcuWidth / h;
2541 	vert = mcuHeight / v;
2542 	vSub = vert / 8;
2543 	for (y2 = 0; y2 < dy1; y2 += vert) {
2544 	  for (x2 = 0; x2 < dx1; x2 += horiz) {
2545 
2546 	    // pull out the current values
2547 	    p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
2548 	    for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2549 	      data[i] = p1[0];
2550 	      data[i+1] = p1[1];
2551 	      data[i+2] = p1[2];
2552 	      data[i+3] = p1[3];
2553 	      data[i+4] = p1[4];
2554 	      data[i+5] = p1[5];
2555 	      data[i+6] = p1[6];
2556 	      data[i+7] = p1[7];
2557 	      p1 += bufWidth * vSub;
2558 	    }
2559 
2560 	    // read one data unit
2561 	    if (progressive) {
2562 	      if (!readProgressiveDataUnit(
2563 		       &dcHuffTables[scanInfo.dcHuffTable[cc]],
2564 		       &acHuffTables[scanInfo.acHuffTable[cc]],
2565 		       &compInfo[cc].prevDC,
2566 		       data)) {
2567 		return;
2568 	      }
2569 	    } else {
2570 	      if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]],
2571 				&acHuffTables[scanInfo.acHuffTable[cc]],
2572 				&compInfo[cc].prevDC,
2573 				data)) {
2574 		return;
2575 	      }
2576 	    }
2577 
2578 	    // add the data unit into frameBuf
2579 	    p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
2580 	    for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2581 	      p1[0] = data[i];
2582 	      p1[1] = data[i+1];
2583 	      p1[2] = data[i+2];
2584 	      p1[3] = data[i+3];
2585 	      p1[4] = data[i+4];
2586 	      p1[5] = data[i+5];
2587 	      p1[6] = data[i+6];
2588 	      p1[7] = data[i+7];
2589 	      p1 += bufWidth * vSub;
2590 	    }
2591 	  }
2592 	}
2593       }
2594       --restartCtr;
2595     }
2596   }
2597 }
2598 
2599 // Read one data unit from a sequential JPEG stream.
readDataUnit(DCTHuffTable * dcHuffTable,DCTHuffTable * acHuffTable,int * prevDC,int data[64])2600 GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
2601 			      DCTHuffTable *acHuffTable,
2602 			      int *prevDC, int data[64]) {
2603   int run, size, amp;
2604   int c;
2605   int i, j;
2606 
2607   if ((size = readHuffSym(dcHuffTable)) == 9999) {
2608     return gFalse;
2609   }
2610   if (size > 0) {
2611     if ((amp = readAmp(size)) == 9999) {
2612       return gFalse;
2613     }
2614   } else {
2615     amp = 0;
2616   }
2617   data[0] = *prevDC += amp;
2618   for (i = 1; i < 64; ++i) {
2619     data[i] = 0;
2620   }
2621   i = 1;
2622   while (i < 64) {
2623     run = 0;
2624     while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30) {
2625       run += 0x10;
2626     }
2627     if (c == 9999) {
2628       return gFalse;
2629     }
2630     if (c == 0x00) {
2631       break;
2632     } else {
2633       run += (c >> 4) & 0x0f;
2634       size = c & 0x0f;
2635       amp = readAmp(size);
2636       if (amp == 9999) {
2637 	return gFalse;
2638       }
2639       i += run;
2640       if (i < 64) {
2641 	j = dctZigZag[i++];
2642 	data[j] = amp;
2643       }
2644     }
2645   }
2646   return gTrue;
2647 }
2648 
2649 // Read one data unit from a progressive JPEG stream.
readProgressiveDataUnit(DCTHuffTable * dcHuffTable,DCTHuffTable * acHuffTable,int * prevDC,int data[64])2650 GBool DCTStream::readProgressiveDataUnit(DCTHuffTable *dcHuffTable,
2651 					 DCTHuffTable *acHuffTable,
2652 					 int *prevDC, int data[64]) {
2653   int run, size, amp, bit, c;
2654   int i, j, k;
2655 
2656   // get the DC coefficient
2657   i = scanInfo.firstCoeff;
2658   if (i == 0) {
2659     if (scanInfo.ah == 0) {
2660       if ((size = readHuffSym(dcHuffTable)) == 9999) {
2661 	return gFalse;
2662       }
2663       if (size > 0) {
2664 	if ((amp = readAmp(size)) == 9999) {
2665 	  return gFalse;
2666 	}
2667       } else {
2668 	amp = 0;
2669       }
2670       data[0] += (*prevDC += amp) << scanInfo.al;
2671     } else {
2672       if ((bit = readBit()) == 9999) {
2673 	return gFalse;
2674       }
2675       if (bit) {
2676 	if (data[0] >= 0) {
2677 	  data[0] += 1 << scanInfo.al;
2678 	} else {
2679 	  data[0] -= 1 << scanInfo.al;
2680 	}
2681       }
2682     }
2683     ++i;
2684   }
2685   if (scanInfo.lastCoeff == 0) {
2686     return gTrue;
2687   }
2688 
2689   // check for an EOB run
2690   if (eobRun > 0) {
2691     while (i <= scanInfo.lastCoeff) {
2692       j = dctZigZag[i++];
2693       if (data[j] != 0) {
2694 	if ((bit = readBit()) == EOF) {
2695 	  return gFalse;
2696 	}
2697 	if (bit) {
2698 	  if (data[j] >= 0) {
2699 	    data[j] += 1 << scanInfo.al;
2700 	  } else {
2701 	    data[j] -= 1 << scanInfo.al;
2702 	  }
2703 	}
2704       }
2705     }
2706     --eobRun;
2707     return gTrue;
2708   }
2709 
2710   // read the AC coefficients
2711   while (i <= scanInfo.lastCoeff) {
2712     if ((c = readHuffSym(acHuffTable)) == 9999) {
2713       return gFalse;
2714     }
2715 
2716     // ZRL
2717     if (c == 0xf0) {
2718       k = 0;
2719       while (k < 16 && i <= scanInfo.lastCoeff) {
2720 	j = dctZigZag[i++];
2721 	if (data[j] == 0) {
2722 	  ++k;
2723 	} else {
2724 	  if ((bit = readBit()) == EOF) {
2725 	    return gFalse;
2726 	  }
2727 	  if (bit) {
2728 	    if (data[j] >= 0) {
2729 	      data[j] += 1 << scanInfo.al;
2730 	    } else {
2731 	      data[j] -= 1 << scanInfo.al;
2732 	    }
2733 	  }
2734 	}
2735       }
2736 
2737     // EOB run
2738     } else if ((c & 0x0f) == 0x00) {
2739       j = c >> 4;
2740       eobRun = 0;
2741       for (k = 0; k < j; ++k) {
2742 	if ((bit = readBit()) == EOF) {
2743 	  return gFalse;
2744 	}
2745 	eobRun = (eobRun << 1) | bit;
2746       }
2747       eobRun += 1 << j;
2748       while (i <= scanInfo.lastCoeff) {
2749 	j = dctZigZag[i++];
2750 	if (data[j] != 0) {
2751 	  if ((bit = readBit()) == EOF) {
2752 	    return gFalse;
2753 	  }
2754 	  if (bit) {
2755 	    if (data[j] >= 0) {
2756 	      data[j] += 1 << scanInfo.al;
2757 	    } else {
2758 	      data[j] -= 1 << scanInfo.al;
2759 	    }
2760 	  }
2761 	}
2762       }
2763       --eobRun;
2764       break;
2765 
2766     // zero run and one AC coefficient
2767     } else {
2768       run = (c >> 4) & 0x0f;
2769       size = c & 0x0f;
2770       if ((amp = readAmp(size)) == 9999) {
2771 	return gFalse;
2772       }
2773       j = 0; // make gcc happy
2774       for (k = 0; k <= run && i <= scanInfo.lastCoeff; ++k) {
2775 	j = dctZigZag[i++];
2776 	while (data[j] != 0 && i <= scanInfo.lastCoeff) {
2777 	  if ((bit = readBit()) == EOF) {
2778 	    return gFalse;
2779 	  }
2780 	  if (bit) {
2781 	    if (data[j] >= 0) {
2782 	      data[j] += 1 << scanInfo.al;
2783 	    } else {
2784 	      data[j] -= 1 << scanInfo.al;
2785 	    }
2786 	  }
2787 	  j = dctZigZag[i++];
2788 	}
2789       }
2790       data[j] = amp << scanInfo.al;
2791     }
2792   }
2793 
2794   return gTrue;
2795 }
2796 
2797 // Decode a progressive JPEG image.
decodeImage()2798 void DCTStream::decodeImage() {
2799   int dataIn[64];
2800   Guchar dataOut[64];
2801   Gushort *quantTable;
2802   int pY, pCb, pCr, pR, pG, pB;
2803   int x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
2804   int h, v, horiz, vert, hSub, vSub;
2805   int *p0, *p1, *p2;
2806 
2807   for (y1 = 0; y1 < bufHeight; y1 += mcuHeight) {
2808     for (x1 = 0; x1 < bufWidth; x1 += mcuWidth) {
2809       for (cc = 0; cc < numComps; ++cc) {
2810 	quantTable = quantTables[compInfo[cc].quantTable];
2811 	h = compInfo[cc].hSample;
2812 	v = compInfo[cc].vSample;
2813 	horiz = mcuWidth / h;
2814 	vert = mcuHeight / v;
2815 	hSub = horiz / 8;
2816 	vSub = vert / 8;
2817 	for (y2 = 0; y2 < mcuHeight; y2 += vert) {
2818 	  for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
2819 
2820 	    // pull out the coded data unit
2821 	    p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
2822 	    for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2823 	      dataIn[i]   = p1[0];
2824 	      dataIn[i+1] = p1[1];
2825 	      dataIn[i+2] = p1[2];
2826 	      dataIn[i+3] = p1[3];
2827 	      dataIn[i+4] = p1[4];
2828 	      dataIn[i+5] = p1[5];
2829 	      dataIn[i+6] = p1[6];
2830 	      dataIn[i+7] = p1[7];
2831 	      p1 += bufWidth * vSub;
2832 	    }
2833 
2834 	    // transform
2835 	    transformDataUnit(quantTable, dataIn, dataOut);
2836 
2837 	    // store back into frameBuf, doing replication for
2838 	    // subsampled components
2839 	    p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
2840 	    if (hSub == 1 && vSub == 1) {
2841 	      for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2842 		p1[0] = dataOut[i] & 0xff;
2843 		p1[1] = dataOut[i+1] & 0xff;
2844 		p1[2] = dataOut[i+2] & 0xff;
2845 		p1[3] = dataOut[i+3] & 0xff;
2846 		p1[4] = dataOut[i+4] & 0xff;
2847 		p1[5] = dataOut[i+5] & 0xff;
2848 		p1[6] = dataOut[i+6] & 0xff;
2849 		p1[7] = dataOut[i+7] & 0xff;
2850 		p1 += bufWidth;
2851 	      }
2852 	    } else if (hSub == 2 && vSub == 2) {
2853 	      p2 = p1 + bufWidth;
2854 	      for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
2855 		p1[0] = p1[1] = p2[0] = p2[1] = dataOut[i] & 0xff;
2856 		p1[2] = p1[3] = p2[2] = p2[3] = dataOut[i+1] & 0xff;
2857 		p1[4] = p1[5] = p2[4] = p2[5] = dataOut[i+2] & 0xff;
2858 		p1[6] = p1[7] = p2[6] = p2[7] = dataOut[i+3] & 0xff;
2859 		p1[8] = p1[9] = p2[8] = p2[9] = dataOut[i+4] & 0xff;
2860 		p1[10] = p1[11] = p2[10] = p2[11] = dataOut[i+5] & 0xff;
2861 		p1[12] = p1[13] = p2[12] = p2[13] = dataOut[i+6] & 0xff;
2862 		p1[14] = p1[15] = p2[14] = p2[15] = dataOut[i+7] & 0xff;
2863 		p1 += bufWidth * 2;
2864 		p2 += bufWidth * 2;
2865 	      }
2866 	    } else {
2867 	      i = 0;
2868 	      for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
2869 		for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
2870 		  p2 = p1 + x4;
2871 		  for (y5 = 0; y5 < vSub; ++y5) {
2872 		    for (x5 = 0; x5 < hSub; ++x5) {
2873 		      p2[x5] = dataOut[i] & 0xff;
2874 		    }
2875 		    p2 += bufWidth;
2876 		  }
2877 		  ++i;
2878 		}
2879 		p1 += bufWidth * vSub;
2880 	      }
2881 	    }
2882 	  }
2883 	}
2884       }
2885 
2886       // color space conversion
2887       if (colorXform) {
2888 	// convert YCbCr to RGB
2889 	if (numComps == 3) {
2890 	  for (y2 = 0; y2 < mcuHeight; ++y2) {
2891 	    p0 = &frameBuf[0][(y1+y2) * bufWidth + x1];
2892 	    p1 = &frameBuf[1][(y1+y2) * bufWidth + x1];
2893 	    p2 = &frameBuf[2][(y1+y2) * bufWidth + x1];
2894 	    for (x2 = 0; x2 < mcuWidth; ++x2) {
2895 	      pY = *p0;
2896 	      pCb = *p1 - 128;
2897 	      pCr = *p2 - 128;
2898 	      pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2899 	      *p0++ = dctClip(pR);
2900 	      pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr +
2901 		    32768) >> 16;
2902 	      *p1++ = dctClip(pG);
2903 	      pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2904 	      *p2++ = dctClip(pB);
2905 	    }
2906 	  }
2907 	// convert YCbCrK to CMYK (K is passed through unchanged)
2908 	} else if (numComps == 4) {
2909 	  for (y2 = 0; y2 < mcuHeight; ++y2) {
2910 	    p0 = &frameBuf[0][(y1+y2) * bufWidth + x1];
2911 	    p1 = &frameBuf[1][(y1+y2) * bufWidth + x1];
2912 	    p2 = &frameBuf[2][(y1+y2) * bufWidth + x1];
2913 	    for (x2 = 0; x2 < mcuWidth; ++x2) {
2914 	      pY = *p0;
2915 	      pCb = *p1 - 128;
2916 	      pCr = *p2 - 128;
2917 	      pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2918 	      *p0++ = 255 - dctClip(pR);
2919 	      pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr +
2920 		    32768) >> 16;
2921 	      *p1++ = 255 - dctClip(pG);
2922 	      pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2923 	      *p2++ = 255 - dctClip(pB);
2924 	    }
2925 	  }
2926 	}
2927       }
2928     }
2929   }
2930 }
2931 
2932 // Transform one data unit -- this performs the dequantization and
2933 // IDCT steps.  This IDCT algorithm is taken from:
2934 //   Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,
2935 //   "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
2936 //   IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
2937 //   988-991.
2938 // The stage numbers mentioned in the comments refer to Figure 1 in this
2939 // paper.
transformDataUnit(Gushort * quantTable,int dataIn[64],Guchar dataOut[64])2940 void DCTStream::transformDataUnit(Gushort *quantTable,
2941 				  int dataIn[64], Guchar dataOut[64]) {
2942   int v0, v1, v2, v3, v4, v5, v6, v7, t0, t1, t2;
2943   int *p;
2944   Gushort *q;
2945   int i;
2946 
2947   // dequant; inverse DCT on rows
2948   for (i = 0; i < 64; i += 8) {
2949     p = dataIn + i;
2950     q = quantTable + i;
2951 
2952     // check for all-zero AC coefficients
2953     if (p[1] == 0 && p[2] == 0 && p[3] == 0 &&
2954 	p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] == 0) {
2955       t0 = p[0] * q[0];
2956       p[0] = t0;
2957       p[1] = t0;
2958       p[2] = t0;
2959       p[3] = t0;
2960       p[4] = t0;
2961       p[5] = t0;
2962       p[6] = t0;
2963       p[7] = t0;
2964       continue;
2965     }
2966 
2967     // stage 4
2968     v0 = p[0] * q[0];
2969     v1 = p[4] * q[4];
2970     v2 = p[2] * q[2];
2971     v3 = p[6] * q[6];
2972     t0 = p[1] * q[1];
2973     t1 = p[7] * q[7];
2974     v4 = t0 - t1;
2975     v7 = t0 + t1;
2976     v5 = (dctSqrt2 * p[3] * q[3]) >> 12;
2977     v6 = (dctSqrt2 * p[5] * q[5]) >> 12;
2978 
2979     // stage 3
2980     t0 = v0 - v1;
2981     v0 = v0 + v1;
2982     v1 = t0;
2983     t0 = dctSqrt2Cos6 * (v2 + v3);
2984     t1 = dctSqrt2Cos6PSin6 * v3;
2985     t2 = dctSqrt2Sin6MCos6 * v2;
2986     v2 = (t0 - t1) >> 12;
2987     v3 = (t0 + t2) >> 12;
2988     t0 = v4 - v6;
2989     v4 = v4 + v6;
2990     v6 = t0;
2991     t0 = v7 + v5;
2992     v5 = v7 - v5;
2993     v7 = t0;
2994 
2995     // stage 2
2996     t0 = v0 - v3;
2997     v0 = v0 + v3;
2998     v3 = t0;
2999     t0 = v1 - v2;
3000     v1 = v1 + v2;
3001     v2 = t0;
3002     t0 = dctCos3 * (v4 + v7);
3003     t1 = dctCos3PSin3 * v7;
3004     t2 = dctSin3MCos3 * v4;
3005     v4 = (t0 - t1) >> 12;
3006     v7 = (t0 + t2) >> 12;
3007     t0 = dctCos1 * (v5 + v6);
3008     t1 = dctCos1PSin1 * v6;
3009     t2 = dctSin1MCos1 * v5;
3010     v5 = (t0 - t1) >> 12;
3011     v6 = (t0 + t2) >> 12;
3012 
3013     // stage 1
3014     p[0] = v0 + v7;
3015     p[7] = v0 - v7;
3016     p[1] = v1 + v6;
3017     p[6] = v1 - v6;
3018     p[2] = v2 + v5;
3019     p[5] = v2 - v5;
3020     p[3] = v3 + v4;
3021     p[4] = v3 - v4;
3022   }
3023 
3024   // inverse DCT on columns
3025   for (i = 0; i < 8; ++i) {
3026     p = dataIn + i;
3027 
3028     // check for all-zero AC coefficients
3029     if (p[1*8] == 0 && p[2*8] == 0 && p[3*8] == 0 &&
3030 	p[4*8] == 0 && p[5*8] == 0 && p[6*8] == 0 && p[7*8] == 0) {
3031       t0 = p[0*8];
3032       p[1*8] = t0;
3033       p[2*8] = t0;
3034       p[3*8] = t0;
3035       p[4*8] = t0;
3036       p[5*8] = t0;
3037       p[6*8] = t0;
3038       p[7*8] = t0;
3039       continue;
3040     }
3041 
3042     // stage 4
3043     v0 = p[0*8];
3044     v1 = p[4*8];
3045     v2 = p[2*8];
3046     v3 = p[6*8];
3047     v4 = p[1*8] - p[7*8];
3048     v7 = p[1*8] + p[7*8];
3049     v5 = (dctSqrt2 * p[3*8]) >> 12;
3050     v6 = (dctSqrt2 * p[5*8]) >> 12;
3051 
3052     // stage 3
3053     t0 = v0 - v1;
3054     v0 = v0 + v1;
3055     v1 = t0;
3056     t0 = dctSqrt2Cos6 * (v2 + v3);
3057     t1 = dctSqrt2Cos6PSin6 * v3;
3058     t2 = dctSqrt2Sin6MCos6 * v2;
3059     v2 = (t0 - t1) >> 12;
3060     v3 = (t0 + t2) >> 12;
3061     t0 = v4 - v6;
3062     v4 = v4 + v6;
3063     v6 = t0;
3064     t0 = v7 + v5;
3065     v5 = v7 - v5;
3066     v7 = t0;
3067 
3068     // stage 2
3069     t0 = v0 - v3;
3070     v0 = v0 + v3;
3071     v3 = t0;
3072     t0 = v1 - v2;
3073     v1 = v1 + v2;
3074     v2 = t0;
3075     t0 = dctCos3 * (v4 + v7);
3076     t1 = dctCos3PSin3 * v7;
3077     t2 = dctSin3MCos3 * v4;
3078     v4 = (t0 - t1) >> 12;
3079     v7 = (t0 + t2) >> 12;
3080     t0 = dctCos1 * (v5 + v6);
3081     t1 = dctCos1PSin1 * v6;
3082     t2 = dctSin1MCos1 * v5;
3083     v5 = (t0 - t1) >> 12;
3084     v6 = (t0 + t2) >> 12;
3085 
3086     // stage 1
3087     p[0*8] = v0 + v7;
3088     p[7*8] = v0 - v7;
3089     p[1*8] = v1 + v6;
3090     p[6*8] = v1 - v6;
3091     p[2*8] = v2 + v5;
3092     p[5*8] = v2 - v5;
3093     p[3*8] = v3 + v4;
3094     p[4*8] = v3 - v4;
3095   }
3096 
3097   // convert to 8-bit integers
3098   for (i = 0; i < 64; ++i) {
3099     dataOut[i] = dctClip(128 + (dataIn[i] >> 3));
3100   }
3101 }
3102 
readHuffSym(DCTHuffTable * table)3103 int DCTStream::readHuffSym(DCTHuffTable *table) {
3104   Gushort code;
3105   int bit;
3106   int codeBits;
3107 
3108   code = 0;
3109   codeBits = 0;
3110   do {
3111     // add a bit to the code
3112     if ((bit = readBit()) == EOF) {
3113       return 9999;
3114     }
3115     code = (code << 1) + bit;
3116     ++codeBits;
3117 
3118     // look up code
3119     if (code < table->firstCode[codeBits]) {
3120       break;
3121     }
3122     if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
3123       code -= table->firstCode[codeBits];
3124       return table->sym[table->firstSym[codeBits] + code];
3125     }
3126   } while (codeBits < 16);
3127 
3128   error(errSyntaxError, getPos(), "Bad Huffman code in DCT stream");
3129   return 9999;
3130 }
3131 
readAmp(int size)3132 int DCTStream::readAmp(int size) {
3133   int amp, bit;
3134   int bits;
3135 
3136   amp = 0;
3137   for (bits = 0; bits < size; ++bits) {
3138     if ((bit = readBit()) == EOF)
3139       return 9999;
3140     amp = (amp << 1) + bit;
3141   }
3142   if (amp < (1 << (size - 1)))
3143     amp -= (1 << size) - 1;
3144   return amp;
3145 }
3146 
readBit()3147 int DCTStream::readBit() {
3148   int bit;
3149   int c, c2;
3150 
3151   if (inputBits == 0) {
3152     if ((c = str->getChar()) == EOF)
3153       return EOF;
3154     if (c == 0xff) {
3155       do {
3156 	c2 = str->getChar();
3157       } while (c2 == 0xff);
3158       if (c2 != 0x00) {
3159 	error(errSyntaxError, getPos(), "Bad DCT data: missing 00 after ff");
3160 	return EOF;
3161       }
3162     }
3163     inputBuf = c;
3164     inputBits = 8;
3165   }
3166   bit = (inputBuf >> (inputBits - 1)) & 1;
3167   --inputBits;
3168   return bit;
3169 }
3170 
readHeader()3171 GBool DCTStream::readHeader() {
3172   GBool doScan;
3173   int n;
3174   int c = 0;
3175 
3176   // read headers
3177   doScan = gFalse;
3178   while (!doScan) {
3179     c = readMarker();
3180     switch (c) {
3181     case 0xc0:			// SOF0 (sequential)
3182     case 0xc1:			// SOF1 (extended sequential)
3183       if (!readBaselineSOF()) {
3184 	return gFalse;
3185       }
3186       break;
3187     case 0xc2:			// SOF2 (progressive)
3188       if (!readProgressiveSOF()) {
3189 	return gFalse;
3190       }
3191       break;
3192     case 0xc4:			// DHT
3193       if (!readHuffmanTables()) {
3194 	return gFalse;
3195       }
3196       break;
3197     case 0xd8:			// SOI
3198       break;
3199     case 0xd9:			// EOI
3200       return gFalse;
3201     case 0xda:			// SOS
3202       if (!readScanInfo()) {
3203 	return gFalse;
3204       }
3205       doScan = gTrue;
3206       break;
3207     case 0xdb:			// DQT
3208       if (!readQuantTables()) {
3209 	return gFalse;
3210       }
3211       break;
3212     case 0xdd:			// DRI
3213       if (!readRestartInterval()) {
3214 	return gFalse;
3215       }
3216       break;
3217     case 0xe0:			// APP0
3218       if (!readJFIFMarker()) {
3219 	return gFalse;
3220       }
3221       break;
3222     case 0xee:			// APP14
3223       if (!readAdobeMarker()) {
3224 	return gFalse;
3225       }
3226       break;
3227     case EOF:
3228       error(errSyntaxError, getPos(), "Bad DCT header");
3229       return gFalse;
3230     default:
3231       // skip APPn / COM / etc.
3232       if (c >= 0xe0) {
3233 	n = read16() - 2;
3234 	str->discardChars(n);
3235       } else {
3236 	error(errSyntaxError, getPos(), "Unknown DCT marker <{0:02x}>", c);
3237 	return gFalse;
3238       }
3239       break;
3240     }
3241   }
3242 
3243   return gTrue;
3244 }
3245 
readBaselineSOF()3246 GBool DCTStream::readBaselineSOF() {
3247   int prec;
3248   int i;
3249   int c;
3250 
3251   read16(); // length
3252   prec = str->getChar();
3253   height = read16();
3254   width = read16();
3255   numComps = str->getChar();
3256   if (numComps <= 0 || numComps > 4) {
3257     error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
3258     numComps = 0;
3259     return gFalse;
3260   }
3261   if (prec != 8) {
3262     error(errSyntaxError, getPos(), "Bad DCT precision {0:d}", prec);
3263     return gFalse;
3264   }
3265   for (i = 0; i < numComps; ++i) {
3266     compInfo[i].id = str->getChar();
3267     c = str->getChar();
3268     compInfo[i].hSample = (c >> 4) & 0x0f;
3269     compInfo[i].vSample = c & 0x0f;
3270     compInfo[i].quantTable = str->getChar();
3271     if (compInfo[i].hSample < 1 || compInfo[i].hSample > 4 ||
3272 	compInfo[i].vSample < 1 || compInfo[i].vSample > 4) {
3273       error(errSyntaxError, getPos(), "Bad DCT sampling factor");
3274       return gFalse;
3275     }
3276     if (compInfo[i].quantTable < 0 || compInfo[i].quantTable > 3) {
3277       error(errSyntaxError, getPos(), "Bad DCT quant table selector");
3278       return gFalse;
3279     }
3280   }
3281   progressive = gFalse;
3282   return gTrue;
3283 }
3284 
readProgressiveSOF()3285 GBool DCTStream::readProgressiveSOF() {
3286   int prec;
3287   int i;
3288   int c;
3289 
3290   read16(); // length
3291   prec = str->getChar();
3292   height = read16();
3293   width = read16();
3294   numComps = str->getChar();
3295   if (numComps <= 0 || numComps > 4) {
3296     error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
3297     numComps = 0;
3298     return gFalse;
3299   }
3300   if (prec != 8) {
3301     error(errSyntaxError, getPos(), "Bad DCT precision {0:d}", prec);
3302     return gFalse;
3303   }
3304   for (i = 0; i < numComps; ++i) {
3305     compInfo[i].id = str->getChar();
3306     c = str->getChar();
3307     compInfo[i].hSample = (c >> 4) & 0x0f;
3308     compInfo[i].vSample = c & 0x0f;
3309     compInfo[i].quantTable = str->getChar();
3310     if (compInfo[i].hSample < 1 || compInfo[i].hSample > 4 ||
3311 	compInfo[i].vSample < 1 || compInfo[i].vSample > 4) {
3312       error(errSyntaxError, getPos(), "Bad DCT sampling factor");
3313       return gFalse;
3314     }
3315     if (compInfo[i].quantTable < 0 || compInfo[i].quantTable > 3) {
3316       error(errSyntaxError, getPos(), "Bad DCT quant table selector");
3317       return gFalse;
3318     }
3319   }
3320   progressive = gTrue;
3321   return gTrue;
3322 }
3323 
readScanInfo()3324 GBool DCTStream::readScanInfo() {
3325   int length;
3326   int id, c;
3327   int i, j;
3328 
3329   length = read16() - 2;
3330   scanInfo.numComps = str->getChar();
3331   if (scanInfo.numComps <= 0 || scanInfo.numComps > 4) {
3332     error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
3333     scanInfo.numComps = 0;
3334     return gFalse;
3335   }
3336   --length;
3337   if (length != 2 * scanInfo.numComps + 3) {
3338     error(errSyntaxError, getPos(), "Bad DCT scan info block");
3339     return gFalse;
3340   }
3341   interleaved = scanInfo.numComps == numComps;
3342   for (j = 0; j < numComps; ++j) {
3343     scanInfo.comp[j] = gFalse;
3344   }
3345   for (i = 0; i < scanInfo.numComps; ++i) {
3346     id = str->getChar();
3347     // some (broken) DCT streams reuse ID numbers, but at least they
3348     // keep the components in order, so we check compInfo[i] first to
3349     // work around the problem
3350     if (id == compInfo[i].id) {
3351       j = i;
3352     } else {
3353       for (j = 0; j < numComps; ++j) {
3354 	if (id == compInfo[j].id) {
3355 	  break;
3356 	}
3357       }
3358       if (j == numComps) {
3359 	error(errSyntaxError, getPos(),
3360 	      "Bad DCT component ID in scan info block");
3361 	return gFalse;
3362       }
3363     }
3364     scanInfo.comp[j] = gTrue;
3365     c = str->getChar();
3366     scanInfo.dcHuffTable[j] = (c >> 4) & 0x0f;
3367     scanInfo.acHuffTable[j] = c & 0x0f;
3368   }
3369   scanInfo.firstCoeff = str->getChar();
3370   scanInfo.lastCoeff = str->getChar();
3371   if (scanInfo.firstCoeff < 0 || scanInfo.lastCoeff > 63 ||
3372       scanInfo.firstCoeff > scanInfo.lastCoeff) {
3373     error(errSyntaxError, getPos(),
3374 	  "Bad DCT coefficient numbers in scan info block");
3375     return gFalse;
3376   }
3377   c = str->getChar();
3378   scanInfo.ah = (c >> 4) & 0x0f;
3379   scanInfo.al = c & 0x0f;
3380   return gTrue;
3381 }
3382 
readQuantTables()3383 GBool DCTStream::readQuantTables() {
3384   int length, prec, i, index;
3385 
3386   length = read16() - 2;
3387   while (length > 0) {
3388     index = str->getChar();
3389     prec = (index >> 4) & 0x0f;
3390     index &= 0x0f;
3391     if (prec > 1 || index >= 4) {
3392       error(errSyntaxError, getPos(), "Bad DCT quantization table");
3393       return gFalse;
3394     }
3395     if (index == numQuantTables) {
3396       numQuantTables = index + 1;
3397     }
3398     for (i = 0; i < 64; ++i) {
3399       if (prec) {
3400 	quantTables[index][dctZigZag[i]] = read16();
3401       } else {
3402 	quantTables[index][dctZigZag[i]] = str->getChar();
3403       }
3404     }
3405     if (prec) {
3406       length -= 129;
3407     } else {
3408       length -= 65;
3409     }
3410   }
3411   return gTrue;
3412 }
3413 
readHuffmanTables()3414 GBool DCTStream::readHuffmanTables() {
3415   DCTHuffTable *tbl;
3416   int length;
3417   int index;
3418   Gushort code;
3419   Guchar sym;
3420   int i;
3421   int c;
3422 
3423   length = read16() - 2;
3424   while (length > 0) {
3425     index = str->getChar();
3426     --length;
3427     if ((index & 0x0f) >= 4) {
3428       error(errSyntaxError, getPos(), "Bad DCT Huffman table");
3429       return gFalse;
3430     }
3431     if (index & 0x10) {
3432       index &= 0x0f;
3433       if (index >= numACHuffTables)
3434 	numACHuffTables = index+1;
3435       tbl = &acHuffTables[index];
3436     } else {
3437       index &= 0x0f;
3438       if (index >= numDCHuffTables)
3439 	numDCHuffTables = index+1;
3440       tbl = &dcHuffTables[index];
3441     }
3442     sym = 0;
3443     code = 0;
3444     for (i = 1; i <= 16; ++i) {
3445       c = str->getChar();
3446       tbl->firstSym[i] = sym;
3447       tbl->firstCode[i] = code;
3448       tbl->numCodes[i] = c;
3449       sym += c;
3450       code = (code + c) << 1;
3451     }
3452     length -= 16;
3453     for (i = 0; i < sym; ++i)
3454       tbl->sym[i] = str->getChar();
3455     length -= sym;
3456   }
3457   return gTrue;
3458 }
3459 
readRestartInterval()3460 GBool DCTStream::readRestartInterval() {
3461   int length;
3462 
3463   length = read16();
3464   if (length != 4) {
3465     error(errSyntaxError, getPos(), "Bad DCT restart interval");
3466     return gFalse;
3467   }
3468   restartInterval = read16();
3469   return gTrue;
3470 }
3471 
readJFIFMarker()3472 GBool DCTStream::readJFIFMarker() {
3473   int length, i;
3474   char buf[5];
3475   int c;
3476 
3477   length = read16();
3478   length -= 2;
3479   if (length >= 5) {
3480     for (i = 0; i < 5; ++i) {
3481       if ((c = str->getChar()) == EOF) {
3482 	error(errSyntaxError, getPos(), "Bad DCT APP0 marker");
3483 	return gFalse;
3484       }
3485       buf[i] = c;
3486     }
3487     length -= 5;
3488     if (!memcmp(buf, "JFIF\0", 5)) {
3489       gotJFIFMarker = gTrue;
3490     }
3491   }
3492   while (length > 0) {
3493     if (str->getChar() == EOF) {
3494       error(errSyntaxError, getPos(), "Bad DCT APP0 marker");
3495       return gFalse;
3496     }
3497     --length;
3498   }
3499   return gTrue;
3500 }
3501 
readAdobeMarker()3502 GBool DCTStream::readAdobeMarker() {
3503   int length, i;
3504   char buf[12];
3505   int c;
3506 
3507   length = read16();
3508   if (length < 14) {
3509     goto err;
3510   }
3511   for (i = 0; i < 12; ++i) {
3512     if ((c = str->getChar()) == EOF) {
3513       goto err;
3514     }
3515     buf[i] = c;
3516   }
3517   if (strncmp(buf, "Adobe", 5)) {
3518     goto err;
3519   }
3520   colorXform = buf[11];
3521   gotAdobeMarker = gTrue;
3522   for (i = 14; i < length; ++i) {
3523     if (str->getChar() == EOF) {
3524       goto err;
3525     }
3526   }
3527   return gTrue;
3528 
3529  err:
3530   error(errSyntaxError, getPos(), "Bad DCT Adobe APP14 marker");
3531   return gFalse;
3532 }
3533 
readTrailer()3534 GBool DCTStream::readTrailer() {
3535   int c;
3536 
3537   c = readMarker();
3538   if (c != 0xd9) {		// EOI
3539     error(errSyntaxError, getPos(), "Bad DCT trailer");
3540     return gFalse;
3541   }
3542   return gTrue;
3543 }
3544 
readMarker()3545 int DCTStream::readMarker() {
3546   int c;
3547 
3548   do {
3549     do {
3550       c = str->getChar();
3551     } while (c != 0xff && c != EOF);
3552     do {
3553       c = str->getChar();
3554     } while (c == 0xff);
3555   } while (c == 0x00);
3556   return c;
3557 }
3558 
read16()3559 int DCTStream::read16() {
3560   int c1, c2;
3561 
3562   if ((c1 = str->getChar()) == EOF)
3563     return EOF;
3564   if ((c2 = str->getChar()) == EOF)
3565     return EOF;
3566   return (c1 << 8) + c2;
3567 }
3568 
getPSFilter(int psLevel,const char * indent)3569 GString *DCTStream::getPSFilter(int psLevel, const char *indent) {
3570   GString *s;
3571 
3572   if (psLevel < 2) {
3573     return NULL;
3574   }
3575   if (!(s = str->getPSFilter(psLevel, indent))) {
3576     return NULL;
3577   }
3578   s->append(indent)->append("<< >> /DCTDecode filter\n");
3579   return s;
3580 }
3581 
isBinary(GBool last)3582 GBool DCTStream::isBinary(GBool last) {
3583   return str->isBinary(gTrue);
3584 }
3585 
3586 //------------------------------------------------------------------------
3587 // FlateStream
3588 //------------------------------------------------------------------------
3589 
3590 int FlateStream::codeLenCodeMap[flateMaxCodeLenCodes] = {
3591   16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
3592 };
3593 
3594 FlateDecode FlateStream::lengthDecode[flateMaxLitCodes-257] = {
3595   {0,   3},
3596   {0,   4},
3597   {0,   5},
3598   {0,   6},
3599   {0,   7},
3600   {0,   8},
3601   {0,   9},
3602   {0,  10},
3603   {1,  11},
3604   {1,  13},
3605   {1,  15},
3606   {1,  17},
3607   {2,  19},
3608   {2,  23},
3609   {2,  27},
3610   {2,  31},
3611   {3,  35},
3612   {3,  43},
3613   {3,  51},
3614   {3,  59},
3615   {4,  67},
3616   {4,  83},
3617   {4,  99},
3618   {4, 115},
3619   {5, 131},
3620   {5, 163},
3621   {5, 195},
3622   {5, 227},
3623   {0, 258},
3624   {0, 258},
3625   {0, 258}
3626 };
3627 
3628 FlateDecode FlateStream::distDecode[flateMaxDistCodes] = {
3629   { 0,     1},
3630   { 0,     2},
3631   { 0,     3},
3632   { 0,     4},
3633   { 1,     5},
3634   { 1,     7},
3635   { 2,     9},
3636   { 2,    13},
3637   { 3,    17},
3638   { 3,    25},
3639   { 4,    33},
3640   { 4,    49},
3641   { 5,    65},
3642   { 5,    97},
3643   { 6,   129},
3644   { 6,   193},
3645   { 7,   257},
3646   { 7,   385},
3647   { 8,   513},
3648   { 8,   769},
3649   { 9,  1025},
3650   { 9,  1537},
3651   {10,  2049},
3652   {10,  3073},
3653   {11,  4097},
3654   {11,  6145},
3655   {12,  8193},
3656   {12, 12289},
3657   {13, 16385},
3658   {13, 24577}
3659 };
3660 
3661 static FlateCode flateFixedLitCodeTabCodes[512] = {
3662   {7, 0x0100},
3663   {8, 0x0050},
3664   {8, 0x0010},
3665   {8, 0x0118},
3666   {7, 0x0110},
3667   {8, 0x0070},
3668   {8, 0x0030},
3669   {9, 0x00c0},
3670   {7, 0x0108},
3671   {8, 0x0060},
3672   {8, 0x0020},
3673   {9, 0x00a0},
3674   {8, 0x0000},
3675   {8, 0x0080},
3676   {8, 0x0040},
3677   {9, 0x00e0},
3678   {7, 0x0104},
3679   {8, 0x0058},
3680   {8, 0x0018},
3681   {9, 0x0090},
3682   {7, 0x0114},
3683   {8, 0x0078},
3684   {8, 0x0038},
3685   {9, 0x00d0},
3686   {7, 0x010c},
3687   {8, 0x0068},
3688   {8, 0x0028},
3689   {9, 0x00b0},
3690   {8, 0x0008},
3691   {8, 0x0088},
3692   {8, 0x0048},
3693   {9, 0x00f0},
3694   {7, 0x0102},
3695   {8, 0x0054},
3696   {8, 0x0014},
3697   {8, 0x011c},
3698   {7, 0x0112},
3699   {8, 0x0074},
3700   {8, 0x0034},
3701   {9, 0x00c8},
3702   {7, 0x010a},
3703   {8, 0x0064},
3704   {8, 0x0024},
3705   {9, 0x00a8},
3706   {8, 0x0004},
3707   {8, 0x0084},
3708   {8, 0x0044},
3709   {9, 0x00e8},
3710   {7, 0x0106},
3711   {8, 0x005c},
3712   {8, 0x001c},
3713   {9, 0x0098},
3714   {7, 0x0116},
3715   {8, 0x007c},
3716   {8, 0x003c},
3717   {9, 0x00d8},
3718   {7, 0x010e},
3719   {8, 0x006c},
3720   {8, 0x002c},
3721   {9, 0x00b8},
3722   {8, 0x000c},
3723   {8, 0x008c},
3724   {8, 0x004c},
3725   {9, 0x00f8},
3726   {7, 0x0101},
3727   {8, 0x0052},
3728   {8, 0x0012},
3729   {8, 0x011a},
3730   {7, 0x0111},
3731   {8, 0x0072},
3732   {8, 0x0032},
3733   {9, 0x00c4},
3734   {7, 0x0109},
3735   {8, 0x0062},
3736   {8, 0x0022},
3737   {9, 0x00a4},
3738   {8, 0x0002},
3739   {8, 0x0082},
3740   {8, 0x0042},
3741   {9, 0x00e4},
3742   {7, 0x0105},
3743   {8, 0x005a},
3744   {8, 0x001a},
3745   {9, 0x0094},
3746   {7, 0x0115},
3747   {8, 0x007a},
3748   {8, 0x003a},
3749   {9, 0x00d4},
3750   {7, 0x010d},
3751   {8, 0x006a},
3752   {8, 0x002a},
3753   {9, 0x00b4},
3754   {8, 0x000a},
3755   {8, 0x008a},
3756   {8, 0x004a},
3757   {9, 0x00f4},
3758   {7, 0x0103},
3759   {8, 0x0056},
3760   {8, 0x0016},
3761   {8, 0x011e},
3762   {7, 0x0113},
3763   {8, 0x0076},
3764   {8, 0x0036},
3765   {9, 0x00cc},
3766   {7, 0x010b},
3767   {8, 0x0066},
3768   {8, 0x0026},
3769   {9, 0x00ac},
3770   {8, 0x0006},
3771   {8, 0x0086},
3772   {8, 0x0046},
3773   {9, 0x00ec},
3774   {7, 0x0107},
3775   {8, 0x005e},
3776   {8, 0x001e},
3777   {9, 0x009c},
3778   {7, 0x0117},
3779   {8, 0x007e},
3780   {8, 0x003e},
3781   {9, 0x00dc},
3782   {7, 0x010f},
3783   {8, 0x006e},
3784   {8, 0x002e},
3785   {9, 0x00bc},
3786   {8, 0x000e},
3787   {8, 0x008e},
3788   {8, 0x004e},
3789   {9, 0x00fc},
3790   {7, 0x0100},
3791   {8, 0x0051},
3792   {8, 0x0011},
3793   {8, 0x0119},
3794   {7, 0x0110},
3795   {8, 0x0071},
3796   {8, 0x0031},
3797   {9, 0x00c2},
3798   {7, 0x0108},
3799   {8, 0x0061},
3800   {8, 0x0021},
3801   {9, 0x00a2},
3802   {8, 0x0001},
3803   {8, 0x0081},
3804   {8, 0x0041},
3805   {9, 0x00e2},
3806   {7, 0x0104},
3807   {8, 0x0059},
3808   {8, 0x0019},
3809   {9, 0x0092},
3810   {7, 0x0114},
3811   {8, 0x0079},
3812   {8, 0x0039},
3813   {9, 0x00d2},
3814   {7, 0x010c},
3815   {8, 0x0069},
3816   {8, 0x0029},
3817   {9, 0x00b2},
3818   {8, 0x0009},
3819   {8, 0x0089},
3820   {8, 0x0049},
3821   {9, 0x00f2},
3822   {7, 0x0102},
3823   {8, 0x0055},
3824   {8, 0x0015},
3825   {8, 0x011d},
3826   {7, 0x0112},
3827   {8, 0x0075},
3828   {8, 0x0035},
3829   {9, 0x00ca},
3830   {7, 0x010a},
3831   {8, 0x0065},
3832   {8, 0x0025},
3833   {9, 0x00aa},
3834   {8, 0x0005},
3835   {8, 0x0085},
3836   {8, 0x0045},
3837   {9, 0x00ea},
3838   {7, 0x0106},
3839   {8, 0x005d},
3840   {8, 0x001d},
3841   {9, 0x009a},
3842   {7, 0x0116},
3843   {8, 0x007d},
3844   {8, 0x003d},
3845   {9, 0x00da},
3846   {7, 0x010e},
3847   {8, 0x006d},
3848   {8, 0x002d},
3849   {9, 0x00ba},
3850   {8, 0x000d},
3851   {8, 0x008d},
3852   {8, 0x004d},
3853   {9, 0x00fa},
3854   {7, 0x0101},
3855   {8, 0x0053},
3856   {8, 0x0013},
3857   {8, 0x011b},
3858   {7, 0x0111},
3859   {8, 0x0073},
3860   {8, 0x0033},
3861   {9, 0x00c6},
3862   {7, 0x0109},
3863   {8, 0x0063},
3864   {8, 0x0023},
3865   {9, 0x00a6},
3866   {8, 0x0003},
3867   {8, 0x0083},
3868   {8, 0x0043},
3869   {9, 0x00e6},
3870   {7, 0x0105},
3871   {8, 0x005b},
3872   {8, 0x001b},
3873   {9, 0x0096},
3874   {7, 0x0115},
3875   {8, 0x007b},
3876   {8, 0x003b},
3877   {9, 0x00d6},
3878   {7, 0x010d},
3879   {8, 0x006b},
3880   {8, 0x002b},
3881   {9, 0x00b6},
3882   {8, 0x000b},
3883   {8, 0x008b},
3884   {8, 0x004b},
3885   {9, 0x00f6},
3886   {7, 0x0103},
3887   {8, 0x0057},
3888   {8, 0x0017},
3889   {8, 0x011f},
3890   {7, 0x0113},
3891   {8, 0x0077},
3892   {8, 0x0037},
3893   {9, 0x00ce},
3894   {7, 0x010b},
3895   {8, 0x0067},
3896   {8, 0x0027},
3897   {9, 0x00ae},
3898   {8, 0x0007},
3899   {8, 0x0087},
3900   {8, 0x0047},
3901   {9, 0x00ee},
3902   {7, 0x0107},
3903   {8, 0x005f},
3904   {8, 0x001f},
3905   {9, 0x009e},
3906   {7, 0x0117},
3907   {8, 0x007f},
3908   {8, 0x003f},
3909   {9, 0x00de},
3910   {7, 0x010f},
3911   {8, 0x006f},
3912   {8, 0x002f},
3913   {9, 0x00be},
3914   {8, 0x000f},
3915   {8, 0x008f},
3916   {8, 0x004f},
3917   {9, 0x00fe},
3918   {7, 0x0100},
3919   {8, 0x0050},
3920   {8, 0x0010},
3921   {8, 0x0118},
3922   {7, 0x0110},
3923   {8, 0x0070},
3924   {8, 0x0030},
3925   {9, 0x00c1},
3926   {7, 0x0108},
3927   {8, 0x0060},
3928   {8, 0x0020},
3929   {9, 0x00a1},
3930   {8, 0x0000},
3931   {8, 0x0080},
3932   {8, 0x0040},
3933   {9, 0x00e1},
3934   {7, 0x0104},
3935   {8, 0x0058},
3936   {8, 0x0018},
3937   {9, 0x0091},
3938   {7, 0x0114},
3939   {8, 0x0078},
3940   {8, 0x0038},
3941   {9, 0x00d1},
3942   {7, 0x010c},
3943   {8, 0x0068},
3944   {8, 0x0028},
3945   {9, 0x00b1},
3946   {8, 0x0008},
3947   {8, 0x0088},
3948   {8, 0x0048},
3949   {9, 0x00f1},
3950   {7, 0x0102},
3951   {8, 0x0054},
3952   {8, 0x0014},
3953   {8, 0x011c},
3954   {7, 0x0112},
3955   {8, 0x0074},
3956   {8, 0x0034},
3957   {9, 0x00c9},
3958   {7, 0x010a},
3959   {8, 0x0064},
3960   {8, 0x0024},
3961   {9, 0x00a9},
3962   {8, 0x0004},
3963   {8, 0x0084},
3964   {8, 0x0044},
3965   {9, 0x00e9},
3966   {7, 0x0106},
3967   {8, 0x005c},
3968   {8, 0x001c},
3969   {9, 0x0099},
3970   {7, 0x0116},
3971   {8, 0x007c},
3972   {8, 0x003c},
3973   {9, 0x00d9},
3974   {7, 0x010e},
3975   {8, 0x006c},
3976   {8, 0x002c},
3977   {9, 0x00b9},
3978   {8, 0x000c},
3979   {8, 0x008c},
3980   {8, 0x004c},
3981   {9, 0x00f9},
3982   {7, 0x0101},
3983   {8, 0x0052},
3984   {8, 0x0012},
3985   {8, 0x011a},
3986   {7, 0x0111},
3987   {8, 0x0072},
3988   {8, 0x0032},
3989   {9, 0x00c5},
3990   {7, 0x0109},
3991   {8, 0x0062},
3992   {8, 0x0022},
3993   {9, 0x00a5},
3994   {8, 0x0002},
3995   {8, 0x0082},
3996   {8, 0x0042},
3997   {9, 0x00e5},
3998   {7, 0x0105},
3999   {8, 0x005a},
4000   {8, 0x001a},
4001   {9, 0x0095},
4002   {7, 0x0115},
4003   {8, 0x007a},
4004   {8, 0x003a},
4005   {9, 0x00d5},
4006   {7, 0x010d},
4007   {8, 0x006a},
4008   {8, 0x002a},
4009   {9, 0x00b5},
4010   {8, 0x000a},
4011   {8, 0x008a},
4012   {8, 0x004a},
4013   {9, 0x00f5},
4014   {7, 0x0103},
4015   {8, 0x0056},
4016   {8, 0x0016},
4017   {8, 0x011e},
4018   {7, 0x0113},
4019   {8, 0x0076},
4020   {8, 0x0036},
4021   {9, 0x00cd},
4022   {7, 0x010b},
4023   {8, 0x0066},
4024   {8, 0x0026},
4025   {9, 0x00ad},
4026   {8, 0x0006},
4027   {8, 0x0086},
4028   {8, 0x0046},
4029   {9, 0x00ed},
4030   {7, 0x0107},
4031   {8, 0x005e},
4032   {8, 0x001e},
4033   {9, 0x009d},
4034   {7, 0x0117},
4035   {8, 0x007e},
4036   {8, 0x003e},
4037   {9, 0x00dd},
4038   {7, 0x010f},
4039   {8, 0x006e},
4040   {8, 0x002e},
4041   {9, 0x00bd},
4042   {8, 0x000e},
4043   {8, 0x008e},
4044   {8, 0x004e},
4045   {9, 0x00fd},
4046   {7, 0x0100},
4047   {8, 0x0051},
4048   {8, 0x0011},
4049   {8, 0x0119},
4050   {7, 0x0110},
4051   {8, 0x0071},
4052   {8, 0x0031},
4053   {9, 0x00c3},
4054   {7, 0x0108},
4055   {8, 0x0061},
4056   {8, 0x0021},
4057   {9, 0x00a3},
4058   {8, 0x0001},
4059   {8, 0x0081},
4060   {8, 0x0041},
4061   {9, 0x00e3},
4062   {7, 0x0104},
4063   {8, 0x0059},
4064   {8, 0x0019},
4065   {9, 0x0093},
4066   {7, 0x0114},
4067   {8, 0x0079},
4068   {8, 0x0039},
4069   {9, 0x00d3},
4070   {7, 0x010c},
4071   {8, 0x0069},
4072   {8, 0x0029},
4073   {9, 0x00b3},
4074   {8, 0x0009},
4075   {8, 0x0089},
4076   {8, 0x0049},
4077   {9, 0x00f3},
4078   {7, 0x0102},
4079   {8, 0x0055},
4080   {8, 0x0015},
4081   {8, 0x011d},
4082   {7, 0x0112},
4083   {8, 0x0075},
4084   {8, 0x0035},
4085   {9, 0x00cb},
4086   {7, 0x010a},
4087   {8, 0x0065},
4088   {8, 0x0025},
4089   {9, 0x00ab},
4090   {8, 0x0005},
4091   {8, 0x0085},
4092   {8, 0x0045},
4093   {9, 0x00eb},
4094   {7, 0x0106},
4095   {8, 0x005d},
4096   {8, 0x001d},
4097   {9, 0x009b},
4098   {7, 0x0116},
4099   {8, 0x007d},
4100   {8, 0x003d},
4101   {9, 0x00db},
4102   {7, 0x010e},
4103   {8, 0x006d},
4104   {8, 0x002d},
4105   {9, 0x00bb},
4106   {8, 0x000d},
4107   {8, 0x008d},
4108   {8, 0x004d},
4109   {9, 0x00fb},
4110   {7, 0x0101},
4111   {8, 0x0053},
4112   {8, 0x0013},
4113   {8, 0x011b},
4114   {7, 0x0111},
4115   {8, 0x0073},
4116   {8, 0x0033},
4117   {9, 0x00c7},
4118   {7, 0x0109},
4119   {8, 0x0063},
4120   {8, 0x0023},
4121   {9, 0x00a7},
4122   {8, 0x0003},
4123   {8, 0x0083},
4124   {8, 0x0043},
4125   {9, 0x00e7},
4126   {7, 0x0105},
4127   {8, 0x005b},
4128   {8, 0x001b},
4129   {9, 0x0097},
4130   {7, 0x0115},
4131   {8, 0x007b},
4132   {8, 0x003b},
4133   {9, 0x00d7},
4134   {7, 0x010d},
4135   {8, 0x006b},
4136   {8, 0x002b},
4137   {9, 0x00b7},
4138   {8, 0x000b},
4139   {8, 0x008b},
4140   {8, 0x004b},
4141   {9, 0x00f7},
4142   {7, 0x0103},
4143   {8, 0x0057},
4144   {8, 0x0017},
4145   {8, 0x011f},
4146   {7, 0x0113},
4147   {8, 0x0077},
4148   {8, 0x0037},
4149   {9, 0x00cf},
4150   {7, 0x010b},
4151   {8, 0x0067},
4152   {8, 0x0027},
4153   {9, 0x00af},
4154   {8, 0x0007},
4155   {8, 0x0087},
4156   {8, 0x0047},
4157   {9, 0x00ef},
4158   {7, 0x0107},
4159   {8, 0x005f},
4160   {8, 0x001f},
4161   {9, 0x009f},
4162   {7, 0x0117},
4163   {8, 0x007f},
4164   {8, 0x003f},
4165   {9, 0x00df},
4166   {7, 0x010f},
4167   {8, 0x006f},
4168   {8, 0x002f},
4169   {9, 0x00bf},
4170   {8, 0x000f},
4171   {8, 0x008f},
4172   {8, 0x004f},
4173   {9, 0x00ff}
4174 };
4175 
4176 FlateHuffmanTab FlateStream::fixedLitCodeTab = {
4177   flateFixedLitCodeTabCodes, 9
4178 };
4179 
4180 static FlateCode flateFixedDistCodeTabCodes[32] = {
4181   {5, 0x0000},
4182   {5, 0x0010},
4183   {5, 0x0008},
4184   {5, 0x0018},
4185   {5, 0x0004},
4186   {5, 0x0014},
4187   {5, 0x000c},
4188   {5, 0x001c},
4189   {5, 0x0002},
4190   {5, 0x0012},
4191   {5, 0x000a},
4192   {5, 0x001a},
4193   {5, 0x0006},
4194   {5, 0x0016},
4195   {5, 0x000e},
4196   {0, 0x0000},
4197   {5, 0x0001},
4198   {5, 0x0011},
4199   {5, 0x0009},
4200   {5, 0x0019},
4201   {5, 0x0005},
4202   {5, 0x0015},
4203   {5, 0x000d},
4204   {5, 0x001d},
4205   {5, 0x0003},
4206   {5, 0x0013},
4207   {5, 0x000b},
4208   {5, 0x001b},
4209   {5, 0x0007},
4210   {5, 0x0017},
4211   {5, 0x000f},
4212   {0, 0x0000}
4213 };
4214 
4215 FlateHuffmanTab FlateStream::fixedDistCodeTab = {
4216   flateFixedDistCodeTabCodes, 5
4217 };
4218 
FlateStream(Stream * strA,int predictor,int columns,int colors,int bits)4219 FlateStream::FlateStream(Stream *strA, int predictor, int columns,
4220 			 int colors, int bits):
4221     FilterStream(strA) {
4222   if (predictor != 1) {
4223     pred = new StreamPredictor(this, predictor, columns, colors, bits);
4224     if (!pred->isOk()) {
4225       delete pred;
4226       pred = NULL;
4227     }
4228   } else {
4229     pred = NULL;
4230   }
4231   litCodeTab.codes = NULL;
4232   distCodeTab.codes = NULL;
4233   memset(buf, 0, flateWindow);
4234 }
4235 
~FlateStream()4236 FlateStream::~FlateStream() {
4237   if (litCodeTab.codes != fixedLitCodeTab.codes) {
4238     gfree(litCodeTab.codes);
4239   }
4240   if (distCodeTab.codes != fixedDistCodeTab.codes) {
4241     gfree(distCodeTab.codes);
4242   }
4243   if (pred) {
4244     delete pred;
4245   }
4246   delete str;
4247 }
4248 
reset()4249 void FlateStream::reset() {
4250   int cmf, flg;
4251 
4252   index = 0;
4253   remain = 0;
4254   codeBuf = 0;
4255   codeSize = 0;
4256   compressedBlock = gFalse;
4257   endOfBlock = gTrue;
4258   eof = gTrue;
4259 
4260   str->reset();
4261   if (pred) {
4262     pred->reset();
4263   }
4264 
4265   // read header
4266   //~ need to look at window size?
4267   endOfBlock = eof = gTrue;
4268   cmf = str->getChar();
4269   flg = str->getChar();
4270   if (cmf == EOF || flg == EOF)
4271     return;
4272   if ((cmf & 0x0f) != 0x08) {
4273     error(errSyntaxError, getPos(),
4274 	  "Unknown compression method in flate stream");
4275     return;
4276   }
4277   if ((((cmf << 8) + flg) % 31) != 0) {
4278     error(errSyntaxError, getPos(), "Bad FCHECK in flate stream");
4279     return;
4280   }
4281   if (flg & 0x20) {
4282     error(errSyntaxError, getPos(), "FDICT bit set in flate stream");
4283     return;
4284   }
4285 
4286   eof = gFalse;
4287 }
4288 
getChar()4289 int FlateStream::getChar() {
4290   int c;
4291 
4292   if (pred) {
4293     return pred->getChar();
4294   }
4295   while (remain == 0) {
4296     if (endOfBlock && eof)
4297       return EOF;
4298     readSome();
4299   }
4300   c = buf[index];
4301   index = (index + 1) & flateMask;
4302   --remain;
4303   return c;
4304 }
4305 
lookChar()4306 int FlateStream::lookChar() {
4307   int c;
4308 
4309   if (pred) {
4310     return pred->lookChar();
4311   }
4312   while (remain == 0) {
4313     if (endOfBlock && eof)
4314       return EOF;
4315     readSome();
4316   }
4317   c = buf[index];
4318   return c;
4319 }
4320 
getRawChar()4321 int FlateStream::getRawChar() {
4322   int c;
4323 
4324   while (remain == 0) {
4325     if (endOfBlock && eof)
4326       return EOF;
4327     readSome();
4328   }
4329   c = buf[index];
4330   index = (index + 1) & flateMask;
4331   --remain;
4332   return c;
4333 }
4334 
getBlock(char * blk,int size)4335 int FlateStream::getBlock(char *blk, int size) {
4336   int n;
4337 
4338   if (pred) {
4339     return pred->getBlock(blk, size);
4340   }
4341 
4342   n = 0;
4343   while (n < size) {
4344     if (remain == 0) {
4345       if (endOfBlock && eof) {
4346 	break;
4347       }
4348       readSome();
4349     }
4350     while (remain && n < size) {
4351       blk[n++] = buf[index];
4352       index = (index + 1) & flateMask;
4353       --remain;
4354     }
4355   }
4356   return n;
4357 }
4358 
getPSFilter(int psLevel,const char * indent)4359 GString *FlateStream::getPSFilter(int psLevel, const char *indent) {
4360   GString *s;
4361 
4362   if (psLevel < 3 || pred) {
4363     return NULL;
4364   }
4365   if (!(s = str->getPSFilter(psLevel, indent))) {
4366     return NULL;
4367   }
4368   s->append(indent)->append("<< >> /FlateDecode filter\n");
4369   return s;
4370 }
4371 
isBinary(GBool last)4372 GBool FlateStream::isBinary(GBool last) {
4373   return str->isBinary(gTrue);
4374 }
4375 
readSome()4376 void FlateStream::readSome() {
4377   int code1, code2;
4378   int len, dist;
4379   int i, j, k;
4380   int c;
4381 
4382   if (endOfBlock) {
4383     if (!startBlock())
4384       return;
4385   }
4386 
4387   if (compressedBlock) {
4388     if ((code1 = getHuffmanCodeWord(&litCodeTab)) == EOF)
4389       goto err;
4390     if (code1 < 256) {
4391       buf[index] = code1;
4392       remain = 1;
4393     } else if (code1 == 256) {
4394       endOfBlock = gTrue;
4395       remain = 0;
4396     } else {
4397       code1 -= 257;
4398       code2 = lengthDecode[code1].bits;
4399       if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
4400 	goto err;
4401       len = lengthDecode[code1].first + code2;
4402       if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF)
4403 	goto err;
4404       code2 = distDecode[code1].bits;
4405       if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
4406 	goto err;
4407       dist = distDecode[code1].first + code2;
4408       i = index;
4409       j = (index - dist) & flateMask;
4410       for (k = 0; k < len; ++k) {
4411 	buf[i] = buf[j];
4412 	i = (i + 1) & flateMask;
4413 	j = (j + 1) & flateMask;
4414       }
4415       remain = len;
4416     }
4417 
4418   } else {
4419     len = (blockLen < flateWindow) ? blockLen : flateWindow;
4420     for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) {
4421       if ((c = str->getChar()) == EOF) {
4422 	endOfBlock = eof = gTrue;
4423 	break;
4424       }
4425       buf[j] = c & 0xff;
4426     }
4427     remain = i;
4428     blockLen -= len;
4429     if (blockLen == 0)
4430       endOfBlock = gTrue;
4431   }
4432 
4433   return;
4434 
4435 err:
4436   error(errSyntaxError, getPos(), "Unexpected end of file in flate stream");
4437   endOfBlock = eof = gTrue;
4438   remain = 0;
4439 }
4440 
startBlock()4441 GBool FlateStream::startBlock() {
4442   int blockHdr;
4443   int c;
4444   int check;
4445 
4446   // free the code tables from the previous block
4447   if (litCodeTab.codes != fixedLitCodeTab.codes) {
4448     gfree(litCodeTab.codes);
4449   }
4450   litCodeTab.codes = NULL;
4451   if (distCodeTab.codes != fixedDistCodeTab.codes) {
4452     gfree(distCodeTab.codes);
4453   }
4454   distCodeTab.codes = NULL;
4455 
4456   // read block header
4457   blockHdr = getCodeWord(3);
4458   if (blockHdr & 1)
4459     eof = gTrue;
4460   blockHdr >>= 1;
4461 
4462   // uncompressed block
4463   if (blockHdr == 0) {
4464     compressedBlock = gFalse;
4465     if ((c = str->getChar()) == EOF)
4466       goto err;
4467     blockLen = c & 0xff;
4468     if ((c = str->getChar()) == EOF)
4469       goto err;
4470     blockLen |= (c & 0xff) << 8;
4471     if ((c = str->getChar()) == EOF)
4472       goto err;
4473     check = c & 0xff;
4474     if ((c = str->getChar()) == EOF)
4475       goto err;
4476     check |= (c & 0xff) << 8;
4477     if (check != (~blockLen & 0xffff))
4478       error(errSyntaxError, getPos(),
4479 	    "Bad uncompressed block length in flate stream");
4480     codeBuf = 0;
4481     codeSize = 0;
4482 
4483   // compressed block with fixed codes
4484   } else if (blockHdr == 1) {
4485     compressedBlock = gTrue;
4486     loadFixedCodes();
4487 
4488   // compressed block with dynamic codes
4489   } else if (blockHdr == 2) {
4490     compressedBlock = gTrue;
4491     if (!readDynamicCodes()) {
4492       goto err;
4493     }
4494 
4495   // unknown block type
4496   } else {
4497     goto err;
4498   }
4499 
4500   endOfBlock = gFalse;
4501   return gTrue;
4502 
4503 err:
4504   error(errSyntaxError, getPos(), "Bad block header in flate stream");
4505   endOfBlock = eof = gTrue;
4506   return gFalse;
4507 }
4508 
loadFixedCodes()4509 void FlateStream::loadFixedCodes() {
4510   litCodeTab.codes = fixedLitCodeTab.codes;
4511   litCodeTab.maxLen = fixedLitCodeTab.maxLen;
4512   distCodeTab.codes = fixedDistCodeTab.codes;
4513   distCodeTab.maxLen = fixedDistCodeTab.maxLen;
4514 }
4515 
readDynamicCodes()4516 GBool FlateStream::readDynamicCodes() {
4517   int numCodeLenCodes;
4518   int numLitCodes;
4519   int numDistCodes;
4520   int codeLenCodeLengths[flateMaxCodeLenCodes];
4521   FlateHuffmanTab codeLenCodeTab;
4522   int len, repeat, code;
4523   int i;
4524 
4525   codeLenCodeTab.codes = NULL;
4526 
4527   // read lengths
4528   if ((numLitCodes = getCodeWord(5)) == EOF) {
4529     goto err;
4530   }
4531   numLitCodes += 257;
4532   if ((numDistCodes = getCodeWord(5)) == EOF) {
4533     goto err;
4534   }
4535   numDistCodes += 1;
4536   if ((numCodeLenCodes = getCodeWord(4)) == EOF) {
4537     goto err;
4538   }
4539   numCodeLenCodes += 4;
4540   if (numLitCodes > flateMaxLitCodes ||
4541       numDistCodes > flateMaxDistCodes ||
4542       numCodeLenCodes > flateMaxCodeLenCodes) {
4543     goto err;
4544   }
4545 
4546   // build the code length code table
4547   for (i = 0; i < flateMaxCodeLenCodes; ++i) {
4548     codeLenCodeLengths[i] = 0;
4549   }
4550   for (i = 0; i < numCodeLenCodes; ++i) {
4551     if ((codeLenCodeLengths[codeLenCodeMap[i]] = getCodeWord(3)) == -1) {
4552       goto err;
4553     }
4554   }
4555   compHuffmanCodes(codeLenCodeLengths, flateMaxCodeLenCodes, &codeLenCodeTab);
4556 
4557   // build the literal and distance code tables
4558   len = 0;
4559   repeat = 0;
4560   i = 0;
4561   while (i < numLitCodes + numDistCodes) {
4562     if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF) {
4563       goto err;
4564     }
4565     if (code == 16) {
4566       if ((repeat = getCodeWord(2)) == EOF) {
4567 	goto err;
4568       }
4569       repeat += 3;
4570       if (i + repeat > numLitCodes + numDistCodes) {
4571 	goto err;
4572       }
4573       for (; repeat > 0; --repeat) {
4574 	codeLengths[i++] = len;
4575       }
4576     } else if (code == 17) {
4577       if ((repeat = getCodeWord(3)) == EOF) {
4578 	goto err;
4579       }
4580       repeat += 3;
4581       if (i + repeat > numLitCodes + numDistCodes) {
4582 	goto err;
4583       }
4584       len = 0;
4585       for (; repeat > 0; --repeat) {
4586 	codeLengths[i++] = 0;
4587       }
4588     } else if (code == 18) {
4589       if ((repeat = getCodeWord(7)) == EOF) {
4590 	goto err;
4591       }
4592       repeat += 11;
4593       if (i + repeat > numLitCodes + numDistCodes) {
4594 	goto err;
4595       }
4596       len = 0;
4597       for (; repeat > 0; --repeat) {
4598 	codeLengths[i++] = 0;
4599       }
4600     } else {
4601       codeLengths[i++] = len = code;
4602     }
4603   }
4604   compHuffmanCodes(codeLengths, numLitCodes, &litCodeTab);
4605   compHuffmanCodes(codeLengths + numLitCodes, numDistCodes, &distCodeTab);
4606 
4607   gfree(codeLenCodeTab.codes);
4608   return gTrue;
4609 
4610 err:
4611   error(errSyntaxError, getPos(), "Bad dynamic code table in flate stream");
4612   gfree(codeLenCodeTab.codes);
4613   return gFalse;
4614 }
4615 
4616 // Convert an array <lengths> of <n> lengths, in value order, into a
4617 // Huffman code lookup table.
compHuffmanCodes(int * lengths,int n,FlateHuffmanTab * tab)4618 void FlateStream::compHuffmanCodes(int *lengths, int n, FlateHuffmanTab *tab) {
4619   int tabSize, len, code, code2, skip, val, i, t;
4620 
4621   // find max code length
4622   tab->maxLen = 0;
4623   for (val = 0; val < n; ++val) {
4624     if (lengths[val] > tab->maxLen) {
4625       tab->maxLen = lengths[val];
4626     }
4627   }
4628 
4629   // allocate the table
4630   tabSize = 1 << tab->maxLen;
4631   tab->codes = (FlateCode *)gmallocn(tabSize, sizeof(FlateCode));
4632 
4633   // clear the table
4634   for (i = 0; i < tabSize; ++i) {
4635     tab->codes[i].len = 0;
4636     tab->codes[i].val = 0;
4637   }
4638 
4639   // build the table
4640   for (len = 1, code = 0, skip = 2;
4641        len <= tab->maxLen;
4642        ++len, code <<= 1, skip <<= 1) {
4643     for (val = 0; val < n; ++val) {
4644       if (lengths[val] == len) {
4645 
4646 	// bit-reverse the code
4647 	code2 = 0;
4648 	t = code;
4649 	for (i = 0; i < len; ++i) {
4650 	  code2 = (code2 << 1) | (t & 1);
4651 	  t >>= 1;
4652 	}
4653 
4654 	// fill in the table entries
4655 	for (i = code2; i < tabSize; i += skip) {
4656 	  tab->codes[i].len = (Gushort)len;
4657 	  tab->codes[i].val = (Gushort)val;
4658 	}
4659 
4660 	++code;
4661       }
4662     }
4663   }
4664 }
4665 
getHuffmanCodeWord(FlateHuffmanTab * tab)4666 int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) {
4667   FlateCode *code;
4668   int c;
4669 
4670   while (codeSize < tab->maxLen) {
4671     if ((c = str->getChar()) == EOF) {
4672       break;
4673     }
4674     codeBuf |= (c & 0xff) << codeSize;
4675     codeSize += 8;
4676   }
4677   code = &tab->codes[codeBuf & ((1 << tab->maxLen) - 1)];
4678   if (codeSize == 0 || codeSize < code->len || code->len == 0) {
4679     return EOF;
4680   }
4681   codeBuf >>= code->len;
4682   codeSize -= code->len;
4683   return (int)code->val;
4684 }
4685 
getCodeWord(int bits)4686 int FlateStream::getCodeWord(int bits) {
4687   int c;
4688 
4689   while (codeSize < bits) {
4690     if ((c = str->getChar()) == EOF)
4691       return EOF;
4692     codeBuf |= (c & 0xff) << codeSize;
4693     codeSize += 8;
4694   }
4695   c = codeBuf & ((1 << bits) - 1);
4696   codeBuf >>= bits;
4697   codeSize -= bits;
4698   return c;
4699 }
4700 
4701 //------------------------------------------------------------------------
4702 // EOFStream
4703 //------------------------------------------------------------------------
4704 
EOFStream(Stream * strA)4705 EOFStream::EOFStream(Stream *strA):
4706     FilterStream(strA) {
4707 }
4708 
~EOFStream()4709 EOFStream::~EOFStream() {
4710   delete str;
4711 }
4712 
4713 //------------------------------------------------------------------------
4714 // BufStream
4715 //------------------------------------------------------------------------
4716 
BufStream(Stream * strA,int bufSizeA)4717 BufStream::BufStream(Stream *strA, int bufSizeA): FilterStream(strA) {
4718   bufSize = bufSizeA;
4719   buf = (int *)gmallocn(bufSize, sizeof(int));
4720 }
4721 
~BufStream()4722 BufStream::~BufStream() {
4723   gfree(buf);
4724   delete str;
4725 }
4726 
reset()4727 void BufStream::reset() {
4728   int i;
4729 
4730   str->reset();
4731   for (i = 0; i < bufSize; ++i) {
4732     buf[i] = str->getChar();
4733   }
4734 }
4735 
getChar()4736 int BufStream::getChar() {
4737   int c, i;
4738 
4739   c = buf[0];
4740   for (i = 1; i < bufSize; ++i) {
4741     buf[i-1] = buf[i];
4742   }
4743   buf[bufSize - 1] = str->getChar();
4744   return c;
4745 }
4746 
lookChar()4747 int BufStream::lookChar() {
4748   return buf[0];
4749 }
4750 
lookChar(int idx)4751 int BufStream::lookChar(int idx) {
4752   return buf[idx];
4753 }
4754 
isBinary(GBool last)4755 GBool BufStream::isBinary(GBool last) {
4756   return str->isBinary(gTrue);
4757 }
4758 
4759 //------------------------------------------------------------------------
4760 // FixedLengthEncoder
4761 //------------------------------------------------------------------------
4762 
FixedLengthEncoder(Stream * strA,int lengthA)4763 FixedLengthEncoder::FixedLengthEncoder(Stream *strA, int lengthA):
4764     FilterStream(strA) {
4765   length = lengthA;
4766   count = 0;
4767 }
4768 
~FixedLengthEncoder()4769 FixedLengthEncoder::~FixedLengthEncoder() {
4770   if (str->isEncoder())
4771     delete str;
4772 }
4773 
reset()4774 void FixedLengthEncoder::reset() {
4775   str->reset();
4776   count = 0;
4777 }
4778 
getChar()4779 int FixedLengthEncoder::getChar() {
4780   if (length >= 0 && count >= length)
4781     return EOF;
4782   ++count;
4783   return str->getChar();
4784 }
4785 
lookChar()4786 int FixedLengthEncoder::lookChar() {
4787   if (length >= 0 && count >= length)
4788     return EOF;
4789   return str->getChar();
4790 }
4791 
isBinary(GBool last)4792 GBool FixedLengthEncoder::isBinary(GBool last) {
4793   return str->isBinary(gTrue);
4794 }
4795 
4796 //------------------------------------------------------------------------
4797 // ASCIIHexEncoder
4798 //------------------------------------------------------------------------
4799 
ASCIIHexEncoder(Stream * strA)4800 ASCIIHexEncoder::ASCIIHexEncoder(Stream *strA):
4801     FilterStream(strA) {
4802   bufPtr = bufEnd = buf;
4803   lineLen = 0;
4804   eof = gFalse;
4805 }
4806 
~ASCIIHexEncoder()4807 ASCIIHexEncoder::~ASCIIHexEncoder() {
4808   if (str->isEncoder()) {
4809     delete str;
4810   }
4811 }
4812 
reset()4813 void ASCIIHexEncoder::reset() {
4814   str->reset();
4815   bufPtr = bufEnd = buf;
4816   lineLen = 0;
4817   eof = gFalse;
4818 }
4819 
fillBuf()4820 GBool ASCIIHexEncoder::fillBuf() {
4821   static const char *hex = "0123456789abcdef";
4822   int c;
4823 
4824   if (eof) {
4825     return gFalse;
4826   }
4827   bufPtr = bufEnd = buf;
4828   if ((c = str->getChar()) == EOF) {
4829     *bufEnd++ = '>';
4830     eof = gTrue;
4831   } else {
4832     if (lineLen >= 64) {
4833       *bufEnd++ = '\n';
4834       lineLen = 0;
4835     }
4836     *bufEnd++ = hex[(c >> 4) & 0x0f];
4837     *bufEnd++ = hex[c & 0x0f];
4838     lineLen += 2;
4839   }
4840   return gTrue;
4841 }
4842 
4843 //------------------------------------------------------------------------
4844 // ASCII85Encoder
4845 //------------------------------------------------------------------------
4846 
ASCII85Encoder(Stream * strA)4847 ASCII85Encoder::ASCII85Encoder(Stream *strA):
4848     FilterStream(strA) {
4849   bufPtr = bufEnd = buf;
4850   lineLen = 0;
4851   eof = gFalse;
4852 }
4853 
~ASCII85Encoder()4854 ASCII85Encoder::~ASCII85Encoder() {
4855   if (str->isEncoder())
4856     delete str;
4857 }
4858 
reset()4859 void ASCII85Encoder::reset() {
4860   str->reset();
4861   bufPtr = bufEnd = buf;
4862   lineLen = 0;
4863   eof = gFalse;
4864 }
4865 
fillBuf()4866 GBool ASCII85Encoder::fillBuf() {
4867   Guint t;
4868   char buf1[5];
4869   int c0, c1, c2, c3;
4870   int n, i;
4871 
4872   if (eof) {
4873     return gFalse;
4874   }
4875   c0 = str->getChar();
4876   c1 = str->getChar();
4877   c2 = str->getChar();
4878   c3 = str->getChar();
4879   bufPtr = bufEnd = buf;
4880   if (c3 == EOF) {
4881     if (c0 == EOF) {
4882       n = 0;
4883       t = 0;
4884     } else {
4885       if (c1 == EOF) {
4886 	n = 1;
4887 	t = c0 << 24;
4888       } else if (c2 == EOF) {
4889 	n = 2;
4890 	t = (c0 << 24) | (c1 << 16);
4891       } else {
4892 	n = 3;
4893 	t = (c0 << 24) | (c1 << 16) | (c2 << 8);
4894       }
4895       for (i = 4; i >= 0; --i) {
4896 	buf1[i] = (char)(t % 85 + 0x21);
4897 	t /= 85;
4898       }
4899       for (i = 0; i <= n; ++i) {
4900 	*bufEnd++ = buf1[i];
4901 	if (++lineLen == 65) {
4902 	  *bufEnd++ = '\n';
4903 	  lineLen = 0;
4904 	}
4905       }
4906     }
4907     *bufEnd++ = '~';
4908     *bufEnd++ = '>';
4909     eof = gTrue;
4910   } else {
4911     t = (c0 << 24) | (c1 << 16) | (c2 << 8) | c3;
4912     if (t == 0) {
4913       *bufEnd++ = 'z';
4914       if (++lineLen == 65) {
4915 	*bufEnd++ = '\n';
4916 	lineLen = 0;
4917       }
4918     } else {
4919       for (i = 4; i >= 0; --i) {
4920 	buf1[i] = (char)(t % 85 + 0x21);
4921 	t /= 85;
4922       }
4923       for (i = 0; i <= 4; ++i) {
4924 	*bufEnd++ = buf1[i];
4925 	if (++lineLen == 65) {
4926 	  *bufEnd++ = '\n';
4927 	  lineLen = 0;
4928 	}
4929       }
4930     }
4931   }
4932   return gTrue;
4933 }
4934 
4935 //------------------------------------------------------------------------
4936 // RunLengthEncoder
4937 //------------------------------------------------------------------------
4938 
RunLengthEncoder(Stream * strA)4939 RunLengthEncoder::RunLengthEncoder(Stream *strA):
4940     FilterStream(strA) {
4941   bufPtr = bufEnd = nextEnd = buf;
4942   eof = gFalse;
4943 }
4944 
~RunLengthEncoder()4945 RunLengthEncoder::~RunLengthEncoder() {
4946   if (str->isEncoder())
4947     delete str;
4948 }
4949 
reset()4950 void RunLengthEncoder::reset() {
4951   str->reset();
4952   bufPtr = bufEnd = nextEnd = buf;
4953   eof = gFalse;
4954 }
4955 
4956 //
4957 // When fillBuf finishes, buf[] looks like this:
4958 //   +-----+--------------+-----------------+--
4959 //   + tag | ... data ... | next 0, 1, or 2 |
4960 //   +-----+--------------+-----------------+--
4961 //    ^                    ^                 ^
4962 //    bufPtr               bufEnd            nextEnd
4963 //
fillBuf()4964 GBool RunLengthEncoder::fillBuf() {
4965   int c, c1, c2;
4966   int n;
4967 
4968   // already hit EOF?
4969   if (eof)
4970     return gFalse;
4971 
4972   // grab two bytes
4973   if (nextEnd < bufEnd + 1) {
4974     if ((c1 = str->getChar()) == EOF) {
4975       eof = gTrue;
4976       return gFalse;
4977     }
4978   } else {
4979     c1 = bufEnd[0] & 0xff;
4980   }
4981   if (nextEnd < bufEnd + 2) {
4982     if ((c2 = str->getChar()) == EOF) {
4983       eof = gTrue;
4984       buf[0] = 0;
4985       buf[1] = c1;
4986       bufPtr = buf;
4987       bufEnd = &buf[2];
4988       return gTrue;
4989     }
4990   } else {
4991     c2 = bufEnd[1] & 0xff;
4992   }
4993 
4994   // check for repeat
4995   c = 0; // make gcc happy
4996   if (c1 == c2) {
4997     n = 2;
4998     while (n < 128 && (c = str->getChar()) == c1)
4999       ++n;
5000     buf[0] = (char)(257 - n);
5001     buf[1] = c1;
5002     bufEnd = &buf[2];
5003     if (c == EOF) {
5004       eof = gTrue;
5005     } else if (n < 128) {
5006       buf[2] = c;
5007       nextEnd = &buf[3];
5008     } else {
5009       nextEnd = bufEnd;
5010     }
5011 
5012   // get up to 128 chars
5013   } else {
5014     buf[1] = c1;
5015     buf[2] = c2;
5016     n = 2;
5017     while (n < 128) {
5018       if ((c = str->getChar()) == EOF) {
5019 	eof = gTrue;
5020 	break;
5021       }
5022       ++n;
5023       buf[n] = c;
5024       if (buf[n] == buf[n-1])
5025 	break;
5026     }
5027     if (buf[n] == buf[n-1]) {
5028       buf[0] = (char)(n-2-1);
5029       bufEnd = &buf[n-1];
5030       nextEnd = &buf[n+1];
5031     } else {
5032       buf[0] = (char)(n-1);
5033       bufEnd = nextEnd = &buf[n+1];
5034     }
5035   }
5036   bufPtr = buf;
5037   return gTrue;
5038 }
5039 
5040 //------------------------------------------------------------------------
5041 // LZWEncoder
5042 //------------------------------------------------------------------------
5043 
LZWEncoder(Stream * strA)5044 LZWEncoder::LZWEncoder(Stream *strA):
5045   FilterStream(strA)
5046 {
5047   inBufLen = 0;
5048   outBufLen = 0;
5049 }
5050 
~LZWEncoder()5051 LZWEncoder::~LZWEncoder() {
5052   if (str->isEncoder()) {
5053     delete str;
5054   }
5055 }
5056 
reset()5057 void LZWEncoder::reset() {
5058   int i;
5059 
5060   str->reset();
5061 
5062   // initialize code table
5063   for (i = 0; i < 256; ++i) {
5064     table[i].byte = i;
5065     table[i].next = NULL;
5066     table[i].children = NULL;
5067   }
5068   nextSeq = 258;
5069   codeLen = 9;
5070 
5071   // initialize input buffer
5072   inBufLen = str->getBlock((char *)inBuf, sizeof(inBuf));
5073 
5074   // initialize output buffer with a clear-table code
5075   outBuf = 256;
5076   outBufLen = 9;
5077   needEOD = gFalse;
5078 }
5079 
getChar()5080 int LZWEncoder::getChar() {
5081   int ret;
5082 
5083   if (inBufLen == 0 && !needEOD && outBufLen == 0) {
5084     return EOF;
5085   }
5086   if (outBufLen < 8 && (inBufLen > 0 || needEOD)) {
5087     fillBuf();
5088   }
5089   if (outBufLen >= 8) {
5090     ret = (outBuf >> (outBufLen - 8)) & 0xff;
5091     outBufLen -= 8;
5092   } else {
5093     ret = (outBuf << (8 - outBufLen)) & 0xff;
5094     outBufLen = 0;
5095   }
5096   return ret;
5097 }
5098 
lookChar()5099 int LZWEncoder::lookChar() {
5100   if (inBufLen == 0 && !needEOD && outBufLen == 0) {
5101     return EOF;
5102   }
5103   if (outBufLen < 8 && (inBufLen > 0 || needEOD)) {
5104     fillBuf();
5105   }
5106   if (outBufLen >= 8) {
5107     return (outBuf >> (outBufLen - 8)) & 0xff;
5108   } else {
5109     return (outBuf << (8 - outBufLen)) & 0xff;
5110   }
5111 }
5112 
5113 // On input, outBufLen < 8.
5114 // This function generates, at most, 2 12-bit codes
5115 //   --> outBufLen < 8 + 12 + 12 = 32
fillBuf()5116 void LZWEncoder::fillBuf() {
5117   LZWEncoderNode *p0, *p1;
5118   int seqLen, code, i;
5119 
5120   if (needEOD) {
5121     outBuf = (outBuf << codeLen) | 257;
5122     outBufLen += codeLen;
5123     needEOD = gFalse;
5124     return;
5125   }
5126 
5127   // find longest matching sequence (if any)
5128   p0 = table + inBuf[0];
5129   seqLen = 1;
5130   while (inBufLen > seqLen) {
5131     for (p1 = p0->children; p1; p1 = p1->next) {
5132       if (p1->byte == inBuf[seqLen]) {
5133 	break;
5134       }
5135     }
5136     if (!p1) {
5137       break;
5138     }
5139     p0 = p1;
5140     ++seqLen;
5141   }
5142   code = (int)(p0 - table);
5143 
5144   // generate an output code
5145   outBuf = (outBuf << codeLen) | code;
5146   outBufLen += codeLen;
5147 
5148   // update the table
5149   table[nextSeq].byte = seqLen < inBufLen ? inBuf[seqLen] : 0;
5150   table[nextSeq].children = NULL;
5151   if (table[code].children) {
5152     table[nextSeq].next = table[code].children;
5153   } else {
5154     table[nextSeq].next = NULL;
5155   }
5156   table[code].children = table + nextSeq;
5157   ++nextSeq;
5158 
5159   // update the input buffer
5160   memmove(inBuf, inBuf + seqLen, inBufLen - seqLen);
5161   inBufLen -= seqLen;
5162   inBufLen += str->getBlock((char *)inBuf + inBufLen,
5163 			    sizeof(inBuf) - inBufLen);
5164 
5165   // increment codeLen; generate clear-table code
5166   if (nextSeq == (1 << codeLen)) {
5167     ++codeLen;
5168     if (codeLen == 13) {
5169       outBuf = (outBuf << 12) | 256;
5170       outBufLen += 12;
5171       for (i = 0; i < 256; ++i) {
5172 	table[i].next = NULL;
5173 	table[i].children = NULL;
5174       }
5175       nextSeq = 258;
5176       codeLen = 9;
5177     }
5178   }
5179 
5180   // generate EOD next time
5181   if (inBufLen == 0) {
5182     needEOD = gTrue;
5183   }
5184 }
5185