]> git.ipfire.org Git - thirdparty/cups.git/blob - pdftops/Stream.cxx
Get rid of compiler warnings.
[thirdparty/cups.git] / pdftops / Stream.cxx
1 //========================================================================
2 //
3 // Stream.cc
4 //
5 // Copyright 1996 Derek B. Noonburg
6 //
7 //========================================================================
8
9 #ifdef __GNUC__
10 #pragma implementation
11 #endif
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <stddef.h>
16 #ifndef WIN32
17 #include <unistd.h>
18 #endif
19 #include <string.h>
20 #include <ctype.h>
21 #include "gmem.h"
22 #include "gfile.h"
23 #include "config.h"
24 #include "Error.h"
25 #include "Object.h"
26 #ifndef NO_DECRYPTION
27 #include "Decrypt.h"
28 #endif
29 #include "Stream.h"
30 #include "Stream-CCITT.h"
31
32 #ifdef __DJGPP__
33 static GBool setDJSYSFLAGS = gFalse;
34 #endif
35
36 #ifdef VMS
37 #if (__VMS_VER < 70000000)
38 extern "C" int unlink(char *filename);
39 #endif
40 #ifdef __GNUC__
41 #define SEEK_SET 0
42 #define SEEK_CUR 1
43 #define SEEK_END 2
44 #endif
45 #endif
46
47 #ifdef MACOS
48 #include "StuffItEngineLib.h"
49 #endif
50
51 //------------------------------------------------------------------------
52 // Stream (base class)
53 //------------------------------------------------------------------------
54
55 Stream::Stream() {
56 ref = 1;
57 }
58
59 Stream::~Stream() {
60 }
61
62 int Stream::getRawChar() {
63 error(-1, "Internal: called getRawChar() on non-predictor stream");
64 return EOF;
65 }
66
67 char *Stream::getLine(char *buf, int size) {
68 int i;
69 int c;
70
71 if (lookChar() == EOF)
72 return NULL;
73 for (i = 0; i < size - 1; ++i) {
74 c = getChar();
75 if (c == EOF || c == '\n')
76 break;
77 if (c == '\r') {
78 if ((c = lookChar()) == '\n')
79 getChar();
80 break;
81 }
82 buf[i] = c;
83 }
84 buf[i] = '\0';
85 return buf;
86 }
87
88 GString *Stream::getPSFilter(const char *indent) {
89 (void)indent;
90
91 return new GString();
92 }
93
94 Stream *Stream::addFilters(Object *dict) {
95 Object obj, obj2;
96 Object params, params2;
97 Stream *str;
98 int i;
99
100 str = this;
101 dict->dictLookup("Filter", &obj);
102 if (obj.isNull()) {
103 obj.free();
104 dict->dictLookup("F", &obj);
105 }
106 dict->dictLookup("DecodeParms", &params);
107 if (params.isNull()) {
108 params.free();
109 dict->dictLookup("DP", &params);
110 }
111 if (obj.isName()) {
112 str = makeFilter(obj.getName(), str, &params);
113 } else if (obj.isArray()) {
114 for (i = 0; i < obj.arrayGetLength(); ++i) {
115 obj.arrayGet(i, &obj2);
116 if (params.isArray())
117 params.arrayGet(i, &params2);
118 else
119 params2.initNull();
120 if (obj2.isName()) {
121 str = makeFilter(obj2.getName(), str, &params2);
122 } else {
123 error(getPos(), "Bad filter name");
124 str = new EOFStream(str);
125 }
126 obj2.free();
127 params2.free();
128 }
129 } else if (!obj.isNull()) {
130 error(getPos(), "Bad 'Filter' attribute in stream");
131 }
132 obj.free();
133 params.free();
134
135 return str;
136 }
137
138 Stream *Stream::makeFilter(const char *name, Stream *str, Object *params) {
139 int pred; // parameters
140 int colors;
141 int bits;
142 int early;
143 int encoding;
144 GBool endOfLine, byteAlign, endOfBlock, black;
145 int columns, rows;
146 Object obj;
147
148 if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) {
149 str = new ASCIIHexStream(str);
150 } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) {
151 str = new ASCII85Stream(str);
152 } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) {
153 pred = 1;
154 columns = 1;
155 colors = 1;
156 bits = 8;
157 early = 1;
158 if (params->isDict()) {
159 params->dictLookup("Predictor", &obj);
160 if (obj.isInt())
161 pred = obj.getInt();
162 obj.free();
163 params->dictLookup("Columns", &obj);
164 if (obj.isInt())
165 columns = obj.getInt();
166 obj.free();
167 params->dictLookup("Colors", &obj);
168 if (obj.isInt())
169 colors = obj.getInt();
170 obj.free();
171 params->dictLookup("BitsPerComponent", &obj);
172 if (obj.isInt())
173 bits = obj.getInt();
174 obj.free();
175 params->dictLookup("EarlyChange", &obj);
176 if (obj.isInt())
177 early = obj.getInt();
178 obj.free();
179 }
180 str = new LZWStream(str, pred, columns, colors, bits, early);
181 } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) {
182 str = new RunLengthStream(str);
183 } else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) {
184 encoding = 0;
185 endOfLine = gFalse;
186 byteAlign = gFalse;
187 columns = 1728;
188 rows = 0;
189 endOfBlock = gTrue;
190 black = gFalse;
191 if (params->isDict()) {
192 params->dictLookup("K", &obj);
193 if (obj.isInt()) {
194 encoding = obj.getInt();
195 }
196 obj.free();
197 params->dictLookup("EndOfLine", &obj);
198 if (obj.isBool()) {
199 endOfLine = obj.getBool();
200 }
201 obj.free();
202 params->dictLookup("EncodedByteAlign", &obj);
203 if (obj.isBool()) {
204 byteAlign = obj.getBool();
205 }
206 obj.free();
207 params->dictLookup("Columns", &obj);
208 if (obj.isInt()) {
209 columns = obj.getInt();
210 }
211 obj.free();
212 params->dictLookup("Rows", &obj);
213 if (obj.isInt()) {
214 rows = obj.getInt();
215 }
216 obj.free();
217 params->dictLookup("EndOfBlock", &obj);
218 if (obj.isBool()) {
219 endOfBlock = obj.getBool();
220 }
221 obj.free();
222 params->dictLookup("BlackIs1", &obj);
223 if (obj.isBool()) {
224 black = obj.getBool();
225 }
226 obj.free();
227 }
228 str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign,
229 columns, rows, endOfBlock, black);
230 } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) {
231 str = new DCTStream(str);
232 } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) {
233 pred = 1;
234 columns = 1;
235 colors = 1;
236 bits = 8;
237 if (params->isDict()) {
238 params->dictLookup("Predictor", &obj);
239 if (obj.isInt())
240 pred = obj.getInt();
241 obj.free();
242 params->dictLookup("Columns", &obj);
243 if (obj.isInt())
244 columns = obj.getInt();
245 obj.free();
246 params->dictLookup("Colors", &obj);
247 if (obj.isInt())
248 colors = obj.getInt();
249 obj.free();
250 params->dictLookup("BitsPerComponent", &obj);
251 if (obj.isInt())
252 bits = obj.getInt();
253 obj.free();
254 }
255 str = new FlateStream(str, pred, columns, colors, bits);
256 } else {
257 error(getPos(), "Unknown filter '%s'", name);
258 str = new EOFStream(str);
259 }
260 return str;
261 }
262
263 //------------------------------------------------------------------------
264 // BaseStream
265 //------------------------------------------------------------------------
266
267 BaseStream::BaseStream(Object *ndict) {
268 dict = *ndict;
269 #ifndef NO_DECRYPTION
270 decrypt = NULL;
271 #endif
272 }
273
274 BaseStream::~BaseStream() {
275 dict.free();
276 #ifndef NO_DECRYPTION
277 if (decrypt)
278 delete decrypt;
279 #endif
280 }
281
282 #ifndef NO_DECRYPTION
283 void BaseStream::doDecryption(Guchar *fileKey, int objNum, int objGen) {
284 decrypt = new Decrypt(fileKey, objNum, objGen);
285 }
286 #endif
287
288 //------------------------------------------------------------------------
289 // FilterStream
290 //------------------------------------------------------------------------
291
292 FilterStream::FilterStream(Stream *nstr) {
293 str = nstr;
294 }
295
296 FilterStream::~FilterStream() {
297 }
298
299 void FilterStream::setPos(int pos) {
300 (void)pos;
301
302 error(-1, "Internal: called setPos() on FilterStream");
303 }
304
305 //------------------------------------------------------------------------
306 // ImageStream
307 //------------------------------------------------------------------------
308
309 ImageStream::ImageStream(Stream *nstr, int nwidth, int nnComps, int nnBits) {
310 int imgLineSize;
311
312 str = nstr;
313 width = nwidth;
314 nComps = nnComps;
315 nBits = nnBits;
316
317 nVals = width * nComps;
318 if (nBits == 1) {
319 imgLineSize = (nVals + 7) & ~7;
320 } else {
321 imgLineSize = nVals;
322 }
323 imgLine = (Guchar *)gmalloc(imgLineSize * sizeof(Guchar));
324 imgIdx = nVals;
325 }
326
327 ImageStream::~ImageStream() {
328 gfree(imgLine);
329 }
330
331 void ImageStream::reset() {
332 str->reset();
333 }
334
335 GBool ImageStream::getPixel(Guchar *pix) {
336 Gulong buf, bitMask;
337 int bits;
338 int c;
339 int i;
340
341 if (imgIdx >= nVals) {
342
343 // read one line of image pixels
344 if (nBits == 1) {
345 for (i = 0; i < nVals; i += 8) {
346 c = str->getChar();
347 imgLine[i+0] = (Guchar)((c >> 7) & 1);
348 imgLine[i+1] = (Guchar)((c >> 6) & 1);
349 imgLine[i+2] = (Guchar)((c >> 5) & 1);
350 imgLine[i+3] = (Guchar)((c >> 4) & 1);
351 imgLine[i+4] = (Guchar)((c >> 3) & 1);
352 imgLine[i+5] = (Guchar)((c >> 2) & 1);
353 imgLine[i+6] = (Guchar)((c >> 1) & 1);
354 imgLine[i+7] = (Guchar)(c & 1);
355 }
356 } else if (nBits == 8) {
357 for (i = 0; i < nVals; ++i) {
358 imgLine[i] = str->getChar();
359 }
360 } else {
361 bitMask = (1 << nBits) - 1;
362 buf = 0;
363 bits = 0;
364 for (i = 0; i < nVals; ++i) {
365 if (bits < nBits) {
366 buf = (buf << 8) | (str->getChar() & 0xff);
367 bits += 8;
368 }
369 imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask);
370 bits -= nBits;
371 }
372 }
373
374 // reset to start of line
375 imgIdx = 0;
376 }
377
378 for (i = 0; i < nComps; ++i)
379 pix[i] = imgLine[imgIdx++];
380 return gTrue;
381 }
382
383 void ImageStream::skipLine() {
384 int n, i;
385
386 n = (nVals * nBits + 7) >> 3;
387 for (i = 0; i < n; ++i) {
388 str->getChar();
389 }
390 }
391
392 //------------------------------------------------------------------------
393 // StreamPredictor
394 //------------------------------------------------------------------------
395
396 StreamPredictor::StreamPredictor(Stream *nstr, int npredictor,
397 int nwidth, int nnComps, int nnBits) {
398 str = nstr;
399 predictor = npredictor;
400 width = nwidth;
401 nComps = nnComps;
402 nBits = nnBits;
403
404 nVals = width * nComps;
405 pixBytes = (nComps * nBits + 7) >> 3;
406 rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes;
407 predLine = (Guchar *)gmalloc(rowBytes);
408 memset(predLine, 0, rowBytes);
409 predIdx = rowBytes;
410 }
411
412 StreamPredictor::~StreamPredictor() {
413 gfree(predLine);
414 }
415
416 int StreamPredictor::lookChar() {
417 if (predIdx >= rowBytes) {
418 if (!getNextLine()) {
419 return EOF;
420 }
421 }
422 return predLine[predIdx];
423 }
424
425 int StreamPredictor::getChar() {
426 if (predIdx >= rowBytes) {
427 if (!getNextLine()) {
428 return EOF;
429 }
430 }
431 return predLine[predIdx++];
432 }
433
434 GBool StreamPredictor::getNextLine() {
435 int curPred;
436 Guchar upLeftBuf[4];
437 int left, up, upLeft, p, pa, pb, pc;
438 int c;
439 Gulong inBuf, outBuf, bitMask;
440 int inBits, outBits;
441 int i, j, k;
442
443 // get PNG optimum predictor number
444 if (predictor == 15) {
445 if ((curPred = str->getRawChar()) == EOF) {
446 return gFalse;
447 }
448 curPred += 10;
449 } else {
450 curPred = predictor;
451 }
452
453 // read the raw line, apply PNG (byte) predictor
454 upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0;
455 for (i = pixBytes; i < rowBytes; ++i) {
456 upLeftBuf[3] = upLeftBuf[2];
457 upLeftBuf[2] = upLeftBuf[1];
458 upLeftBuf[1] = upLeftBuf[0];
459 upLeftBuf[0] = predLine[i];
460 if ((c = str->getRawChar()) == EOF) {
461 break;
462 }
463 switch (curPred) {
464 case 11: // PNG sub
465 predLine[i] = predLine[i - pixBytes] + (Guchar)c;
466 break;
467 case 12: // PNG up
468 predLine[i] = predLine[i] + (Guchar)c;
469 break;
470 case 13: // PNG average
471 predLine[i] = ((predLine[i - pixBytes] + predLine[i]) >> 1) +
472 (Guchar)c;
473 break;
474 case 14: // PNG Paeth
475 left = predLine[i - pixBytes];
476 up = predLine[i];
477 upLeft = upLeftBuf[pixBytes];
478 p = left + up - upLeft;
479 if ((pa = p - left) < 0)
480 pa = -pa;
481 if ((pb = p - up) < 0)
482 pb = -pb;
483 if ((pc = p - upLeft) < 0)
484 pc = -pc;
485 if (pa <= pb && pa <= pc)
486 predLine[i] = pa + (Guchar)c;
487 else if (pb <= pc)
488 predLine[i] = pb + (Guchar)c;
489 else
490 predLine[i] = pc + (Guchar)c;
491 break;
492 case 10: // PNG none
493 default: // no predictor or TIFF predictor
494 predLine[i] = (Guchar)c;
495 break;
496 }
497 }
498
499 // apply TIFF (component) predictor
500 //~ this is completely untested
501 if (predictor == 2) {
502 if (nBits == 1) {
503 inBuf = predLine[pixBytes - 1];
504 for (i = pixBytes; i < rowBytes; i += 8) {
505 // 1-bit add is just xor
506 inBuf = (inBuf << 8) | predLine[i];
507 predLine[i] ^= inBuf >> nComps;
508 }
509 } else if (nBits == 8) {
510 for (i = pixBytes; i < rowBytes; ++i) {
511 predLine[i] += predLine[i - nComps];
512 }
513 } else {
514 upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0;
515 bitMask = (1 << nBits) - 1;
516 inBuf = outBuf = 0;
517 inBits = outBits = 0;
518 j = k = pixBytes;
519 for (i = 0; i < nVals; ++i) {
520 if (inBits < nBits) {
521 inBuf = (inBuf << 8) | (predLine[j++] & 0xff);
522 inBits += 8;
523 }
524 upLeftBuf[3] = upLeftBuf[2];
525 upLeftBuf[2] = upLeftBuf[1];
526 upLeftBuf[1] = upLeftBuf[0];
527 upLeftBuf[0] = (upLeftBuf[nComps] +
528 (inBuf >> (inBits - nBits))) & bitMask;
529 outBuf = (outBuf << nBits) | upLeftBuf[0];
530 inBits -= nBits;
531 outBits += nBits;
532 if (outBits > 8) {
533 predLine[k++] = (Guchar)(outBuf >> (outBits - 8));
534 }
535 }
536 if (outBits > 0) {
537 predLine[k++] = (Guchar)(outBuf << (8 - outBits));
538 }
539 }
540 }
541
542 // reset to start of line
543 predIdx = pixBytes;
544
545 return gTrue;
546 }
547
548 //------------------------------------------------------------------------
549 // FileStream
550 //------------------------------------------------------------------------
551
552 FileStream::FileStream(FILE *nf, int nstart, int nlength, Object *dict):
553 BaseStream(dict) {
554 f = nf;
555 start = nstart;
556 length = nlength;
557 bufPtr = bufEnd = buf;
558 bufPos = start;
559 savePos = -1;
560 }
561
562 FileStream::~FileStream() {
563 if (savePos >= 0) {
564 fseek(f, savePos, SEEK_SET);
565 }
566 }
567
568 Stream *FileStream::makeSubStream(int nstart, int nlength, Object *ndict) {
569 return new FileStream(f, nstart, nlength, ndict);
570 }
571
572 void FileStream::reset() {
573 savePos = (int)ftell(f);
574 fseek(f, start, SEEK_SET);
575 bufPtr = bufEnd = buf;
576 bufPos = start;
577 #ifndef NO_DECRYPTION
578 if (decrypt)
579 decrypt->reset();
580 #endif
581 }
582
583 GBool FileStream::fillBuf() {
584 int n;
585 #ifndef NO_DECRYPTION
586 char *p;
587 #endif
588
589 bufPos += bufEnd - buf;
590 bufPtr = bufEnd = buf;
591 if (length >= 0 && bufPos >= start + length)
592 return gFalse;
593 if (length >= 0 && bufPos + 256 > start + length)
594 n = start + length - bufPos;
595 else
596 n = 256;
597 n = fread(buf, 1, n, f);
598 bufEnd = buf + n;
599 if (bufPtr >= bufEnd)
600 return gFalse;
601 #ifndef NO_DECRYPTION
602 if (decrypt) {
603 for (p = buf; p < bufEnd; ++p)
604 *p = (char)decrypt->decryptByte((Guchar)*p);
605 }
606 #endif
607 return gTrue;
608 }
609
610 void FileStream::setPos(int pos1) {
611 long size;
612
613 if (pos1 >= 0) {
614 fseek(f, pos1, SEEK_SET);
615 bufPos = pos1;
616 } else {
617 fseek(f, 0, SEEK_END);
618 size = ftell(f);
619 if (pos1 < -size)
620 pos1 = (int)(-size);
621 fseek(f, pos1, SEEK_END);
622 bufPos = (int)ftell(f);
623 }
624 bufPtr = bufEnd = buf;
625 }
626
627 void FileStream::moveStart(int delta) {
628 this->start += delta;
629 bufPtr = bufEnd = buf;
630 bufPos = start;
631 }
632
633 //------------------------------------------------------------------------
634 // EmbedStream
635 //------------------------------------------------------------------------
636
637 EmbedStream::EmbedStream(Stream *nstr, Object *ndict):
638 BaseStream(ndict) {
639 str = nstr;
640 }
641
642 EmbedStream::~EmbedStream() {
643 }
644
645 Stream *EmbedStream::makeSubStream(int start, int length, Object *ndict) {
646 (void)start;
647 (void)length;
648 (void)ndict;
649
650 error(-1, "Internal: called makeSubStream() on EmbedStream");
651 return NULL;
652 }
653
654 void EmbedStream::setPos(int pos) {
655 (void)pos;
656
657 error(-1, "Internal: called setPos() on EmbedStream");
658 }
659
660 int EmbedStream::getStart() {
661 error(-1, "Internal: called getStart() on EmbedStream");
662 return 0;
663 }
664
665 void EmbedStream::moveStart(int start) {
666 (void)start;
667
668 error(-1, "Internal: called moveStart() on EmbedStream");
669 }
670
671 //------------------------------------------------------------------------
672 // ASCIIHexStream
673 //------------------------------------------------------------------------
674
675 ASCIIHexStream::ASCIIHexStream(Stream *str):
676 FilterStream(str) {
677 buf = EOF;
678 eof = gFalse;
679 }
680
681 ASCIIHexStream::~ASCIIHexStream() {
682 delete str;
683 }
684
685 void ASCIIHexStream::reset() {
686 str->reset();
687 buf = EOF;
688 eof = gFalse;
689 }
690
691 int ASCIIHexStream::lookChar() {
692 int c1, c2, x;
693
694 if (buf != EOF)
695 return buf;
696 if (eof) {
697 buf = EOF;
698 return EOF;
699 }
700 do {
701 c1 = str->getChar();
702 } while (isspace(c1));
703 if (c1 == '>') {
704 eof = gTrue;
705 buf = EOF;
706 return buf;
707 }
708 do {
709 c2 = str->getChar();
710 } while (isspace(c2));
711 if (c2 == '>') {
712 eof = gTrue;
713 c2 = '0';
714 }
715 if (c1 >= '0' && c1 <= '9') {
716 x = (c1 - '0') << 4;
717 } else if (c1 >= 'A' && c1 <= 'F') {
718 x = (c1 - 'A' + 10) << 4;
719 } else if (c1 >= 'a' && c1 <= 'f') {
720 x = (c1 - 'a' + 10) << 4;
721 } else if (c1 == EOF) {
722 eof = gTrue;
723 x = 0;
724 } else {
725 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c1);
726 x = 0;
727 }
728 if (c2 >= '0' && c2 <= '9') {
729 x += c2 - '0';
730 } else if (c2 >= 'A' && c2 <= 'F') {
731 x += c2 - 'A' + 10;
732 } else if (c2 >= 'a' && c2 <= 'f') {
733 x += c2 - 'a' + 10;
734 } else if (c2 == EOF) {
735 eof = gTrue;
736 x = 0;
737 } else {
738 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c2);
739 }
740 buf = x & 0xff;
741 return buf;
742 }
743
744 GString *ASCIIHexStream::getPSFilter(const char *indent) {
745 GString *s;
746
747 s = str->getPSFilter(indent);
748 s->append(indent)->append("/ASCIIHexDecode filter\n");
749 return s;
750 }
751
752 GBool ASCIIHexStream::isBinary(GBool last) {
753 (void)last;
754
755 return str->isBinary(gFalse);
756 }
757
758 //------------------------------------------------------------------------
759 // ASCII85Stream
760 //------------------------------------------------------------------------
761
762 ASCII85Stream::ASCII85Stream(Stream *str):
763 FilterStream(str) {
764 index = n = 0;
765 eof = gFalse;
766 }
767
768 ASCII85Stream::~ASCII85Stream() {
769 delete str;
770 }
771
772 void ASCII85Stream::reset() {
773 str->reset();
774 index = n = 0;
775 eof = gFalse;
776 }
777
778 int ASCII85Stream::lookChar() {
779 int k;
780 Gulong t;
781
782 if (index >= n) {
783 if (eof)
784 return EOF;
785 index = 0;
786 do {
787 c[0] = str->getChar();
788 } while (c[0] == '\n' || c[0] == '\r');
789 if (c[0] == '~' || c[0] == EOF) {
790 eof = gTrue;
791 n = 0;
792 return EOF;
793 } else if (c[0] == 'z') {
794 b[0] = b[1] = b[2] = b[3] = 0;
795 n = 4;
796 } else {
797 for (k = 1; k < 5; ++k) {
798 do {
799 c[k] = str->getChar();
800 } while (c[k] == '\n' || c[k] == '\r');
801 if (c[k] == '~' || c[k] == EOF)
802 break;
803 }
804 n = k - 1;
805 if (k < 5 && (c[k] == '~' || c[k] == EOF)) {
806 for (++k; k < 5; ++k)
807 c[k] = 0x21 + 84;
808 eof = gTrue;
809 }
810 t = 0;
811 for (k = 0; k < 5; ++k)
812 t = t * 85 + (c[k] - 0x21);
813 for (k = 3; k >= 0; --k) {
814 b[k] = (int)(t & 0xff);
815 t >>= 8;
816 }
817 }
818 }
819 return b[index];
820 }
821
822 GString *ASCII85Stream::getPSFilter(const char *indent) {
823 GString *s;
824
825 s = str->getPSFilter(indent);
826 s->append(indent)->append("/ASCII85Decode filter\n");
827 return s;
828 }
829
830 GBool ASCII85Stream::isBinary(GBool last) {
831 (void)last;
832
833 return str->isBinary(gFalse);
834 }
835
836 //------------------------------------------------------------------------
837 // LZWStream
838 //------------------------------------------------------------------------
839
840 LZWStream::LZWStream(Stream *str, int predictor1, int columns1, int colors1,
841 int bits1, int early1):
842 FilterStream(str) {
843 if (predictor1 != 1) {
844 pred = new StreamPredictor(this, predictor1, columns1, colors1, bits1);
845 } else {
846 pred = NULL;
847 }
848 early = early1;
849 zPipe = NULL;
850 bufPtr = bufEnd = buf;
851 }
852
853 LZWStream::~LZWStream() {
854 if (zPipe) {
855 #ifdef HAVE_POPEN
856 pclose(zPipe);
857 #else
858 fclose(zPipe);
859 #endif
860 zPipe = NULL;
861 unlink(zName->getCString());
862 delete zName;
863 }
864 if (pred) {
865 delete pred;
866 }
867 delete str;
868 }
869
870 int LZWStream::getChar() {
871 if (pred) {
872 return pred->getChar();
873 }
874 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
875 }
876
877 int LZWStream::lookChar() {
878 if (pred) {
879 return pred->lookChar();
880 }
881 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff);
882 }
883
884 int LZWStream::getRawChar() {
885 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
886 }
887
888 void LZWStream::reset() {
889 FILE *f;
890 GString *zCmd;
891
892 //----- close old LZW stream
893 if (zPipe) {
894 #ifdef HAVE_POPEN
895 pclose(zPipe);
896 #else
897 fclose(zPipe);
898 #endif
899 zPipe = NULL;
900 unlink(zName->getCString());
901 delete zName;
902 }
903
904 //----- tell Delorie runtime to spawn a new instance of COMMAND.COM
905 // to run gzip
906 #if __DJGPP__
907 if (!setDJSYSFLAGS) {
908 setenv("DJSYSFLAGS", "0x0002", 0);
909 setDJSYSFLAGS = gTrue;
910 }
911 #endif
912
913 //----- create the .Z file
914 if (!openTempFile(&zName, &f, "wb", ".Z")) {
915 error(getPos(), "Couldn't create temporary file for LZW stream");
916 return;
917 }
918 dumpFile(f);
919 fclose(f);
920
921 //----- execute uncompress / gzip
922 zCmd = new GString(uncompressCmd);
923 zCmd->append(' ');
924 zCmd->append(zName);
925 #if defined(MACOS)
926 long magicCookie;
927 // first we open the engine up
928 OSErr err = OpenSITEngine(kUseExternalEngine, &magicCookie);
929 // if we found it - let's use it!
930 if (!err && magicCookie) {
931 // make sure we have the correct version of the Engine
932 if (GetSITEngineVersion(magicCookie) >= kFirstSupportedEngine) {
933 FSSpec myFSS;
934 Str255 pName;
935 strcpy((char *)pName, zName->getCString());
936 c2pstr((char *)pName);
937 FSMakeFSSpec(0, 0, pName, &myFSS);
938 short ftype = DetermineFileType(magicCookie, &myFSS);
939 OSErr expandErr = ExpandFSSpec(magicCookie, ftype, &myFSS,
940 NULL, NULL, kCreateFolderNever,
941 kDeleteOriginal, kTextConvertSmart);
942 }
943 }
944 #elif defined(HAVE_POPEN)
945 if (!(zPipe = popen(zCmd->getCString(), POPEN_READ_MODE))) {
946 error(getPos(), "Couldn't popen '%s'", zCmd->getCString());
947 unlink(zName->getCString());
948 delete zName;
949 return;
950 }
951 #else // HAVE_POPEN
952 #ifdef VMS
953 if (!system(zCmd->getCString())) {
954 #else
955 if (system(zCmd->getCString())) {
956 #endif
957 error(getPos(), "Couldn't execute '%s'", zCmd->getCString());
958 unlink(zName->getCString());
959 delete zName;
960 return;
961 }
962 zName->del(zName->getLength() - 2, 2);
963 if (!(zPipe = fopen(zName->getCString(), "rb"))) {
964 error(getPos(), "Couldn't open uncompress file '%s'", zName->getCString());
965 unlink(zName->getCString());
966 delete zName;
967 return;
968 }
969 #endif // HAVE_POPEN
970
971 //----- clean up
972 delete zCmd;
973
974 //----- initialize buffer
975 bufPtr = bufEnd = buf;
976 }
977
978 void LZWStream::dumpFile(FILE *f) {
979 int outCodeBits; // size of output code
980 int outBits; // max output code
981 int outBuf[8]; // output buffer
982 int outData; // temporary output buffer
983 int inCode, outCode; // input and output codes
984 int nextCode; // next code index
985 GBool eof; // set when EOF is reached
986 GBool clear; // set if table needs to be cleared
987 GBool first; // indicates first code word after clear
988 int i, j;
989
990 str->reset();
991
992 // magic number
993 fputc(0x1f, f);
994 fputc(0x9d, f);
995
996 // max code length, block mode flag
997 fputc(0x8c, f);
998
999 // init input side
1000 inCodeBits = 9;
1001 inputBuf = 0;
1002 inputBits = 0;
1003 eof = gFalse;
1004
1005 // init output side
1006 outCodeBits = 9;
1007
1008 // clear table
1009 first = gTrue;
1010 nextCode = 258;
1011
1012 clear = gFalse;
1013 do {
1014 for (i = 0; i < 8; ++i) {
1015 // check for table overflow
1016 if (nextCode + early > 0x1001) {
1017 inCode = 256;
1018
1019 // read input code
1020 } else {
1021 do {
1022 inCode = getCode();
1023 if (inCode == EOF) {
1024 eof = gTrue;
1025 inCode = 0;
1026 }
1027 } while (first && inCode == 256);
1028 }
1029
1030 // compute output code
1031 if (inCode < 256) {
1032 outCode = inCode;
1033 } else if (inCode == 256) {
1034 outCode = 256;
1035 clear = gTrue;
1036 } else if (inCode == 257) {
1037 outCode = 0;
1038 eof = gTrue;
1039 } else {
1040 outCode = inCode - 1;
1041 }
1042 outBuf[i] = outCode;
1043
1044 // next code index
1045 if (first)
1046 first = gFalse;
1047 else
1048 ++nextCode;
1049
1050 // check input code size
1051 if (nextCode + early == 0x200)
1052 inCodeBits = 10;
1053 else if (nextCode + early == 0x400) {
1054 inCodeBits = 11;
1055 } else if (nextCode + early == 0x800) {
1056 inCodeBits = 12;
1057 }
1058
1059 // check for eof/clear
1060 if (eof)
1061 break;
1062 if (clear) {
1063 i = 8;
1064 break;
1065 }
1066 }
1067
1068 // write output block
1069 outData = 0;
1070 outBits = 0;
1071 j = 0;
1072 while (j < i || outBits > 0) {
1073 if (outBits < 8 && j < i) {
1074 outData = outData | (outBuf[j++] << outBits);
1075 outBits += outCodeBits;
1076 }
1077 fputc(outData & 0xff, f);
1078 outData >>= 8;
1079 outBits -= 8;
1080 }
1081
1082 // check output code size
1083 if (nextCode - 1 == 512 ||
1084 nextCode - 1 == 1024 ||
1085 nextCode - 1 == 2048 ||
1086 nextCode - 1 == 4096) {
1087 outCodeBits = inCodeBits;
1088 }
1089
1090 // clear table if necessary
1091 if (clear) {
1092 inCodeBits = 9;
1093 outCodeBits = 9;
1094 first = gTrue;
1095 nextCode = 258;
1096 clear = gFalse;
1097 }
1098 } while (!eof);
1099 }
1100
1101 int LZWStream::getCode() {
1102 int c;
1103 int code;
1104
1105 while (inputBits < inCodeBits) {
1106 if ((c = str->getChar()) == EOF)
1107 return EOF;
1108 inputBuf = (inputBuf << 8) | (c & 0xff);
1109 inputBits += 8;
1110 }
1111 code = (inputBuf >> (inputBits - inCodeBits)) & ((1 << inCodeBits) - 1);
1112 inputBits -= inCodeBits;
1113 return code;
1114 }
1115
1116 GBool LZWStream::fillBuf() {
1117 int n;
1118
1119 if (!zPipe)
1120 return gFalse;
1121 if ((n = fread(buf, 1, 256, zPipe)) < 256) {
1122 #ifdef HAVE_POPEN
1123 pclose(zPipe);
1124 #else
1125 fclose(zPipe);
1126 #endif
1127 zPipe = NULL;
1128 unlink(zName->getCString());
1129 delete zName;
1130 }
1131 bufPtr = buf;
1132 bufEnd = buf + n;
1133 return n > 0;
1134 }
1135
1136 GString *LZWStream::getPSFilter(const char *indent) {
1137 GString *s;
1138
1139 if (pred) {
1140 return NULL;
1141 }
1142 s = str->getPSFilter(indent);
1143 s->append(indent)->append("/LZWDecode filter\n");
1144 return s;
1145 }
1146
1147 GBool LZWStream::isBinary(GBool last) {
1148 (void)last;
1149
1150 return str->isBinary(gTrue);
1151 }
1152
1153 //------------------------------------------------------------------------
1154 // RunLengthStream
1155 //------------------------------------------------------------------------
1156
1157 RunLengthStream::RunLengthStream(Stream *str):
1158 FilterStream(str) {
1159 bufPtr = bufEnd = buf;
1160 eof = gFalse;
1161 }
1162
1163 RunLengthStream::~RunLengthStream() {
1164 delete str;
1165 }
1166
1167 void RunLengthStream::reset() {
1168 str->reset();
1169 bufPtr = bufEnd = buf;
1170 eof = gFalse;
1171 }
1172
1173 GString *RunLengthStream::getPSFilter(const char *indent) {
1174 GString *s;
1175
1176 s = str->getPSFilter(indent);
1177 s->append(indent)->append("/RunLengthDecode filter\n");
1178 return s;
1179 }
1180
1181 GBool RunLengthStream::isBinary(GBool last) {
1182 (void)last;
1183
1184 return str->isBinary(gTrue);
1185 }
1186
1187 GBool RunLengthStream::fillBuf() {
1188 int c;
1189 int n, i;
1190
1191 if (eof)
1192 return gFalse;
1193 c = str->getChar();
1194 if (c == 0x80 || c == EOF) {
1195 eof = gTrue;
1196 return gFalse;
1197 }
1198 if (c < 0x80) {
1199 n = c + 1;
1200 for (i = 0; i < n; ++i)
1201 buf[i] = (char)str->getChar();
1202 } else {
1203 n = 0x101 - c;
1204 c = str->getChar();
1205 for (i = 0; i < n; ++i)
1206 buf[i] = (char)c;
1207 }
1208 bufPtr = buf;
1209 bufEnd = buf + n;
1210 return gTrue;
1211 }
1212
1213 //------------------------------------------------------------------------
1214 // CCITTFaxStream
1215 //------------------------------------------------------------------------
1216
1217 CCITTFaxStream::CCITTFaxStream(Stream *str, int nencoding, GBool nendOfLine,
1218 GBool nbyteAlign, int ncolumns, int nrows,
1219 GBool nendOfBlock, GBool nblack):
1220 FilterStream(str) {
1221 encoding = nencoding;
1222 endOfLine = nendOfLine;
1223 byteAlign = nbyteAlign;
1224 columns = ncolumns;
1225 rows = nrows;
1226 endOfBlock = nendOfBlock;
1227 black = nblack;
1228 refLine = (short *)gmalloc((columns + 3) * sizeof(short));
1229 codingLine = (short *)gmalloc((columns + 2) * sizeof(short));
1230
1231 eof = gFalse;
1232 row = 0;
1233 nextLine2D = encoding < 0;
1234 inputBits = 0;
1235 codingLine[0] = 0;
1236 codingLine[1] = refLine[2] = columns;
1237 a0 = 1;
1238
1239 buf = EOF;
1240 }
1241
1242 CCITTFaxStream::~CCITTFaxStream() {
1243 delete str;
1244 gfree(refLine);
1245 gfree(codingLine);
1246 }
1247
1248 void CCITTFaxStream::reset() {
1249 int n;
1250
1251 str->reset();
1252 eof = gFalse;
1253 row = 0;
1254 nextLine2D = encoding < 0;
1255 inputBits = 0;
1256 codingLine[0] = 0;
1257 codingLine[1] = refLine[2] = columns;
1258 a0 = 1;
1259 buf = EOF;
1260
1261 // get initial end-of-line marker and 2D encoding tag
1262 if (endOfBlock) {
1263 if (lookBits(12) == 0x001) {
1264 eatBits(12);
1265 }
1266 } else {
1267 for (n = 0; n < 11 && lookBits(n) == 0; ++n) ;
1268 if (n == 11 && lookBits(12) == 0x001) {
1269 eatBits(12);
1270 }
1271 }
1272 if (encoding > 0) {
1273 nextLine2D = !lookBits(1);
1274 eatBits(1);
1275 }
1276 }
1277
1278 int CCITTFaxStream::lookChar() {
1279 short code1, code2, code3;
1280 int a0New;
1281 #if 0 //~
1282 GBool err;
1283 #endif
1284 int ret;
1285 int bits, i, n;
1286
1287 // if at eof just return EOF
1288 if (eof && codingLine[a0] >= columns) {
1289 return EOF;
1290 }
1291
1292 // read the next row
1293 #if 0 //~
1294 err = gFalse;
1295 #endif
1296 if (codingLine[a0] >= columns) {
1297
1298 // 2-D encoding
1299 if (nextLine2D) {
1300 for (i = 0; codingLine[i] < columns; ++i)
1301 refLine[i] = codingLine[i];
1302 refLine[i] = refLine[i + 1] = columns;
1303 b1 = 1;
1304 a0New = codingLine[a0 = 0] = 0;
1305 do {
1306 code1 = getTwoDimCode();
1307 switch (code1) {
1308 case twoDimPass:
1309 if (refLine[b1] < columns) {
1310 a0New = refLine[b1 + 1];
1311 b1 += 2;
1312 }
1313 break;
1314 case twoDimHoriz:
1315 if ((a0 & 1) == 0) {
1316 code1 = code2 = 0;
1317 do {
1318 code1 += code3 = getWhiteCode();
1319 } while (code3 >= 64);
1320 do {
1321 code2 += code3 = getBlackCode();
1322 } while (code3 >= 64);
1323 } else {
1324 code1 = code2 = 0;
1325 do {
1326 code1 += code3 = getBlackCode();
1327 } while (code3 >= 64);
1328 do {
1329 code2 += code3 = getWhiteCode();
1330 } while (code3 >= 64);
1331 }
1332 codingLine[a0 + 1] = a0New + code1;
1333 ++a0;
1334 a0New = codingLine[a0 + 1] = codingLine[a0] + code2;
1335 ++a0;
1336 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1337 b1 += 2;
1338 break;
1339 case twoDimVert0:
1340 a0New = codingLine[++a0] = refLine[b1];
1341 if (refLine[b1] < columns) {
1342 ++b1;
1343 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1344 b1 += 2;
1345 }
1346 break;
1347 case twoDimVertR1:
1348 a0New = codingLine[++a0] = refLine[b1] + 1;
1349 if (refLine[b1] < columns) {
1350 ++b1;
1351 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1352 b1 += 2;
1353 }
1354 break;
1355 case twoDimVertL1:
1356 a0New = codingLine[++a0] = refLine[b1] - 1;
1357 --b1;
1358 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1359 b1 += 2;
1360 break;
1361 case twoDimVertR2:
1362 a0New = codingLine[++a0] = refLine[b1] + 2;
1363 if (refLine[b1] < columns) {
1364 ++b1;
1365 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1366 b1 += 2;
1367 }
1368 break;
1369 case twoDimVertL2:
1370 a0New = codingLine[++a0] = refLine[b1] - 2;
1371 --b1;
1372 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1373 b1 += 2;
1374 break;
1375 case twoDimVertR3:
1376 a0New = codingLine[++a0] = refLine[b1] + 3;
1377 if (refLine[b1] < columns) {
1378 ++b1;
1379 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1380 b1 += 2;
1381 }
1382 break;
1383 case twoDimVertL3:
1384 a0New = codingLine[++a0] = refLine[b1] - 3;
1385 --b1;
1386 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1387 b1 += 2;
1388 break;
1389 case EOF:
1390 eof = gTrue;
1391 codingLine[a0 = 0] = columns;
1392 return EOF;
1393 default:
1394 error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1);
1395 #if 0 //~
1396 err = gTrue;
1397 break;
1398 #else
1399 eof = gTrue;
1400 return EOF;
1401 #endif
1402 }
1403 } while (codingLine[a0] < columns);
1404
1405 // 1-D encoding
1406 } else {
1407 codingLine[a0 = 0] = 0;
1408 while (1) {
1409 code1 = 0;
1410 do {
1411 code1 += code3 = getWhiteCode();
1412 } while (code3 >= 64);
1413 codingLine[a0+1] = codingLine[a0] + code1;
1414 ++a0;
1415 if (codingLine[a0] >= columns)
1416 break;
1417 code2 = 0;
1418 do {
1419 code2 += code3 = getBlackCode();
1420 } while (code3 >= 64);
1421 codingLine[a0+1] = codingLine[a0] + code2;
1422 ++a0;
1423 if (codingLine[a0] >= columns)
1424 break;
1425 }
1426 }
1427
1428 if (codingLine[a0] != columns) {
1429 error(getPos(), "CCITTFax row is wrong length (%d)", codingLine[a0]);
1430 #if 0 //~
1431 err = gTrue;
1432 #endif
1433 }
1434
1435 // byte-align the row
1436 if (byteAlign) {
1437 inputBits &= ~7;
1438 }
1439
1440 // check for end-of-line marker, end-of-block marker, and
1441 // 2D encoding tag
1442 if (endOfBlock) {
1443 code1 = lookBits(12);
1444 if (code1 == EOF) {
1445 eof = gTrue;
1446 } else if (code1 == 0x001) {
1447 eatBits(12);
1448 if (encoding > 0) {
1449 nextLine2D = !lookBits(1);
1450 eatBits(1);
1451 }
1452 code1 = lookBits(12);
1453 if (code1 == 0x001) {
1454 eatBits(12);
1455 if (encoding > 0) {
1456 lookBits(1);
1457 eatBits(1);
1458 }
1459 if (encoding >= 0) {
1460 for (i = 0; i < 4; ++i) {
1461 code1 = lookBits(12);
1462 if (code1 != 0x001) {
1463 error(getPos(), "Bad RTC code in CCITTFax stream");
1464 }
1465 eatBits(12);
1466 if (encoding > 0) {
1467 lookBits(1);
1468 eatBits(1);
1469 }
1470 }
1471 }
1472 eof = gTrue;
1473 }
1474 } else {
1475 if (encoding > 0) {
1476 nextLine2D = !lookBits(1);
1477 eatBits(1);
1478 }
1479 }
1480 } else {
1481 if (row == rows - 1) {
1482 eof = gTrue;
1483 } else {
1484 for (n = 0; n < 11 && lookBits(n) == 0; ++n) ;
1485 if (n == 11 && lookBits(12) == 0x001) {
1486 eatBits(12);
1487 }
1488 if (encoding > 0) {
1489 nextLine2D = !lookBits(1);
1490 eatBits(1);
1491 }
1492 }
1493 }
1494
1495 #if 0 //~
1496 // This looks for an end-of-line marker after an error, however
1497 // some (most?) CCITT streams in PDF files don't use end-of-line
1498 // markers, and the just-plow-on technique works better in those
1499 // cases.
1500 else if (err) {
1501 do {
1502 if (code1 == EOF) {
1503 eof = gTrue;
1504 return EOF;
1505 }
1506 eatBits(1);
1507 code1 = look13Bits();
1508 } while ((code1 >> 1) != 0x001);
1509 eatBits(12);
1510 codingLine[++a0] = columns;
1511 if (encoding > 0) {
1512 eatBits(1);
1513 nextLine2D = !(code1 & 1);
1514 }
1515 }
1516 #endif
1517
1518 a0 = 0;
1519 outputBits = codingLine[1] - codingLine[0];
1520 if (outputBits == 0) {
1521 a0 = 1;
1522 outputBits = codingLine[2] - codingLine[1];
1523 }
1524
1525 ++row;
1526 }
1527
1528 // get a byte
1529 if (outputBits >= 8) {
1530 ret = ((a0 & 1) == 0) ? 0xff : 0x00;
1531 if ((outputBits -= 8) == 0) {
1532 ++a0;
1533 if (codingLine[a0] < columns) {
1534 outputBits = codingLine[a0 + 1] - codingLine[a0];
1535 }
1536 }
1537 } else {
1538 bits = 8;
1539 ret = 0;
1540 do {
1541 if (outputBits > bits) {
1542 i = bits;
1543 bits = 0;
1544 if ((a0 & 1) == 0) {
1545 ret |= 0xff >> (8 - i);
1546 }
1547 outputBits -= i;
1548 } else {
1549 i = outputBits;
1550 bits -= outputBits;
1551 if ((a0 & 1) == 0) {
1552 ret |= (0xff >> (8 - i)) << bits;
1553 }
1554 outputBits = 0;
1555 ++a0;
1556 if (codingLine[a0] < columns) {
1557 outputBits = codingLine[a0 + 1] - codingLine[a0];
1558 }
1559 }
1560 } while (bits > 0 && codingLine[a0] < columns);
1561 }
1562 buf = black ? (ret ^ 0xff) : ret;
1563 return buf;
1564 }
1565
1566 short CCITTFaxStream::getTwoDimCode() {
1567 short code;
1568 CCITTCode *p;
1569 int n;
1570
1571 code = 0; // make gcc happy
1572 if (endOfBlock) {
1573 code = lookBits(7);
1574 p = &twoDimTab1[code];
1575 if (p->bits > 0) {
1576 eatBits(p->bits);
1577 return p->n;
1578 }
1579 } else {
1580 for (n = 1; n <= 7; ++n) {
1581 code = lookBits(n);
1582 if (n < 7) {
1583 code <<= 7 - n;
1584 }
1585 p = &twoDimTab1[code];
1586 if (p->bits == n) {
1587 eatBits(n);
1588 return p->n;
1589 }
1590 }
1591 }
1592 error(getPos(), "Bad two dim code (%04x) in CCITTFax stream", code);
1593 return EOF;
1594 }
1595
1596 short CCITTFaxStream::getWhiteCode() {
1597 short code;
1598 CCITTCode *p;
1599 int n;
1600
1601 code = 0; // make gcc happy
1602 if (endOfBlock) {
1603 code = lookBits(12);
1604 if ((code >> 5) == 0)
1605 p = &whiteTab1[code];
1606 else
1607 p = &whiteTab2[code >> 3];
1608 if (p->bits > 0) {
1609 eatBits(p->bits);
1610 return p->n;
1611 }
1612 } else {
1613 for (n = 1; n <= 9; ++n) {
1614 code = lookBits(n);
1615 if (n < 9) {
1616 code <<= 9 - n;
1617 }
1618 p = &whiteTab2[code];
1619 if (p->bits == n) {
1620 eatBits(n);
1621 return p->n;
1622 }
1623 }
1624 for (n = 11; n <= 12; ++n) {
1625 code = lookBits(n);
1626 if (n < 12) {
1627 code <<= 12 - n;
1628 }
1629 p = &whiteTab1[code];
1630 if (p->bits == n) {
1631 eatBits(n);
1632 return p->n;
1633 }
1634 }
1635 }
1636 error(getPos(), "Bad white code (%04x) in CCITTFax stream", code);
1637 return EOF;
1638 }
1639
1640 short CCITTFaxStream::getBlackCode() {
1641 short code;
1642 CCITTCode *p;
1643 int n;
1644
1645 code = 0; // make gcc happy
1646 if (endOfBlock) {
1647 code = lookBits(13);
1648 if ((code >> 7) == 0)
1649 p = &blackTab1[code];
1650 else if ((code >> 9) == 0)
1651 p = &blackTab2[(code >> 1) - 64];
1652 else
1653 p = &blackTab3[code >> 7];
1654 if (p->bits > 0) {
1655 eatBits(p->bits);
1656 return p->n;
1657 }
1658 } else {
1659 for (n = 2; n <= 6; ++n) {
1660 code = lookBits(n);
1661 if (n < 6) {
1662 code <<= 6 - n;
1663 }
1664 p = &blackTab3[code];
1665 if (p->bits == n) {
1666 eatBits(n);
1667 return p->n;
1668 }
1669 }
1670 for (n = 7; n <= 12; ++n) {
1671 code = lookBits(n);
1672 if (n < 12) {
1673 code <<= 12 - n;
1674 }
1675 if (code >= 64) {
1676 p = &blackTab2[code - 64];
1677 if (p->bits == n) {
1678 eatBits(n);
1679 return p->n;
1680 }
1681 }
1682 }
1683 for (n = 10; n <= 13; ++n) {
1684 code = lookBits(n);
1685 if (n < 13) {
1686 code <<= 13 - n;
1687 }
1688 p = &blackTab1[code];
1689 if (p->bits == n) {
1690 eatBits(n);
1691 return p->n;
1692 }
1693 }
1694 }
1695 error(getPos(), "Bad black code (%04x) in CCITTFax stream", code);
1696 return EOF;
1697 }
1698
1699 short CCITTFaxStream::lookBits(int n) {
1700 int c;
1701
1702 while (inputBits < n) {
1703 if ((c = str->getChar()) == EOF) {
1704 if (inputBits == 0)
1705 return EOF;
1706 c = 0;
1707 }
1708 inputBuf = (inputBuf << 8) + c;
1709 inputBits += 8;
1710 }
1711 return (inputBuf >> (inputBits - n)) & (0xffff >> (16 - n));
1712 }
1713
1714 GString *CCITTFaxStream::getPSFilter(const char *indent) {
1715 GString *s;
1716 char s1[50];
1717
1718 s = str->getPSFilter(indent);
1719 s->append(indent)->append("<< ");
1720 if (encoding != 0) {
1721 sprintf(s1, "/K %d ", encoding);
1722 s->append(s1);
1723 }
1724 if (endOfLine) {
1725 s->append("/EndOfLine true ");
1726 }
1727 if (byteAlign) {
1728 s->append("/EncodedByteAlign true ");
1729 }
1730 sprintf(s1, "/Columns %d ", columns);
1731 s->append(s1);
1732 if (rows != 0) {
1733 sprintf(s1, "/Rows %d ", rows);
1734 s->append(s1);
1735 }
1736 if (!endOfBlock) {
1737 s->append("/EndOfBlock false ");
1738 }
1739 if (black) {
1740 s->append("/BlackIs1 true ");
1741 }
1742 s->append(">> /CCITTFaxDecode filter\n");
1743 return s;
1744 }
1745
1746 GBool CCITTFaxStream::isBinary(GBool last) {
1747 (void)last;
1748
1749 return str->isBinary(gTrue);
1750 }
1751
1752 //------------------------------------------------------------------------
1753 // DCTStream
1754 //------------------------------------------------------------------------
1755
1756 // IDCT constants (20.12 fixed point format)
1757 #ifndef FP_IDCT
1758 #define dctCos1 4017 // cos(pi/16)
1759 #define dctSin1 799 // sin(pi/16)
1760 #define dctCos3 3406 // cos(3*pi/16)
1761 #define dctSin3 2276 // sin(3*pi/16)
1762 #define dctCos6 1567 // cos(6*pi/16)
1763 #define dctSin6 3784 // sin(6*pi/16)
1764 #define dctSqrt2 5793 // sqrt(2)
1765 #define dctSqrt1d2 2896 // sqrt(2) / 2
1766 #endif
1767
1768 // IDCT constants
1769 #ifdef FP_IDCT
1770 #define dctCos1 0.98078528 // cos(pi/16)
1771 #define dctSin1 0.19509032 // sin(pi/16)
1772 #define dctCos3 0.83146961 // cos(3*pi/16)
1773 #define dctSin3 0.55557023 // sin(3*pi/16)
1774 #define dctCos6 0.38268343 // cos(6*pi/16)
1775 #define dctSin6 0.92387953 // sin(6*pi/16)
1776 #define dctSqrt2 1.41421356 // sqrt(2)
1777 #define dctSqrt1d2 0.70710678 // sqrt(2) / 2
1778 #endif
1779
1780 // color conversion parameters (16.16 fixed point format)
1781 #define dctCrToR 91881 // 1.4020
1782 #define dctCbToG -22553 // -0.3441363
1783 #define dctCrToG -46802 // -0.71413636
1784 #define dctCbToB 116130 // 1.772
1785
1786 // clip [-256,511] --> [0,255]
1787 #define dctClipOffset 256
1788 static Guchar dctClip[768];
1789 static int dctClipInit = 0;
1790
1791 // zig zag decode map
1792 static int dctZigZag[64] = {
1793 0,
1794 1, 8,
1795 16, 9, 2,
1796 3, 10, 17, 24,
1797 32, 25, 18, 11, 4,
1798 5, 12, 19, 26, 33, 40,
1799 48, 41, 34, 27, 20, 13, 6,
1800 7, 14, 21, 28, 35, 42, 49, 56,
1801 57, 50, 43, 36, 29, 22, 15,
1802 23, 30, 37, 44, 51, 58,
1803 59, 52, 45, 38, 31,
1804 39, 46, 53, 60,
1805 61, 54, 47,
1806 55, 62,
1807 63
1808 };
1809
1810 DCTStream::DCTStream(Stream *str):
1811 FilterStream(str) {
1812 int i, j;
1813
1814 width = height = 0;
1815 mcuWidth = mcuHeight = 0;
1816 numComps = 0;
1817 comp = 0;
1818 x = y = dy = 0;
1819 for (i = 0; i < 4; ++i)
1820 for (j = 0; j < 32; ++j)
1821 rowBuf[i][j] = NULL;
1822
1823 if (!dctClipInit) {
1824 for (i = -256; i < 0; ++i)
1825 dctClip[dctClipOffset + i] = 0;
1826 for (i = 0; i < 256; ++i)
1827 dctClip[dctClipOffset + i] = i;
1828 for (i = 256; i < 512; ++i)
1829 dctClip[dctClipOffset + i] = 255;
1830 dctClipInit = 1;
1831 }
1832 }
1833
1834 DCTStream::~DCTStream() {
1835 int i, j;
1836
1837 delete str;
1838 for (i = 0; i < numComps; ++i)
1839 for (j = 0; j < mcuHeight; ++j)
1840 gfree(rowBuf[i][j]);
1841 }
1842
1843 void DCTStream::reset() {
1844 str->reset();
1845 if (!readHeader()) {
1846 y = height;
1847 return;
1848 }
1849 restartMarker = 0xd0;
1850 restart();
1851 }
1852
1853 int DCTStream::getChar() {
1854 int c;
1855
1856 c = lookChar();
1857 if (c == EOF)
1858 return EOF;
1859 if (++comp == numComps) {
1860 comp = 0;
1861 if (++x == width) {
1862 x = 0;
1863 ++y;
1864 ++dy;
1865 }
1866 }
1867 if (y == height)
1868 readTrailer();
1869 return c;
1870 }
1871
1872 int DCTStream::lookChar() {
1873 if (y >= height)
1874 return EOF;
1875 if (dy >= mcuHeight) {
1876 if (!readMCURow()) {
1877 y = height;
1878 return EOF;
1879 }
1880 comp = 0;
1881 x = 0;
1882 dy = 0;
1883 }
1884 return rowBuf[comp][dy][x];
1885 }
1886
1887 void DCTStream::restart() {
1888 int i;
1889
1890 inputBits = 0;
1891 restartCtr = restartInterval;
1892 for (i = 0; i < numComps; ++i)
1893 compInfo[i].prevDC = 0;
1894 }
1895
1896 GBool DCTStream::readMCURow() {
1897 Guchar data[64];
1898 Guchar *p1, *p2;
1899 int pY, pCb, pCr, pR, pG, pB;
1900 int h, v, horiz, vert, hSub, vSub;
1901 int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
1902 int c;
1903
1904 for (x1 = 0; x1 < width; x1 += mcuWidth) {
1905
1906 // deal with restart marker
1907 if (restartInterval > 0 && restartCtr == 0) {
1908 c = readMarker();
1909 if (c != restartMarker) {
1910 error(getPos(), "Bad DCT data: incorrect restart marker");
1911 return gFalse;
1912 }
1913 if (++restartMarker == 0xd8)
1914 restartMarker = 0xd0;
1915 restart();
1916 }
1917
1918 // read one MCU
1919 for (cc = 0; cc < numComps; ++cc) {
1920 h = compInfo[cc].hSample;
1921 v = compInfo[cc].vSample;
1922 horiz = mcuWidth / h;
1923 vert = mcuHeight / v;
1924 hSub = horiz / 8;
1925 vSub = vert / 8;
1926 for (y2 = 0; y2 < mcuHeight; y2 += vert) {
1927 for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
1928 if (!readDataUnit(&dcHuffTables[compInfo[cc].dcHuffTable],
1929 &acHuffTables[compInfo[cc].acHuffTable],
1930 quantTables[compInfo[cc].quantTable],
1931 &compInfo[cc].prevDC,
1932 data))
1933 return gFalse;
1934 if (hSub == 1 && vSub == 1) {
1935 for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
1936 p1 = &rowBuf[cc][y2+y3][x1+x2];
1937 p1[0] = data[i];
1938 p1[1] = data[i+1];
1939 p1[2] = data[i+2];
1940 p1[3] = data[i+3];
1941 p1[4] = data[i+4];
1942 p1[5] = data[i+5];
1943 p1[6] = data[i+6];
1944 p1[7] = data[i+7];
1945 }
1946 } else if (hSub == 2 && vSub == 2) {
1947 for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
1948 p1 = &rowBuf[cc][y2+y3][x1+x2];
1949 p2 = &rowBuf[cc][y2+y3+1][x1+x2];
1950 p1[0] = p1[1] = p2[0] = p2[1] = data[i];
1951 p1[2] = p1[3] = p2[2] = p2[3] = data[i+1];
1952 p1[4] = p1[5] = p2[4] = p2[5] = data[i+2];
1953 p1[6] = p1[7] = p2[6] = p2[7] = data[i+3];
1954 p1[8] = p1[9] = p2[8] = p2[9] = data[i+4];
1955 p1[10] = p1[11] = p2[10] = p2[11] = data[i+5];
1956 p1[12] = p1[13] = p2[12] = p2[13] = data[i+6];
1957 p1[14] = p1[15] = p2[14] = p2[15] = data[i+7];
1958 }
1959 } else {
1960 i = 0;
1961 for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
1962 for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
1963 for (y5 = 0; y5 < vSub; ++y5)
1964 for (x5 = 0; x5 < hSub; ++x5)
1965 rowBuf[cc][y2+y4+y5][x1+x2+x4+x5] = data[i];
1966 ++i;
1967 }
1968 }
1969 }
1970 }
1971 }
1972 }
1973 --restartCtr;
1974
1975 // color space conversion
1976 if (colorXform) {
1977 // convert YCbCr to RGB
1978 if (numComps == 3) {
1979 for (y2 = 0; y2 < mcuHeight; ++y2) {
1980 for (x2 = 0; x2 < mcuWidth; ++x2) {
1981 pY = rowBuf[0][y2][x1+x2];
1982 pCb = rowBuf[1][y2][x1+x2] - 128;
1983 pCr = rowBuf[2][y2][x1+x2] - 128;
1984 pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
1985 rowBuf[0][y2][x1+x2] = dctClip[dctClipOffset + pR];
1986 pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
1987 rowBuf[1][y2][x1+x2] = dctClip[dctClipOffset + pG];
1988 pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
1989 rowBuf[2][y2][x1+x2] = dctClip[dctClipOffset + pB];
1990 }
1991 }
1992 // convert YCbCrK to CMYK (K is passed through unchanged)
1993 } else if (numComps == 4) {
1994 for (y2 = 0; y2 < mcuHeight; ++y2) {
1995 for (x2 = 0; x2 < mcuWidth; ++x2) {
1996 pY = rowBuf[0][y2][x1+x2];
1997 pCb = rowBuf[1][y2][x1+x2] - 128;
1998 pCr = rowBuf[2][y2][x1+x2] - 128;
1999 pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2000 rowBuf[0][y2][x1+x2] = 255 - dctClip[dctClipOffset + pR];
2001 pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32678) >> 16;
2002 rowBuf[1][y2][x1+x2] = 255 - dctClip[dctClipOffset + pG];
2003 pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2004 rowBuf[2][y2][x1+x2] = 255 - dctClip[dctClipOffset + pB];
2005 }
2006 }
2007 }
2008 }
2009 }
2010 return gTrue;
2011 }
2012
2013 // This IDCT algorithm is taken from:
2014 // Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,
2015 // "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
2016 // IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
2017 // 988-991.
2018 // The stage numbers mentioned in the comments refer to Figure 1 in this
2019 // paper.
2020 #ifndef FP_IDCT
2021 GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
2022 DCTHuffTable *acHuffTable,
2023 Guchar quantTable[64], int *prevDC,
2024 Guchar data[64]) {
2025 int tmp1[64];
2026 int v0, v1, v2, v3, v4, v5, v6, v7, t;
2027 int run, size, amp;
2028 int c;
2029 int i, j;
2030
2031 // Huffman decode and dequantize
2032 size = readHuffSym(dcHuffTable);
2033 if (size == 9999)
2034 return gFalse;
2035 if (size > 0) {
2036 amp = readAmp(size);
2037 if (amp == 9999)
2038 return gFalse;
2039 } else {
2040 amp = 0;
2041 }
2042 tmp1[0] = (*prevDC += amp) * quantTable[0];
2043 for (i = 1; i < 64; ++i)
2044 tmp1[i] = 0;
2045 i = 1;
2046 while (i < 64) {
2047 run = 0;
2048 while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30)
2049 run += 0x10;
2050 if (c == 9999)
2051 return gFalse;
2052 if (c == 0x00) {
2053 break;
2054 } else {
2055 run += (c >> 4) & 0x0f;
2056 size = c & 0x0f;
2057 amp = readAmp(size);
2058 if (amp == 9999)
2059 return gFalse;
2060 i += run;
2061 j = dctZigZag[i++];
2062 tmp1[j] = amp * quantTable[j];
2063 }
2064 }
2065
2066 // inverse DCT on rows
2067 for (i = 0; i < 64; i += 8) {
2068
2069 // stage 4
2070 v0 = (dctSqrt2 * tmp1[i+0] + 128) >> 8;
2071 v1 = (dctSqrt2 * tmp1[i+4] + 128) >> 8;
2072 v2 = tmp1[i+2];
2073 v3 = tmp1[i+6];
2074 v4 = (dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]) + 128) >> 8;
2075 v7 = (dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]) + 128) >> 8;
2076 v5 = tmp1[i+3] << 4;
2077 v6 = tmp1[i+5] << 4;
2078
2079 // stage 3
2080 t = (v0 - v1+ 1) >> 1;
2081 v0 = (v0 + v1 + 1) >> 1;
2082 v1 = t;
2083 t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8;
2084 v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8;
2085 v3 = t;
2086 t = (v4 - v6 + 1) >> 1;
2087 v4 = (v4 + v6 + 1) >> 1;
2088 v6 = t;
2089 t = (v7 + v5 + 1) >> 1;
2090 v5 = (v7 - v5 + 1) >> 1;
2091 v7 = t;
2092
2093 // stage 2
2094 t = (v0 - v3 + 1) >> 1;
2095 v0 = (v0 + v3 + 1) >> 1;
2096 v3 = t;
2097 t = (v1 - v2 + 1) >> 1;
2098 v1 = (v1 + v2 + 1) >> 1;
2099 v2 = t;
2100 t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
2101 v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
2102 v7 = t;
2103 t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
2104 v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
2105 v6 = t;
2106
2107 // stage 1
2108 tmp1[i+0] = v0 + v7;
2109 tmp1[i+7] = v0 - v7;
2110 tmp1[i+1] = v1 + v6;
2111 tmp1[i+6] = v1 - v6;
2112 tmp1[i+2] = v2 + v5;
2113 tmp1[i+5] = v2 - v5;
2114 tmp1[i+3] = v3 + v4;
2115 tmp1[i+4] = v3 - v4;
2116 }
2117
2118 // inverse DCT on columns
2119 for (i = 0; i < 8; ++i) {
2120
2121 // stage 4
2122 v0 = (dctSqrt2 * tmp1[0*8+i] + 2048) >> 12;
2123 v1 = (dctSqrt2 * tmp1[4*8+i] + 2048) >> 12;
2124 v2 = tmp1[2*8+i];
2125 v3 = tmp1[6*8+i];
2126 v4 = (dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]) + 2048) >> 12;
2127 v7 = (dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]) + 2048) >> 12;
2128 v5 = tmp1[3*8+i];
2129 v6 = tmp1[5*8+i];
2130
2131 // stage 3
2132 t = (v0 - v1 + 1) >> 1;
2133 v0 = (v0 + v1 + 1) >> 1;
2134 v1 = t;
2135 t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12;
2136 v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12;
2137 v3 = t;
2138 t = (v4 - v6 + 1) >> 1;
2139 v4 = (v4 + v6 + 1) >> 1;
2140 v6 = t;
2141 t = (v7 + v5 + 1) >> 1;
2142 v5 = (v7 - v5 + 1) >> 1;
2143 v7 = t;
2144
2145 // stage 2
2146 t = (v0 - v3 + 1) >> 1;
2147 v0 = (v0 + v3 + 1) >> 1;
2148 v3 = t;
2149 t = (v1 - v2 + 1) >> 1;
2150 v1 = (v1 + v2 + 1) >> 1;
2151 v2 = t;
2152 t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
2153 v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
2154 v7 = t;
2155 t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
2156 v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
2157 v6 = t;
2158
2159 // stage 1
2160 tmp1[0*8+i] = v0 + v7;
2161 tmp1[7*8+i] = v0 - v7;
2162 tmp1[1*8+i] = v1 + v6;
2163 tmp1[6*8+i] = v1 - v6;
2164 tmp1[2*8+i] = v2 + v5;
2165 tmp1[5*8+i] = v2 - v5;
2166 tmp1[3*8+i] = v3 + v4;
2167 tmp1[4*8+i] = v3 - v4;
2168 }
2169
2170 // convert to 8-bit integers
2171 for (i = 0; i < 64; ++i)
2172 data[i] = dctClip[dctClipOffset + 128 + ((tmp1[i] + 8) >> 4)];
2173
2174 return gTrue;
2175 }
2176 #endif
2177
2178 #ifdef FP_IDCT
2179 GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
2180 DCTHuffTable *acHuffTable,
2181 Guchar quantTable[64], int *prevDC,
2182 Guchar data[64]) {
2183 double tmp1[64];
2184 double v0, v1, v2, v3, v4, v5, v6, v7, t;
2185 int run, size, amp;
2186 int c;
2187 int i, j;
2188
2189 // Huffman decode and dequantize
2190 size = readHuffSym(dcHuffTable);
2191 if (size == 9999)
2192 return gFalse;
2193 if (size > 0) {
2194 amp = readAmp(size);
2195 if (amp == 9999)
2196 return gFalse;
2197 } else {
2198 amp = 0;
2199 }
2200 tmp1[0] = (*prevDC += amp) * quantTable[0];
2201 for (i = 1; i < 64; ++i)
2202 tmp1[i] = 0;
2203 i = 1;
2204 while (i < 64) {
2205 run = 0;
2206 while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30)
2207 run += 0x10;
2208 if (c == 9999)
2209 return gFalse;
2210 if (c == 0x00) {
2211 break;
2212 } else {
2213 run += (c >> 4) & 0x0f;
2214 size = c & 0x0f;
2215 amp = readAmp(size);
2216 if (amp == 9999)
2217 return gFalse;
2218 i += run;
2219 j = dctZigZag[i++];
2220 tmp1[j] = amp * quantTable[j];
2221 }
2222 }
2223
2224 // inverse DCT on rows
2225 for (i = 0; i < 64; i += 8) {
2226
2227 // stage 4
2228 v0 = dctSqrt2 * tmp1[i+0];
2229 v1 = dctSqrt2 * tmp1[i+4];
2230 v2 = tmp1[i+2];
2231 v3 = tmp1[i+6];
2232 v4 = dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]);
2233 v7 = dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]);
2234 v5 = tmp1[i+3];
2235 v6 = tmp1[i+5];
2236
2237 // stage 3
2238 t = 0.5 * (v0 - v1);
2239 v0 = 0.5 * (v0 + v1);
2240 v1 = t;
2241 t = v2 * dctSin6 + v3 * dctCos6;
2242 v2 = v2 * dctCos6 - v3 * dctSin6;
2243 v3 = t;
2244 t = 0.5 * (v4 - v6);
2245 v4 = 0.5 * (v4 + v6);
2246 v6 = t;
2247 t = 0.5 * (v7 + v5);
2248 v5 = 0.5 * (v7 - v5);
2249 v7 = t;
2250
2251 // stage 2
2252 t = 0.5 * (v0 - v3);
2253 v0 = 0.5 * (v0 + v3);
2254 v3 = t;
2255 t = 0.5 * (v1 - v2);
2256 v1 = 0.5 * (v1 + v2);
2257 v2 = t;
2258 t = v4 * dctSin3 + v7 * dctCos3;
2259 v4 = v4 * dctCos3 - v7 * dctSin3;
2260 v7 = t;
2261 t = v5 * dctSin1 + v6 * dctCos1;
2262 v5 = v5 * dctCos1 - v6 * dctSin1;
2263 v6 = t;
2264
2265 // stage 1
2266 tmp1[i+0] = v0 + v7;
2267 tmp1[i+7] = v0 - v7;
2268 tmp1[i+1] = v1 + v6;
2269 tmp1[i+6] = v1 - v6;
2270 tmp1[i+2] = v2 + v5;
2271 tmp1[i+5] = v2 - v5;
2272 tmp1[i+3] = v3 + v4;
2273 tmp1[i+4] = v3 - v4;
2274 }
2275
2276 // inverse DCT on columns
2277 for (i = 0; i < 8; ++i) {
2278
2279 // stage 4
2280 v0 = dctSqrt2 * tmp1[0*8+i];
2281 v1 = dctSqrt2 * tmp1[4*8+i];
2282 v2 = tmp1[2*8+i];
2283 v3 = tmp1[6*8+i];
2284 v4 = dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]);
2285 v7 = dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]);
2286 v5 = tmp1[3*8+i];
2287 v6 = tmp1[5*8+i];
2288
2289 // stage 3
2290 t = 0.5 * (v0 - v1);
2291 v0 = 0.5 * (v0 + v1);
2292 v1 = t;
2293 t = v2 * dctSin6 + v3 * dctCos6;
2294 v2 = v2 * dctCos6 - v3 * dctSin6;
2295 v3 = t;
2296 t = 0.5 * (v4 - v6);
2297 v4 = 0.5 * (v4 + v6);
2298 v6 = t;
2299 t = 0.5 * (v7 + v5);
2300 v5 = 0.5 * (v7 - v5);
2301 v7 = t;
2302
2303 // stage 2
2304 t = 0.5 * (v0 - v3);
2305 v0 = 0.5 * (v0 + v3);
2306 v3 = t;
2307 t = 0.5 * (v1 - v2);
2308 v1 = 0.5 * (v1 + v2);
2309 v2 = t;
2310 t = v4 * dctSin3 + v7 * dctCos3;
2311 v4 = v4 * dctCos3 - v7 * dctSin3;
2312 v7 = t;
2313 t = v5 * dctSin1 + v6 * dctCos1;
2314 v5 = v5 * dctCos1 - v6 * dctSin1;
2315 v6 = t;
2316
2317 // stage 1
2318 tmp1[0*8+i] = v0 + v7;
2319 tmp1[7*8+i] = v0 - v7;
2320 tmp1[1*8+i] = v1 + v6;
2321 tmp1[6*8+i] = v1 - v6;
2322 tmp1[2*8+i] = v2 + v5;
2323 tmp1[5*8+i] = v2 - v5;
2324 tmp1[3*8+i] = v3 + v4;
2325 tmp1[4*8+i] = v3 - v4;
2326 }
2327
2328 // convert to 8-bit integers
2329 for (i = 0; i < 64; ++i)
2330 data[i] = dctClip[dctClipOffset + (int)(tmp1[i] + 128.5)];
2331
2332 return gTrue;
2333 }
2334 #endif
2335
2336 int DCTStream::readHuffSym(DCTHuffTable *table) {
2337 Gushort code;
2338 int bit;
2339 int codeBits;
2340
2341 code = 0;
2342 codeBits = 0;
2343 do {
2344 // add a bit to the code
2345 if ((bit = readBit()) == EOF)
2346 return 9999;
2347 code = (code << 1) + bit;
2348 ++codeBits;
2349
2350 // look up code
2351 if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
2352 code -= table->firstCode[codeBits];
2353 return table->sym[table->firstSym[codeBits] + code];
2354 }
2355 } while (codeBits < 16);
2356
2357 error(getPos(), "Bad Huffman code in DCT stream");
2358 return 9999;
2359 }
2360
2361 int DCTStream::readAmp(int size) {
2362 int amp, bit;
2363 int bits;
2364
2365 amp = 0;
2366 for (bits = 0; bits < size; ++bits) {
2367 if ((bit = readBit()) == EOF)
2368 return 9999;
2369 amp = (amp << 1) + bit;
2370 }
2371 if (amp < (1 << (size - 1)))
2372 amp -= (1 << size) - 1;
2373 return amp;
2374 }
2375
2376 int DCTStream::readBit() {
2377 int bit;
2378 int c, c2;
2379
2380 if (inputBits == 0) {
2381 if ((c = str->getChar()) == EOF)
2382 return EOF;
2383 if (c == 0xff) {
2384 do {
2385 c2 = str->getChar();
2386 } while (c2 == 0xff);
2387 if (c2 != 0x00) {
2388 error(getPos(), "Bad DCT data: missing 00 after ff");
2389 return EOF;
2390 }
2391 }
2392 inputBuf = c;
2393 inputBits = 8;
2394 }
2395 bit = (inputBuf >> (inputBits - 1)) & 1;
2396 --inputBits;
2397 return bit;
2398 }
2399
2400 GBool DCTStream::readHeader() {
2401 GBool doScan;
2402 int minHSample, minVSample;
2403 int bufWidth;
2404 int n;
2405 int c = 0;
2406 int i, j;
2407
2408 width = height = 0;
2409 numComps = 0;
2410 numQuantTables = 0;
2411 numDCHuffTables = 0;
2412 numACHuffTables = 0;
2413 colorXform = 0;
2414 gotAdobeMarker = gFalse;
2415 restartInterval = 0;
2416
2417 // read headers
2418 doScan = gFalse;
2419 while (!doScan) {
2420 c = readMarker();
2421 switch (c) {
2422 case 0xc0: // SOF0
2423 if (!readFrameInfo())
2424 return gFalse;
2425 break;
2426 case 0xc4: // DHT
2427 if (!readHuffmanTables())
2428 return gFalse;
2429 break;
2430 case 0xd8: // SOI
2431 break;
2432 case 0xda: // SOS
2433 if (!readScanInfo())
2434 return gFalse;
2435 doScan = gTrue;
2436 break;
2437 case 0xdb: // DQT
2438 if (!readQuantTables())
2439 return gFalse;
2440 break;
2441 case 0xdd: // DRI
2442 if (!readRestartInterval())
2443 return gFalse;
2444 break;
2445 case 0xee: // APP14
2446 if (!readAdobeMarker())
2447 return gFalse;
2448 break;
2449 case EOF:
2450 error(getPos(), "Bad DCT header");
2451 return gFalse;
2452 default:
2453 // skip APPn / COM / etc.
2454 if (c >= 0xe0) {
2455 n = read16() - 2;
2456 for (i = 0; i < n; ++i)
2457 str->getChar();
2458 } else {
2459 error(getPos(), "Unknown DCT marker <%02x>", c);
2460 return gFalse;
2461 }
2462 break;
2463 }
2464 }
2465
2466 // compute MCU size
2467 mcuWidth = minHSample = compInfo[0].hSample;
2468 mcuHeight = minVSample = compInfo[0].vSample;
2469 for (i = 1; i < numComps; ++i) {
2470 if (compInfo[i].hSample < minHSample)
2471 minHSample = compInfo[i].hSample;
2472 if (compInfo[i].vSample < minVSample)
2473 minVSample = compInfo[i].vSample;
2474 if (compInfo[i].hSample > mcuWidth)
2475 mcuWidth = compInfo[i].hSample;
2476 if (compInfo[i].vSample > mcuHeight)
2477 mcuHeight = compInfo[i].vSample;
2478 }
2479 for (i = 0; i < numComps; ++i) {
2480 compInfo[i].hSample /= minHSample;
2481 compInfo[i].vSample /= minVSample;
2482 }
2483 mcuWidth = (mcuWidth / minHSample) * 8;
2484 mcuHeight = (mcuHeight / minVSample) * 8;
2485
2486 // allocate buffers
2487 bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
2488 for (i = 0; i < numComps; ++i)
2489 for (j = 0; j < mcuHeight; ++j)
2490 rowBuf[i][j] = (Guchar *)gmalloc(bufWidth * sizeof(Guchar));
2491
2492 // figure out color transform
2493 if (!gotAdobeMarker && numComps == 3) {
2494 if (compInfo[0].id == 1 && compInfo[1].id == 2 && compInfo[2].id == 3) {
2495 colorXform = 1;
2496 }
2497 }
2498
2499 // initialize counters
2500 comp = 0;
2501 x = 0;
2502 y = 0;
2503 dy = mcuHeight;
2504
2505 return gTrue;
2506 }
2507
2508 GBool DCTStream::readFrameInfo() {
2509 int length;
2510 int prec;
2511 int i;
2512 int c;
2513
2514 length = read16() - 2;
2515 prec = str->getChar();
2516 height = read16();
2517 width = read16();
2518 numComps = str->getChar();
2519 length -= 6;
2520 if (prec != 8) {
2521 error(getPos(), "Bad DCT precision %d", prec);
2522 return gFalse;
2523 }
2524 for (i = 0; i < numComps; ++i) {
2525 compInfo[i].id = str->getChar();
2526 compInfo[i].inScan = gFalse;
2527 c = str->getChar();
2528 compInfo[i].hSample = (c >> 4) & 0x0f;
2529 compInfo[i].vSample = c & 0x0f;
2530 compInfo[i].quantTable = str->getChar();
2531 compInfo[i].dcHuffTable = 0;
2532 compInfo[i].acHuffTable = 0;
2533 }
2534 return gTrue;
2535 }
2536
2537 GBool DCTStream::readScanInfo() {
2538 int length;
2539 int scanComps, id, c;
2540 int i, j;
2541
2542 length = read16() - 2;
2543 scanComps = str->getChar();
2544 --length;
2545 if (length != 2 * scanComps + 3) {
2546 error(getPos(), "Bad DCT scan info block");
2547 return gFalse;
2548 }
2549 for (i = 0; i < scanComps; ++i) {
2550 id = str->getChar();
2551 for (j = 0; j < numComps; ++j) {
2552 if (id == compInfo[j].id)
2553 break;
2554 }
2555 if (j == numComps) {
2556 error(getPos(), "Bad DCT component ID in scan info block");
2557 return gFalse;
2558 }
2559 compInfo[j].inScan = gTrue;
2560 c = str->getChar();
2561 compInfo[j].dcHuffTable = (c >> 4) & 0x0f;
2562 compInfo[j].acHuffTable = c & 0x0f;
2563 }
2564 str->getChar();
2565 str->getChar();
2566 str->getChar();
2567 return gTrue;
2568 }
2569
2570 GBool DCTStream::readQuantTables() {
2571 int length;
2572 int i;
2573 int index;
2574
2575 length = read16() - 2;
2576 while (length > 0) {
2577 index = str->getChar();
2578 if ((index & 0xf0) || index >= 4) {
2579 error(getPos(), "Bad DCT quantization table");
2580 return gFalse;
2581 }
2582 if (index == numQuantTables)
2583 numQuantTables = index + 1;
2584 for (i = 0; i < 64; ++i)
2585 quantTables[index][dctZigZag[i]] = str->getChar();
2586 length -= 65;
2587 }
2588 return gTrue;
2589 }
2590
2591 GBool DCTStream::readHuffmanTables() {
2592 DCTHuffTable *tbl;
2593 int length;
2594 int index;
2595 Gushort code;
2596 Guchar sym;
2597 int i;
2598 int c;
2599
2600 length = read16() - 2;
2601 while (length > 0) {
2602 index = str->getChar();
2603 --length;
2604 if ((index & 0x0f) >= 4) {
2605 error(getPos(), "Bad DCT Huffman table");
2606 return gFalse;
2607 }
2608 if (index & 0x10) {
2609 index &= 0x0f;
2610 if (index >= numACHuffTables)
2611 numACHuffTables = index+1;
2612 tbl = &acHuffTables[index];
2613 } else {
2614 if (index >= numDCHuffTables)
2615 numDCHuffTables = index+1;
2616 tbl = &dcHuffTables[index];
2617 }
2618 sym = 0;
2619 code = 0;
2620 for (i = 1; i <= 16; ++i) {
2621 c = str->getChar();
2622 tbl->firstSym[i] = sym;
2623 tbl->firstCode[i] = code;
2624 tbl->numCodes[i] = c;
2625 sym += c;
2626 code = (code + c) << 1;
2627 }
2628 length -= 16;
2629 for (i = 0; i < sym; ++i)
2630 tbl->sym[i] = str->getChar();
2631 length -= sym;
2632 }
2633 return gTrue;
2634 }
2635
2636 GBool DCTStream::readRestartInterval() {
2637 int length;
2638
2639 length = read16();
2640 if (length != 4) {
2641 error(getPos(), "Bad DCT restart interval");
2642 return gFalse;
2643 }
2644 restartInterval = read16();
2645 return gTrue;
2646 }
2647
2648 GBool DCTStream::readAdobeMarker() {
2649 int length, i;
2650 char buf[12];
2651 int c;
2652
2653 length = read16();
2654 if (length != 14)
2655 goto err;
2656 for (i = 0; i < 12; ++i) {
2657 if ((c = str->getChar()) == EOF)
2658 goto err;
2659 buf[i] = c;
2660 }
2661 if (strncmp(buf, "Adobe", 5))
2662 goto err;
2663 colorXform = buf[11];
2664 gotAdobeMarker = gTrue;
2665 return gTrue;
2666
2667 err:
2668 error(getPos(), "Bad DCT Adobe APP14 marker");
2669 return gFalse;
2670 }
2671
2672 GBool DCTStream::readTrailer() {
2673 int c;
2674
2675 c = readMarker();
2676 if (c != 0xd9) { // EOI
2677 error(getPos(), "Bad DCT trailer");
2678 return gFalse;
2679 }
2680 return gTrue;
2681 }
2682
2683 int DCTStream::readMarker() {
2684 int c;
2685
2686 do {
2687 do {
2688 c = str->getChar();
2689 } while (c != 0xff);
2690 do {
2691 c = str->getChar();
2692 } while (c == 0xff);
2693 } while (c == 0x00);
2694 return c;
2695 }
2696
2697 int DCTStream::read16() {
2698 int c1, c2;
2699
2700 if ((c1 = str->getChar()) == EOF)
2701 return EOF;
2702 if ((c2 = str->getChar()) == EOF)
2703 return EOF;
2704 return (c1 << 8) + c2;
2705 }
2706
2707 GString *DCTStream::getPSFilter(const char *indent) {
2708 GString *s;
2709
2710 s = str->getPSFilter(indent);
2711 s->append(indent)->append("<< >> /DCTDecode filter\n");
2712 return s;
2713 }
2714
2715 GBool DCTStream::isBinary(GBool last) {
2716 (void)last;
2717
2718 return str->isBinary(gTrue);
2719 }
2720
2721 //------------------------------------------------------------------------
2722 // FlateStream
2723 //------------------------------------------------------------------------
2724
2725 int FlateStream::codeLenCodeMap[flateMaxCodeLenCodes] = {
2726 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
2727 };
2728
2729 FlateDecode FlateStream::lengthDecode[flateMaxLitCodes-257] = {
2730 {0, 3},
2731 {0, 4},
2732 {0, 5},
2733 {0, 6},
2734 {0, 7},
2735 {0, 8},
2736 {0, 9},
2737 {0, 10},
2738 {1, 11},
2739 {1, 13},
2740 {1, 15},
2741 {1, 17},
2742 {2, 19},
2743 {2, 23},
2744 {2, 27},
2745 {2, 31},
2746 {3, 35},
2747 {3, 43},
2748 {3, 51},
2749 {3, 59},
2750 {4, 67},
2751 {4, 83},
2752 {4, 99},
2753 {4, 115},
2754 {5, 131},
2755 {5, 163},
2756 {5, 195},
2757 {5, 227},
2758 {0, 258}
2759 };
2760
2761 FlateDecode FlateStream::distDecode[flateMaxDistCodes] = {
2762 { 0, 1},
2763 { 0, 2},
2764 { 0, 3},
2765 { 0, 4},
2766 { 1, 5},
2767 { 1, 7},
2768 { 2, 9},
2769 { 2, 13},
2770 { 3, 17},
2771 { 3, 25},
2772 { 4, 33},
2773 { 4, 49},
2774 { 5, 65},
2775 { 5, 97},
2776 { 6, 129},
2777 { 6, 193},
2778 { 7, 257},
2779 { 7, 385},
2780 { 8, 513},
2781 { 8, 769},
2782 { 9, 1025},
2783 { 9, 1537},
2784 {10, 2049},
2785 {10, 3073},
2786 {11, 4097},
2787 {11, 6145},
2788 {12, 8193},
2789 {12, 12289},
2790 {13, 16385},
2791 {13, 24577}
2792 };
2793
2794 FlateStream::FlateStream(Stream *str, int predictor1, int columns1,
2795 int colors1, int bits1):
2796 FilterStream(str) {
2797 if (predictor1 != 1) {
2798 pred = new StreamPredictor(this, predictor1, columns1, colors1, bits1);
2799 } else {
2800 pred = NULL;
2801 }
2802 }
2803
2804 FlateStream::~FlateStream() {
2805 if (pred) {
2806 delete pred;
2807 }
2808 delete str;
2809 }
2810
2811 void FlateStream::reset() {
2812 int cmf, flg;
2813
2814 str->reset();
2815
2816 // read header
2817 //~ need to look at window size?
2818 endOfBlock = eof = gTrue;
2819 cmf = str->getChar();
2820 flg = str->getChar();
2821 if (cmf == EOF || flg == EOF)
2822 return;
2823 if ((cmf & 0x0f) != 0x08) {
2824 error(getPos(), "Unknown compression method in flate stream");
2825 return;
2826 }
2827 if ((((cmf << 8) + flg) % 31) != 0) {
2828 error(getPos(), "Bad FCHECK in flate stream");
2829 return;
2830 }
2831 if (flg & 0x20) {
2832 error(getPos(), "FDICT bit set in flate stream");
2833 return;
2834 }
2835
2836 // initialize
2837 index = 0;
2838 remain = 0;
2839 codeBuf = 0;
2840 codeSize = 0;
2841 compressedBlock = gFalse;
2842 endOfBlock = gTrue;
2843 eof = gFalse;
2844 }
2845
2846 int FlateStream::getChar() {
2847 int c;
2848
2849 if (pred) {
2850 return pred->getChar();
2851 }
2852 while (remain == 0) {
2853 if (endOfBlock && eof)
2854 return EOF;
2855 readSome();
2856 }
2857 c = buf[index];
2858 index = (index + 1) & flateMask;
2859 --remain;
2860 return c;
2861 }
2862
2863 int FlateStream::lookChar() {
2864 int c;
2865
2866 if (pred) {
2867 return pred->lookChar();
2868 }
2869 while (remain == 0) {
2870 if (endOfBlock && eof)
2871 return EOF;
2872 readSome();
2873 }
2874 c = buf[index];
2875 return c;
2876 }
2877
2878 int FlateStream::getRawChar() {
2879 int c;
2880
2881 while (remain == 0) {
2882 if (endOfBlock && eof)
2883 return EOF;
2884 readSome();
2885 }
2886 c = buf[index];
2887 index = (index + 1) & flateMask;
2888 --remain;
2889 return c;
2890 }
2891
2892 GString *FlateStream::getPSFilter(const char *indent) {
2893 (void)indent;
2894
2895 return NULL;
2896 }
2897
2898 GBool FlateStream::isBinary(GBool last) {
2899 (void)last;
2900
2901 return str->isBinary(gTrue);
2902 }
2903
2904 void FlateStream::readSome() {
2905 int code1, code2;
2906 int len, dist;
2907 int i, j, k;
2908 int c;
2909
2910 if (endOfBlock) {
2911 if (!startBlock())
2912 return;
2913 }
2914
2915 if (compressedBlock) {
2916 if ((code1 = getHuffmanCodeWord(&litCodeTab)) == EOF)
2917 goto err;
2918 if (code1 < 256) {
2919 buf[index] = code1;
2920 remain = 1;
2921 } else if (code1 == 256) {
2922 endOfBlock = gTrue;
2923 remain = 0;
2924 } else {
2925 code1 -= 257;
2926 code2 = lengthDecode[code1].bits;
2927 if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
2928 goto err;
2929 len = lengthDecode[code1].first + code2;
2930 if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF)
2931 goto err;
2932 code2 = distDecode[code1].bits;
2933 if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
2934 goto err;
2935 dist = distDecode[code1].first + code2;
2936 i = index;
2937 j = (index - dist) & flateMask;
2938 for (k = 0; k < len; ++k) {
2939 buf[i] = buf[j];
2940 i = (i + 1) & flateMask;
2941 j = (j + 1) & flateMask;
2942 }
2943 remain = len;
2944 }
2945
2946 } else {
2947 len = (blockLen < flateWindow) ? blockLen : flateWindow;
2948 for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) {
2949 if ((c = str->getChar()) == EOF) {
2950 endOfBlock = eof = gTrue;
2951 break;
2952 }
2953 buf[j] = c & 0xff;
2954 }
2955 remain = i;
2956 blockLen -= len;
2957 if (blockLen == 0)
2958 endOfBlock = gTrue;
2959 }
2960
2961 return;
2962
2963 err:
2964 error(getPos(), "Unexpected end of file in flate stream");
2965 endOfBlock = eof = gTrue;
2966 remain = 0;
2967 }
2968
2969 GBool FlateStream::startBlock() {
2970 int blockHdr;
2971 int c;
2972 int check;
2973
2974 // read block header
2975 blockHdr = getCodeWord(3);
2976 if (blockHdr & 1)
2977 eof = gTrue;
2978 blockHdr >>= 1;
2979
2980 // uncompressed block
2981 if (blockHdr == 0) {
2982 compressedBlock = gFalse;
2983 if ((c = str->getChar()) == EOF)
2984 goto err;
2985 blockLen = c & 0xff;
2986 if ((c = str->getChar()) == EOF)
2987 goto err;
2988 blockLen |= (c & 0xff) << 8;
2989 if ((c = str->getChar()) == EOF)
2990 goto err;
2991 check = c & 0xff;
2992 if ((c = str->getChar()) == EOF)
2993 goto err;
2994 check |= (c & 0xff) << 8;
2995 if (check != (~blockLen & 0xffff))
2996 error(getPos(), "Bad uncompressed block length in flate stream");
2997 codeBuf = 0;
2998 codeSize = 0;
2999
3000 // compressed block with fixed codes
3001 } else if (blockHdr == 1) {
3002 compressedBlock = gTrue;
3003 loadFixedCodes();
3004
3005 // compressed block with dynamic codes
3006 } else if (blockHdr == 2) {
3007 compressedBlock = gTrue;
3008 if (!readDynamicCodes())
3009 goto err;
3010
3011 // unknown block type
3012 } else {
3013 goto err;
3014 }
3015
3016 endOfBlock = gFalse;
3017 return gTrue;
3018
3019 err:
3020 error(getPos(), "Bad block header in flate stream");
3021 endOfBlock = eof = gTrue;
3022 return gFalse;
3023 }
3024
3025 void FlateStream::loadFixedCodes() {
3026 int i;
3027
3028 // set up code arrays
3029 litCodeTab.codes = allCodes;
3030 distCodeTab.codes = allCodes + flateMaxLitCodes;
3031
3032 // initialize literal code table
3033 for (i = 0; i <= 143; ++i)
3034 litCodeTab.codes[i].len = 8;
3035 for (i = 144; i <= 255; ++i)
3036 litCodeTab.codes[i].len = 9;
3037 for (i = 256; i <= 279; ++i)
3038 litCodeTab.codes[i].len = 7;
3039 for (i = 280; i <= 287; ++i)
3040 litCodeTab.codes[i].len = 8;
3041 compHuffmanCodes(&litCodeTab, flateMaxLitCodes);
3042
3043 // initialize distance code table
3044 for (i = 0; i <= 5; ++i) {
3045 distCodeTab.start[i] = 0;
3046 }
3047 for (i = 6; i <= flateMaxHuffman+1; ++i) {
3048 distCodeTab.start[i] = flateMaxDistCodes;
3049 }
3050 for (i = 0; i < flateMaxDistCodes; ++i) {
3051 distCodeTab.codes[i].len = 5;
3052 distCodeTab.codes[i].code = i;
3053 distCodeTab.codes[i].val = i;
3054 }
3055 }
3056
3057 GBool FlateStream::readDynamicCodes() {
3058 int numCodeLenCodes;
3059 int numLitCodes;
3060 int numDistCodes;
3061 FlateCode codeLenCodes[flateMaxCodeLenCodes];
3062 FlateHuffmanTab codeLenCodeTab;
3063 int len, repeat, code;
3064 int i;
3065
3066 // read lengths
3067 if ((numLitCodes = getCodeWord(5)) == EOF)
3068 goto err;
3069 numLitCodes += 257;
3070 if ((numDistCodes = getCodeWord(5)) == EOF)
3071 goto err;
3072 numDistCodes += 1;
3073 if ((numCodeLenCodes = getCodeWord(4)) == EOF)
3074 goto err;
3075 numCodeLenCodes += 4;
3076 if (numLitCodes > flateMaxLitCodes ||
3077 numDistCodes > flateMaxDistCodes ||
3078 numCodeLenCodes > flateMaxCodeLenCodes)
3079 goto err;
3080
3081 // read code length code table
3082 codeLenCodeTab.codes = codeLenCodes;
3083 for (i = 0; i < flateMaxCodeLenCodes; ++i)
3084 codeLenCodes[i].len = 0;
3085 for (i = 0; i < numCodeLenCodes; ++i) {
3086 if ((codeLenCodes[codeLenCodeMap[i]].len = getCodeWord(3)) == -1)
3087 goto err;
3088 }
3089 compHuffmanCodes(&codeLenCodeTab, flateMaxCodeLenCodes);
3090
3091 // set up code arrays
3092 litCodeTab.codes = allCodes;
3093 distCodeTab.codes = allCodes + numLitCodes;
3094
3095 // read literal and distance code tables
3096 len = 0;
3097 repeat = 0;
3098 i = 0;
3099 while (i < numLitCodes + numDistCodes) {
3100 if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF)
3101 goto err;
3102 if (code == 16) {
3103 if ((repeat = getCodeWord(2)) == EOF)
3104 goto err;
3105 for (repeat += 3; repeat > 0; --repeat)
3106 allCodes[i++].len = len;
3107 } else if (code == 17) {
3108 if ((repeat = getCodeWord(3)) == EOF)
3109 goto err;
3110 len = 0;
3111 for (repeat += 3; repeat > 0; --repeat)
3112 allCodes[i++].len = 0;
3113 } else if (code == 18) {
3114 if ((repeat = getCodeWord(7)) == EOF)
3115 goto err;
3116 len = 0;
3117 for (repeat += 11; repeat > 0; --repeat)
3118 allCodes[i++].len = 0;
3119 } else {
3120 allCodes[i++].len = len = code;
3121 }
3122 }
3123 compHuffmanCodes(&litCodeTab, numLitCodes);
3124 compHuffmanCodes(&distCodeTab, numDistCodes);
3125
3126 return gTrue;
3127
3128 err:
3129 error(getPos(), "Bad dynamic code table in flate stream");
3130 return gFalse;
3131 }
3132
3133 // On entry, the <tab->codes> array contains the lengths of each code,
3134 // stored in code value order. This function computes the code words.
3135 // The result is sorted in order of (1) code length and (2) code word.
3136 // The length values are no longer valid. The <tab->start> array is
3137 // filled with the indexes of the first code of each length.
3138 void FlateStream::compHuffmanCodes(FlateHuffmanTab *tab, int n) {
3139 int numLengths[flateMaxHuffman+1];
3140 int nextCode[flateMaxHuffman+1];
3141 int nextIndex[flateMaxHuffman+2];
3142 int code;
3143 int i, j;
3144
3145 // count number of codes for each code length
3146 for (i = 0; i <= flateMaxHuffman; ++i)
3147 numLengths[i] = 0;
3148 for (i = 0; i < n; ++i)
3149 ++numLengths[tab->codes[i].len];
3150
3151 // compute first index for each length
3152 tab->start[0] = nextIndex[0] = 0;
3153 for (i = 1; i <= flateMaxHuffman + 1; ++i)
3154 tab->start[i] = nextIndex[i] = tab->start[i-1] + numLengths[i-1];
3155
3156 // compute first code for each length
3157 code = 0;
3158 numLengths[0] = 0;
3159 for (i = 1; i <= flateMaxHuffman; ++i) {
3160 code = (code + numLengths[i-1]) << 1;
3161 nextCode[i] = code;
3162 }
3163
3164 // compute the codes -- this permutes the codes array from value
3165 // order to length/code order
3166 for (i = 0; i < n; ++i) {
3167 j = nextIndex[tab->codes[i].len]++;
3168 if (tab->codes[i].len == 0)
3169 tab->codes[j].code = 0;
3170 else
3171 tab->codes[j].code = nextCode[tab->codes[i].len]++;
3172 tab->codes[j].val = i;
3173 }
3174 }
3175
3176 int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) {
3177 int len;
3178 int code;
3179 int c;
3180 int i, j;
3181
3182 code = 0;
3183 for (len = 1; len <= flateMaxHuffman; ++len) {
3184
3185 // add a bit to the code
3186 if (codeSize == 0) {
3187 if ((c = str->getChar()) == EOF)
3188 return EOF;
3189 codeBuf = c & 0xff;
3190 codeSize = 8;
3191 }
3192 code = (code << 1) | (codeBuf & 1);
3193 codeBuf >>= 1;
3194 --codeSize;
3195
3196 // look for code
3197 i = tab->start[len];
3198 j = tab->start[len + 1];
3199 if (i < j && code >= tab->codes[i].code && code <= tab->codes[j-1].code) {
3200 i += code - tab->codes[i].code;
3201 return tab->codes[i].val;
3202 }
3203 }
3204
3205 // not found
3206 error(getPos(), "Bad code (%04x) in flate stream", code);
3207 return EOF;
3208 }
3209
3210 int FlateStream::getCodeWord(int bits) {
3211 int c;
3212
3213 while (codeSize < bits) {
3214 if ((c = str->getChar()) == EOF)
3215 return EOF;
3216 codeBuf |= (c & 0xff) << codeSize;
3217 codeSize += 8;
3218 }
3219 c = codeBuf & ((1 << bits) - 1);
3220 codeBuf >>= bits;
3221 codeSize -= bits;
3222 return c;
3223 }
3224
3225 //------------------------------------------------------------------------
3226 // EOFStream
3227 //------------------------------------------------------------------------
3228
3229 EOFStream::EOFStream(Stream *str):
3230 FilterStream(str) {
3231 }
3232
3233 EOFStream::~EOFStream() {
3234 delete str;
3235 }
3236
3237 //------------------------------------------------------------------------
3238 // FixedLengthEncoder
3239 //------------------------------------------------------------------------
3240
3241 FixedLengthEncoder::FixedLengthEncoder(Stream *str, int length1):
3242 FilterStream(str) {
3243 length = length1;
3244 count = 0;
3245 }
3246
3247 FixedLengthEncoder::~FixedLengthEncoder() {
3248 if (str->isEncoder())
3249 delete str;
3250 }
3251
3252 void FixedLengthEncoder::reset() {
3253 str->reset();
3254 count = 0;
3255 }
3256
3257 int FixedLengthEncoder::getChar() {
3258 if (length >= 0 && count >= length)
3259 return EOF;
3260 ++count;
3261 return str->getChar();
3262 }
3263
3264 int FixedLengthEncoder::lookChar() {
3265 if (length >= 0 && count >= length)
3266 return EOF;
3267 return str->getChar();
3268 }
3269
3270 //------------------------------------------------------------------------
3271 // ASCII85Encoder
3272 //------------------------------------------------------------------------
3273
3274 ASCII85Encoder::ASCII85Encoder(Stream *str):
3275 FilterStream(str) {
3276 bufPtr = bufEnd = buf;
3277 lineLen = 0;
3278 eof = gFalse;
3279 }
3280
3281 ASCII85Encoder::~ASCII85Encoder() {
3282 if (str->isEncoder())
3283 delete str;
3284 }
3285
3286 void ASCII85Encoder::reset() {
3287 str->reset();
3288 bufPtr = bufEnd = buf;
3289 lineLen = 0;
3290 eof = gFalse;
3291 }
3292
3293 GBool ASCII85Encoder::fillBuf() {
3294 Gulong t;
3295 char buf1[5];
3296 int c;
3297 int n, i;
3298
3299 if (eof)
3300 return gFalse;
3301 t = 0;
3302 for (n = 0; n < 4; ++n) {
3303 if ((c = str->getChar()) == EOF)
3304 break;
3305 t = (t << 8) + c;
3306 }
3307 bufPtr = bufEnd = buf;
3308 if (n > 0) {
3309 if (n == 4 && t == 0) {
3310 *bufEnd++ = 'z';
3311 if (++lineLen == 65) {
3312 *bufEnd++ = '\n';
3313 lineLen = 0;
3314 }
3315 } else {
3316 if (n < 4)
3317 t <<= 8 * (4 - n);
3318 for (i = 4; i >= 0; --i) {
3319 buf1[i] = (char)(t % 85 + 0x21);
3320 t /= 85;
3321 }
3322 for (i = 0; i <= n; ++i) {
3323 *bufEnd++ = buf1[i];
3324 if (++lineLen == 65) {
3325 *bufEnd++ = '\n';
3326 lineLen = 0;
3327 }
3328 }
3329 }
3330 }
3331 if (n < 4) {
3332 *bufEnd++ = '~';
3333 *bufEnd++ = '>';
3334 eof = gTrue;
3335 }
3336 return bufPtr < bufEnd;
3337 }
3338
3339 //------------------------------------------------------------------------
3340 // RunLengthEncoder
3341 //------------------------------------------------------------------------
3342
3343 RunLengthEncoder::RunLengthEncoder(Stream *str):
3344 FilterStream(str) {
3345 bufPtr = bufEnd = nextEnd = buf;
3346 eof = gFalse;
3347 }
3348
3349 RunLengthEncoder::~RunLengthEncoder() {
3350 if (str->isEncoder())
3351 delete str;
3352 }
3353
3354 void RunLengthEncoder::reset() {
3355 str->reset();
3356 bufPtr = bufEnd = nextEnd = buf;
3357 eof = gFalse;
3358 }
3359
3360 //
3361 // When fillBuf finishes, buf[] looks like this:
3362 // +-----+--------------+-----------------+--
3363 // + tag | ... data ... | next 0, 1, or 2 |
3364 // +-----+--------------+-----------------+--
3365 // ^ ^ ^
3366 // bufPtr bufEnd nextEnd
3367 //
3368 GBool RunLengthEncoder::fillBuf() {
3369 int c, c1, c2;
3370 int n;
3371
3372 // already hit EOF?
3373 if (eof)
3374 return gFalse;
3375
3376 // grab two bytes
3377 if (nextEnd < bufEnd + 1) {
3378 if ((c1 = str->getChar()) == EOF) {
3379 eof = gTrue;
3380 return gFalse;
3381 }
3382 } else {
3383 c1 = bufEnd[0] & 0xff;
3384 }
3385 if (nextEnd < bufEnd + 2) {
3386 if ((c2 = str->getChar()) == EOF) {
3387 eof = gTrue;
3388 buf[0] = 0;
3389 buf[1] = c1;
3390 bufPtr = buf;
3391 bufEnd = &buf[2];
3392 return gTrue;
3393 }
3394 } else {
3395 c2 = bufEnd[1] & 0xff;
3396 }
3397
3398 // check for repeat
3399 c = 0; // make gcc happy
3400 if (c1 == c2) {
3401 n = 2;
3402 c = 0; // suppress bogus compiler warning
3403 while (n < 128 && (c = str->getChar()) == c1)
3404 ++n;
3405 buf[0] = (char)(257 - n);
3406 buf[1] = c1;
3407 bufEnd = &buf[2];
3408 if (c == EOF) {
3409 eof = gTrue;
3410 } else if (n < 128) {
3411 buf[2] = c;
3412 nextEnd = &buf[3];
3413 } else {
3414 nextEnd = bufEnd;
3415 }
3416
3417 // get up to 128 chars
3418 } else {
3419 buf[1] = c1;
3420 buf[2] = c2;
3421 n = 2;
3422 while (n < 128) {
3423 if ((c = str->getChar()) == EOF) {
3424 eof = gTrue;
3425 break;
3426 }
3427 ++n;
3428 buf[n] = c;
3429 if (buf[n] == buf[n-1])
3430 break;
3431 }
3432 if (buf[n] == buf[n-1]) {
3433 buf[0] = (char)(n-2-1);
3434 bufEnd = &buf[n-1];
3435 nextEnd = &buf[n+1];
3436 } else {
3437 buf[0] = (char)(n-1);
3438 bufEnd = nextEnd = &buf[n+1];
3439 }
3440 }
3441 bufPtr = buf;
3442 return gTrue;
3443 }