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 GBool FileStream::checkHeader() {
515 char hdrBuf[headerSearchSize+1];
520 for (i = 0; i < headerSearchSize; ++i)
521 hdrBuf[i] = getChar();
522 hdrBuf[headerSearchSize] = '\0';
523 for (i = 0; i < headerSearchSize - 5; ++i) {
524 if (!strncmp(&hdrBuf[i], "%PDF-", 5))
527 if (i >= headerSearchSize - 5) {
528 error(-1, "May not be a PDF file (continuing anyway)");
532 p = strtok(&hdrBuf[i+5], " \t\n\r");
534 if (!(hdrBuf[i+5] >= '0' && hdrBuf[i+5] <= '9') ||
535 version > pdfVersionNum + 0.0001) {
536 error(getPos(), "PDF version %s -- xpdf supports version %s"
537 " (continuing anyway)", p, pdfVersion);
543 FILE *fileOpen (GString *fileName1) {
550 if (!(file = fopen(fileName->getCString(), "rb", "ctx=stm"))) {
551 error(-1, "Couldn't open file '%s'", fileName->getCString());
555 if (!(file = fopen(fileName1->getCString(), "rb"))) {
556 fileName2 = fileName1->copy();
557 fileName2->lowerCase();
558 if (!(file = fopen(fileName2->getCString(), "rb"))) {
559 fileName2->upperCase();
560 if (!(file = fopen(fileName2->getCString(), "rb"))) {
561 error(-1, "Couldn't open file '%s'", fileName1->getCString());
572 FileStream::FileStream(FILE *f1) {
576 bufPtr = bufEnd = buf;
583 Stream *FileStream::subStream (int start1, int length1, Object *dict1) {
586 bufPtr = bufEnd = buf;
592 FileStream::~FileStream() {
594 fseek(f, savePos, SEEK_SET);
598 void FileStream::reset() {
599 savePos = (int)ftell(f);
600 fseek(f, start, SEEK_SET);
601 bufPtr = bufEnd = buf;
605 GBool FileStream::fillBuf() {
608 bufPos += bufEnd - buf;
609 bufPtr = bufEnd = buf;
610 if (length >= 0 && bufPos >= start + length)
612 if (length >= 0 && bufPos + 256 > start + length)
613 n = start + length - bufPos;
616 n = fread(buf, 1, n, f);
618 if (bufPtr >= bufEnd)
623 void FileStream::setPos(int pos1) {
627 fseek(f, pos1, SEEK_SET);
630 fseek(f, 0, SEEK_END);
634 fseek(f, pos1, SEEK_END);
635 bufPos = (int)ftell(f);
637 bufPtr = bufEnd = buf;
640 //------------------------------------------------------------------------
642 //------------------------------------------------------------------------
644 SubStream::SubStream(Stream *str1, Object *dict1) {
649 SubStream::~SubStream() {
653 //------------------------------------------------------------------------
655 //------------------------------------------------------------------------
657 ASCIIHexStream::ASCIIHexStream(Stream *str1) {
663 ASCIIHexStream::~ASCIIHexStream() {
667 void ASCIIHexStream::reset() {
673 int ASCIIHexStream::lookChar() {
684 } while (isspace(c1));
692 } while (isspace(c2));
697 if (c1 >= '0' && c1 <= '9') {
699 } else if (c1 >= 'A' && c1 <= 'F') {
700 x = (c1 - 'A' + 10) << 4;
701 } else if (c1 >= 'a' && c1 <= 'f') {
702 x = (c1 - 'a' + 10) << 4;
703 } else if (c1 == EOF) {
707 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c1);
710 if (c2 >= '0' && c2 <= '9') {
712 } else if (c2 >= 'A' && c2 <= 'F') {
714 } else if (c2 >= 'a' && c2 <= 'f') {
716 } else if (c2 == EOF) {
720 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c2);
726 GString *ASCIIHexStream::getPSFilter(char *indent) {
729 s = str->getPSFilter(indent);
730 s->append(indent)->append("/ASCIIHexDecode filter\n");
734 GBool ASCIIHexStream::isBinary(GBool last) {
735 return str->isBinary(gFalse);
738 //------------------------------------------------------------------------
740 //------------------------------------------------------------------------
742 ASCII85Stream::ASCII85Stream(Stream *str1) {
748 ASCII85Stream::~ASCII85Stream() {
752 void ASCII85Stream::reset() {
758 int ASCII85Stream::lookChar() {
767 c[0] = str->getChar();
768 } while (c[0] == '\n' || c[0] == '\r');
769 if (c[0] == '~' || c[0] == EOF) {
773 } else if (c[0] == 'z') {
774 b[0] = b[1] = b[2] = b[3] = 0;
777 for (k = 1; k < 5; ++k) {
779 c[k] = str->getChar();
780 } while (c[k] == '\n' || c[k] == '\r');
781 if (c[k] == '~' || c[k] == EOF)
785 if (k < 5 && (c[k] == '~' || c[k] == EOF)) {
786 for (++k; k < 5; ++k)
791 for (k = 0; k < 5; ++k)
792 t = t * 85 + (c[k] - 0x21);
793 for (k = 3; k >= 0; --k) {
794 b[k] = (int)(t & 0xff);
802 GString *ASCII85Stream::getPSFilter(char *indent) {
805 s = str->getPSFilter(indent);
806 s->append(indent)->append("/ASCII85Decode filter\n");
810 GBool ASCII85Stream::isBinary(GBool last) {
811 return str->isBinary(gFalse);
814 //------------------------------------------------------------------------
816 //------------------------------------------------------------------------
818 LZWStream::LZWStream(Stream *str1, int predictor1, int columns1, int colors1,
819 int bits1, int early1) {
821 if (predictor1 != 1) {
822 pred = new StreamPredictor(this, predictor1, columns1, colors1, bits1);
828 bufPtr = bufEnd = buf;
831 LZWStream::~LZWStream() {
847 int LZWStream::getChar() {
849 return pred->getChar();
851 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
854 int LZWStream::lookChar() {
856 return pred->lookChar();
858 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff);
861 int LZWStream::getRawChar() {
862 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
865 void LZWStream::reset() {
869 bufPtr = bufEnd = buf;
880 if (!setDJSYSFLAGS) {
881 setenv("DJSYSFLAGS", "0x0002", 0);
882 setDJSYSFLAGS = gTrue;
885 strcpy(zCmd, uncompressCmd);
887 zName = zCmd + strlen(zCmd);
890 zName[strlen(zName) - 2] = '\0';
893 if (!(f = fopen(zName, "wb"))) {
894 error(getPos(), "Couldn't open temporary file '%s'", zName);
900 if (!(zPipe = popen(zCmd, "r"))) {
901 error(getPos(), "Couldn't popen '%s'", zCmd);
911 error(getPos(), "Couldn't execute '%s'", zCmd);
915 zName[strlen(zName) - 2] = '\0';
916 if (!(zPipe = fopen(zName, "rb"))) {
917 error(getPos(), "Couldn't open uncompress file '%s'", zName);
924 void LZWStream::dumpFile(FILE *f) {
925 int outCodeBits; // size of output code
926 int outBits; // max output code
927 int outBuf[8]; // output buffer
928 int outData; // temporary output buffer
929 int inCode, outCode; // input and output codes
930 int nextCode; // next code index
931 GBool eof; // set when EOF is reached
932 GBool clear; // set if table needs to be cleared
933 GBool first; // indicates first code word after clear
940 // max code length, block mode flag
958 for (i = 0; i < 8; ++i) {
959 // check for table overflow
960 if (nextCode + early > 0x1001) {
971 } while (first && inCode == 256);
974 // compute output code
977 } else if (inCode == 256) {
980 } else if (inCode == 257) {
984 outCode = inCode - 1;
994 // check input code size
995 if (nextCode + early == 0x200)
997 else if (nextCode + early == 0x400) {
999 } else if (nextCode + early == 0x800) {
1003 // check for eof/clear
1012 // write output block
1016 while (j < i || outBits > 0) {
1017 if (outBits < 8 && j < i) {
1018 outData = outData | (outBuf[j++] << outBits);
1019 outBits += outCodeBits;
1021 fputc(outData & 0xff, f);
1026 // check output code size
1027 if (nextCode - 1 == 512 ||
1028 nextCode - 1 == 1024 ||
1029 nextCode - 1 == 2048 ||
1030 nextCode - 1 == 4096) {
1031 outCodeBits = inCodeBits;
1034 // clear table if necessary
1045 int LZWStream::getCode() {
1049 while (inputBits < inCodeBits) {
1050 if ((c = str->getChar()) == EOF)
1052 inputBuf = (inputBuf << 8) | (c & 0xff);
1055 code = (inputBuf >> (inputBits - inCodeBits)) & ((1 << inCodeBits) - 1);
1056 inputBits -= inCodeBits;
1060 GBool LZWStream::fillBuf() {
1065 if ((n = fread(buf, 1, 256, zPipe)) < 256) {
1079 GString *LZWStream::getPSFilter(char *indent) {
1085 s = str->getPSFilter(indent);
1086 s->append(indent)->append("/LZWDecode filter\n");
1090 GBool LZWStream::isBinary(GBool last) {
1091 return str->isBinary(gTrue);
1094 //------------------------------------------------------------------------
1096 //------------------------------------------------------------------------
1098 RunLengthStream::RunLengthStream(Stream *str1) {
1100 bufPtr = bufEnd = buf;
1104 RunLengthStream::~RunLengthStream() {
1108 void RunLengthStream::reset() {
1110 bufPtr = bufEnd = buf;
1114 GString *RunLengthStream::getPSFilter(char *indent) {
1117 s = str->getPSFilter(indent);
1118 s->append(indent)->append("/RunLengthDecode filter\n");
1122 GBool RunLengthStream::isBinary(GBool last) {
1123 return str->isBinary(gTrue);
1126 GBool RunLengthStream::fillBuf() {
1133 if (c == 0x80 || c == EOF) {
1139 for (i = 0; i < n; ++i)
1140 buf[i] = (char)str->getChar();
1144 for (i = 0; i < n; ++i)
1152 //------------------------------------------------------------------------
1154 //------------------------------------------------------------------------
1156 CCITTFaxStream::CCITTFaxStream(Stream *str, int encoding, GBool endOfLine,
1157 GBool byteAlign, int columns, int rows,
1158 GBool endOfBlock, GBool black) {
1160 this->encoding = encoding;
1161 this->endOfLine = endOfLine;
1162 this->byteAlign = byteAlign;
1163 this->columns = columns;
1165 this->endOfBlock = endOfBlock;
1166 this->black = black;
1167 refLine = (short *)gmalloc((columns + 2) * sizeof(short));
1168 codingLine = (short *)gmalloc((columns + 2) * sizeof(short));
1172 nextLine2D = encoding < 0;
1175 codingLine[1] = refLine[2] = columns;
1181 CCITTFaxStream::~CCITTFaxStream() {
1187 void CCITTFaxStream::reset() {
1193 nextLine2D = encoding < 0;
1196 codingLine[1] = refLine[2] = columns;
1200 // get initial end-of-line marker and 2D encoding tag
1202 if (lookBits(12) == 0x001) {
1206 for (n = 0; n < 11 && lookBits(n) == 0; ++n) ;
1207 if (n == 11 && lookBits(12) == 0x001) {
1212 nextLine2D = !lookBits(1);
1217 int CCITTFaxStream::lookChar() {
1218 short code1, code2, code3;
1226 // if at eof just return EOF
1227 if (eof && codingLine[a0] >= columns) {
1231 // read the next row
1235 if (codingLine[a0] >= columns) {
1239 for (i = 0; codingLine[i] < columns; ++i)
1240 refLine[i] = codingLine[i];
1241 refLine[i] = refLine[i + 1] = columns;
1243 a0New = codingLine[a0 = 0] = 0;
1245 code1 = getTwoDimCode();
1248 if (refLine[b1] < columns) {
1249 a0New = refLine[b1 + 1];
1254 if ((a0 & 1) == 0) {
1257 code1 += code3 = getWhiteCode();
1258 } while (code3 >= 64);
1260 code2 += code3 = getBlackCode();
1261 } while (code3 >= 64);
1265 code1 += code3 = getBlackCode();
1266 } while (code3 >= 64);
1268 code2 += code3 = getWhiteCode();
1269 } while (code3 >= 64);
1271 codingLine[a0 + 1] = a0New + code1;
1273 a0New = codingLine[a0 + 1] = codingLine[a0] + code2;
1275 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1279 a0New = codingLine[++a0] = refLine[b1];
1280 if (refLine[b1] < columns) {
1282 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1287 a0New = codingLine[++a0] = refLine[b1] + 1;
1288 if (refLine[b1] < columns) {
1290 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1295 a0New = codingLine[++a0] = refLine[b1] - 1;
1297 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1301 a0New = codingLine[++a0] = refLine[b1] + 2;
1302 if (refLine[b1] < columns) {
1304 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1309 a0New = codingLine[++a0] = refLine[b1] - 2;
1311 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1315 a0New = codingLine[++a0] = refLine[b1] + 3;
1316 if (refLine[b1] < columns) {
1318 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1323 a0New = codingLine[++a0] = refLine[b1] - 3;
1325 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1330 codingLine[a0 = 0] = columns;
1333 error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1);
1342 } while (codingLine[a0] < columns);
1346 codingLine[a0 = 0] = 0;
1350 code1 += code3 = getWhiteCode();
1351 } while (code3 >= 64);
1352 codingLine[a0+1] = codingLine[a0] + code1;
1354 if (codingLine[a0] >= columns)
1358 code2 += code3 = getBlackCode();
1359 } while (code3 >= 64);
1360 codingLine[a0+1] = codingLine[a0] + code2;
1362 if (codingLine[a0] >= columns)
1367 if (codingLine[a0] != columns) {
1368 error(getPos(), "CCITTFax row is wrong length (%d)", codingLine[a0]);
1374 // byte-align the row
1379 // check for end-of-line marker, end-of-block marker, and
1382 code1 = lookBits(12);
1385 } else if (code1 == 0x001) {
1388 nextLine2D = !lookBits(1);
1391 code1 = lookBits(12);
1392 if (code1 == 0x001) {
1398 if (encoding >= 0) {
1399 for (i = 0; i < 4; ++i) {
1400 code1 = lookBits(12);
1401 if (code1 != 0x001) {
1402 error(getPos(), "Bad RTC code in CCITTFax stream");
1415 nextLine2D = !lookBits(1);
1420 if (row == rows - 1) {
1423 for (n = 0; n < 11 && lookBits(n) == 0; ++n) ;
1424 if (n == 11 && lookBits(12) == 0x001) {
1428 nextLine2D = !lookBits(1);
1435 // This looks for an end-of-line marker after an error, however
1436 // some (most?) CCITT streams in PDF files don't use end-of-line
1437 // markers, and the just-plow-on technique works better in those
1446 code1 = look13Bits();
1447 } while ((code1 >> 1) != 0x001);
1449 codingLine[++a0] = columns;
1452 nextLine2D = !(code1 & 1);
1458 outputBits = codingLine[1] - codingLine[0];
1459 if (outputBits == 0) {
1461 outputBits = codingLine[2] - codingLine[1];
1468 if (outputBits >= 8) {
1469 ret = ((a0 & 1) == 0) ? 0xff : 0x00;
1470 if ((outputBits -= 8) == 0) {
1472 if (codingLine[a0] < columns) {
1473 outputBits = codingLine[a0 + 1] - codingLine[a0];
1480 if (outputBits > bits) {
1483 if ((a0 & 1) == 0) {
1484 ret |= 0xff >> (8 - i);
1490 if ((a0 & 1) == 0) {
1491 ret |= (0xff >> (8 - i)) << bits;
1495 if (codingLine[a0] < columns) {
1496 outputBits = codingLine[a0 + 1] - codingLine[a0];
1499 } while (bits > 0 && codingLine[a0] < columns);
1501 buf = black ? (ret ^ 0xff) : ret;
1505 short CCITTFaxStream::getTwoDimCode() {
1510 code = 0; // make gcc happy
1513 p = &twoDimTab1[code];
1519 for (n = 1; n <= 7; ++n) {
1524 p = &twoDimTab1[code];
1531 error(getPos(), "Bad two dim code (%04x) in CCITTFax stream", code);
1535 short CCITTFaxStream::getWhiteCode() {
1540 code = 0; // make gcc happy
1542 code = lookBits(12);
1543 if ((code >> 5) == 0)
1544 p = &whiteTab1[code];
1546 p = &whiteTab2[code >> 3];
1552 for (n = 1; n <= 9; ++n) {
1557 p = &whiteTab2[code];
1563 for (n = 11; n <= 12; ++n) {
1568 p = &whiteTab1[code];
1575 error(getPos(), "Bad white code (%04x) in CCITTFax stream", code);
1579 short CCITTFaxStream::getBlackCode() {
1584 code = 0; // make gcc happy
1586 code = lookBits(13);
1587 if ((code >> 7) == 0)
1588 p = &blackTab1[code];
1589 else if ((code >> 9) == 0)
1590 p = &blackTab2[(code >> 1) - 64];
1592 p = &blackTab3[code >> 7];
1598 for (n = 2; n <= 6; ++n) {
1603 p = &blackTab3[code];
1609 for (n = 7; n <= 12; ++n) {
1615 p = &blackTab2[code - 64];
1622 for (n = 10; n <= 13; ++n) {
1627 p = &blackTab1[code];
1634 error(getPos(), "Bad black code (%04x) in CCITTFax stream", code);
1638 short CCITTFaxStream::lookBits(int n) {
1641 while (inputBits < n) {
1642 if ((c = str->getChar()) == EOF) {
1647 inputBuf = (inputBuf << 8) + c;
1650 return (inputBuf >> (inputBits - n)) & (0xffff >> (16 - n));
1653 GString *CCITTFaxStream::getPSFilter(char *indent) {
1657 s = str->getPSFilter(indent);
1658 s->append(indent)->append("<< ");
1659 if (encoding != 0) {
1660 sprintf(s1, "/K %d ", encoding);
1664 s->append("/EndOfLine true ");
1667 s->append("/EncodedByteAlign true ");
1669 sprintf(s1, "/Columns %d ", columns);
1672 sprintf(s1, "/Rows %d ", rows);
1676 s->append("/EndOfBlock false ");
1679 s->append("/BlackIs1 true ");
1681 s->append(">> /CCITTFaxDecode filter\n");
1685 GBool CCITTFaxStream::isBinary(GBool last) {
1686 return str->isBinary(gTrue);
1689 //------------------------------------------------------------------------
1691 //------------------------------------------------------------------------
1693 // IDCT constants (20.12 fixed point format)
1695 #define dctCos1 4017 // cos(pi/16)
1696 #define dctSin1 799 // sin(pi/16)
1697 #define dctCos3 3406 // cos(3*pi/16)
1698 #define dctSin3 2276 // sin(3*pi/16)
1699 #define dctCos6 1567 // cos(6*pi/16)
1700 #define dctSin6 3784 // sin(6*pi/16)
1701 #define dctSqrt2 5793 // sqrt(2)
1702 #define dctSqrt1d2 2896 // sqrt(2) / 2
1707 #define dctCos1 0.98078528 // cos(pi/16)
1708 #define dctSin1 0.19509032 // sin(pi/16)
1709 #define dctCos3 0.83146961 // cos(3*pi/16)
1710 #define dctSin3 0.55557023 // sin(3*pi/16)
1711 #define dctCos6 0.38268343 // cos(6*pi/16)
1712 #define dctSin6 0.92387953 // sin(6*pi/16)
1713 #define dctSqrt2 1.41421356 // sqrt(2)
1714 #define dctSqrt1d2 0.70710678 // sqrt(2) / 2
1717 // color conversion parameters (16.16 fixed point format)
1718 #define dctCrToR 91881 // 1.4020
1719 #define dctCbToG -22553 // -0.3441363
1720 #define dctCrToG -46802 // -0.71413636
1721 #define dctCbToB 116130 // 1.772
1723 // clip [-256,511] --> [0,255]
1724 #define dctClipOffset 256
1725 static Guchar dctClip[768];
1726 static int dctClipInit = 0;
1728 // zig zag decode map
1729 static int dctZigZag[64] = {
1735 5, 12, 19, 26, 33, 40,
1736 48, 41, 34, 27, 20, 13, 6,
1737 7, 14, 21, 28, 35, 42, 49, 56,
1738 57, 50, 43, 36, 29, 22, 15,
1739 23, 30, 37, 44, 51, 58,
1747 DCTStream::DCTStream(Stream *str1) {
1752 mcuWidth = mcuHeight = 0;
1756 for (i = 0; i < 4; ++i)
1757 for (j = 0; j < 32; ++j)
1758 rowBuf[i][j] = NULL;
1761 for (i = -256; i < 0; ++i)
1762 dctClip[dctClipOffset + i] = 0;
1763 for (i = 0; i < 256; ++i)
1764 dctClip[dctClipOffset + i] = i;
1765 for (i = 256; i < 512; ++i)
1766 dctClip[dctClipOffset + i] = 255;
1771 DCTStream::~DCTStream() {
1775 for (i = 0; i < numComps; ++i)
1776 for (j = 0; j < mcuHeight; ++j)
1777 gfree(rowBuf[i][j]);
1780 void DCTStream::reset() {
1782 if (!readHeader()) {
1786 restartMarker = 0xd0;
1790 int DCTStream::getChar() {
1796 if (++comp == numComps) {
1809 int DCTStream::lookChar() {
1812 if (dy >= mcuHeight) {
1813 if (!readMCURow()) {
1821 return rowBuf[comp][dy][x];
1824 void DCTStream::restart() {
1828 restartCtr = restartInterval;
1829 for (i = 0; i < numComps; ++i)
1830 compInfo[i].prevDC = 0;
1833 GBool DCTStream::readMCURow() {
1836 int pY, pCb, pCr, pR, pG, pB;
1837 int h, v, horiz, vert, hSub, vSub;
1838 int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
1841 for (x1 = 0; x1 < width; x1 += mcuWidth) {
1843 // deal with restart marker
1844 if (restartInterval > 0 && restartCtr == 0) {
1846 if (c != restartMarker) {
1847 error(getPos(), "Bad DCT data: incorrect restart marker");
1850 if (++restartMarker == 0xd8)
1851 restartMarker = 0xd0;
1856 for (cc = 0; cc < numComps; ++cc) {
1857 h = compInfo[cc].hSample;
1858 v = compInfo[cc].vSample;
1859 horiz = mcuWidth / h;
1860 vert = mcuHeight / v;
1863 for (y2 = 0; y2 < mcuHeight; y2 += vert) {
1864 for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
1865 if (!readDataUnit(&dcHuffTables[compInfo[cc].dcHuffTable],
1866 &acHuffTables[compInfo[cc].acHuffTable],
1867 quantTables[compInfo[cc].quantTable],
1868 &compInfo[cc].prevDC,
1871 if (hSub == 1 && vSub == 1) {
1872 for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
1873 p1 = &rowBuf[cc][y2+y3][x1+x2];
1883 } else if (hSub == 2 && vSub == 2) {
1884 for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
1885 p1 = &rowBuf[cc][y2+y3][x1+x2];
1886 p2 = &rowBuf[cc][y2+y3+1][x1+x2];
1887 p1[0] = p1[1] = p2[0] = p2[1] = data[i];
1888 p1[2] = p1[3] = p2[2] = p2[3] = data[i+1];
1889 p1[4] = p1[5] = p2[4] = p2[5] = data[i+2];
1890 p1[6] = p1[7] = p2[6] = p2[7] = data[i+3];
1891 p1[8] = p1[9] = p2[8] = p2[9] = data[i+4];
1892 p1[10] = p1[11] = p2[10] = p2[11] = data[i+5];
1893 p1[12] = p1[13] = p2[12] = p2[13] = data[i+6];
1894 p1[14] = p1[15] = p2[14] = p2[15] = data[i+7];
1898 for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
1899 for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
1900 for (y5 = 0; y5 < vSub; ++y5)
1901 for (x5 = 0; x5 < hSub; ++x5)
1902 rowBuf[cc][y2+y4+y5][x1+x2+x4+x5] = data[i];
1912 // color space conversion
1914 // convert YCbCr to RGB
1915 if (numComps == 3) {
1916 for (y2 = 0; y2 < mcuHeight; ++y2) {
1917 for (x2 = 0; x2 < mcuWidth; ++x2) {
1918 pY = rowBuf[0][y2][x1+x2];
1919 pCb = rowBuf[1][y2][x1+x2] - 128;
1920 pCr = rowBuf[2][y2][x1+x2] - 128;
1921 pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
1922 rowBuf[0][y2][x1+x2] = dctClip[dctClipOffset + pR];
1923 pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
1924 rowBuf[1][y2][x1+x2] = dctClip[dctClipOffset + pG];
1925 pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
1926 rowBuf[2][y2][x1+x2] = dctClip[dctClipOffset + pB];
1929 // convert YCbCrK to CMYK (K is passed through unchanged)
1930 } else if (numComps == 4) {
1931 for (y2 = 0; y2 < mcuHeight; ++y2) {
1932 for (x2 = 0; x2 < mcuWidth; ++x2) {
1933 pY = rowBuf[0][y2][x1+x2];
1934 pCb = rowBuf[1][y2][x1+x2] - 128;
1935 pCr = rowBuf[2][y2][x1+x2] - 128;
1936 pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
1937 rowBuf[0][y2][x1+x2] = 255 - dctClip[dctClipOffset + pR];
1938 pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32678) >> 16;
1939 rowBuf[1][y2][x1+x2] = 255 - dctClip[dctClipOffset + pG];
1940 pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
1941 rowBuf[2][y2][x1+x2] = 255 - dctClip[dctClipOffset + pB];
1950 // This IDCT algorithm is taken from:
1951 // Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,
1952 // "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
1953 // IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
1955 // The stage numbers mentioned in the comments refer to Figure 1 in this
1958 GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
1959 DCTHuffTable *acHuffTable,
1960 Guchar quantTable[64], int *prevDC,
1963 int v0, v1, v2, v3, v4, v5, v6, v7, t;
1968 // Huffman decode and dequantize
1969 size = readHuffSym(dcHuffTable);
1973 amp = readAmp(size);
1979 tmp1[0] = (*prevDC += amp) * quantTable[0];
1980 for (i = 1; i < 64; ++i)
1985 while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30)
1992 run += (c >> 4) & 0x0f;
1994 amp = readAmp(size);
1999 tmp1[j] = amp * quantTable[j];
2003 // inverse DCT on rows
2004 for (i = 0; i < 64; i += 8) {
2007 v0 = (dctSqrt2 * tmp1[i+0] + 128) >> 8;
2008 v1 = (dctSqrt2 * tmp1[i+4] + 128) >> 8;
2011 v4 = (dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]) + 128) >> 8;
2012 v7 = (dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]) + 128) >> 8;
2013 v5 = tmp1[i+3] << 4;
2014 v6 = tmp1[i+5] << 4;
2017 t = (v0 - v1+ 1) >> 1;
2018 v0 = (v0 + v1 + 1) >> 1;
2020 t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8;
2021 v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8;
2023 t = (v4 - v6 + 1) >> 1;
2024 v4 = (v4 + v6 + 1) >> 1;
2026 t = (v7 + v5 + 1) >> 1;
2027 v5 = (v7 - v5 + 1) >> 1;
2031 t = (v0 - v3 + 1) >> 1;
2032 v0 = (v0 + v3 + 1) >> 1;
2034 t = (v1 - v2 + 1) >> 1;
2035 v1 = (v1 + v2 + 1) >> 1;
2037 t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
2038 v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
2040 t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
2041 v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
2045 tmp1[i+0] = v0 + v7;
2046 tmp1[i+7] = v0 - v7;
2047 tmp1[i+1] = v1 + v6;
2048 tmp1[i+6] = v1 - v6;
2049 tmp1[i+2] = v2 + v5;
2050 tmp1[i+5] = v2 - v5;
2051 tmp1[i+3] = v3 + v4;
2052 tmp1[i+4] = v3 - v4;
2055 // inverse DCT on columns
2056 for (i = 0; i < 8; ++i) {
2059 v0 = (dctSqrt2 * tmp1[0*8+i] + 2048) >> 12;
2060 v1 = (dctSqrt2 * tmp1[4*8+i] + 2048) >> 12;
2063 v4 = (dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]) + 2048) >> 12;
2064 v7 = (dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]) + 2048) >> 12;
2069 t = (v0 - v1 + 1) >> 1;
2070 v0 = (v0 + v1 + 1) >> 1;
2072 t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12;
2073 v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12;
2075 t = (v4 - v6 + 1) >> 1;
2076 v4 = (v4 + v6 + 1) >> 1;
2078 t = (v7 + v5 + 1) >> 1;
2079 v5 = (v7 - v5 + 1) >> 1;
2083 t = (v0 - v3 + 1) >> 1;
2084 v0 = (v0 + v3 + 1) >> 1;
2086 t = (v1 - v2 + 1) >> 1;
2087 v1 = (v1 + v2 + 1) >> 1;
2089 t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
2090 v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
2092 t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
2093 v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
2097 tmp1[0*8+i] = v0 + v7;
2098 tmp1[7*8+i] = v0 - v7;
2099 tmp1[1*8+i] = v1 + v6;
2100 tmp1[6*8+i] = v1 - v6;
2101 tmp1[2*8+i] = v2 + v5;
2102 tmp1[5*8+i] = v2 - v5;
2103 tmp1[3*8+i] = v3 + v4;
2104 tmp1[4*8+i] = v3 - v4;
2107 // convert to 8-bit integers
2108 for (i = 0; i < 64; ++i)
2109 data[i] = dctClip[dctClipOffset + 128 + ((tmp1[i] + 8) >> 4)];
2116 GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
2117 DCTHuffTable *acHuffTable,
2118 Guchar quantTable[64], int *prevDC,
2121 double v0, v1, v2, v3, v4, v5, v6, v7, t;
2126 // Huffman decode and dequantize
2127 size = readHuffSym(dcHuffTable);
2131 amp = readAmp(size);
2137 tmp1[0] = (*prevDC += amp) * quantTable[0];
2138 for (i = 1; i < 64; ++i)
2143 while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30)
2150 run += (c >> 4) & 0x0f;
2152 amp = readAmp(size);
2157 tmp1[j] = amp * quantTable[j];
2161 // inverse DCT on rows
2162 for (i = 0; i < 64; i += 8) {
2165 v0 = dctSqrt2 * tmp1[i+0];
2166 v1 = dctSqrt2 * tmp1[i+4];
2169 v4 = dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]);
2170 v7 = dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]);
2175 t = 0.5 * (v0 - v1);
2176 v0 = 0.5 * (v0 + v1);
2178 t = v2 * dctSin6 + v3 * dctCos6;
2179 v2 = v2 * dctCos6 - v3 * dctSin6;
2181 t = 0.5 * (v4 - v6);
2182 v4 = 0.5 * (v4 + v6);
2184 t = 0.5 * (v7 + v5);
2185 v5 = 0.5 * (v7 - v5);
2189 t = 0.5 * (v0 - v3);
2190 v0 = 0.5 * (v0 + v3);
2192 t = 0.5 * (v1 - v2);
2193 v1 = 0.5 * (v1 + v2);
2195 t = v4 * dctSin3 + v7 * dctCos3;
2196 v4 = v4 * dctCos3 - v7 * dctSin3;
2198 t = v5 * dctSin1 + v6 * dctCos1;
2199 v5 = v5 * dctCos1 - v6 * dctSin1;
2203 tmp1[i+0] = v0 + v7;
2204 tmp1[i+7] = v0 - v7;
2205 tmp1[i+1] = v1 + v6;
2206 tmp1[i+6] = v1 - v6;
2207 tmp1[i+2] = v2 + v5;
2208 tmp1[i+5] = v2 - v5;
2209 tmp1[i+3] = v3 + v4;
2210 tmp1[i+4] = v3 - v4;
2213 // inverse DCT on columns
2214 for (i = 0; i < 8; ++i) {
2217 v0 = dctSqrt2 * tmp1[0*8+i];
2218 v1 = dctSqrt2 * tmp1[4*8+i];
2221 v4 = dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]);
2222 v7 = dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]);
2227 t = 0.5 * (v0 - v1);
2228 v0 = 0.5 * (v0 + v1);
2230 t = v2 * dctSin6 + v3 * dctCos6;
2231 v2 = v2 * dctCos6 - v3 * dctSin6;
2233 t = 0.5 * (v4 - v6);
2234 v4 = 0.5 * (v4 + v6);
2236 t = 0.5 * (v7 + v5);
2237 v5 = 0.5 * (v7 - v5);
2241 t = 0.5 * (v0 - v3);
2242 v0 = 0.5 * (v0 + v3);
2244 t = 0.5 * (v1 - v2);
2245 v1 = 0.5 * (v1 + v2);
2247 t = v4 * dctSin3 + v7 * dctCos3;
2248 v4 = v4 * dctCos3 - v7 * dctSin3;
2250 t = v5 * dctSin1 + v6 * dctCos1;
2251 v5 = v5 * dctCos1 - v6 * dctSin1;
2255 tmp1[0*8+i] = v0 + v7;
2256 tmp1[7*8+i] = v0 - v7;
2257 tmp1[1*8+i] = v1 + v6;
2258 tmp1[6*8+i] = v1 - v6;
2259 tmp1[2*8+i] = v2 + v5;
2260 tmp1[5*8+i] = v2 - v5;
2261 tmp1[3*8+i] = v3 + v4;
2262 tmp1[4*8+i] = v3 - v4;
2265 // convert to 8-bit integers
2266 for (i = 0; i < 64; ++i)
2267 data[i] = dctClip[dctClipOffset + (int)(tmp1[i] + 128.5)];
2273 int DCTStream::readHuffSym(DCTHuffTable *table) {
2281 // add a bit to the code
2282 if ((bit = readBit()) == EOF)
2284 code = (code << 1) + bit;
2288 if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
2289 code -= table->firstCode[codeBits];
2290 return table->sym[table->firstSym[codeBits] + code];
2292 } while (codeBits < 16);
2294 error(getPos(), "Bad Huffman code in DCT stream");
2298 int DCTStream::readAmp(int size) {
2303 for (bits = 0; bits < size; ++bits) {
2304 if ((bit = readBit()) == EOF)
2306 amp = (amp << 1) + bit;
2308 if (amp < (1 << (size - 1)))
2309 amp -= (1 << size) - 1;
2313 int DCTStream::readBit() {
2317 if (inputBits == 0) {
2318 if ((c = str->getChar()) == EOF)
2322 c2 = str->getChar();
2323 } while (c2 == 0xff);
2325 error(getPos(), "Bad DCT data: missing 00 after ff");
2332 bit = (inputBuf >> (inputBits - 1)) & 1;
2337 GBool DCTStream::readHeader() {
2339 int minHSample, minVSample;
2348 numDCHuffTables = 0;
2349 numACHuffTables = 0;
2351 gotAdobeMarker = gFalse;
2352 restartInterval = 0;
2360 if (!readFrameInfo())
2364 if (!readHuffmanTables())
2370 if (!readScanInfo())
2375 if (!readQuantTables())
2379 if (!readRestartInterval())
2383 if (!readAdobeMarker())
2387 error(getPos(), "Bad DCT header");
2390 // skip APPn / COM / etc.
2393 for (i = 0; i < n; ++i)
2396 error(getPos(), "Unknown DCT marker <%02x>", c);
2404 mcuWidth = minHSample = compInfo[0].hSample;
2405 mcuHeight = minVSample = compInfo[0].vSample;
2406 for (i = 1; i < numComps; ++i) {
2407 if (compInfo[i].hSample < minHSample)
2408 minHSample = compInfo[i].hSample;
2409 if (compInfo[i].vSample < minVSample)
2410 minVSample = compInfo[i].vSample;
2411 if (compInfo[i].hSample > mcuWidth)
2412 mcuWidth = compInfo[i].hSample;
2413 if (compInfo[i].vSample > mcuHeight)
2414 mcuHeight = compInfo[i].vSample;
2416 for (i = 0; i < numComps; ++i) {
2417 compInfo[i].hSample /= minHSample;
2418 compInfo[i].vSample /= minVSample;
2420 mcuWidth = (mcuWidth / minHSample) * 8;
2421 mcuHeight = (mcuHeight / minVSample) * 8;
2424 bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
2425 for (i = 0; i < numComps; ++i)
2426 for (j = 0; j < mcuHeight; ++j)
2427 rowBuf[i][j] = (Guchar *)gmalloc(bufWidth * sizeof(Guchar));
2429 // figure out color transform
2430 if (!gotAdobeMarker && numComps == 3) {
2431 if (compInfo[0].id == 1 && compInfo[1].id == 2 && compInfo[2].id == 3) {
2436 // initialize counters
2445 GBool DCTStream::readFrameInfo() {
2451 length = read16() - 2;
2452 prec = str->getChar();
2455 numComps = str->getChar();
2458 error(getPos(), "Bad DCT precision %d", prec);
2461 for (i = 0; i < numComps; ++i) {
2462 compInfo[i].id = str->getChar();
2463 compInfo[i].inScan = gFalse;
2465 compInfo[i].hSample = (c >> 4) & 0x0f;
2466 compInfo[i].vSample = c & 0x0f;
2467 compInfo[i].quantTable = str->getChar();
2468 compInfo[i].dcHuffTable = 0;
2469 compInfo[i].acHuffTable = 0;
2474 GBool DCTStream::readScanInfo() {
2476 int scanComps, id, c;
2479 length = read16() - 2;
2480 scanComps = str->getChar();
2482 if (length != 2 * scanComps + 3) {
2483 error(getPos(), "Bad DCT scan info block");
2486 for (i = 0; i < scanComps; ++i) {
2487 id = str->getChar();
2488 for (j = 0; j < numComps; ++j) {
2489 if (id == compInfo[j].id)
2492 if (j == numComps) {
2493 error(getPos(), "Bad DCT component ID in scan info block");
2496 compInfo[j].inScan = gTrue;
2498 compInfo[j].dcHuffTable = (c >> 4) & 0x0f;
2499 compInfo[j].acHuffTable = c & 0x0f;
2507 GBool DCTStream::readQuantTables() {
2512 length = read16() - 2;
2513 while (length > 0) {
2514 index = str->getChar();
2515 if ((index & 0xf0) || index >= 4) {
2516 error(getPos(), "Bad DCT quantization table");
2519 if (index == numQuantTables)
2520 numQuantTables = index + 1;
2521 for (i = 0; i < 64; ++i)
2522 quantTables[index][dctZigZag[i]] = str->getChar();
2528 GBool DCTStream::readHuffmanTables() {
2537 length = read16() - 2;
2538 while (length > 0) {
2539 index = str->getChar();
2541 if ((index & 0x0f) >= 4) {
2542 error(getPos(), "Bad DCT Huffman table");
2547 if (index >= numACHuffTables)
2548 numACHuffTables = index+1;
2549 tbl = &acHuffTables[index];
2551 if (index >= numDCHuffTables)
2552 numDCHuffTables = index+1;
2553 tbl = &dcHuffTables[index];
2557 for (i = 1; i <= 16; ++i) {
2559 tbl->firstSym[i] = sym;
2560 tbl->firstCode[i] = code;
2561 tbl->numCodes[i] = c;
2563 code = (code + c) << 1;
2566 for (i = 0; i < sym; ++i)
2567 tbl->sym[i] = str->getChar();
2573 GBool DCTStream::readRestartInterval() {
2578 error(getPos(), "Bad DCT restart interval");
2581 restartInterval = read16();
2585 GBool DCTStream::readAdobeMarker() {
2593 for (i = 0; i < 12; ++i) {
2594 if ((c = str->getChar()) == EOF)
2598 if (strncmp(buf, "Adobe", 5))
2600 colorXform = buf[11];
2601 gotAdobeMarker = gTrue;
2605 error(getPos(), "Bad DCT Adobe APP14 marker");
2609 GBool DCTStream::readTrailer() {
2613 if (c != 0xd9) { // EOI
2614 error(getPos(), "Bad DCT trailer");
2620 int DCTStream::readMarker() {
2626 } while (c != 0xff);
2629 } while (c == 0xff);
2630 } while (c == 0x00);
2634 int DCTStream::read16() {
2637 if ((c1 = str->getChar()) == EOF)
2639 if ((c2 = str->getChar()) == EOF)
2641 return (c1 << 8) + c2;
2644 GString *DCTStream::getPSFilter(char *indent) {
2647 s = str->getPSFilter(indent);
2648 s->append(indent)->append("<< >> /DCTDecode filter\n");
2652 GBool DCTStream::isBinary(GBool last) {
2653 return str->isBinary(gTrue);
2656 //------------------------------------------------------------------------
2658 //------------------------------------------------------------------------
2660 int FlateStream::codeLenCodeMap[flateMaxCodeLenCodes] = {
2661 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
2664 FlateDecode FlateStream::lengthDecode[flateMaxLitCodes-257] = {
2696 FlateDecode FlateStream::distDecode[flateMaxDistCodes] = {
2729 FlateStream::FlateStream(Stream *str1, int predictor1, int columns1,
2730 int colors1, int bits1) {
2732 if (predictor1 != 1) {
2733 pred = new StreamPredictor(this, predictor1, columns1, colors1, bits1);
2739 FlateStream::~FlateStream() {
2746 void FlateStream::reset() {
2752 //~ need to look at window size?
2753 endOfBlock = eof = gTrue;
2754 cmf = str->getChar();
2755 flg = str->getChar();
2756 if (cmf == EOF || flg == EOF)
2758 if ((cmf & 0x0f) != 0x08) {
2759 error(getPos(), "Unknown compression method in flate stream");
2762 if ((((cmf << 8) + flg) % 31) != 0) {
2763 error(getPos(), "Bad FCHECK in flate stream");
2767 error(getPos(), "FDICT bit set in flate stream");
2776 compressedBlock = gFalse;
2781 int FlateStream::getChar() {
2785 return pred->getChar();
2787 while (remain == 0) {
2788 if (endOfBlock && eof)
2793 index = (index + 1) & flateMask;
2798 int FlateStream::lookChar() {
2802 return pred->lookChar();
2804 while (remain == 0) {
2805 if (endOfBlock && eof)
2813 int FlateStream::getRawChar() {
2816 while (remain == 0) {
2817 if (endOfBlock && eof)
2822 index = (index + 1) & flateMask;
2827 GString *FlateStream::getPSFilter(char *indent) {
2831 GBool FlateStream::isBinary(GBool last) {
2832 return str->isBinary(gTrue);
2835 void FlateStream::readSome() {
2846 if (compressedBlock) {
2847 if ((code1 = getHuffmanCodeWord(&litCodeTab)) == EOF)
2852 } else if (code1 == 256) {
2857 code2 = lengthDecode[code1].bits;
2858 if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
2860 len = lengthDecode[code1].first + code2;
2861 if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF)
2863 code2 = distDecode[code1].bits;
2864 if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
2866 dist = distDecode[code1].first + code2;
2868 j = (index - dist) & flateMask;
2869 for (k = 0; k < len; ++k) {
2871 i = (i + 1) & flateMask;
2872 j = (j + 1) & flateMask;
2878 len = (blockLen < flateWindow) ? blockLen : flateWindow;
2879 for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) {
2880 if ((c = str->getChar()) == EOF) {
2881 endOfBlock = eof = gTrue;
2895 error(getPos(), "Unexpected end of file in flate stream");
2896 endOfBlock = eof = gTrue;
2900 GBool FlateStream::startBlock() {
2905 // read block header
2906 blockHdr = getCodeWord(3);
2911 // uncompressed block
2912 if (blockHdr == 0) {
2913 compressedBlock = gFalse;
2914 if ((c = str->getChar()) == EOF)
2916 blockLen = c & 0xff;
2917 if ((c = str->getChar()) == EOF)
2919 blockLen |= (c & 0xff) << 8;
2920 if ((c = str->getChar()) == EOF)
2923 if ((c = str->getChar()) == EOF)
2925 check |= (c & 0xff) << 8;
2926 if (check != (~blockLen & 0xffff))
2927 error(getPos(), "Bad uncompressed block length in flate stream");
2931 // compressed block with fixed codes
2932 } else if (blockHdr == 1) {
2933 compressedBlock = gTrue;
2936 // compressed block with dynamic codes
2937 } else if (blockHdr == 2) {
2938 compressedBlock = gTrue;
2939 if (!readDynamicCodes())
2942 // unknown block type
2947 endOfBlock = gFalse;
2951 error(getPos(), "Bad block header in flate stream");
2952 endOfBlock = eof = gTrue;
2956 void FlateStream::loadFixedCodes() {
2959 // set up code arrays
2960 litCodeTab.codes = allCodes;
2961 distCodeTab.codes = allCodes + flateMaxLitCodes;
2963 // initialize literal code table
2964 for (i = 0; i <= 143; ++i)
2965 litCodeTab.codes[i].len = 8;
2966 for (i = 144; i <= 255; ++i)
2967 litCodeTab.codes[i].len = 9;
2968 for (i = 256; i <= 279; ++i)
2969 litCodeTab.codes[i].len = 7;
2970 for (i = 280; i <= 287; ++i)
2971 litCodeTab.codes[i].len = 8;
2972 compHuffmanCodes(&litCodeTab, flateMaxLitCodes);
2974 // initialize distance code table
2975 for (i = 0; i < 5; ++i)
2976 distCodeTab.start[i] = 0;
2977 distCodeTab.start[5] = 0;
2978 for (i = 6; i <= flateMaxHuffman+1; ++i)
2979 distCodeTab.start[6] = flateMaxDistCodes;
2980 for (i = 0; i < flateMaxDistCodes; ++i) {
2981 distCodeTab.codes[i].len = 5;
2982 distCodeTab.codes[i].code = i;
2983 distCodeTab.codes[i].val = i;
2987 GBool FlateStream::readDynamicCodes() {
2988 int numCodeLenCodes;
2991 FlateCode codeLenCodes[flateMaxCodeLenCodes];
2992 FlateHuffmanTab codeLenCodeTab;
2993 int len, repeat, code;
2997 if ((numLitCodes = getCodeWord(5)) == EOF)
3000 if ((numDistCodes = getCodeWord(5)) == EOF)
3003 if ((numCodeLenCodes = getCodeWord(4)) == EOF)
3005 numCodeLenCodes += 4;
3006 if (numLitCodes > flateMaxLitCodes ||
3007 numDistCodes > flateMaxDistCodes ||
3008 numCodeLenCodes > flateMaxCodeLenCodes)
3011 // read code length code table
3012 codeLenCodeTab.codes = codeLenCodes;
3013 for (i = 0; i < flateMaxCodeLenCodes; ++i)
3014 codeLenCodes[i].len = 0;
3015 for (i = 0; i < numCodeLenCodes; ++i) {
3016 if ((codeLenCodes[codeLenCodeMap[i]].len = getCodeWord(3)) == -1)
3019 compHuffmanCodes(&codeLenCodeTab, flateMaxCodeLenCodes);
3021 // set up code arrays
3022 litCodeTab.codes = allCodes;
3023 distCodeTab.codes = allCodes + numLitCodes;
3025 // read literal and distance code tables
3029 while (i < numLitCodes + numDistCodes) {
3030 if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF)
3033 if ((repeat = getCodeWord(2)) == EOF)
3035 for (repeat += 3; repeat > 0; --repeat)
3036 allCodes[i++].len = len;
3037 } else if (code == 17) {
3038 if ((repeat = getCodeWord(3)) == EOF)
3041 for (repeat += 3; repeat > 0; --repeat)
3042 allCodes[i++].len = 0;
3043 } else if (code == 18) {
3044 if ((repeat = getCodeWord(7)) == EOF)
3047 for (repeat += 11; repeat > 0; --repeat)
3048 allCodes[i++].len = 0;
3050 allCodes[i++].len = len = code;
3053 compHuffmanCodes(&litCodeTab, numLitCodes);
3054 compHuffmanCodes(&distCodeTab, numDistCodes);
3059 error(getPos(), "Bad dynamic code table in flate stream");
3063 // On entry, the <tab->codes> array contains the lengths of each code,
3064 // stored in code value order. This function computes the code words.
3065 // The result is sorted in order of (1) code length and (2) code word.
3066 // The length values are no longer valid. The <tab->start> array is
3067 // filled with the indexes of the first code of each length.
3068 void FlateStream::compHuffmanCodes(FlateHuffmanTab *tab, int n) {
3069 int numLengths[flateMaxHuffman+1];
3070 int nextCode[flateMaxHuffman+1];
3071 int nextIndex[flateMaxHuffman+2];
3075 // count number of codes for each code length
3076 for (i = 0; i <= flateMaxHuffman; ++i)
3078 for (i = 0; i < n; ++i)
3079 ++numLengths[tab->codes[i].len];
3081 // compute first index for each length
3082 tab->start[0] = nextIndex[0] = 0;
3083 for (i = 1; i <= flateMaxHuffman + 1; ++i)
3084 tab->start[i] = nextIndex[i] = tab->start[i-1] + numLengths[i-1];
3086 // compute first code for each length
3089 for (i = 1; i <= flateMaxHuffman; ++i) {
3090 code = (code + numLengths[i-1]) << 1;
3094 // compute the codes -- this permutes the codes array from value
3095 // order to length/code order
3096 for (i = 0; i < n; ++i) {
3097 j = nextIndex[tab->codes[i].len]++;
3098 if (tab->codes[i].len == 0)
3099 tab->codes[j].code = 0;
3101 tab->codes[j].code = nextCode[tab->codes[i].len]++;
3102 tab->codes[j].val = i;
3106 int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) {
3113 for (len = 1; len <= flateMaxHuffman; ++len) {
3115 // add a bit to the code
3116 if (codeSize == 0) {
3117 if ((c = str->getChar()) == EOF)
3122 code = (code << 1) | (codeBuf & 1);
3127 i = tab->start[len];
3128 j = tab->start[len + 1];
3129 if (i < j && code >= tab->codes[i].code && code <= tab->codes[j-1].code) {
3130 i += code - tab->codes[i].code;
3131 return tab->codes[i].val;
3136 error(getPos(), "Bad code (%04x) in flate stream", code);
3140 int FlateStream::getCodeWord(int bits) {
3143 while (codeSize < bits) {
3144 if ((c = str->getChar()) == EOF)
3146 codeBuf |= (c & 0xff) << codeSize;
3149 c = codeBuf & ((1 << bits) - 1);
3155 //------------------------------------------------------------------------
3157 //------------------------------------------------------------------------
3159 EOFStream::EOFStream(Stream *str1) {
3163 EOFStream::~EOFStream() {
3167 //------------------------------------------------------------------------
3168 // FixedLengthEncoder
3169 //------------------------------------------------------------------------
3171 FixedLengthEncoder::FixedLengthEncoder(Stream *str1, int length1) {
3177 FixedLengthEncoder::~FixedLengthEncoder() {
3178 if (str->isEncoder())
3182 void FixedLengthEncoder::reset() {
3187 int FixedLengthEncoder::getChar() {
3188 if (length >= 0 && count >= length)
3191 return str->getChar();
3194 int FixedLengthEncoder::lookChar() {
3195 if (length >= 0 && count >= length)
3197 return str->getChar();
3200 //------------------------------------------------------------------------
3202 //------------------------------------------------------------------------
3204 ASCII85Encoder::ASCII85Encoder(Stream *str1) {
3206 bufPtr = bufEnd = buf;
3211 ASCII85Encoder::~ASCII85Encoder() {
3212 if (str->isEncoder())
3216 void ASCII85Encoder::reset() {
3218 bufPtr = bufEnd = buf;
3223 GBool ASCII85Encoder::fillBuf() {
3232 for (n = 0; n < 4; ++n) {
3233 if ((c = str->getChar()) == EOF)
3237 bufPtr = bufEnd = buf;
3239 if (n == 4 && t == 0) {
3241 if (++lineLen == 65) {
3248 for (i = 4; i >= 0; --i) {
3249 buf1[i] = (char)(t % 85 + 0x21);
3252 for (i = 0; i <= n; ++i) {
3253 *bufEnd++ = buf1[i];
3254 if (++lineLen == 65) {
3266 return bufPtr < bufEnd;
3269 //------------------------------------------------------------------------
3271 //------------------------------------------------------------------------
3273 RunLengthEncoder::RunLengthEncoder(Stream *str1) {
3275 bufPtr = bufEnd = nextEnd = buf;
3279 RunLengthEncoder::~RunLengthEncoder() {
3280 if (str->isEncoder())
3284 void RunLengthEncoder::reset() {
3286 bufPtr = bufEnd = nextEnd = buf;
3291 // When fillBuf finishes, buf[] looks like this:
3292 // +-----+--------------+-----------------+--
3293 // + tag | ... data ... | next 0, 1, or 2 |
3294 // +-----+--------------+-----------------+--
3296 // bufPtr bufEnd nextEnd
3298 GBool RunLengthEncoder::fillBuf() {
3307 if (nextEnd < bufEnd + 1) {
3308 if ((c1 = str->getChar()) == EOF) {
3313 c1 = bufEnd[0] & 0xff;
3315 if (nextEnd < bufEnd + 2) {
3316 if ((c2 = str->getChar()) == EOF) {
3325 c2 = bufEnd[1] & 0xff;
3331 while (n < 128 && (c = str->getChar()) == c1)
3333 buf[0] = (char)(257 - n);
3338 } else if (n < 128) {
3345 // get up to 128 chars
3351 if ((c = str->getChar()) == EOF) {
3357 if (buf[n] == buf[n-1])
3360 if (buf[n] == buf[n-1]) {
3361 buf[0] = (char)(n-2-1);
3363 nextEnd = &buf[n+1];
3365 buf[0] = (char)(n-1);
3366 bufEnd = nextEnd = &buf[n+1];