1 //========================================================================
5 // Copyright 1996 Derek B. Noonburg
7 //========================================================================
10 #pragma implementation
26 #include "Stream-CCITT.h"
30 #define pclose _pclose
34 static GBool setDJSYSFLAGS = gFalse;
38 #if (__VMS_VER < 70000000)
39 extern "C" int unlink(char *filename);
48 //------------------------------------------------------------------------
50 #define headerSearchSize 1024 // read this many bytes at beginning of
51 // file to look for '%PDF'
53 //------------------------------------------------------------------------
54 // Stream (base class)
55 //------------------------------------------------------------------------
64 int Stream::getRawChar() {
65 error(-1, "Internal: called getRawChar() on non-predictor stream");
69 char *Stream::getLine(char *buf, int size) {
73 if (lookChar() == EOF)
75 for (i = 0; i < size - 1; ++i) {
77 if (c == EOF || c == '\n')
80 if ((c = lookChar()) == '\n')
90 void Stream::setPos(int pos) {
91 error(-1, "Internal: called setPos() on non-FileStream");
94 GString *Stream::getPSFilter(char *indent) {
98 Stream *Stream::addFilters(Object *dict) {
100 Object params, params2;
105 dict->dictLookup("Filter", &obj);
108 dict->dictLookup("F", &obj);
110 dict->dictLookup("DecodeParms", ¶ms);
111 if (params.isNull()) {
113 dict->dictLookup("DP", ¶ms);
116 str = makeFilter(obj.getName(), str, ¶ms);
117 } else if (obj.isArray()) {
118 for (i = 0; i < obj.arrayGetLength(); ++i) {
119 obj.arrayGet(i, &obj2);
120 if (params.isArray())
121 params.arrayGet(i, ¶ms2);
125 str = makeFilter(obj2.getName(), str, ¶ms2);
127 error(getPos(), "Bad filter name");
128 str = new EOFStream(str);
133 } else if (!obj.isNull()) {
134 error(getPos(), "Bad 'Filter' attribute in stream");
142 Stream *Stream::makeFilter(char *name, Stream *str, Object *params) {
143 int pred; // parameters
148 GBool endOfLine, byteAlign, endOfBlock, black;
152 if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) {
153 str = new ASCIIHexStream(str);
154 } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) {
155 str = new ASCII85Stream(str);
156 } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) {
162 if (params->isDict()) {
163 params->dictLookup("Predictor", &obj);
167 params->dictLookup("Columns", &obj);
169 columns = obj.getInt();
171 params->dictLookup("Colors", &obj);
173 colors = obj.getInt();
175 params->dictLookup("BitsPerComponent", &obj);
179 params->dictLookup("EarlyChange", &obj);
181 early = obj.getInt();
184 str = new LZWStream(str, pred, columns, colors, bits, early);
185 } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) {
186 str = new RunLengthStream(str);
187 } else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) {
195 if (params->isDict()) {
196 params->dictLookup("K", &obj);
198 encoding = obj.getInt();
201 params->dictLookup("EndOfLine", &obj);
203 endOfLine = obj.getBool();
206 params->dictLookup("EncodedByteAlign", &obj);
208 byteAlign = obj.getBool();
211 params->dictLookup("Columns", &obj);
213 columns = obj.getInt();
216 params->dictLookup("Rows", &obj);
221 params->dictLookup("EndOfBlock", &obj);
223 endOfBlock = obj.getBool();
226 params->dictLookup("BlackIs1", &obj);
228 black = obj.getBool();
232 str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign,
233 columns, rows, endOfBlock, black);
234 } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) {
235 str = new DCTStream(str);
236 } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) {
241 if (params->isDict()) {
242 params->dictLookup("Predictor", &obj);
246 params->dictLookup("Columns", &obj);
248 columns = obj.getInt();
250 params->dictLookup("Colors", &obj);
252 colors = obj.getInt();
254 params->dictLookup("BitsPerComponent", &obj);
259 str = new FlateStream(str, pred, columns, colors, bits);
261 error(getPos(), "Unknown filter '%s'", name);
262 str = new EOFStream(str);
267 //------------------------------------------------------------------------
269 //------------------------------------------------------------------------
271 ImageStream::ImageStream(Stream *str, int width, int nComps, int nBits) {
276 this->nComps = nComps;
279 nVals = width * nComps;
281 imgLineSize = (nVals + 7) & ~7;
285 imgLine = (Guchar *)gmalloc(imgLineSize * sizeof(Guchar));
289 ImageStream::~ImageStream() {
293 void ImageStream::reset() {
297 GBool ImageStream::getPixel(Guchar *pix) {
303 if (imgIdx >= nVals) {
305 // read one line of image pixels
307 for (i = 0; i < nVals; i += 8) {
309 imgLine[i+0] = (Guchar)((c >> 7) & 1);
310 imgLine[i+1] = (Guchar)((c >> 6) & 1);
311 imgLine[i+2] = (Guchar)((c >> 5) & 1);
312 imgLine[i+3] = (Guchar)((c >> 4) & 1);
313 imgLine[i+4] = (Guchar)((c >> 3) & 1);
314 imgLine[i+5] = (Guchar)((c >> 2) & 1);
315 imgLine[i+6] = (Guchar)((c >> 1) & 1);
316 imgLine[i+7] = (Guchar)(c & 1);
318 } else if (nBits == 8) {
319 for (i = 0; i < nVals; ++i) {
320 imgLine[i] = str->getChar();
323 bitMask = (1 << nBits) - 1;
326 for (i = 0; i < nVals; ++i) {
328 buf = (buf << 8) | (str->getChar() & 0xff);
331 imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask);
336 // reset to start of line
340 for (i = 0; i < nComps; ++i)
341 pix[i] = imgLine[imgIdx++];
345 void ImageStream::skipLine() {
348 n = (nVals * nBits + 7) >> 3;
349 for (i = 0; i < n; ++i) {
354 //------------------------------------------------------------------------
356 //------------------------------------------------------------------------
358 StreamPredictor::StreamPredictor(Stream *str, int predictor,
359 int width, int nComps, int nBits) {
361 this->predictor = predictor;
363 this->nComps = nComps;
366 nVals = width * nComps;
367 pixBytes = (nComps * nBits + 7) >> 3;
368 rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes;
369 predLine = (Guchar *)gmalloc(rowBytes);
370 memset(predLine, 0, rowBytes);
374 StreamPredictor::~StreamPredictor() {
378 int StreamPredictor::lookChar() {
379 if (predIdx >= rowBytes) {
380 if (!getNextLine()) {
384 return predLine[predIdx];
387 int StreamPredictor::getChar() {
388 if (predIdx >= rowBytes) {
389 if (!getNextLine()) {
393 return predLine[predIdx++];
396 GBool StreamPredictor::getNextLine() {
399 int left, up, upLeft, p, pa, pb, pc;
401 Gulong inBuf, outBuf, bitMask;
405 // get PNG optimum predictor number
406 if (predictor == 15) {
407 if ((curPred = str->getRawChar()) == EOF) {
415 // read the raw line, apply PNG (byte) predictor
416 upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0;
417 for (i = pixBytes; i < rowBytes; ++i) {
418 upLeftBuf[3] = upLeftBuf[2];
419 upLeftBuf[2] = upLeftBuf[1];
420 upLeftBuf[1] = upLeftBuf[0];
421 upLeftBuf[0] = predLine[i];
422 if ((c = str->getRawChar()) == EOF) {
427 predLine[i] = predLine[i - pixBytes] + (Guchar)c;
430 predLine[i] = predLine[i] + (Guchar)c;
432 case 13: // PNG average
433 predLine[i] = ((predLine[i - pixBytes] + predLine[i]) >> 1) +
436 case 14: // PNG Paeth
437 left = predLine[i - pixBytes];
439 upLeft = upLeftBuf[pixBytes];
440 p = left + up - upLeft;
441 if ((pa = p - left) < 0)
443 if ((pb = p - up) < 0)
445 if ((pc = p - upLeft) < 0)
447 if (pa <= pb && pa <= pc)
448 predLine[i] = pa + (Guchar)c;
450 predLine[i] = pb + (Guchar)c;
452 predLine[i] = pc + (Guchar)c;
455 default: // no predictor or TIFF predictor
456 predLine[i] = (Guchar)c;
461 // apply TIFF (component) predictor
462 //~ this is completely untested
463 if (predictor == 2) {
465 inBuf = predLine[pixBytes - 1];
466 for (i = pixBytes; i < rowBytes; i += 8) {
467 // 1-bit add is just xor
468 inBuf = (inBuf << 8) | predLine[i];
469 predLine[i] ^= inBuf >> nComps;
471 } else if (nBits == 8) {
472 for (i = pixBytes; i < rowBytes; ++i) {
473 predLine[i] += predLine[i - nComps];
476 upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0;
477 bitMask = (1 << nBits) - 1;
479 inBits = outBits = 0;
481 for (i = 0; i < nVals; ++i) {
482 if (inBits < nBits) {
483 inBuf = (inBuf << 8) | (predLine[j++] & 0xff);
486 upLeftBuf[3] = upLeftBuf[2];
487 upLeftBuf[2] = upLeftBuf[1];
488 upLeftBuf[1] = upLeftBuf[0];
489 upLeftBuf[0] = (upLeftBuf[nComps] +
490 (inBuf >> (inBits - nBits))) & bitMask;
491 outBuf = (outBuf << nBits) | upLeftBuf[0];
495 predLine[k++] = (Guchar)(outBuf >> (outBits - 8));
499 predLine[k++] = (Guchar)(outBuf << (8 - outBits));
504 // reset to start of line
510 //------------------------------------------------------------------------
512 //------------------------------------------------------------------------
514 FileStream::FileStream(FILE *f1, int start1, int length1, Object *dict1) {
518 bufPtr = bufEnd = buf;
524 FileStream::~FileStream() {
526 fseek(f, savePos, SEEK_SET);
530 void FileStream::reset() {
531 savePos = (int)ftell(f);
532 fseek(f, start, SEEK_SET);
533 bufPtr = bufEnd = buf;
537 GBool FileStream::fillBuf() {
540 bufPos += bufEnd - buf;
541 bufPtr = bufEnd = buf;
542 if (length >= 0 && bufPos >= start + length)
544 if (length >= 0 && bufPos + 256 > start + length)
545 n = start + length - bufPos;
548 n = fread(buf, 1, n, f);
550 if (bufPtr >= bufEnd)
555 void FileStream::setPos(int pos1) {
559 fseek(f, pos1, SEEK_SET);
562 fseek(f, 0, SEEK_END);
566 fseek(f, pos1, SEEK_END);
567 bufPos = (int)ftell(f);
569 bufPtr = bufEnd = buf;
572 GBool FileStream::checkHeader() {
573 char hdrBuf[headerSearchSize+1];
578 for (i = 0; i < headerSearchSize; ++i)
579 hdrBuf[i] = getChar();
580 hdrBuf[headerSearchSize] = '\0';
581 for (i = 0; i < headerSearchSize - 5; ++i) {
582 if (!strncmp(&hdrBuf[i], "%PDF-", 5))
585 if (i >= headerSearchSize - 5) {
586 error(-1, "May not be a PDF file (continuing anyway)");
590 p = strtok(&hdrBuf[i+5], " \t\n\r");
592 if (!(hdrBuf[i+5] >= '0' && hdrBuf[i+5] <= '9') ||
593 version > pdfVersionNum + 0.0001) {
594 error(getPos(), "PDF version %s -- xpdf supports version %s"
595 " (continuing anyway)", p, pdfVersion);
601 //------------------------------------------------------------------------
603 //------------------------------------------------------------------------
605 SubStream::SubStream(Stream *str1, Object *dict1) {
610 SubStream::~SubStream() {
614 //------------------------------------------------------------------------
616 //------------------------------------------------------------------------
618 ASCIIHexStream::ASCIIHexStream(Stream *str1) {
624 ASCIIHexStream::~ASCIIHexStream() {
628 void ASCIIHexStream::reset() {
634 int ASCIIHexStream::lookChar() {
645 } while (isspace(c1));
653 } while (isspace(c2));
658 if (c1 >= '0' && c1 <= '9') {
660 } else if (c1 >= 'A' && c1 <= 'F') {
661 x = (c1 - 'A' + 10) << 4;
662 } else if (c1 >= 'a' && c1 <= 'f') {
663 x = (c1 - 'a' + 10) << 4;
664 } else if (c1 == EOF) {
668 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c1);
671 if (c2 >= '0' && c2 <= '9') {
673 } else if (c2 >= 'A' && c2 <= 'F') {
675 } else if (c2 >= 'a' && c2 <= 'f') {
677 } else if (c2 == EOF) {
681 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c2);
687 GString *ASCIIHexStream::getPSFilter(char *indent) {
690 s = str->getPSFilter(indent);
691 s->append(indent)->append("/ASCIIHexDecode filter\n");
695 GBool ASCIIHexStream::isBinary(GBool last) {
696 return str->isBinary(gFalse);
699 //------------------------------------------------------------------------
701 //------------------------------------------------------------------------
703 ASCII85Stream::ASCII85Stream(Stream *str1) {
709 ASCII85Stream::~ASCII85Stream() {
713 void ASCII85Stream::reset() {
719 int ASCII85Stream::lookChar() {
728 c[0] = str->getChar();
729 } while (c[0] == '\n' || c[0] == '\r');
730 if (c[0] == '~' || c[0] == EOF) {
734 } else if (c[0] == 'z') {
735 b[0] = b[1] = b[2] = b[3] = 0;
738 for (k = 1; k < 5; ++k) {
740 c[k] = str->getChar();
741 } while (c[k] == '\n' || c[k] == '\r');
742 if (c[k] == '~' || c[k] == EOF)
746 if (k < 5 && (c[k] == '~' || c[k] == EOF)) {
747 for (++k; k < 5; ++k)
752 for (k = 0; k < 5; ++k)
753 t = t * 85 + (c[k] - 0x21);
754 for (k = 3; k >= 0; --k) {
755 b[k] = (int)(t & 0xff);
763 GString *ASCII85Stream::getPSFilter(char *indent) {
766 s = str->getPSFilter(indent);
767 s->append(indent)->append("/ASCII85Decode filter\n");
771 GBool ASCII85Stream::isBinary(GBool last) {
772 return str->isBinary(gFalse);
775 //------------------------------------------------------------------------
777 //------------------------------------------------------------------------
779 LZWStream::LZWStream(Stream *str1, int predictor1, int columns1, int colors1,
780 int bits1, int early1) {
782 if (predictor1 != 1) {
783 pred = new StreamPredictor(this, predictor1, columns1, colors1, bits1);
789 bufPtr = bufEnd = buf;
792 LZWStream::~LZWStream() {
808 int LZWStream::getChar() {
810 return pred->getChar();
812 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
815 int LZWStream::lookChar() {
817 return pred->lookChar();
819 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff);
822 int LZWStream::getRawChar() {
823 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
826 void LZWStream::reset() {
830 bufPtr = bufEnd = buf;
841 if (!setDJSYSFLAGS) {
842 setenv("DJSYSFLAGS", "0x0002", 0);
843 setDJSYSFLAGS = gTrue;
846 strcpy(zCmd, uncompressCmd);
848 zName = zCmd + strlen(zCmd);
851 zName[strlen(zName) - 2] = '\0';
854 if (!(f = fopen(zName, "wb"))) {
855 error(getPos(), "Couldn't open temporary file '%s'", zName);
861 if (!(zPipe = popen(zCmd, "r"))) {
862 error(getPos(), "Couldn't popen '%s'", zCmd);
872 error(getPos(), "Couldn't execute '%s'", zCmd);
876 zName[strlen(zName) - 2] = '\0';
877 if (!(zPipe = fopen(zName, "rb"))) {
878 error(getPos(), "Couldn't open uncompress file '%s'", zName);
885 void LZWStream::dumpFile(FILE *f) {
886 int outCodeBits; // size of output code
887 int outBits; // max output code
888 int outBuf[8]; // output buffer
889 int outData; // temporary output buffer
890 int inCode, outCode; // input and output codes
891 int nextCode; // next code index
892 GBool eof; // set when EOF is reached
893 GBool clear; // set if table needs to be cleared
894 GBool first; // indicates first code word after clear
901 // max code length, block mode flag
919 for (i = 0; i < 8; ++i) {
920 // check for table overflow
921 if (nextCode + early > 0x1001) {
932 } while (first && inCode == 256);
935 // compute output code
938 } else if (inCode == 256) {
941 } else if (inCode == 257) {
945 outCode = inCode - 1;
955 // check input code size
956 if (nextCode + early == 0x200)
958 else if (nextCode + early == 0x400) {
960 } else if (nextCode + early == 0x800) {
964 // check for eof/clear
973 // write output block
977 while (j < i || outBits > 0) {
978 if (outBits < 8 && j < i) {
979 outData = outData | (outBuf[j++] << outBits);
980 outBits += outCodeBits;
982 fputc(outData & 0xff, f);
987 // check output code size
988 if (nextCode - 1 == 512 ||
989 nextCode - 1 == 1024 ||
990 nextCode - 1 == 2048 ||
991 nextCode - 1 == 4096) {
992 outCodeBits = inCodeBits;
995 // clear table if necessary
1006 int LZWStream::getCode() {
1010 while (inputBits < inCodeBits) {
1011 if ((c = str->getChar()) == EOF)
1013 inputBuf = (inputBuf << 8) | (c & 0xff);
1016 code = (inputBuf >> (inputBits - inCodeBits)) & ((1 << inCodeBits) - 1);
1017 inputBits -= inCodeBits;
1021 GBool LZWStream::fillBuf() {
1026 if ((n = fread(buf, 1, 256, zPipe)) < 256) {
1040 GString *LZWStream::getPSFilter(char *indent) {
1046 s = str->getPSFilter(indent);
1047 s->append(indent)->append("/LZWDecode filter\n");
1051 GBool LZWStream::isBinary(GBool last) {
1052 return str->isBinary(gTrue);
1055 //------------------------------------------------------------------------
1057 //------------------------------------------------------------------------
1059 RunLengthStream::RunLengthStream(Stream *str1) {
1061 bufPtr = bufEnd = buf;
1065 RunLengthStream::~RunLengthStream() {
1069 void RunLengthStream::reset() {
1071 bufPtr = bufEnd = buf;
1075 GString *RunLengthStream::getPSFilter(char *indent) {
1078 s = str->getPSFilter(indent);
1079 s->append(indent)->append("/RunLengthDecode filter\n");
1083 GBool RunLengthStream::isBinary(GBool last) {
1084 return str->isBinary(gTrue);
1087 GBool RunLengthStream::fillBuf() {
1094 if (c == 0x80 || c == EOF) {
1100 for (i = 0; i < n; ++i)
1101 buf[i] = (char)str->getChar();
1105 for (i = 0; i < n; ++i)
1113 //------------------------------------------------------------------------
1115 //------------------------------------------------------------------------
1117 CCITTFaxStream::CCITTFaxStream(Stream *str, int encoding, GBool endOfLine,
1118 GBool byteAlign, int columns, int rows,
1119 GBool endOfBlock, GBool black) {
1121 this->encoding = encoding;
1122 this->endOfLine = endOfLine;
1123 this->byteAlign = byteAlign;
1124 this->columns = columns;
1126 this->endOfBlock = endOfBlock;
1127 this->black = black;
1128 refLine = (short *)gmalloc((columns + 2) * sizeof(short));
1129 codingLine = (short *)gmalloc((columns + 2) * sizeof(short));
1133 nextLine2D = encoding < 0;
1136 codingLine[1] = refLine[2] = columns;
1142 CCITTFaxStream::~CCITTFaxStream() {
1148 void CCITTFaxStream::reset() {
1154 nextLine2D = encoding < 0;
1157 codingLine[1] = refLine[2] = columns;
1161 // get initial end-of-line marker and 2D encoding tag
1163 if (lookBits(12) == 0x001) {
1167 for (n = 0; n < 11 && lookBits(n) == 0; ++n) ;
1168 if (n == 11 && lookBits(12) == 0x001) {
1173 nextLine2D = !lookBits(1);
1178 int CCITTFaxStream::lookChar() {
1179 short code1, code2, code3;
1187 // if at eof just return EOF
1188 if (eof && codingLine[a0] >= columns) {
1192 // read the next row
1196 if (codingLine[a0] >= columns) {
1200 for (i = 0; codingLine[i] < columns; ++i)
1201 refLine[i] = codingLine[i];
1202 refLine[i] = refLine[i + 1] = columns;
1204 a0New = codingLine[a0 = 0] = 0;
1206 code1 = getTwoDimCode();
1209 if (refLine[b1] < columns) {
1210 a0New = refLine[b1 + 1];
1215 if ((a0 & 1) == 0) {
1218 code1 += code3 = getWhiteCode();
1219 } while (code3 >= 64);
1221 code2 += code3 = getBlackCode();
1222 } while (code3 >= 64);
1226 code1 += code3 = getBlackCode();
1227 } while (code3 >= 64);
1229 code2 += code3 = getWhiteCode();
1230 } while (code3 >= 64);
1232 codingLine[a0 + 1] = a0New + code1;
1234 a0New = codingLine[a0 + 1] = codingLine[a0] + code2;
1236 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1240 a0New = codingLine[++a0] = refLine[b1];
1241 if (refLine[b1] < columns) {
1243 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1248 a0New = codingLine[++a0] = refLine[b1] + 1;
1249 if (refLine[b1] < columns) {
1251 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1256 a0New = codingLine[++a0] = refLine[b1] - 1;
1258 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1262 a0New = codingLine[++a0] = refLine[b1] + 2;
1263 if (refLine[b1] < columns) {
1265 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1270 a0New = codingLine[++a0] = refLine[b1] - 2;
1272 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1276 a0New = codingLine[++a0] = refLine[b1] + 3;
1277 if (refLine[b1] < columns) {
1279 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1284 a0New = codingLine[++a0] = refLine[b1] - 3;
1286 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1291 codingLine[a0 = 0] = columns;
1294 error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1);
1303 } while (codingLine[a0] < columns);
1307 codingLine[a0 = 0] = 0;
1311 code1 += code3 = getWhiteCode();
1312 } while (code3 >= 64);
1313 codingLine[a0+1] = codingLine[a0] + code1;
1315 if (codingLine[a0] >= columns)
1319 code2 += code3 = getBlackCode();
1320 } while (code3 >= 64);
1321 codingLine[a0+1] = codingLine[a0] + code2;
1323 if (codingLine[a0] >= columns)
1328 if (codingLine[a0] != columns) {
1329 error(getPos(), "CCITTFax row is wrong length (%d)", codingLine[a0]);
1335 // byte-align the row
1340 // check for end-of-line marker, end-of-block marker, and
1343 code1 = lookBits(12);
1346 } else if (code1 == 0x001) {
1349 nextLine2D = !lookBits(1);
1352 code1 = lookBits(12);
1353 if (code1 == 0x001) {
1359 if (encoding >= 0) {
1360 for (i = 0; i < 4; ++i) {
1361 code1 = lookBits(12);
1362 if (code1 != 0x001) {
1363 error(getPos(), "Bad RTC code in CCITTFax stream");
1376 nextLine2D = !lookBits(1);
1381 if (row == rows - 1) {
1384 for (n = 0; n < 11 && lookBits(n) == 0; ++n) ;
1385 if (n == 11 && lookBits(12) == 0x001) {
1389 nextLine2D = !lookBits(1);
1396 // This looks for an end-of-line marker after an error, however
1397 // some (most?) CCITT streams in PDF files don't use end-of-line
1398 // markers, and the just-plow-on technique works better in those
1407 code1 = look13Bits();
1408 } while ((code1 >> 1) != 0x001);
1410 codingLine[++a0] = columns;
1413 nextLine2D = !(code1 & 1);
1419 outputBits = codingLine[1] - codingLine[0];
1420 if (outputBits == 0) {
1422 outputBits = codingLine[2] - codingLine[1];
1429 if (outputBits >= 8) {
1430 ret = ((a0 & 1) == 0) ? 0xff : 0x00;
1431 if ((outputBits -= 8) == 0) {
1433 if (codingLine[a0] < columns) {
1434 outputBits = codingLine[a0 + 1] - codingLine[a0];
1441 if (outputBits > bits) {
1444 if ((a0 & 1) == 0) {
1445 ret |= 0xff >> (8 - i);
1451 if ((a0 & 1) == 0) {
1452 ret |= (0xff >> (8 - i)) << bits;
1456 if (codingLine[a0] < columns) {
1457 outputBits = codingLine[a0 + 1] - codingLine[a0];
1460 } while (bits > 0 && codingLine[a0] < columns);
1462 buf = black ? (ret ^ 0xff) : ret;
1466 short CCITTFaxStream::getTwoDimCode() {
1471 code = 0; // make gcc happy
1474 p = &twoDimTab1[code];
1480 for (n = 1; n <= 7; ++n) {
1485 p = &twoDimTab1[code];
1492 error(getPos(), "Bad two dim code (%04x) in CCITTFax stream", code);
1496 short CCITTFaxStream::getWhiteCode() {
1501 code = 0; // make gcc happy
1503 code = lookBits(12);
1504 if ((code >> 5) == 0)
1505 p = &whiteTab1[code];
1507 p = &whiteTab2[code >> 3];
1513 for (n = 1; n <= 9; ++n) {
1518 p = &whiteTab2[code];
1524 for (n = 11; n <= 12; ++n) {
1529 p = &whiteTab1[code];
1536 error(getPos(), "Bad white code (%04x) in CCITTFax stream", code);
1540 short CCITTFaxStream::getBlackCode() {
1545 code = 0; // make gcc happy
1547 code = lookBits(13);
1548 if ((code >> 7) == 0)
1549 p = &blackTab1[code];
1550 else if ((code >> 9) == 0)
1551 p = &blackTab2[(code >> 1) - 64];
1553 p = &blackTab3[code >> 7];
1559 for (n = 2; n <= 6; ++n) {
1564 p = &blackTab3[code];
1570 for (n = 7; n <= 12; ++n) {
1576 p = &blackTab2[code - 64];
1583 for (n = 10; n <= 13; ++n) {
1588 p = &blackTab1[code];
1595 error(getPos(), "Bad black code (%04x) in CCITTFax stream", code);
1599 short CCITTFaxStream::lookBits(int n) {
1602 while (inputBits < n) {
1603 if ((c = str->getChar()) == EOF) {
1608 inputBuf = (inputBuf << 8) + c;
1611 return (inputBuf >> (inputBits - n)) & (0xffff >> (16 - n));
1614 GString *CCITTFaxStream::getPSFilter(char *indent) {
1618 s = str->getPSFilter(indent);
1619 s->append(indent)->append("<< ");
1620 if (encoding != 0) {
1621 sprintf(s1, "/K %d ", encoding);
1625 s->append("/EndOfLine true ");
1628 s->append("/EncodedByteAlign true ");
1630 sprintf(s1, "/Columns %d ", columns);
1633 sprintf(s1, "/Rows %d ", rows);
1637 s->append("/EndOfBlock false ");
1640 s->append("/BlackIs1 true ");
1642 s->append(">> /CCITTFaxDecode filter\n");
1646 GBool CCITTFaxStream::isBinary(GBool last) {
1647 return str->isBinary(gTrue);
1650 //------------------------------------------------------------------------
1652 //------------------------------------------------------------------------
1654 // IDCT constants (20.12 fixed point format)
1656 #define dctCos1 4017 // cos(pi/16)
1657 #define dctSin1 799 // sin(pi/16)
1658 #define dctCos3 3406 // cos(3*pi/16)
1659 #define dctSin3 2276 // sin(3*pi/16)
1660 #define dctCos6 1567 // cos(6*pi/16)
1661 #define dctSin6 3784 // sin(6*pi/16)
1662 #define dctSqrt2 5793 // sqrt(2)
1663 #define dctSqrt1d2 2896 // sqrt(2) / 2
1668 #define dctCos1 0.98078528 // cos(pi/16)
1669 #define dctSin1 0.19509032 // sin(pi/16)
1670 #define dctCos3 0.83146961 // cos(3*pi/16)
1671 #define dctSin3 0.55557023 // sin(3*pi/16)
1672 #define dctCos6 0.38268343 // cos(6*pi/16)
1673 #define dctSin6 0.92387953 // sin(6*pi/16)
1674 #define dctSqrt2 1.41421356 // sqrt(2)
1675 #define dctSqrt1d2 0.70710678 // sqrt(2) / 2
1678 // color conversion parameters (16.16 fixed point format)
1679 #define dctCrToR 91881 // 1.4020
1680 #define dctCbToG -22553 // -0.3441363
1681 #define dctCrToG -46802 // -0.71413636
1682 #define dctCbToB 116130 // 1.772
1684 // clip [-256,511] --> [0,255]
1685 #define dctClipOffset 256
1686 static Guchar dctClip[768];
1687 static int dctClipInit = 0;
1689 // zig zag decode map
1690 static int dctZigZag[64] = {
1696 5, 12, 19, 26, 33, 40,
1697 48, 41, 34, 27, 20, 13, 6,
1698 7, 14, 21, 28, 35, 42, 49, 56,
1699 57, 50, 43, 36, 29, 22, 15,
1700 23, 30, 37, 44, 51, 58,
1708 DCTStream::DCTStream(Stream *str1) {
1713 mcuWidth = mcuHeight = 0;
1717 for (i = 0; i < 4; ++i)
1718 for (j = 0; j < 32; ++j)
1719 rowBuf[i][j] = NULL;
1722 for (i = -256; i < 0; ++i)
1723 dctClip[dctClipOffset + i] = 0;
1724 for (i = 0; i < 256; ++i)
1725 dctClip[dctClipOffset + i] = i;
1726 for (i = 256; i < 512; ++i)
1727 dctClip[dctClipOffset + i] = 255;
1732 DCTStream::~DCTStream() {
1736 for (i = 0; i < numComps; ++i)
1737 for (j = 0; j < mcuHeight; ++j)
1738 gfree(rowBuf[i][j]);
1741 void DCTStream::reset() {
1743 if (!readHeader()) {
1747 restartMarker = 0xd0;
1751 int DCTStream::getChar() {
1757 if (++comp == numComps) {
1770 int DCTStream::lookChar() {
1773 if (dy >= mcuHeight) {
1774 if (!readMCURow()) {
1782 return rowBuf[comp][dy][x];
1785 void DCTStream::restart() {
1789 restartCtr = restartInterval;
1790 for (i = 0; i < numComps; ++i)
1791 compInfo[i].prevDC = 0;
1794 GBool DCTStream::readMCURow() {
1797 int pY, pCb, pCr, pR, pG, pB;
1798 int h, v, horiz, vert, hSub, vSub;
1799 int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
1802 for (x1 = 0; x1 < width; x1 += mcuWidth) {
1804 // deal with restart marker
1805 if (restartInterval > 0 && restartCtr == 0) {
1807 if (c != restartMarker) {
1808 error(getPos(), "Bad DCT data: incorrect restart marker");
1811 if (++restartMarker == 0xd8)
1812 restartMarker = 0xd0;
1817 for (cc = 0; cc < numComps; ++cc) {
1818 h = compInfo[cc].hSample;
1819 v = compInfo[cc].vSample;
1820 horiz = mcuWidth / h;
1821 vert = mcuHeight / v;
1824 for (y2 = 0; y2 < mcuHeight; y2 += vert) {
1825 for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
1826 if (!readDataUnit(&dcHuffTables[compInfo[cc].dcHuffTable],
1827 &acHuffTables[compInfo[cc].acHuffTable],
1828 quantTables[compInfo[cc].quantTable],
1829 &compInfo[cc].prevDC,
1832 if (hSub == 1 && vSub == 1) {
1833 for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
1834 p1 = &rowBuf[cc][y2+y3][x1+x2];
1844 } else if (hSub == 2 && vSub == 2) {
1845 for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
1846 p1 = &rowBuf[cc][y2+y3][x1+x2];
1847 p2 = &rowBuf[cc][y2+y3+1][x1+x2];
1848 p1[0] = p1[1] = p2[0] = p2[1] = data[i];
1849 p1[2] = p1[3] = p2[2] = p2[3] = data[i+1];
1850 p1[4] = p1[5] = p2[4] = p2[5] = data[i+2];
1851 p1[6] = p1[7] = p2[6] = p2[7] = data[i+3];
1852 p1[8] = p1[9] = p2[8] = p2[9] = data[i+4];
1853 p1[10] = p1[11] = p2[10] = p2[11] = data[i+5];
1854 p1[12] = p1[13] = p2[12] = p2[13] = data[i+6];
1855 p1[14] = p1[15] = p2[14] = p2[15] = data[i+7];
1859 for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
1860 for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
1861 for (y5 = 0; y5 < vSub; ++y5)
1862 for (x5 = 0; x5 < hSub; ++x5)
1863 rowBuf[cc][y2+y4+y5][x1+x2+x4+x5] = data[i];
1873 // color space conversion
1875 // convert YCbCr to RGB
1876 if (numComps == 3) {
1877 for (y2 = 0; y2 < mcuHeight; ++y2) {
1878 for (x2 = 0; x2 < mcuWidth; ++x2) {
1879 pY = rowBuf[0][y2][x1+x2];
1880 pCb = rowBuf[1][y2][x1+x2] - 128;
1881 pCr = rowBuf[2][y2][x1+x2] - 128;
1882 pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
1883 rowBuf[0][y2][x1+x2] = dctClip[dctClipOffset + pR];
1884 pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
1885 rowBuf[1][y2][x1+x2] = dctClip[dctClipOffset + pG];
1886 pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
1887 rowBuf[2][y2][x1+x2] = dctClip[dctClipOffset + pB];
1890 // convert YCbCrK to CMYK (K is passed through unchanged)
1891 } else if (numComps == 4) {
1892 for (y2 = 0; y2 < mcuHeight; ++y2) {
1893 for (x2 = 0; x2 < mcuWidth; ++x2) {
1894 pY = rowBuf[0][y2][x1+x2];
1895 pCb = rowBuf[1][y2][x1+x2] - 128;
1896 pCr = rowBuf[2][y2][x1+x2] - 128;
1897 pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
1898 rowBuf[0][y2][x1+x2] = 255 - dctClip[dctClipOffset + pR];
1899 pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32678) >> 16;
1900 rowBuf[1][y2][x1+x2] = 255 - dctClip[dctClipOffset + pG];
1901 pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
1902 rowBuf[2][y2][x1+x2] = 255 - dctClip[dctClipOffset + pB];
1911 // This IDCT algorithm is taken from:
1912 // Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,
1913 // "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
1914 // IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
1916 // The stage numbers mentioned in the comments refer to Figure 1 in this
1919 GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
1920 DCTHuffTable *acHuffTable,
1921 Guchar quantTable[64], int *prevDC,
1924 int v0, v1, v2, v3, v4, v5, v6, v7, t;
1929 // Huffman decode and dequantize
1930 size = readHuffSym(dcHuffTable);
1934 amp = readAmp(size);
1940 tmp1[0] = (*prevDC += amp) * quantTable[0];
1941 for (i = 1; i < 64; ++i)
1946 while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30)
1953 run += (c >> 4) & 0x0f;
1955 amp = readAmp(size);
1960 tmp1[j] = amp * quantTable[j];
1964 // inverse DCT on rows
1965 for (i = 0; i < 64; i += 8) {
1968 v0 = (dctSqrt2 * tmp1[i+0] + 128) >> 8;
1969 v1 = (dctSqrt2 * tmp1[i+4] + 128) >> 8;
1972 v4 = (dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]) + 128) >> 8;
1973 v7 = (dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]) + 128) >> 8;
1974 v5 = tmp1[i+3] << 4;
1975 v6 = tmp1[i+5] << 4;
1978 t = (v0 - v1+ 1) >> 1;
1979 v0 = (v0 + v1 + 1) >> 1;
1981 t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8;
1982 v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8;
1984 t = (v4 - v6 + 1) >> 1;
1985 v4 = (v4 + v6 + 1) >> 1;
1987 t = (v7 + v5 + 1) >> 1;
1988 v5 = (v7 - v5 + 1) >> 1;
1992 t = (v0 - v3 + 1) >> 1;
1993 v0 = (v0 + v3 + 1) >> 1;
1995 t = (v1 - v2 + 1) >> 1;
1996 v1 = (v1 + v2 + 1) >> 1;
1998 t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
1999 v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
2001 t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
2002 v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
2006 tmp1[i+0] = v0 + v7;
2007 tmp1[i+7] = v0 - v7;
2008 tmp1[i+1] = v1 + v6;
2009 tmp1[i+6] = v1 - v6;
2010 tmp1[i+2] = v2 + v5;
2011 tmp1[i+5] = v2 - v5;
2012 tmp1[i+3] = v3 + v4;
2013 tmp1[i+4] = v3 - v4;
2016 // inverse DCT on columns
2017 for (i = 0; i < 8; ++i) {
2020 v0 = (dctSqrt2 * tmp1[0*8+i] + 2048) >> 12;
2021 v1 = (dctSqrt2 * tmp1[4*8+i] + 2048) >> 12;
2024 v4 = (dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]) + 2048) >> 12;
2025 v7 = (dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]) + 2048) >> 12;
2030 t = (v0 - v1 + 1) >> 1;
2031 v0 = (v0 + v1 + 1) >> 1;
2033 t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12;
2034 v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12;
2036 t = (v4 - v6 + 1) >> 1;
2037 v4 = (v4 + v6 + 1) >> 1;
2039 t = (v7 + v5 + 1) >> 1;
2040 v5 = (v7 - v5 + 1) >> 1;
2044 t = (v0 - v3 + 1) >> 1;
2045 v0 = (v0 + v3 + 1) >> 1;
2047 t = (v1 - v2 + 1) >> 1;
2048 v1 = (v1 + v2 + 1) >> 1;
2050 t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
2051 v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
2053 t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
2054 v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
2058 tmp1[0*8+i] = v0 + v7;
2059 tmp1[7*8+i] = v0 - v7;
2060 tmp1[1*8+i] = v1 + v6;
2061 tmp1[6*8+i] = v1 - v6;
2062 tmp1[2*8+i] = v2 + v5;
2063 tmp1[5*8+i] = v2 - v5;
2064 tmp1[3*8+i] = v3 + v4;
2065 tmp1[4*8+i] = v3 - v4;
2068 // convert to 8-bit integers
2069 for (i = 0; i < 64; ++i)
2070 data[i] = dctClip[dctClipOffset + 128 + ((tmp1[i] + 8) >> 4)];
2077 GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
2078 DCTHuffTable *acHuffTable,
2079 Guchar quantTable[64], int *prevDC,
2082 double v0, v1, v2, v3, v4, v5, v6, v7, t;
2087 // Huffman decode and dequantize
2088 size = readHuffSym(dcHuffTable);
2092 amp = readAmp(size);
2098 tmp1[0] = (*prevDC += amp) * quantTable[0];
2099 for (i = 1; i < 64; ++i)
2104 while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30)
2111 run += (c >> 4) & 0x0f;
2113 amp = readAmp(size);
2118 tmp1[j] = amp * quantTable[j];
2122 // inverse DCT on rows
2123 for (i = 0; i < 64; i += 8) {
2126 v0 = dctSqrt2 * tmp1[i+0];
2127 v1 = dctSqrt2 * tmp1[i+4];
2130 v4 = dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]);
2131 v7 = dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]);
2136 t = 0.5 * (v0 - v1);
2137 v0 = 0.5 * (v0 + v1);
2139 t = v2 * dctSin6 + v3 * dctCos6;
2140 v2 = v2 * dctCos6 - v3 * dctSin6;
2142 t = 0.5 * (v4 - v6);
2143 v4 = 0.5 * (v4 + v6);
2145 t = 0.5 * (v7 + v5);
2146 v5 = 0.5 * (v7 - v5);
2150 t = 0.5 * (v0 - v3);
2151 v0 = 0.5 * (v0 + v3);
2153 t = 0.5 * (v1 - v2);
2154 v1 = 0.5 * (v1 + v2);
2156 t = v4 * dctSin3 + v7 * dctCos3;
2157 v4 = v4 * dctCos3 - v7 * dctSin3;
2159 t = v5 * dctSin1 + v6 * dctCos1;
2160 v5 = v5 * dctCos1 - v6 * dctSin1;
2164 tmp1[i+0] = v0 + v7;
2165 tmp1[i+7] = v0 - v7;
2166 tmp1[i+1] = v1 + v6;
2167 tmp1[i+6] = v1 - v6;
2168 tmp1[i+2] = v2 + v5;
2169 tmp1[i+5] = v2 - v5;
2170 tmp1[i+3] = v3 + v4;
2171 tmp1[i+4] = v3 - v4;
2174 // inverse DCT on columns
2175 for (i = 0; i < 8; ++i) {
2178 v0 = dctSqrt2 * tmp1[0*8+i];
2179 v1 = dctSqrt2 * tmp1[4*8+i];
2182 v4 = dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]);
2183 v7 = dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]);
2188 t = 0.5 * (v0 - v1);
2189 v0 = 0.5 * (v0 + v1);
2191 t = v2 * dctSin6 + v3 * dctCos6;
2192 v2 = v2 * dctCos6 - v3 * dctSin6;
2194 t = 0.5 * (v4 - v6);
2195 v4 = 0.5 * (v4 + v6);
2197 t = 0.5 * (v7 + v5);
2198 v5 = 0.5 * (v7 - v5);
2202 t = 0.5 * (v0 - v3);
2203 v0 = 0.5 * (v0 + v3);
2205 t = 0.5 * (v1 - v2);
2206 v1 = 0.5 * (v1 + v2);
2208 t = v4 * dctSin3 + v7 * dctCos3;
2209 v4 = v4 * dctCos3 - v7 * dctSin3;
2211 t = v5 * dctSin1 + v6 * dctCos1;
2212 v5 = v5 * dctCos1 - v6 * dctSin1;
2216 tmp1[0*8+i] = v0 + v7;
2217 tmp1[7*8+i] = v0 - v7;
2218 tmp1[1*8+i] = v1 + v6;
2219 tmp1[6*8+i] = v1 - v6;
2220 tmp1[2*8+i] = v2 + v5;
2221 tmp1[5*8+i] = v2 - v5;
2222 tmp1[3*8+i] = v3 + v4;
2223 tmp1[4*8+i] = v3 - v4;
2226 // convert to 8-bit integers
2227 for (i = 0; i < 64; ++i)
2228 data[i] = dctClip[dctClipOffset + (int)(tmp1[i] + 128.5)];
2234 int DCTStream::readHuffSym(DCTHuffTable *table) {
2242 // add a bit to the code
2243 if ((bit = readBit()) == EOF)
2245 code = (code << 1) + bit;
2249 if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
2250 code -= table->firstCode[codeBits];
2251 return table->sym[table->firstSym[codeBits] + code];
2253 } while (codeBits < 16);
2255 error(getPos(), "Bad Huffman code in DCT stream");
2259 int DCTStream::readAmp(int size) {
2264 for (bits = 0; bits < size; ++bits) {
2265 if ((bit = readBit()) == EOF)
2267 amp = (amp << 1) + bit;
2269 if (amp < (1 << (size - 1)))
2270 amp -= (1 << size) - 1;
2274 int DCTStream::readBit() {
2278 if (inputBits == 0) {
2279 if ((c = str->getChar()) == EOF)
2283 c2 = str->getChar();
2284 } while (c2 == 0xff);
2286 error(getPos(), "Bad DCT data: missing 00 after ff");
2293 bit = (inputBuf >> (inputBits - 1)) & 1;
2298 GBool DCTStream::readHeader() {
2300 int minHSample, minVSample;
2309 numDCHuffTables = 0;
2310 numACHuffTables = 0;
2312 gotAdobeMarker = gFalse;
2313 restartInterval = 0;
2321 if (!readFrameInfo())
2325 if (!readHuffmanTables())
2331 if (!readScanInfo())
2336 if (!readQuantTables())
2340 if (!readRestartInterval())
2344 if (!readAdobeMarker())
2348 error(getPos(), "Bad DCT header");
2351 // skip APPn / COM / etc.
2354 for (i = 0; i < n; ++i)
2357 error(getPos(), "Unknown DCT marker <%02x>", c);
2365 mcuWidth = minHSample = compInfo[0].hSample;
2366 mcuHeight = minVSample = compInfo[0].vSample;
2367 for (i = 1; i < numComps; ++i) {
2368 if (compInfo[i].hSample < minHSample)
2369 minHSample = compInfo[i].hSample;
2370 if (compInfo[i].vSample < minVSample)
2371 minVSample = compInfo[i].vSample;
2372 if (compInfo[i].hSample > mcuWidth)
2373 mcuWidth = compInfo[i].hSample;
2374 if (compInfo[i].vSample > mcuHeight)
2375 mcuHeight = compInfo[i].vSample;
2377 for (i = 0; i < numComps; ++i) {
2378 compInfo[i].hSample /= minHSample;
2379 compInfo[i].vSample /= minVSample;
2381 mcuWidth = (mcuWidth / minHSample) * 8;
2382 mcuHeight = (mcuHeight / minVSample) * 8;
2385 bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
2386 for (i = 0; i < numComps; ++i)
2387 for (j = 0; j < mcuHeight; ++j)
2388 rowBuf[i][j] = (Guchar *)gmalloc(bufWidth * sizeof(Guchar));
2390 // figure out color transform
2391 if (!gotAdobeMarker && numComps == 3) {
2392 if (compInfo[0].id == 1 && compInfo[1].id == 2 && compInfo[2].id == 3) {
2397 // initialize counters
2406 GBool DCTStream::readFrameInfo() {
2412 length = read16() - 2;
2413 prec = str->getChar();
2416 numComps = str->getChar();
2419 error(getPos(), "Bad DCT precision %d", prec);
2422 for (i = 0; i < numComps; ++i) {
2423 compInfo[i].id = str->getChar();
2424 compInfo[i].inScan = gFalse;
2426 compInfo[i].hSample = (c >> 4) & 0x0f;
2427 compInfo[i].vSample = c & 0x0f;
2428 compInfo[i].quantTable = str->getChar();
2429 compInfo[i].dcHuffTable = 0;
2430 compInfo[i].acHuffTable = 0;
2435 GBool DCTStream::readScanInfo() {
2437 int scanComps, id, c;
2440 length = read16() - 2;
2441 scanComps = str->getChar();
2443 if (length != 2 * scanComps + 3) {
2444 error(getPos(), "Bad DCT scan info block");
2447 for (i = 0; i < scanComps; ++i) {
2448 id = str->getChar();
2449 for (j = 0; j < numComps; ++j) {
2450 if (id == compInfo[j].id)
2453 if (j == numComps) {
2454 error(getPos(), "Bad DCT component ID in scan info block");
2457 compInfo[j].inScan = gTrue;
2459 compInfo[j].dcHuffTable = (c >> 4) & 0x0f;
2460 compInfo[j].acHuffTable = c & 0x0f;
2468 GBool DCTStream::readQuantTables() {
2473 length = read16() - 2;
2474 while (length > 0) {
2475 index = str->getChar();
2476 if ((index & 0xf0) || index >= 4) {
2477 error(getPos(), "Bad DCT quantization table");
2480 if (index == numQuantTables)
2481 numQuantTables = index + 1;
2482 for (i = 0; i < 64; ++i)
2483 quantTables[index][dctZigZag[i]] = str->getChar();
2489 GBool DCTStream::readHuffmanTables() {
2498 length = read16() - 2;
2499 while (length > 0) {
2500 index = str->getChar();
2502 if ((index & 0x0f) >= 4) {
2503 error(getPos(), "Bad DCT Huffman table");
2508 if (index >= numACHuffTables)
2509 numACHuffTables = index+1;
2510 tbl = &acHuffTables[index];
2512 if (index >= numDCHuffTables)
2513 numDCHuffTables = index+1;
2514 tbl = &dcHuffTables[index];
2518 for (i = 1; i <= 16; ++i) {
2520 tbl->firstSym[i] = sym;
2521 tbl->firstCode[i] = code;
2522 tbl->numCodes[i] = c;
2524 code = (code + c) << 1;
2527 for (i = 0; i < sym; ++i)
2528 tbl->sym[i] = str->getChar();
2534 GBool DCTStream::readRestartInterval() {
2539 error(getPos(), "Bad DCT restart interval");
2542 restartInterval = read16();
2546 GBool DCTStream::readAdobeMarker() {
2554 for (i = 0; i < 12; ++i) {
2555 if ((c = str->getChar()) == EOF)
2559 if (strncmp(buf, "Adobe", 5))
2561 colorXform = buf[11];
2562 gotAdobeMarker = gTrue;
2566 error(getPos(), "Bad DCT Adobe APP14 marker");
2570 GBool DCTStream::readTrailer() {
2574 if (c != 0xd9) { // EOI
2575 error(getPos(), "Bad DCT trailer");
2581 int DCTStream::readMarker() {
2587 } while (c != 0xff);
2590 } while (c == 0xff);
2591 } while (c == 0x00);
2595 int DCTStream::read16() {
2598 if ((c1 = str->getChar()) == EOF)
2600 if ((c2 = str->getChar()) == EOF)
2602 return (c1 << 8) + c2;
2605 GString *DCTStream::getPSFilter(char *indent) {
2608 s = str->getPSFilter(indent);
2609 s->append(indent)->append("<< >> /DCTDecode filter\n");
2613 GBool DCTStream::isBinary(GBool last) {
2614 return str->isBinary(gTrue);
2617 //------------------------------------------------------------------------
2619 //------------------------------------------------------------------------
2621 int FlateStream::codeLenCodeMap[flateMaxCodeLenCodes] = {
2622 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
2625 FlateDecode FlateStream::lengthDecode[flateMaxLitCodes-257] = {
2657 FlateDecode FlateStream::distDecode[flateMaxDistCodes] = {
2690 FlateStream::FlateStream(Stream *str1, int predictor1, int columns1,
2691 int colors1, int bits1) {
2693 if (predictor1 != 1) {
2694 pred = new StreamPredictor(this, predictor1, columns1, colors1, bits1);
2700 FlateStream::~FlateStream() {
2707 void FlateStream::reset() {
2713 //~ need to look at window size?
2714 endOfBlock = eof = gTrue;
2715 cmf = str->getChar();
2716 flg = str->getChar();
2717 if (cmf == EOF || flg == EOF)
2719 if ((cmf & 0x0f) != 0x08) {
2720 error(getPos(), "Unknown compression method in flate stream");
2723 if ((((cmf << 8) + flg) % 31) != 0) {
2724 error(getPos(), "Bad FCHECK in flate stream");
2728 error(getPos(), "FDICT bit set in flate stream");
2737 compressedBlock = gFalse;
2742 int FlateStream::getChar() {
2746 return pred->getChar();
2748 while (remain == 0) {
2749 if (endOfBlock && eof)
2754 index = (index + 1) & flateMask;
2759 int FlateStream::lookChar() {
2763 return pred->lookChar();
2765 while (remain == 0) {
2766 if (endOfBlock && eof)
2774 int FlateStream::getRawChar() {
2777 while (remain == 0) {
2778 if (endOfBlock && eof)
2783 index = (index + 1) & flateMask;
2788 GString *FlateStream::getPSFilter(char *indent) {
2792 GBool FlateStream::isBinary(GBool last) {
2793 return str->isBinary(gTrue);
2796 void FlateStream::readSome() {
2807 if (compressedBlock) {
2808 if ((code1 = getHuffmanCodeWord(&litCodeTab)) == EOF)
2813 } else if (code1 == 256) {
2818 code2 = lengthDecode[code1].bits;
2819 if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
2821 len = lengthDecode[code1].first + code2;
2822 if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF)
2824 code2 = distDecode[code1].bits;
2825 if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
2827 dist = distDecode[code1].first + code2;
2829 j = (index - dist) & flateMask;
2830 for (k = 0; k < len; ++k) {
2832 i = (i + 1) & flateMask;
2833 j = (j + 1) & flateMask;
2839 len = (blockLen < flateWindow) ? blockLen : flateWindow;
2840 for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) {
2841 if ((c = str->getChar()) == EOF) {
2842 endOfBlock = eof = gTrue;
2856 error(getPos(), "Unexpected end of file in flate stream");
2857 endOfBlock = eof = gTrue;
2861 GBool FlateStream::startBlock() {
2866 // read block header
2867 blockHdr = getCodeWord(3);
2872 // uncompressed block
2873 if (blockHdr == 0) {
2874 compressedBlock = gFalse;
2875 if ((c = str->getChar()) == EOF)
2877 blockLen = c & 0xff;
2878 if ((c = str->getChar()) == EOF)
2880 blockLen |= (c & 0xff) << 8;
2881 if ((c = str->getChar()) == EOF)
2884 if ((c = str->getChar()) == EOF)
2886 check |= (c & 0xff) << 8;
2887 if (check != (~blockLen & 0xffff))
2888 error(getPos(), "Bad uncompressed block length in flate stream");
2892 // compressed block with fixed codes
2893 } else if (blockHdr == 1) {
2894 compressedBlock = gTrue;
2897 // compressed block with dynamic codes
2898 } else if (blockHdr == 2) {
2899 compressedBlock = gTrue;
2900 if (!readDynamicCodes())
2903 // unknown block type
2908 endOfBlock = gFalse;
2912 error(getPos(), "Bad block header in flate stream");
2913 endOfBlock = eof = gTrue;
2917 void FlateStream::loadFixedCodes() {
2920 // set up code arrays
2921 litCodeTab.codes = allCodes;
2922 distCodeTab.codes = allCodes + flateMaxLitCodes;
2924 // initialize literal code table
2925 for (i = 0; i <= 143; ++i)
2926 litCodeTab.codes[i].len = 8;
2927 for (i = 144; i <= 255; ++i)
2928 litCodeTab.codes[i].len = 9;
2929 for (i = 256; i <= 279; ++i)
2930 litCodeTab.codes[i].len = 7;
2931 for (i = 280; i <= 287; ++i)
2932 litCodeTab.codes[i].len = 8;
2933 compHuffmanCodes(&litCodeTab, flateMaxLitCodes);
2935 // initialize distance code table
2936 for (i = 0; i < 5; ++i)
2937 distCodeTab.start[i] = 0;
2938 distCodeTab.start[5] = 0;
2939 for (i = 6; i <= flateMaxHuffman+1; ++i)
2940 distCodeTab.start[6] = flateMaxDistCodes;
2941 for (i = 0; i < flateMaxDistCodes; ++i) {
2942 distCodeTab.codes[i].len = 5;
2943 distCodeTab.codes[i].code = i;
2944 distCodeTab.codes[i].val = i;
2948 GBool FlateStream::readDynamicCodes() {
2949 int numCodeLenCodes;
2952 FlateCode codeLenCodes[flateMaxCodeLenCodes];
2953 FlateHuffmanTab codeLenCodeTab;
2954 int len, repeat, code;
2958 if ((numLitCodes = getCodeWord(5)) == EOF)
2961 if ((numDistCodes = getCodeWord(5)) == EOF)
2964 if ((numCodeLenCodes = getCodeWord(4)) == EOF)
2966 numCodeLenCodes += 4;
2967 if (numLitCodes > flateMaxLitCodes ||
2968 numDistCodes > flateMaxDistCodes ||
2969 numCodeLenCodes > flateMaxCodeLenCodes)
2972 // read code length code table
2973 codeLenCodeTab.codes = codeLenCodes;
2974 for (i = 0; i < flateMaxCodeLenCodes; ++i)
2975 codeLenCodes[i].len = 0;
2976 for (i = 0; i < numCodeLenCodes; ++i) {
2977 if ((codeLenCodes[codeLenCodeMap[i]].len = getCodeWord(3)) == -1)
2980 compHuffmanCodes(&codeLenCodeTab, flateMaxCodeLenCodes);
2982 // set up code arrays
2983 litCodeTab.codes = allCodes;
2984 distCodeTab.codes = allCodes + numLitCodes;
2986 // read literal and distance code tables
2990 while (i < numLitCodes + numDistCodes) {
2991 if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF)
2994 if ((repeat = getCodeWord(2)) == EOF)
2996 for (repeat += 3; repeat > 0; --repeat)
2997 allCodes[i++].len = len;
2998 } else if (code == 17) {
2999 if ((repeat = getCodeWord(3)) == EOF)
3002 for (repeat += 3; repeat > 0; --repeat)
3003 allCodes[i++].len = 0;
3004 } else if (code == 18) {
3005 if ((repeat = getCodeWord(7)) == EOF)
3008 for (repeat += 11; repeat > 0; --repeat)
3009 allCodes[i++].len = 0;
3011 allCodes[i++].len = len = code;
3014 compHuffmanCodes(&litCodeTab, numLitCodes);
3015 compHuffmanCodes(&distCodeTab, numDistCodes);
3020 error(getPos(), "Bad dynamic code table in flate stream");
3024 // On entry, the <tab->codes> array contains the lengths of each code,
3025 // stored in code value order. This function computes the code words.
3026 // The result is sorted in order of (1) code length and (2) code word.
3027 // The length values are no longer valid. The <tab->start> array is
3028 // filled with the indexes of the first code of each length.
3029 void FlateStream::compHuffmanCodes(FlateHuffmanTab *tab, int n) {
3030 int numLengths[flateMaxHuffman+1];
3031 int nextCode[flateMaxHuffman+1];
3032 int nextIndex[flateMaxHuffman+2];
3036 // count number of codes for each code length
3037 for (i = 0; i <= flateMaxHuffman; ++i)
3039 for (i = 0; i < n; ++i)
3040 ++numLengths[tab->codes[i].len];
3042 // compute first index for each length
3043 tab->start[0] = nextIndex[0] = 0;
3044 for (i = 1; i <= flateMaxHuffman + 1; ++i)
3045 tab->start[i] = nextIndex[i] = tab->start[i-1] + numLengths[i-1];
3047 // compute first code for each length
3050 for (i = 1; i <= flateMaxHuffman; ++i) {
3051 code = (code + numLengths[i-1]) << 1;
3055 // compute the codes -- this permutes the codes array from value
3056 // order to length/code order
3057 for (i = 0; i < n; ++i) {
3058 j = nextIndex[tab->codes[i].len]++;
3059 if (tab->codes[i].len == 0)
3060 tab->codes[j].code = 0;
3062 tab->codes[j].code = nextCode[tab->codes[i].len]++;
3063 tab->codes[j].val = i;
3067 int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) {
3074 for (len = 1; len <= flateMaxHuffman; ++len) {
3076 // add a bit to the code
3077 if (codeSize == 0) {
3078 if ((c = str->getChar()) == EOF)
3083 code = (code << 1) | (codeBuf & 1);
3088 i = tab->start[len];
3089 j = tab->start[len + 1];
3090 if (i < j && code >= tab->codes[i].code && code <= tab->codes[j-1].code) {
3091 i += code - tab->codes[i].code;
3092 return tab->codes[i].val;
3097 error(getPos(), "Bad code (%04x) in flate stream", code);
3101 int FlateStream::getCodeWord(int bits) {
3104 while (codeSize < bits) {
3105 if ((c = str->getChar()) == EOF)
3107 codeBuf |= (c & 0xff) << codeSize;
3110 c = codeBuf & ((1 << bits) - 1);
3116 //------------------------------------------------------------------------
3118 //------------------------------------------------------------------------
3120 EOFStream::EOFStream(Stream *str1) {
3124 EOFStream::~EOFStream() {
3128 //------------------------------------------------------------------------
3129 // FixedLengthEncoder
3130 //------------------------------------------------------------------------
3132 FixedLengthEncoder::FixedLengthEncoder(Stream *str1, int length1) {
3138 FixedLengthEncoder::~FixedLengthEncoder() {
3139 if (str->isEncoder())
3143 void FixedLengthEncoder::reset() {
3148 int FixedLengthEncoder::getChar() {
3149 if (length >= 0 && count >= length)
3152 return str->getChar();
3155 int FixedLengthEncoder::lookChar() {
3156 if (length >= 0 && count >= length)
3158 return str->getChar();
3161 //------------------------------------------------------------------------
3163 //------------------------------------------------------------------------
3165 ASCII85Encoder::ASCII85Encoder(Stream *str1) {
3167 bufPtr = bufEnd = buf;
3172 ASCII85Encoder::~ASCII85Encoder() {
3173 if (str->isEncoder())
3177 void ASCII85Encoder::reset() {
3179 bufPtr = bufEnd = buf;
3184 GBool ASCII85Encoder::fillBuf() {
3193 for (n = 0; n < 4; ++n) {
3194 if ((c = str->getChar()) == EOF)
3198 bufPtr = bufEnd = buf;
3200 if (n == 4 && t == 0) {
3202 if (++lineLen == 65) {
3209 for (i = 4; i >= 0; --i) {
3210 buf1[i] = (char)(t % 85 + 0x21);
3213 for (i = 0; i <= n; ++i) {
3214 *bufEnd++ = buf1[i];
3215 if (++lineLen == 65) {
3227 return bufPtr < bufEnd;
3230 //------------------------------------------------------------------------
3232 //------------------------------------------------------------------------
3234 RunLengthEncoder::RunLengthEncoder(Stream *str1) {
3236 bufPtr = bufEnd = nextEnd = buf;
3240 RunLengthEncoder::~RunLengthEncoder() {
3241 if (str->isEncoder())
3245 void RunLengthEncoder::reset() {
3247 bufPtr = bufEnd = nextEnd = buf;
3252 // When fillBuf finishes, buf[] looks like this:
3253 // +-----+--------------+-----------------+--
3254 // + tag | ... data ... | next 0, 1, or 2 |
3255 // +-----+--------------+-----------------+--
3257 // bufPtr bufEnd nextEnd
3259 GBool RunLengthEncoder::fillBuf() {
3268 if (nextEnd < bufEnd + 1) {
3269 if ((c1 = str->getChar()) == EOF) {
3274 c1 = bufEnd[0] & 0xff;
3276 if (nextEnd < bufEnd + 2) {
3277 if ((c2 = str->getChar()) == EOF) {
3286 c2 = bufEnd[1] & 0xff;
3292 while (n < 128 && (c = str->getChar()) == c1)
3294 buf[0] = (char)(257 - n);
3299 } else if (n < 128) {
3306 // get up to 128 chars
3312 if ((c = str->getChar()) == EOF) {
3318 if (buf[n] == buf[n-1])
3321 if (buf[n] == buf[n-1]) {
3322 buf[0] = (char)(n-2-1);
3324 nextEnd = &buf[n+1];
3326 buf[0] = (char)(n-1);
3327 bufEnd = nextEnd = &buf[n+1];