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