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() {
575 FileStream::FileStream(FILE *f1) {
579 bufPtr = bufEnd = buf;
587 Stream *FileStream::subStream (int start1, int length1, Object *dict1) {
588 FileStream *scp = new FileStream ();
591 scp->length = length1;
592 scp->bufPtr = bufEnd = buf;
599 FileStream::~FileStream() {
601 fseek(f, savePos, SEEK_SET);
605 void FileStream::reset() {
606 savePos = (int)ftell(f);
607 fseek(f, start, SEEK_SET);
608 bufPtr = bufEnd = buf;
612 GBool FileStream::fillBuf() {
615 bufPos += bufEnd - buf;
616 bufPtr = bufEnd = buf;
617 if (length >= 0 && bufPos >= start + length)
619 if (length >= 0 && bufPos + 256 > start + length)
620 n = start + length - bufPos;
623 n = fread(buf, 1, n, f);
625 if (bufPtr >= bufEnd)
630 void FileStream::setPos(int pos1) {
634 fseek(f, pos1, SEEK_SET);
637 fseek(f, 0, SEEK_END);
641 fseek(f, pos1, SEEK_END);
642 bufPos = (int)ftell(f);
644 bufPtr = bufEnd = buf;
647 //------------------------------------------------------------------------
649 //------------------------------------------------------------------------
651 SubStream::SubStream(Stream *str1, Object *dict1) {
656 SubStream::~SubStream() {
660 //------------------------------------------------------------------------
662 //------------------------------------------------------------------------
664 ASCIIHexStream::ASCIIHexStream(Stream *str1) {
670 ASCIIHexStream::~ASCIIHexStream() {
674 void ASCIIHexStream::reset() {
680 int ASCIIHexStream::lookChar() {
691 } while (isspace(c1));
699 } while (isspace(c2));
704 if (c1 >= '0' && c1 <= '9') {
706 } else if (c1 >= 'A' && c1 <= 'F') {
707 x = (c1 - 'A' + 10) << 4;
708 } else if (c1 >= 'a' && c1 <= 'f') {
709 x = (c1 - 'a' + 10) << 4;
710 } else if (c1 == EOF) {
714 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c1);
717 if (c2 >= '0' && c2 <= '9') {
719 } else if (c2 >= 'A' && c2 <= 'F') {
721 } else if (c2 >= 'a' && c2 <= 'f') {
723 } else if (c2 == EOF) {
727 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c2);
733 GString *ASCIIHexStream::getPSFilter(char *indent) {
736 s = str->getPSFilter(indent);
737 s->append(indent)->append("/ASCIIHexDecode filter\n");
741 GBool ASCIIHexStream::isBinary(GBool last) {
742 return str->isBinary(gFalse);
745 //------------------------------------------------------------------------
747 //------------------------------------------------------------------------
749 ASCII85Stream::ASCII85Stream(Stream *str1) {
755 ASCII85Stream::~ASCII85Stream() {
759 void ASCII85Stream::reset() {
765 int ASCII85Stream::lookChar() {
774 c[0] = str->getChar();
775 } while (c[0] == '\n' || c[0] == '\r');
776 if (c[0] == '~' || c[0] == EOF) {
780 } else if (c[0] == 'z') {
781 b[0] = b[1] = b[2] = b[3] = 0;
784 for (k = 1; k < 5; ++k) {
786 c[k] = str->getChar();
787 } while (c[k] == '\n' || c[k] == '\r');
788 if (c[k] == '~' || c[k] == EOF)
792 if (k < 5 && (c[k] == '~' || c[k] == EOF)) {
793 for (++k; k < 5; ++k)
798 for (k = 0; k < 5; ++k)
799 t = t * 85 + (c[k] - 0x21);
800 for (k = 3; k >= 0; --k) {
801 b[k] = (int)(t & 0xff);
809 GString *ASCII85Stream::getPSFilter(char *indent) {
812 s = str->getPSFilter(indent);
813 s->append(indent)->append("/ASCII85Decode filter\n");
817 GBool ASCII85Stream::isBinary(GBool last) {
818 return str->isBinary(gFalse);
821 //------------------------------------------------------------------------
823 //------------------------------------------------------------------------
825 LZWStream::LZWStream(Stream *str1, int predictor1, int columns1, int colors1,
826 int bits1, int early1) {
828 if (predictor1 != 1) {
829 pred = new StreamPredictor(this, predictor1, columns1, colors1, bits1);
835 bufPtr = bufEnd = buf;
838 LZWStream::~LZWStream() {
854 int LZWStream::getChar() {
856 return pred->getChar();
858 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
861 int LZWStream::lookChar() {
863 return pred->lookChar();
865 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff);
868 int LZWStream::getRawChar() {
869 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
872 void LZWStream::reset() {
876 bufPtr = bufEnd = buf;
887 if (!setDJSYSFLAGS) {
888 setenv("DJSYSFLAGS", "0x0002", 0);
889 setDJSYSFLAGS = gTrue;
892 strcpy(zCmd, uncompressCmd);
894 zName = zCmd + strlen(zCmd);
897 zName[strlen(zName) - 2] = '\0';
900 if (!(f = fopen(zName, "wb"))) {
901 error(getPos(), "Couldn't open temporary file '%s'", zName);
907 if (!(zPipe = popen(zCmd, "r"))) {
908 error(getPos(), "Couldn't popen '%s'", zCmd);
918 error(getPos(), "Couldn't execute '%s'", zCmd);
922 zName[strlen(zName) - 2] = '\0';
923 if (!(zPipe = fopen(zName, "rb"))) {
924 error(getPos(), "Couldn't open uncompress file '%s'", zName);
931 void LZWStream::dumpFile(FILE *f) {
932 int outCodeBits; // size of output code
933 int outBits; // max output code
934 int outBuf[8]; // output buffer
935 int outData; // temporary output buffer
936 int inCode, outCode; // input and output codes
937 int nextCode; // next code index
938 GBool eof; // set when EOF is reached
939 GBool clear; // set if table needs to be cleared
940 GBool first; // indicates first code word after clear
947 // max code length, block mode flag
965 for (i = 0; i < 8; ++i) {
966 // check for table overflow
967 if (nextCode + early > 0x1001) {
978 } while (first && inCode == 256);
981 // compute output code
984 } else if (inCode == 256) {
987 } else if (inCode == 257) {
991 outCode = inCode - 1;
1001 // check input code size
1002 if (nextCode + early == 0x200)
1004 else if (nextCode + early == 0x400) {
1006 } else if (nextCode + early == 0x800) {
1010 // check for eof/clear
1019 // write output block
1023 while (j < i || outBits > 0) {
1024 if (outBits < 8 && j < i) {
1025 outData = outData | (outBuf[j++] << outBits);
1026 outBits += outCodeBits;
1028 fputc(outData & 0xff, f);
1033 // check output code size
1034 if (nextCode - 1 == 512 ||
1035 nextCode - 1 == 1024 ||
1036 nextCode - 1 == 2048 ||
1037 nextCode - 1 == 4096) {
1038 outCodeBits = inCodeBits;
1041 // clear table if necessary
1052 int LZWStream::getCode() {
1056 while (inputBits < inCodeBits) {
1057 if ((c = str->getChar()) == EOF)
1059 inputBuf = (inputBuf << 8) | (c & 0xff);
1062 code = (inputBuf >> (inputBits - inCodeBits)) & ((1 << inCodeBits) - 1);
1063 inputBits -= inCodeBits;
1067 GBool LZWStream::fillBuf() {
1072 if ((n = fread(buf, 1, 256, zPipe)) < 256) {
1086 GString *LZWStream::getPSFilter(char *indent) {
1092 s = str->getPSFilter(indent);
1093 s->append(indent)->append("/LZWDecode filter\n");
1097 GBool LZWStream::isBinary(GBool last) {
1098 return str->isBinary(gTrue);
1101 //------------------------------------------------------------------------
1103 //------------------------------------------------------------------------
1105 RunLengthStream::RunLengthStream(Stream *str1) {
1107 bufPtr = bufEnd = buf;
1111 RunLengthStream::~RunLengthStream() {
1115 void RunLengthStream::reset() {
1117 bufPtr = bufEnd = buf;
1121 GString *RunLengthStream::getPSFilter(char *indent) {
1124 s = str->getPSFilter(indent);
1125 s->append(indent)->append("/RunLengthDecode filter\n");
1129 GBool RunLengthStream::isBinary(GBool last) {
1130 return str->isBinary(gTrue);
1133 GBool RunLengthStream::fillBuf() {
1140 if (c == 0x80 || c == EOF) {
1146 for (i = 0; i < n; ++i)
1147 buf[i] = (char)str->getChar();
1151 for (i = 0; i < n; ++i)
1159 //------------------------------------------------------------------------
1161 //------------------------------------------------------------------------
1163 CCITTFaxStream::CCITTFaxStream(Stream *str, int encoding, GBool endOfLine,
1164 GBool byteAlign, int columns, int rows,
1165 GBool endOfBlock, GBool black) {
1167 this->encoding = encoding;
1168 this->endOfLine = endOfLine;
1169 this->byteAlign = byteAlign;
1170 this->columns = columns;
1172 this->endOfBlock = endOfBlock;
1173 this->black = black;
1174 refLine = (short *)gmalloc((columns + 2) * sizeof(short));
1175 codingLine = (short *)gmalloc((columns + 2) * sizeof(short));
1179 nextLine2D = encoding < 0;
1182 codingLine[1] = refLine[2] = columns;
1188 CCITTFaxStream::~CCITTFaxStream() {
1194 void CCITTFaxStream::reset() {
1200 nextLine2D = encoding < 0;
1203 codingLine[1] = refLine[2] = columns;
1207 // get initial end-of-line marker and 2D encoding tag
1209 if (lookBits(12) == 0x001) {
1213 for (n = 0; n < 11 && lookBits(n) == 0; ++n) ;
1214 if (n == 11 && lookBits(12) == 0x001) {
1219 nextLine2D = !lookBits(1);
1224 int CCITTFaxStream::lookChar() {
1225 short code1, code2, code3;
1233 // if at eof just return EOF
1234 if (eof && codingLine[a0] >= columns) {
1238 // read the next row
1242 if (codingLine[a0] >= columns) {
1246 for (i = 0; codingLine[i] < columns; ++i)
1247 refLine[i] = codingLine[i];
1248 refLine[i] = refLine[i + 1] = columns;
1250 a0New = codingLine[a0 = 0] = 0;
1252 code1 = getTwoDimCode();
1255 if (refLine[b1] < columns) {
1256 a0New = refLine[b1 + 1];
1261 if ((a0 & 1) == 0) {
1264 code1 += code3 = getWhiteCode();
1265 } while (code3 >= 64);
1267 code2 += code3 = getBlackCode();
1268 } while (code3 >= 64);
1272 code1 += code3 = getBlackCode();
1273 } while (code3 >= 64);
1275 code2 += code3 = getWhiteCode();
1276 } while (code3 >= 64);
1278 codingLine[a0 + 1] = a0New + code1;
1280 a0New = codingLine[a0 + 1] = codingLine[a0] + code2;
1282 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1286 a0New = codingLine[++a0] = refLine[b1];
1287 if (refLine[b1] < columns) {
1289 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1294 a0New = codingLine[++a0] = refLine[b1] + 1;
1295 if (refLine[b1] < columns) {
1297 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1302 a0New = codingLine[++a0] = refLine[b1] - 1;
1304 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1308 a0New = codingLine[++a0] = refLine[b1] + 2;
1309 if (refLine[b1] < columns) {
1311 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1316 a0New = codingLine[++a0] = refLine[b1] - 2;
1318 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1322 a0New = codingLine[++a0] = refLine[b1] + 3;
1323 if (refLine[b1] < columns) {
1325 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1330 a0New = codingLine[++a0] = refLine[b1] - 3;
1332 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1337 codingLine[a0 = 0] = columns;
1340 error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1);
1349 } while (codingLine[a0] < columns);
1353 codingLine[a0 = 0] = 0;
1357 code1 += code3 = getWhiteCode();
1358 } while (code3 >= 64);
1359 codingLine[a0+1] = codingLine[a0] + code1;
1361 if (codingLine[a0] >= columns)
1365 code2 += code3 = getBlackCode();
1366 } while (code3 >= 64);
1367 codingLine[a0+1] = codingLine[a0] + code2;
1369 if (codingLine[a0] >= columns)
1374 if (codingLine[a0] != columns) {
1375 error(getPos(), "CCITTFax row is wrong length (%d)", codingLine[a0]);
1381 // byte-align the row
1386 // check for end-of-line marker, end-of-block marker, and
1389 code1 = lookBits(12);
1392 } else if (code1 == 0x001) {
1395 nextLine2D = !lookBits(1);
1398 code1 = lookBits(12);
1399 if (code1 == 0x001) {
1405 if (encoding >= 0) {
1406 for (i = 0; i < 4; ++i) {
1407 code1 = lookBits(12);
1408 if (code1 != 0x001) {
1409 error(getPos(), "Bad RTC code in CCITTFax stream");
1422 nextLine2D = !lookBits(1);
1427 if (row == rows - 1) {
1430 for (n = 0; n < 11 && lookBits(n) == 0; ++n) ;
1431 if (n == 11 && lookBits(12) == 0x001) {
1435 nextLine2D = !lookBits(1);
1442 // This looks for an end-of-line marker after an error, however
1443 // some (most?) CCITT streams in PDF files don't use end-of-line
1444 // markers, and the just-plow-on technique works better in those
1453 code1 = look13Bits();
1454 } while ((code1 >> 1) != 0x001);
1456 codingLine[++a0] = columns;
1459 nextLine2D = !(code1 & 1);
1465 outputBits = codingLine[1] - codingLine[0];
1466 if (outputBits == 0) {
1468 outputBits = codingLine[2] - codingLine[1];
1475 if (outputBits >= 8) {
1476 ret = ((a0 & 1) == 0) ? 0xff : 0x00;
1477 if ((outputBits -= 8) == 0) {
1479 if (codingLine[a0] < columns) {
1480 outputBits = codingLine[a0 + 1] - codingLine[a0];
1487 if (outputBits > bits) {
1490 if ((a0 & 1) == 0) {
1491 ret |= 0xff >> (8 - i);
1497 if ((a0 & 1) == 0) {
1498 ret |= (0xff >> (8 - i)) << bits;
1502 if (codingLine[a0] < columns) {
1503 outputBits = codingLine[a0 + 1] - codingLine[a0];
1506 } while (bits > 0 && codingLine[a0] < columns);
1508 buf = black ? (ret ^ 0xff) : ret;
1512 short CCITTFaxStream::getTwoDimCode() {
1517 code = 0; // make gcc happy
1520 p = &twoDimTab1[code];
1526 for (n = 1; n <= 7; ++n) {
1531 p = &twoDimTab1[code];
1538 error(getPos(), "Bad two dim code (%04x) in CCITTFax stream", code);
1542 short CCITTFaxStream::getWhiteCode() {
1547 code = 0; // make gcc happy
1549 code = lookBits(12);
1550 if ((code >> 5) == 0)
1551 p = &whiteTab1[code];
1553 p = &whiteTab2[code >> 3];
1559 for (n = 1; n <= 9; ++n) {
1564 p = &whiteTab2[code];
1570 for (n = 11; n <= 12; ++n) {
1575 p = &whiteTab1[code];
1582 error(getPos(), "Bad white code (%04x) in CCITTFax stream", code);
1586 short CCITTFaxStream::getBlackCode() {
1591 code = 0; // make gcc happy
1593 code = lookBits(13);
1594 if ((code >> 7) == 0)
1595 p = &blackTab1[code];
1596 else if ((code >> 9) == 0)
1597 p = &blackTab2[(code >> 1) - 64];
1599 p = &blackTab3[code >> 7];
1605 for (n = 2; n <= 6; ++n) {
1610 p = &blackTab3[code];
1616 for (n = 7; n <= 12; ++n) {
1622 p = &blackTab2[code - 64];
1629 for (n = 10; n <= 13; ++n) {
1634 p = &blackTab1[code];
1641 error(getPos(), "Bad black code (%04x) in CCITTFax stream", code);
1645 short CCITTFaxStream::lookBits(int n) {
1648 while (inputBits < n) {
1649 if ((c = str->getChar()) == EOF) {
1654 inputBuf = (inputBuf << 8) + c;
1657 return (inputBuf >> (inputBits - n)) & (0xffff >> (16 - n));
1660 GString *CCITTFaxStream::getPSFilter(char *indent) {
1664 s = str->getPSFilter(indent);
1665 s->append(indent)->append("<< ");
1666 if (encoding != 0) {
1667 sprintf(s1, "/K %d ", encoding);
1671 s->append("/EndOfLine true ");
1674 s->append("/EncodedByteAlign true ");
1676 sprintf(s1, "/Columns %d ", columns);
1679 sprintf(s1, "/Rows %d ", rows);
1683 s->append("/EndOfBlock false ");
1686 s->append("/BlackIs1 true ");
1688 s->append(">> /CCITTFaxDecode filter\n");
1692 GBool CCITTFaxStream::isBinary(GBool last) {
1693 return str->isBinary(gTrue);
1696 //------------------------------------------------------------------------
1698 //------------------------------------------------------------------------
1700 // IDCT constants (20.12 fixed point format)
1702 #define dctCos1 4017 // cos(pi/16)
1703 #define dctSin1 799 // sin(pi/16)
1704 #define dctCos3 3406 // cos(3*pi/16)
1705 #define dctSin3 2276 // sin(3*pi/16)
1706 #define dctCos6 1567 // cos(6*pi/16)
1707 #define dctSin6 3784 // sin(6*pi/16)
1708 #define dctSqrt2 5793 // sqrt(2)
1709 #define dctSqrt1d2 2896 // sqrt(2) / 2
1714 #define dctCos1 0.98078528 // cos(pi/16)
1715 #define dctSin1 0.19509032 // sin(pi/16)
1716 #define dctCos3 0.83146961 // cos(3*pi/16)
1717 #define dctSin3 0.55557023 // sin(3*pi/16)
1718 #define dctCos6 0.38268343 // cos(6*pi/16)
1719 #define dctSin6 0.92387953 // sin(6*pi/16)
1720 #define dctSqrt2 1.41421356 // sqrt(2)
1721 #define dctSqrt1d2 0.70710678 // sqrt(2) / 2
1724 // color conversion parameters (16.16 fixed point format)
1725 #define dctCrToR 91881 // 1.4020
1726 #define dctCbToG -22553 // -0.3441363
1727 #define dctCrToG -46802 // -0.71413636
1728 #define dctCbToB 116130 // 1.772
1730 // clip [-256,511] --> [0,255]
1731 #define dctClipOffset 256
1732 static Guchar dctClip[768];
1733 static int dctClipInit = 0;
1735 // zig zag decode map
1736 static int dctZigZag[64] = {
1742 5, 12, 19, 26, 33, 40,
1743 48, 41, 34, 27, 20, 13, 6,
1744 7, 14, 21, 28, 35, 42, 49, 56,
1745 57, 50, 43, 36, 29, 22, 15,
1746 23, 30, 37, 44, 51, 58,
1754 DCTStream::DCTStream(Stream *str1) {
1759 mcuWidth = mcuHeight = 0;
1763 for (i = 0; i < 4; ++i)
1764 for (j = 0; j < 32; ++j)
1765 rowBuf[i][j] = NULL;
1768 for (i = -256; i < 0; ++i)
1769 dctClip[dctClipOffset + i] = 0;
1770 for (i = 0; i < 256; ++i)
1771 dctClip[dctClipOffset + i] = i;
1772 for (i = 256; i < 512; ++i)
1773 dctClip[dctClipOffset + i] = 255;
1778 DCTStream::~DCTStream() {
1782 for (i = 0; i < numComps; ++i)
1783 for (j = 0; j < mcuHeight; ++j)
1784 gfree(rowBuf[i][j]);
1787 void DCTStream::reset() {
1789 if (!readHeader()) {
1793 restartMarker = 0xd0;
1797 int DCTStream::getChar() {
1803 if (++comp == numComps) {
1816 int DCTStream::lookChar() {
1819 if (dy >= mcuHeight) {
1820 if (!readMCURow()) {
1828 return rowBuf[comp][dy][x];
1831 void DCTStream::restart() {
1835 restartCtr = restartInterval;
1836 for (i = 0; i < numComps; ++i)
1837 compInfo[i].prevDC = 0;
1840 GBool DCTStream::readMCURow() {
1843 int pY, pCb, pCr, pR, pG, pB;
1844 int h, v, horiz, vert, hSub, vSub;
1845 int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
1848 for (x1 = 0; x1 < width; x1 += mcuWidth) {
1850 // deal with restart marker
1851 if (restartInterval > 0 && restartCtr == 0) {
1853 if (c != restartMarker) {
1854 error(getPos(), "Bad DCT data: incorrect restart marker");
1857 if (++restartMarker == 0xd8)
1858 restartMarker = 0xd0;
1863 for (cc = 0; cc < numComps; ++cc) {
1864 h = compInfo[cc].hSample;
1865 v = compInfo[cc].vSample;
1866 horiz = mcuWidth / h;
1867 vert = mcuHeight / v;
1870 for (y2 = 0; y2 < mcuHeight; y2 += vert) {
1871 for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
1872 if (!readDataUnit(&dcHuffTables[compInfo[cc].dcHuffTable],
1873 &acHuffTables[compInfo[cc].acHuffTable],
1874 quantTables[compInfo[cc].quantTable],
1875 &compInfo[cc].prevDC,
1878 if (hSub == 1 && vSub == 1) {
1879 for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
1880 p1 = &rowBuf[cc][y2+y3][x1+x2];
1890 } else if (hSub == 2 && vSub == 2) {
1891 for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
1892 p1 = &rowBuf[cc][y2+y3][x1+x2];
1893 p2 = &rowBuf[cc][y2+y3+1][x1+x2];
1894 p1[0] = p1[1] = p2[0] = p2[1] = data[i];
1895 p1[2] = p1[3] = p2[2] = p2[3] = data[i+1];
1896 p1[4] = p1[5] = p2[4] = p2[5] = data[i+2];
1897 p1[6] = p1[7] = p2[6] = p2[7] = data[i+3];
1898 p1[8] = p1[9] = p2[8] = p2[9] = data[i+4];
1899 p1[10] = p1[11] = p2[10] = p2[11] = data[i+5];
1900 p1[12] = p1[13] = p2[12] = p2[13] = data[i+6];
1901 p1[14] = p1[15] = p2[14] = p2[15] = data[i+7];
1905 for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
1906 for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
1907 for (y5 = 0; y5 < vSub; ++y5)
1908 for (x5 = 0; x5 < hSub; ++x5)
1909 rowBuf[cc][y2+y4+y5][x1+x2+x4+x5] = data[i];
1919 // color space conversion
1921 // convert YCbCr to RGB
1922 if (numComps == 3) {
1923 for (y2 = 0; y2 < mcuHeight; ++y2) {
1924 for (x2 = 0; x2 < mcuWidth; ++x2) {
1925 pY = rowBuf[0][y2][x1+x2];
1926 pCb = rowBuf[1][y2][x1+x2] - 128;
1927 pCr = rowBuf[2][y2][x1+x2] - 128;
1928 pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
1929 rowBuf[0][y2][x1+x2] = dctClip[dctClipOffset + pR];
1930 pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
1931 rowBuf[1][y2][x1+x2] = dctClip[dctClipOffset + pG];
1932 pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
1933 rowBuf[2][y2][x1+x2] = dctClip[dctClipOffset + pB];
1936 // convert YCbCrK to CMYK (K is passed through unchanged)
1937 } else if (numComps == 4) {
1938 for (y2 = 0; y2 < mcuHeight; ++y2) {
1939 for (x2 = 0; x2 < mcuWidth; ++x2) {
1940 pY = rowBuf[0][y2][x1+x2];
1941 pCb = rowBuf[1][y2][x1+x2] - 128;
1942 pCr = rowBuf[2][y2][x1+x2] - 128;
1943 pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
1944 rowBuf[0][y2][x1+x2] = 255 - dctClip[dctClipOffset + pR];
1945 pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32678) >> 16;
1946 rowBuf[1][y2][x1+x2] = 255 - dctClip[dctClipOffset + pG];
1947 pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
1948 rowBuf[2][y2][x1+x2] = 255 - dctClip[dctClipOffset + pB];
1957 // This IDCT algorithm is taken from:
1958 // Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,
1959 // "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
1960 // IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
1962 // The stage numbers mentioned in the comments refer to Figure 1 in this
1965 GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
1966 DCTHuffTable *acHuffTable,
1967 Guchar quantTable[64], int *prevDC,
1970 int v0, v1, v2, v3, v4, v5, v6, v7, t;
1975 // Huffman decode and dequantize
1976 size = readHuffSym(dcHuffTable);
1980 amp = readAmp(size);
1986 tmp1[0] = (*prevDC += amp) * quantTable[0];
1987 for (i = 1; i < 64; ++i)
1992 while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30)
1999 run += (c >> 4) & 0x0f;
2001 amp = readAmp(size);
2006 tmp1[j] = amp * quantTable[j];
2010 // inverse DCT on rows
2011 for (i = 0; i < 64; i += 8) {
2014 v0 = (dctSqrt2 * tmp1[i+0] + 128) >> 8;
2015 v1 = (dctSqrt2 * tmp1[i+4] + 128) >> 8;
2018 v4 = (dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]) + 128) >> 8;
2019 v7 = (dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]) + 128) >> 8;
2020 v5 = tmp1[i+3] << 4;
2021 v6 = tmp1[i+5] << 4;
2024 t = (v0 - v1+ 1) >> 1;
2025 v0 = (v0 + v1 + 1) >> 1;
2027 t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8;
2028 v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8;
2030 t = (v4 - v6 + 1) >> 1;
2031 v4 = (v4 + v6 + 1) >> 1;
2033 t = (v7 + v5 + 1) >> 1;
2034 v5 = (v7 - v5 + 1) >> 1;
2038 t = (v0 - v3 + 1) >> 1;
2039 v0 = (v0 + v3 + 1) >> 1;
2041 t = (v1 - v2 + 1) >> 1;
2042 v1 = (v1 + v2 + 1) >> 1;
2044 t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
2045 v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
2047 t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
2048 v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
2052 tmp1[i+0] = v0 + v7;
2053 tmp1[i+7] = v0 - v7;
2054 tmp1[i+1] = v1 + v6;
2055 tmp1[i+6] = v1 - v6;
2056 tmp1[i+2] = v2 + v5;
2057 tmp1[i+5] = v2 - v5;
2058 tmp1[i+3] = v3 + v4;
2059 tmp1[i+4] = v3 - v4;
2062 // inverse DCT on columns
2063 for (i = 0; i < 8; ++i) {
2066 v0 = (dctSqrt2 * tmp1[0*8+i] + 2048) >> 12;
2067 v1 = (dctSqrt2 * tmp1[4*8+i] + 2048) >> 12;
2070 v4 = (dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]) + 2048) >> 12;
2071 v7 = (dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]) + 2048) >> 12;
2076 t = (v0 - v1 + 1) >> 1;
2077 v0 = (v0 + v1 + 1) >> 1;
2079 t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12;
2080 v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12;
2082 t = (v4 - v6 + 1) >> 1;
2083 v4 = (v4 + v6 + 1) >> 1;
2085 t = (v7 + v5 + 1) >> 1;
2086 v5 = (v7 - v5 + 1) >> 1;
2090 t = (v0 - v3 + 1) >> 1;
2091 v0 = (v0 + v3 + 1) >> 1;
2093 t = (v1 - v2 + 1) >> 1;
2094 v1 = (v1 + v2 + 1) >> 1;
2096 t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
2097 v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
2099 t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
2100 v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
2104 tmp1[0*8+i] = v0 + v7;
2105 tmp1[7*8+i] = v0 - v7;
2106 tmp1[1*8+i] = v1 + v6;
2107 tmp1[6*8+i] = v1 - v6;
2108 tmp1[2*8+i] = v2 + v5;
2109 tmp1[5*8+i] = v2 - v5;
2110 tmp1[3*8+i] = v3 + v4;
2111 tmp1[4*8+i] = v3 - v4;
2114 // convert to 8-bit integers
2115 for (i = 0; i < 64; ++i)
2116 data[i] = dctClip[dctClipOffset + 128 + ((tmp1[i] + 8) >> 4)];
2123 GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
2124 DCTHuffTable *acHuffTable,
2125 Guchar quantTable[64], int *prevDC,
2128 double v0, v1, v2, v3, v4, v5, v6, v7, t;
2133 // Huffman decode and dequantize
2134 size = readHuffSym(dcHuffTable);
2138 amp = readAmp(size);
2144 tmp1[0] = (*prevDC += amp) * quantTable[0];
2145 for (i = 1; i < 64; ++i)
2150 while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30)
2157 run += (c >> 4) & 0x0f;
2159 amp = readAmp(size);
2164 tmp1[j] = amp * quantTable[j];
2168 // inverse DCT on rows
2169 for (i = 0; i < 64; i += 8) {
2172 v0 = dctSqrt2 * tmp1[i+0];
2173 v1 = dctSqrt2 * tmp1[i+4];
2176 v4 = dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]);
2177 v7 = dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]);
2182 t = 0.5 * (v0 - v1);
2183 v0 = 0.5 * (v0 + v1);
2185 t = v2 * dctSin6 + v3 * dctCos6;
2186 v2 = v2 * dctCos6 - v3 * dctSin6;
2188 t = 0.5 * (v4 - v6);
2189 v4 = 0.5 * (v4 + v6);
2191 t = 0.5 * (v7 + v5);
2192 v5 = 0.5 * (v7 - v5);
2196 t = 0.5 * (v0 - v3);
2197 v0 = 0.5 * (v0 + v3);
2199 t = 0.5 * (v1 - v2);
2200 v1 = 0.5 * (v1 + v2);
2202 t = v4 * dctSin3 + v7 * dctCos3;
2203 v4 = v4 * dctCos3 - v7 * dctSin3;
2205 t = v5 * dctSin1 + v6 * dctCos1;
2206 v5 = v5 * dctCos1 - v6 * dctSin1;
2210 tmp1[i+0] = v0 + v7;
2211 tmp1[i+7] = v0 - v7;
2212 tmp1[i+1] = v1 + v6;
2213 tmp1[i+6] = v1 - v6;
2214 tmp1[i+2] = v2 + v5;
2215 tmp1[i+5] = v2 - v5;
2216 tmp1[i+3] = v3 + v4;
2217 tmp1[i+4] = v3 - v4;
2220 // inverse DCT on columns
2221 for (i = 0; i < 8; ++i) {
2224 v0 = dctSqrt2 * tmp1[0*8+i];
2225 v1 = dctSqrt2 * tmp1[4*8+i];
2228 v4 = dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]);
2229 v7 = dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]);
2234 t = 0.5 * (v0 - v1);
2235 v0 = 0.5 * (v0 + v1);
2237 t = v2 * dctSin6 + v3 * dctCos6;
2238 v2 = v2 * dctCos6 - v3 * dctSin6;
2240 t = 0.5 * (v4 - v6);
2241 v4 = 0.5 * (v4 + v6);
2243 t = 0.5 * (v7 + v5);
2244 v5 = 0.5 * (v7 - v5);
2248 t = 0.5 * (v0 - v3);
2249 v0 = 0.5 * (v0 + v3);
2251 t = 0.5 * (v1 - v2);
2252 v1 = 0.5 * (v1 + v2);
2254 t = v4 * dctSin3 + v7 * dctCos3;
2255 v4 = v4 * dctCos3 - v7 * dctSin3;
2257 t = v5 * dctSin1 + v6 * dctCos1;
2258 v5 = v5 * dctCos1 - v6 * dctSin1;
2262 tmp1[0*8+i] = v0 + v7;
2263 tmp1[7*8+i] = v0 - v7;
2264 tmp1[1*8+i] = v1 + v6;
2265 tmp1[6*8+i] = v1 - v6;
2266 tmp1[2*8+i] = v2 + v5;
2267 tmp1[5*8+i] = v2 - v5;
2268 tmp1[3*8+i] = v3 + v4;
2269 tmp1[4*8+i] = v3 - v4;
2272 // convert to 8-bit integers
2273 for (i = 0; i < 64; ++i)
2274 data[i] = dctClip[dctClipOffset + (int)(tmp1[i] + 128.5)];
2280 int DCTStream::readHuffSym(DCTHuffTable *table) {
2288 // add a bit to the code
2289 if ((bit = readBit()) == EOF)
2291 code = (code << 1) + bit;
2295 if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
2296 code -= table->firstCode[codeBits];
2297 return table->sym[table->firstSym[codeBits] + code];
2299 } while (codeBits < 16);
2301 error(getPos(), "Bad Huffman code in DCT stream");
2305 int DCTStream::readAmp(int size) {
2310 for (bits = 0; bits < size; ++bits) {
2311 if ((bit = readBit()) == EOF)
2313 amp = (amp << 1) + bit;
2315 if (amp < (1 << (size - 1)))
2316 amp -= (1 << size) - 1;
2320 int DCTStream::readBit() {
2324 if (inputBits == 0) {
2325 if ((c = str->getChar()) == EOF)
2329 c2 = str->getChar();
2330 } while (c2 == 0xff);
2332 error(getPos(), "Bad DCT data: missing 00 after ff");
2339 bit = (inputBuf >> (inputBits - 1)) & 1;
2344 GBool DCTStream::readHeader() {
2346 int minHSample, minVSample;
2355 numDCHuffTables = 0;
2356 numACHuffTables = 0;
2358 gotAdobeMarker = gFalse;
2359 restartInterval = 0;
2367 if (!readFrameInfo())
2371 if (!readHuffmanTables())
2377 if (!readScanInfo())
2382 if (!readQuantTables())
2386 if (!readRestartInterval())
2390 if (!readAdobeMarker())
2394 error(getPos(), "Bad DCT header");
2397 // skip APPn / COM / etc.
2400 for (i = 0; i < n; ++i)
2403 error(getPos(), "Unknown DCT marker <%02x>", c);
2411 mcuWidth = minHSample = compInfo[0].hSample;
2412 mcuHeight = minVSample = compInfo[0].vSample;
2413 for (i = 1; i < numComps; ++i) {
2414 if (compInfo[i].hSample < minHSample)
2415 minHSample = compInfo[i].hSample;
2416 if (compInfo[i].vSample < minVSample)
2417 minVSample = compInfo[i].vSample;
2418 if (compInfo[i].hSample > mcuWidth)
2419 mcuWidth = compInfo[i].hSample;
2420 if (compInfo[i].vSample > mcuHeight)
2421 mcuHeight = compInfo[i].vSample;
2423 for (i = 0; i < numComps; ++i) {
2424 compInfo[i].hSample /= minHSample;
2425 compInfo[i].vSample /= minVSample;
2427 mcuWidth = (mcuWidth / minHSample) * 8;
2428 mcuHeight = (mcuHeight / minVSample) * 8;
2431 bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
2432 for (i = 0; i < numComps; ++i)
2433 for (j = 0; j < mcuHeight; ++j)
2434 rowBuf[i][j] = (Guchar *)gmalloc(bufWidth * sizeof(Guchar));
2436 // figure out color transform
2437 if (!gotAdobeMarker && numComps == 3) {
2438 if (compInfo[0].id == 1 && compInfo[1].id == 2 && compInfo[2].id == 3) {
2443 // initialize counters
2452 GBool DCTStream::readFrameInfo() {
2458 length = read16() - 2;
2459 prec = str->getChar();
2462 numComps = str->getChar();
2465 error(getPos(), "Bad DCT precision %d", prec);
2468 for (i = 0; i < numComps; ++i) {
2469 compInfo[i].id = str->getChar();
2470 compInfo[i].inScan = gFalse;
2472 compInfo[i].hSample = (c >> 4) & 0x0f;
2473 compInfo[i].vSample = c & 0x0f;
2474 compInfo[i].quantTable = str->getChar();
2475 compInfo[i].dcHuffTable = 0;
2476 compInfo[i].acHuffTable = 0;
2481 GBool DCTStream::readScanInfo() {
2483 int scanComps, id, c;
2486 length = read16() - 2;
2487 scanComps = str->getChar();
2489 if (length != 2 * scanComps + 3) {
2490 error(getPos(), "Bad DCT scan info block");
2493 for (i = 0; i < scanComps; ++i) {
2494 id = str->getChar();
2495 for (j = 0; j < numComps; ++j) {
2496 if (id == compInfo[j].id)
2499 if (j == numComps) {
2500 error(getPos(), "Bad DCT component ID in scan info block");
2503 compInfo[j].inScan = gTrue;
2505 compInfo[j].dcHuffTable = (c >> 4) & 0x0f;
2506 compInfo[j].acHuffTable = c & 0x0f;
2514 GBool DCTStream::readQuantTables() {
2519 length = read16() - 2;
2520 while (length > 0) {
2521 index = str->getChar();
2522 if ((index & 0xf0) || index >= 4) {
2523 error(getPos(), "Bad DCT quantization table");
2526 if (index == numQuantTables)
2527 numQuantTables = index + 1;
2528 for (i = 0; i < 64; ++i)
2529 quantTables[index][dctZigZag[i]] = str->getChar();
2535 GBool DCTStream::readHuffmanTables() {
2544 length = read16() - 2;
2545 while (length > 0) {
2546 index = str->getChar();
2548 if ((index & 0x0f) >= 4) {
2549 error(getPos(), "Bad DCT Huffman table");
2554 if (index >= numACHuffTables)
2555 numACHuffTables = index+1;
2556 tbl = &acHuffTables[index];
2558 if (index >= numDCHuffTables)
2559 numDCHuffTables = index+1;
2560 tbl = &dcHuffTables[index];
2564 for (i = 1; i <= 16; ++i) {
2566 tbl->firstSym[i] = sym;
2567 tbl->firstCode[i] = code;
2568 tbl->numCodes[i] = c;
2570 code = (code + c) << 1;
2573 for (i = 0; i < sym; ++i)
2574 tbl->sym[i] = str->getChar();
2580 GBool DCTStream::readRestartInterval() {
2585 error(getPos(), "Bad DCT restart interval");
2588 restartInterval = read16();
2592 GBool DCTStream::readAdobeMarker() {
2600 for (i = 0; i < 12; ++i) {
2601 if ((c = str->getChar()) == EOF)
2605 if (strncmp(buf, "Adobe", 5))
2607 colorXform = buf[11];
2608 gotAdobeMarker = gTrue;
2612 error(getPos(), "Bad DCT Adobe APP14 marker");
2616 GBool DCTStream::readTrailer() {
2620 if (c != 0xd9) { // EOI
2621 error(getPos(), "Bad DCT trailer");
2627 int DCTStream::readMarker() {
2633 } while (c != 0xff);
2636 } while (c == 0xff);
2637 } while (c == 0x00);
2641 int DCTStream::read16() {
2644 if ((c1 = str->getChar()) == EOF)
2646 if ((c2 = str->getChar()) == EOF)
2648 return (c1 << 8) + c2;
2651 GString *DCTStream::getPSFilter(char *indent) {
2654 s = str->getPSFilter(indent);
2655 s->append(indent)->append("<< >> /DCTDecode filter\n");
2659 GBool DCTStream::isBinary(GBool last) {
2660 return str->isBinary(gTrue);
2663 //------------------------------------------------------------------------
2665 //------------------------------------------------------------------------
2667 int FlateStream::codeLenCodeMap[flateMaxCodeLenCodes] = {
2668 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
2671 FlateDecode FlateStream::lengthDecode[flateMaxLitCodes-257] = {
2703 FlateDecode FlateStream::distDecode[flateMaxDistCodes] = {
2736 FlateStream::FlateStream(Stream *str1, int predictor1, int columns1,
2737 int colors1, int bits1) {
2739 if (predictor1 != 1) {
2740 pred = new StreamPredictor(this, predictor1, columns1, colors1, bits1);
2746 FlateStream::~FlateStream() {
2753 void FlateStream::reset() {
2759 //~ need to look at window size?
2760 endOfBlock = eof = gTrue;
2761 cmf = str->getChar();
2762 flg = str->getChar();
2763 if (cmf == EOF || flg == EOF)
2765 if ((cmf & 0x0f) != 0x08) {
2766 error(getPos(), "Unknown compression method in flate stream");
2769 if ((((cmf << 8) + flg) % 31) != 0) {
2770 error(getPos(), "Bad FCHECK in flate stream");
2774 error(getPos(), "FDICT bit set in flate stream");
2783 compressedBlock = gFalse;
2788 int FlateStream::getChar() {
2792 return pred->getChar();
2794 while (remain == 0) {
2795 if (endOfBlock && eof)
2800 index = (index + 1) & flateMask;
2805 int FlateStream::lookChar() {
2809 return pred->lookChar();
2811 while (remain == 0) {
2812 if (endOfBlock && eof)
2820 int FlateStream::getRawChar() {
2823 while (remain == 0) {
2824 if (endOfBlock && eof)
2829 index = (index + 1) & flateMask;
2834 GString *FlateStream::getPSFilter(char *indent) {
2838 GBool FlateStream::isBinary(GBool last) {
2839 return str->isBinary(gTrue);
2842 void FlateStream::readSome() {
2853 if (compressedBlock) {
2854 if ((code1 = getHuffmanCodeWord(&litCodeTab)) == EOF)
2859 } else if (code1 == 256) {
2864 code2 = lengthDecode[code1].bits;
2865 if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
2867 len = lengthDecode[code1].first + code2;
2868 if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF)
2870 code2 = distDecode[code1].bits;
2871 if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
2873 dist = distDecode[code1].first + code2;
2875 j = (index - dist) & flateMask;
2876 for (k = 0; k < len; ++k) {
2878 i = (i + 1) & flateMask;
2879 j = (j + 1) & flateMask;
2885 len = (blockLen < flateWindow) ? blockLen : flateWindow;
2886 for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) {
2887 if ((c = str->getChar()) == EOF) {
2888 endOfBlock = eof = gTrue;
2902 error(getPos(), "Unexpected end of file in flate stream");
2903 endOfBlock = eof = gTrue;
2907 GBool FlateStream::startBlock() {
2912 // read block header
2913 blockHdr = getCodeWord(3);
2918 // uncompressed block
2919 if (blockHdr == 0) {
2920 compressedBlock = gFalse;
2921 if ((c = str->getChar()) == EOF)
2923 blockLen = c & 0xff;
2924 if ((c = str->getChar()) == EOF)
2926 blockLen |= (c & 0xff) << 8;
2927 if ((c = str->getChar()) == EOF)
2930 if ((c = str->getChar()) == EOF)
2932 check |= (c & 0xff) << 8;
2933 if (check != (~blockLen & 0xffff))
2934 error(getPos(), "Bad uncompressed block length in flate stream");
2938 // compressed block with fixed codes
2939 } else if (blockHdr == 1) {
2940 compressedBlock = gTrue;
2943 // compressed block with dynamic codes
2944 } else if (blockHdr == 2) {
2945 compressedBlock = gTrue;
2946 if (!readDynamicCodes())
2949 // unknown block type
2954 endOfBlock = gFalse;
2958 error(getPos(), "Bad block header in flate stream");
2959 endOfBlock = eof = gTrue;
2963 void FlateStream::loadFixedCodes() {
2966 // set up code arrays
2967 litCodeTab.codes = allCodes;
2968 distCodeTab.codes = allCodes + flateMaxLitCodes;
2970 // initialize literal code table
2971 for (i = 0; i <= 143; ++i)
2972 litCodeTab.codes[i].len = 8;
2973 for (i = 144; i <= 255; ++i)
2974 litCodeTab.codes[i].len = 9;
2975 for (i = 256; i <= 279; ++i)
2976 litCodeTab.codes[i].len = 7;
2977 for (i = 280; i <= 287; ++i)
2978 litCodeTab.codes[i].len = 8;
2979 compHuffmanCodes(&litCodeTab, flateMaxLitCodes);
2981 // initialize distance code table
2982 for (i = 0; i < 5; ++i)
2983 distCodeTab.start[i] = 0;
2984 distCodeTab.start[5] = 0;
2985 for (i = 6; i <= flateMaxHuffman+1; ++i)
2986 distCodeTab.start[6] = flateMaxDistCodes;
2987 for (i = 0; i < flateMaxDistCodes; ++i) {
2988 distCodeTab.codes[i].len = 5;
2989 distCodeTab.codes[i].code = i;
2990 distCodeTab.codes[i].val = i;
2994 GBool FlateStream::readDynamicCodes() {
2995 int numCodeLenCodes;
2998 FlateCode codeLenCodes[flateMaxCodeLenCodes];
2999 FlateHuffmanTab codeLenCodeTab;
3000 int len, repeat, code;
3004 if ((numLitCodes = getCodeWord(5)) == EOF)
3007 if ((numDistCodes = getCodeWord(5)) == EOF)
3010 if ((numCodeLenCodes = getCodeWord(4)) == EOF)
3012 numCodeLenCodes += 4;
3013 if (numLitCodes > flateMaxLitCodes ||
3014 numDistCodes > flateMaxDistCodes ||
3015 numCodeLenCodes > flateMaxCodeLenCodes)
3018 // read code length code table
3019 codeLenCodeTab.codes = codeLenCodes;
3020 for (i = 0; i < flateMaxCodeLenCodes; ++i)
3021 codeLenCodes[i].len = 0;
3022 for (i = 0; i < numCodeLenCodes; ++i) {
3023 if ((codeLenCodes[codeLenCodeMap[i]].len = getCodeWord(3)) == -1)
3026 compHuffmanCodes(&codeLenCodeTab, flateMaxCodeLenCodes);
3028 // set up code arrays
3029 litCodeTab.codes = allCodes;
3030 distCodeTab.codes = allCodes + numLitCodes;
3032 // read literal and distance code tables
3036 while (i < numLitCodes + numDistCodes) {
3037 if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF)
3040 if ((repeat = getCodeWord(2)) == EOF)
3042 for (repeat += 3; repeat > 0; --repeat)
3043 allCodes[i++].len = len;
3044 } else if (code == 17) {
3045 if ((repeat = getCodeWord(3)) == EOF)
3048 for (repeat += 3; repeat > 0; --repeat)
3049 allCodes[i++].len = 0;
3050 } else if (code == 18) {
3051 if ((repeat = getCodeWord(7)) == EOF)
3054 for (repeat += 11; repeat > 0; --repeat)
3055 allCodes[i++].len = 0;
3057 allCodes[i++].len = len = code;
3060 compHuffmanCodes(&litCodeTab, numLitCodes);
3061 compHuffmanCodes(&distCodeTab, numDistCodes);
3066 error(getPos(), "Bad dynamic code table in flate stream");
3070 // On entry, the <tab->codes> array contains the lengths of each code,
3071 // stored in code value order. This function computes the code words.
3072 // The result is sorted in order of (1) code length and (2) code word.
3073 // The length values are no longer valid. The <tab->start> array is
3074 // filled with the indexes of the first code of each length.
3075 void FlateStream::compHuffmanCodes(FlateHuffmanTab *tab, int n) {
3076 int numLengths[flateMaxHuffman+1];
3077 int nextCode[flateMaxHuffman+1];
3078 int nextIndex[flateMaxHuffman+2];
3082 // count number of codes for each code length
3083 for (i = 0; i <= flateMaxHuffman; ++i)
3085 for (i = 0; i < n; ++i)
3086 ++numLengths[tab->codes[i].len];
3088 // compute first index for each length
3089 tab->start[0] = nextIndex[0] = 0;
3090 for (i = 1; i <= flateMaxHuffman + 1; ++i)
3091 tab->start[i] = nextIndex[i] = tab->start[i-1] + numLengths[i-1];
3093 // compute first code for each length
3096 for (i = 1; i <= flateMaxHuffman; ++i) {
3097 code = (code + numLengths[i-1]) << 1;
3101 // compute the codes -- this permutes the codes array from value
3102 // order to length/code order
3103 for (i = 0; i < n; ++i) {
3104 j = nextIndex[tab->codes[i].len]++;
3105 if (tab->codes[i].len == 0)
3106 tab->codes[j].code = 0;
3108 tab->codes[j].code = nextCode[tab->codes[i].len]++;
3109 tab->codes[j].val = i;
3113 int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) {
3120 for (len = 1; len <= flateMaxHuffman; ++len) {
3122 // add a bit to the code
3123 if (codeSize == 0) {
3124 if ((c = str->getChar()) == EOF)
3129 code = (code << 1) | (codeBuf & 1);
3134 i = tab->start[len];
3135 j = tab->start[len + 1];
3136 if (i < j && code >= tab->codes[i].code && code <= tab->codes[j-1].code) {
3137 i += code - tab->codes[i].code;
3138 return tab->codes[i].val;
3143 error(getPos(), "Bad code (%04x) in flate stream", code);
3147 int FlateStream::getCodeWord(int bits) {
3150 while (codeSize < bits) {
3151 if ((c = str->getChar()) == EOF)
3153 codeBuf |= (c & 0xff) << codeSize;
3156 c = codeBuf & ((1 << bits) - 1);
3162 //------------------------------------------------------------------------
3164 //------------------------------------------------------------------------
3166 EOFStream::EOFStream(Stream *str1) {
3170 EOFStream::~EOFStream() {
3174 //------------------------------------------------------------------------
3175 // FixedLengthEncoder
3176 //------------------------------------------------------------------------
3178 FixedLengthEncoder::FixedLengthEncoder(Stream *str1, int length1) {
3184 FixedLengthEncoder::~FixedLengthEncoder() {
3185 if (str->isEncoder())
3189 void FixedLengthEncoder::reset() {
3194 int FixedLengthEncoder::getChar() {
3195 if (length >= 0 && count >= length)
3198 return str->getChar();
3201 int FixedLengthEncoder::lookChar() {
3202 if (length >= 0 && count >= length)
3204 return str->getChar();
3207 //------------------------------------------------------------------------
3209 //------------------------------------------------------------------------
3211 ASCII85Encoder::ASCII85Encoder(Stream *str1) {
3213 bufPtr = bufEnd = buf;
3218 ASCII85Encoder::~ASCII85Encoder() {
3219 if (str->isEncoder())
3223 void ASCII85Encoder::reset() {
3225 bufPtr = bufEnd = buf;
3230 GBool ASCII85Encoder::fillBuf() {
3239 for (n = 0; n < 4; ++n) {
3240 if ((c = str->getChar()) == EOF)
3244 bufPtr = bufEnd = buf;
3246 if (n == 4 && t == 0) {
3248 if (++lineLen == 65) {
3255 for (i = 4; i >= 0; --i) {
3256 buf1[i] = (char)(t % 85 + 0x21);
3259 for (i = 0; i <= n; ++i) {
3260 *bufEnd++ = buf1[i];
3261 if (++lineLen == 65) {
3273 return bufPtr < bufEnd;
3276 //------------------------------------------------------------------------
3278 //------------------------------------------------------------------------
3280 RunLengthEncoder::RunLengthEncoder(Stream *str1) {
3282 bufPtr = bufEnd = nextEnd = buf;
3286 RunLengthEncoder::~RunLengthEncoder() {
3287 if (str->isEncoder())
3291 void RunLengthEncoder::reset() {
3293 bufPtr = bufEnd = nextEnd = buf;
3298 // When fillBuf finishes, buf[] looks like this:
3299 // +-----+--------------+-----------------+--
3300 // + tag | ... data ... | next 0, 1, or 2 |
3301 // +-----+--------------+-----------------+--
3303 // bufPtr bufEnd nextEnd
3305 GBool RunLengthEncoder::fillBuf() {
3314 if (nextEnd < bufEnd + 1) {
3315 if ((c1 = str->getChar()) == EOF) {
3320 c1 = bufEnd[0] & 0xff;
3322 if (nextEnd < bufEnd + 2) {
3323 if ((c2 = str->getChar()) == EOF) {
3332 c2 = bufEnd[1] & 0xff;
3338 while (n < 128 && (c = str->getChar()) == c1)
3340 buf[0] = (char)(257 - n);
3345 } else if (n < 128) {
3352 // get up to 128 chars
3358 if ((c = str->getChar()) == EOF) {
3364 if (buf[n] == buf[n-1])
3367 if (buf[n] == buf[n-1]) {
3368 buf[0] = (char)(n-2-1);
3370 nextEnd = &buf[n+1];
3372 buf[0] = (char)(n-1);
3373 bufEnd = nextEnd = &buf[n+1];