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