filters

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