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