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