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", ¶ms, recursion);
142 if (params.isNull()) {
143 params.free();
144 dict->dictLookup("DP", ¶ms, recursion);
145 }
146 if (obj.isName()) {
147 str = makeFilter(obj.getName(), str, ¶ms, 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, ¶ms2, recursion);
153 else
154 params2.initNull();
155 if (obj2.isName()) {
156 str = makeFilter(obj2.getName(), str, ¶ms2, 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