1 //========================================================================
5 // Copyright 1996 Derek B. Noonburg
7 //========================================================================
10 #pragma implementation
26 #include "Stream-CCITT.h"
29 #if (__VMS_VER < 70000000)
30 extern "C" int unlink(char *filename);
39 //------------------------------------------------------------------------
41 #define headerSearchSize 1024 // read this many bytes at beginning of
42 // file to look for '%PDF'
44 //------------------------------------------------------------------------
45 // Stream (base class)
46 //------------------------------------------------------------------------
60 void Stream::resetImage(int width1, int nComps1, int nBits1) {
63 (width1 != width || nComps != nComps || nBits1 != nBits))
64 error(-1, "Mismatched image parameters in predictor");
68 nVals = width * nComps;
69 pixBytes = (nComps * nBits + 7) >> 3;
70 rowBytes = (nVals * nBits + 7) >> 3;
71 rawLine = (Guchar *)grealloc(rawLine, rowBytes + pixBytes);
72 memset(rawLine, 0, rowBytes);
73 pixLine = (Guchar *)grealloc(pixLine, ((nVals + 7) & ~7) * sizeof(Guchar));
77 char *Stream::getLine(char *buf, int size) {
81 if (lookChar() == EOF)
83 for (i = 0; i < size - 1; ++i) {
85 if (c == EOF || c == '\n')
88 if ((c = lookChar()) == '\n')
98 GBool Stream::getImagePixel(Guchar *pix) {
100 int left, up, upLeft, p, pa, pb, pc;
107 // read an image line
108 if (pixIdx >= nVals) {
110 // get PNG optimum predictor number
111 if (predictor == 15) {
112 if ((curPred = getChar()) == EOF)
119 // read the raw line, apply byte predictor
120 upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0;
121 for (i = 0; i < rowBytes; ++i) {
122 upLeftBuf[3] = upLeftBuf[2];
123 upLeftBuf[2] = upLeftBuf[1];
124 upLeftBuf[1] = upLeftBuf[0];
125 upLeftBuf[0] = rawLine[pixBytes+i];
126 if ((c = getChar()) == EOF)
130 rawLine[pixBytes+i] = rawLine[i] + (Guchar)c;
133 rawLine[pixBytes+i] = rawLine[pixBytes+i] + (Guchar)c;
135 case 13: // PNG average
136 rawLine[pixBytes+i] = ((rawLine[i] + rawLine[pixBytes+i]) >> 1) +
139 case 14: // PNG Paeth
141 up = rawLine[pixBytes+i];
142 upLeft = upLeftBuf[pixBytes];
143 p = left + up - upLeft;
144 if ((pa = p - left) < 0)
146 if ((pb = p - up) < 0)
148 if ((pc = p - upLeft) < 0)
150 if (pa <= pb && pa <= pc)
151 rawLine[pixBytes+i] = pa + (Guchar)c;
153 rawLine[pixBytes+i] = pb + (Guchar)c;
155 rawLine[pixBytes+i] = pc + (Guchar)c;
158 default: // no predictor or TIFF predictor
159 rawLine[pixBytes+i] = (Guchar)c;
164 // convert into pixels, apply component predictor
165 if (predictor == 2) {
167 for (i = 0, j = pixBytes; i < nVals; i += 8, ++j) {
169 pixLine[i+0] = (Guchar)((pixLine[i+0] + (c >> 7)) & 1);
170 pixLine[i+1] = (Guchar)((pixLine[i+1] + (c >> 6)) & 1);
171 pixLine[i+2] = (Guchar)((pixLine[i+2] + (c >> 5)) & 1);
172 pixLine[i+3] = (Guchar)((pixLine[i+3] + (c >> 4)) & 1);
173 pixLine[i+4] = (Guchar)((pixLine[i+4] + (c >> 3)) & 1);
174 pixLine[i+5] = (Guchar)((pixLine[i+5] + (c >> 2)) & 1);
175 pixLine[i+6] = (Guchar)((pixLine[i+6] + (c >> 1)) & 1);
176 pixLine[i+7] = (Guchar)((pixLine[i+7] + c) & 1);
178 } else if (nBits == 8) {
179 for (i = 0, j = pixBytes; i < nVals; ++i, ++j)
180 pixLine[i] = pixLine[i] + rawLine[j];
182 bitMask = (1 << nBits) - 1;
186 for (i = 0; i < nVals; ++i) {
188 buf = (buf << 8) | (rawLine[j++] & 0xff);
191 pixLine[i] = (Guchar)((pixLine[i] +
192 (buf >> (bits - nBits))) & bitMask);
198 for (i = 0, j = pixBytes; i < nVals; i += 8, ++j) {
200 pixLine[i+0] = (Guchar)((c >> 7) & 1);
201 pixLine[i+1] = (Guchar)((c >> 6) & 1);
202 pixLine[i+2] = (Guchar)((c >> 5) & 1);
203 pixLine[i+3] = (Guchar)((c >> 4) & 1);
204 pixLine[i+4] = (Guchar)((c >> 3) & 1);
205 pixLine[i+5] = (Guchar)((c >> 2) & 1);
206 pixLine[i+6] = (Guchar)((c >> 1) & 1);
207 pixLine[i+7] = (Guchar)(c & 1);
209 } else if (nBits == 8) {
210 for (i = 0, j = pixBytes; i < nVals; ++i, ++j)
211 pixLine[i] = rawLine[j];
213 bitMask = (1 << nBits) - 1;
217 for (i = 0; i < nVals; ++i) {
219 buf = (buf << 8) | (rawLine[j++] & 0xff);
222 pixLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask);
228 // read from start of line
232 for (i = 0; i < nComps; ++i)
233 pix[i] = pixLine[pixIdx++];
237 void Stream::skipImageLine() {
240 n = (nVals * nBits + 7) / 8;
241 for (i = 0; i < n; ++i)
246 void Stream::setPos(int pos) {
247 error(-1, "Internal: called setPos() on non-FileStream");
250 GString *Stream::getPSFilter(char *indent) {
251 return new GString();
254 Stream *Stream::addFilters(Object *dict) {
256 Object params, params2;
261 dict->dictLookup("Filter", &obj);
264 dict->dictLookup("F", &obj);
266 dict->dictLookup("DecodeParms", ¶ms);
267 if (params.isNull()) {
269 dict->dictLookup("DP", ¶ms);
272 str = makeFilter(obj.getName(), str, ¶ms);
273 } else if (obj.isArray()) {
274 for (i = 0; i < obj.arrayGetLength(); ++i) {
275 obj.arrayGet(i, &obj2);
276 if (params.isArray())
277 params.arrayGet(i, ¶ms2);
281 str = makeFilter(obj2.getName(), str, ¶ms2);
283 error(getPos(), "Bad filter name");
284 str = new EOFStream(str);
289 } else if (!obj.isNull()) {
290 error(getPos(), "Bad 'Filter' attribute in stream");
298 Stream *Stream::makeFilter(char *name, Stream *str, Object *params) {
299 int pred; // parameters
309 if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) {
310 str = new ASCIIHexStream(str);
311 } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) {
312 str = new ASCII85Stream(str);
313 } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) {
319 if (params->isDict()) {
320 params->dictLookup("Predictor", &obj);
324 params->dictLookup("Columns", &obj);
326 columns = obj.getInt();
328 params->dictLookup("Colors", &obj);
330 colors = obj.getInt();
332 params->dictLookup("BitsPerComponent", &obj);
336 params->dictLookup("EarlyChange", &obj);
338 early = obj.getInt();
341 str = new LZWStream(str, pred, columns, colors, bits, early);
342 } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) {
343 str = new RunLengthStream(str);
344 } else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) {
350 if (params->isDict()) {
351 params->dictLookup("K", &obj);
353 encoding = obj.getInt();
355 params->dictLookup("EncodedByteAlign", &obj);
357 byteAlign = obj.getBool();
359 params->dictLookup("Columns", &obj);
361 columns = obj.getInt();
363 params->dictLookup("Rows", &obj);
367 params->dictLookup("BlackIs1", &obj);
369 black = obj.getBool();
372 str = new CCITTFaxStream(str, encoding, byteAlign, columns, rows, black);
373 } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) {
374 str = new DCTStream(str);
375 } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) {
380 if (params->isDict()) {
381 params->dictLookup("Predictor", &obj);
385 params->dictLookup("Columns", &obj);
387 columns = obj.getInt();
389 params->dictLookup("Colors", &obj);
391 colors = obj.getInt();
393 params->dictLookup("BitsPerComponent", &obj);
398 str = new FlateStream(str, pred, columns, colors, bits);
400 error(getPos(), "Unknown filter '%s'", name);
401 str = new EOFStream(str);
406 //------------------------------------------------------------------------
408 //------------------------------------------------------------------------
410 FileStream::FileStream(FILE *f1, int start1, int length1, Object *dict1) {
414 bufPtr = bufEnd = buf;
420 FileStream::~FileStream() {
422 fseek(f, savePos, SEEK_SET);
426 void FileStream::reset() {
427 savePos = (int)ftell(f);
428 fseek(f, start, SEEK_SET);
429 bufPtr = bufEnd = buf;
433 GBool FileStream::fillBuf() {
436 bufPos += bufEnd - buf;
437 bufPtr = bufEnd = buf;
438 if (length >= 0 && bufPos >= start + length)
440 if (length >= 0 && bufPos + 256 > start + length)
441 n = start + length - bufPos;
444 n = fread(buf, 1, n, f);
446 if (bufPtr >= bufEnd)
451 void FileStream::setPos(int pos1) {
455 fseek(f, pos1, SEEK_SET);
458 fseek(f, 0, SEEK_END);
462 fseek(f, pos1, SEEK_END);
463 bufPos = (int)ftell(f);
465 bufPtr = bufEnd = buf;
468 GBool FileStream::checkHeader() {
469 char hdrBuf[headerSearchSize+1];
474 for (i = 0; i < headerSearchSize; ++i)
475 hdrBuf[i] = getChar();
476 hdrBuf[headerSearchSize] = '\0';
477 for (i = 0; i < headerSearchSize - 5; ++i) {
478 if (!strncmp(&hdrBuf[i], "%PDF-", 5))
481 if (i >= headerSearchSize - 5) {
482 error(-1, "May not be a PDF file (continuing anyway)");
486 p = strtok(&hdrBuf[i+5], " \t\n\r");
488 if (!(hdrBuf[i+5] >= '0' && hdrBuf[i+5] <= '9') || version > pdfVersionNum) {
489 error(getPos(), "PDF version %s -- xpdf supports version %s"
490 " (continuing anyway)", p, pdfVersion);
496 //------------------------------------------------------------------------
498 //------------------------------------------------------------------------
500 SubStream::SubStream(Stream *str1, Object *dict1) {
505 SubStream::~SubStream() {
509 //------------------------------------------------------------------------
511 //------------------------------------------------------------------------
513 ASCIIHexStream::ASCIIHexStream(Stream *str1) {
519 ASCIIHexStream::~ASCIIHexStream() {
523 void ASCIIHexStream::reset() {
529 int ASCIIHexStream::lookChar() {
540 } while (isspace(c1));
548 } while (isspace(c2));
553 if (c1 >= '0' && c1 <= '9') {
555 } else if (c1 >= 'A' && c1 <= 'F') {
556 x = (c1 - 'A' + 10) << 4;
557 } else if (c1 >= 'a' && c1 <= 'f') {
558 x = (c1 - 'a' + 10) << 4;
559 } else if (c1 == EOF) {
563 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c1);
566 if (c2 >= '0' && c2 <= '9') {
568 } else if (c2 >= 'A' && c2 <= 'F') {
570 } else if (c2 >= 'a' && c2 <= 'f') {
572 } else if (c2 == EOF) {
576 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c2);
582 GString *ASCIIHexStream::getPSFilter(char *indent) {
585 s = str->getPSFilter(indent);
586 s->append(indent)->append("/ASCIIHexDecode filter\n");
590 GBool ASCIIHexStream::isBinary(GBool last) {
591 return str->isBinary(gFalse);
594 //------------------------------------------------------------------------
596 //------------------------------------------------------------------------
598 ASCII85Stream::ASCII85Stream(Stream *str1) {
604 ASCII85Stream::~ASCII85Stream() {
608 void ASCII85Stream::reset() {
614 int ASCII85Stream::lookChar() {
623 c[0] = str->getChar();
624 } while (c[0] == '\n' || c[0] == '\r');
625 if (c[0] == '~' || c[0] == EOF) {
629 } else if (c[0] == 'z') {
630 b[0] = b[1] = b[2] = b[3] = 0;
633 for (k = 1; k < 5; ++k) {
635 c[k] = str->getChar();
636 } while (c[k] == '\n' || c[k] == '\r');
637 if (c[k] == '~' || c[k] == EOF)
641 if (k < 5 && (c[k] == '~' || c[k] == EOF)) {
642 for (++k; k < 5; ++k)
647 for (k = 0; k < 5; ++k)
648 t = t * 85 + (c[k] - 0x21);
649 for (k = 3; k >= 0; --k) {
650 b[k] = (int)(t & 0xff);
658 GString *ASCII85Stream::getPSFilter(char *indent) {
661 s = str->getPSFilter(indent);
662 s->append(indent)->append("/ASCII85Decode filter\n");
666 GBool ASCII85Stream::isBinary(GBool last) {
667 return str->isBinary(gFalse);
670 //------------------------------------------------------------------------
672 //------------------------------------------------------------------------
674 LZWStream::LZWStream(Stream *str1, int predictor1, int columns1, int colors1,
675 int bits1, int early1) {
677 predictor = predictor1;
678 if (predictor1 > 1) {
685 bufPtr = bufEnd = buf;
688 LZWStream::~LZWStream() {
701 int LZWStream::getChar() {
702 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
705 int LZWStream::lookChar() {
706 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff);
709 void LZWStream::reset() {
713 bufPtr = bufEnd = buf;
723 strcpy(zCmd, uncompressCmd);
725 zName = zCmd + strlen(zCmd);
728 if (!(f = fopen(zName, "wb"))) {
729 error(getPos(), "Couldn't open temporary file '%s'", zName);
735 if (!(zPipe = popen(zCmd, "r"))) {
736 error(getPos(), "Couldn't popen '%s'", zCmd);
746 error(getPos(), "Couldn't execute '%s'", zCmd);
750 zName[strlen(zName) - 2] = '\0';
751 if (!(zPipe = fopen(zName, "rb"))) {
752 error(getPos(), "Couldn't open uncompress file '%s'", zName);
759 void LZWStream::dumpFile(FILE *f) {
760 int outCodeBits; // size of output code
761 int outBits; // max output code
762 int outBuf[8]; // output buffer
763 int outData; // temporary output buffer
764 int inCode, outCode; // input and output codes
765 int nextCode; // next code index
766 GBool eof; // set when EOF is reached
767 GBool clear; // set if table needs to be cleared
768 GBool first; // indicates first code word after clear
775 // max code length, block mode flag
793 for (i = 0; i < 8; ++i) {
794 // check for table overflow
795 if (nextCode + early > 0x1001) {
806 } while (first && inCode == 256);
809 // compute output code
812 } else if (inCode == 256) {
815 } else if (inCode == 257) {
819 outCode = inCode - 1;
829 // check input code size
830 if (nextCode + early == 0x200)
832 else if (nextCode + early == 0x400) {
834 } else if (nextCode + early == 0x800) {
838 // check for eof/clear
847 // write output block
851 while (j < i || outBits > 0) {
852 if (outBits < 8 && j < i) {
853 outData = outData | (outBuf[j++] << outBits);
854 outBits += outCodeBits;
856 fputc(outData & 0xff, f);
861 // check output code size
862 if (nextCode - 1 == 512 ||
863 nextCode - 1 == 1024 ||
864 nextCode - 1 == 2048 ||
865 nextCode - 1 == 4096) {
866 outCodeBits = inCodeBits;
869 // clear table if necessary
880 int LZWStream::getCode() {
884 while (inputBits < inCodeBits) {
885 if ((c = str->getChar()) == EOF)
887 inputBuf = (inputBuf << 8) | (c & 0xff);
890 code = (inputBuf >> (inputBits - inCodeBits)) & ((1 << inCodeBits) - 1);
891 inputBits -= inCodeBits;
895 GBool LZWStream::fillBuf() {
900 if ((n = fread(buf, 1, 256, zPipe)) < 256) {
914 GString *LZWStream::getPSFilter(char *indent) {
917 s = str->getPSFilter(indent);
918 s->append(indent)->append("/LZWDecode filter\n");
922 GBool LZWStream::isBinary(GBool last) {
923 return str->isBinary(gTrue);
926 //------------------------------------------------------------------------
928 //------------------------------------------------------------------------
930 RunLengthStream::RunLengthStream(Stream *str1) {
932 bufPtr = bufEnd = buf;
936 RunLengthStream::~RunLengthStream() {
940 void RunLengthStream::reset() {
942 bufPtr = bufEnd = buf;
946 GString *RunLengthStream::getPSFilter(char *indent) {
949 s = str->getPSFilter(indent);
950 s->append(indent)->append("/RunLengthDecode filter\n");
954 GBool RunLengthStream::isBinary(GBool last) {
955 return str->isBinary(gTrue);
958 GBool RunLengthStream::fillBuf() {
965 if (c == 0x80 || c == EOF) {
971 for (i = 0; i < n; ++i)
972 buf[i] = (char)str->getChar();
976 for (i = 0; i < n; ++i)
984 //------------------------------------------------------------------------
986 //------------------------------------------------------------------------
988 CCITTFaxStream::CCITTFaxStream(Stream *str1, int encoding1, GBool byteAlign1,
989 int columns1, int rows1, GBool black1) {
991 encoding = encoding1;
992 byteAlign = byteAlign1;
996 refLine = (short *)gmalloc((columns + 2) * sizeof(short));
997 codingLine = (short *)gmalloc((columns + 2) * sizeof(short));
1000 nextLine2D = encoding < 0;
1003 codingLine[1] = refLine[2] = columns;
1009 CCITTFaxStream::~CCITTFaxStream() {
1015 void CCITTFaxStream::reset() {
1018 nextLine2D = encoding < 0;
1020 if ((look13Bits() >> 1) == 0x001)
1023 codingLine[1] = refLine[2] = columns;
1028 int CCITTFaxStream::lookChar() {
1029 short code1, code2, code3;
1034 // if at eof just return EOF
1035 if (eof && codingLine[a0] >= columns)
1038 // read the next row
1039 if (codingLine[a0] >= columns) {
1041 // check for end of file
1043 if (i == EOF || (i >> 1) == 0x001) {
1045 codingLine[a0 = 0] = columns;
1051 for (i = 0; codingLine[i] < columns; ++i)
1052 refLine[i] = codingLine[i];
1053 refLine[i] = refLine[i + 1] = columns;
1055 a0New = codingLine[a0 = 0] = 0;
1057 code1 = getTwoDimCode();
1060 if (refLine[b1] < columns) {
1061 a0New = refLine[b1 + 1];
1066 if ((a0 & 1) == 0) {
1069 code1 += code3 = getWhiteCode();
1070 } while (code3 >= 64);
1072 code2 += code3 = getBlackCode();
1073 } while (code3 >= 64);
1077 code1 += code3 = getBlackCode();
1078 } while (code3 >= 64);
1080 code2 += code3 = getWhiteCode();
1081 } while (code3 >= 64);
1083 codingLine[a0 + 1] = a0New + code1;
1085 a0New = codingLine[a0 + 1] = codingLine[a0] + code2;
1087 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1091 a0New = codingLine[++a0] = refLine[b1];
1092 if (refLine[b1] < columns) {
1094 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1099 a0New = codingLine[++a0] = refLine[b1] + 1;
1100 if (refLine[b1] < columns) {
1102 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1107 a0New = codingLine[++a0] = refLine[b1] - 1;
1109 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1113 a0New = codingLine[++a0] = refLine[b1] + 2;
1114 if (refLine[b1] < columns) {
1116 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1121 a0New = codingLine[++a0] = refLine[b1] - 2;
1123 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1127 a0New = codingLine[++a0] = refLine[b1] + 3;
1128 if (refLine[b1] < columns) {
1130 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1135 a0New = codingLine[++a0] = refLine[b1] - 3;
1137 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1142 codingLine[a0 = 0] = columns;
1145 error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1);
1148 } while (codingLine[a0] < columns);
1152 codingLine[a0 = 0] = 0;
1156 code1 += code3 = getWhiteCode();
1157 } while (code3 >= 64);
1158 codingLine[a0+1] = codingLine[a0] + code1;
1160 if (codingLine[a0] >= columns)
1164 code2 += code3 = getBlackCode();
1165 } while (code3 >= 64);
1166 codingLine[a0+1] = codingLine[a0] + code2;
1168 if (codingLine[a0] >= columns)
1173 if (codingLine[a0] != columns)
1174 error(getPos(), "CCITTFax row is wrong length (%d)", codingLine[a0]);
1176 // check for end-of-line marker
1177 code1 = look13Bits();
1178 if ((code1 >> 1) == 0x001) {
1182 nextLine2D = !(code1 & 1);
1187 outputBits = codingLine[1] - codingLine[0];
1191 if (outputBits >= 8) {
1192 ret = ((a0 & 1) == 0) ? 0xff : 0x00;
1193 if ((outputBits -= 8) == 0) {
1195 if (codingLine[a0] < columns)
1196 outputBits = codingLine[a0 + 1] - codingLine[a0];
1202 if (outputBits > bits) {
1206 ret |= 0xff >> (8 - i);
1212 ret |= (0xff >> (8 - i)) << bits;
1215 if (codingLine[a0] < columns)
1216 outputBits = codingLine[a0 + 1] - codingLine[a0];
1218 } while (bits > 0 && codingLine[a0] < columns);
1220 buf = black ? (ret ^ 0xff) : ret;
1224 short CCITTFaxStream::getTwoDimCode() {
1228 code0 = look13Bits();
1230 if (code == 0x0002) {
1232 return twoDimVertL3;
1234 if (code == 0x0003) {
1236 return twoDimVertR3;
1239 if (code == 0x0002) {
1241 return twoDimVertL2;
1243 if (code == 0x0003) {
1245 return twoDimVertR2;
1248 p = &twoDimTab1[code];
1253 error(getPos(), "Bad two dim code (%04x) in CCITTFax stream", code0);
1257 short CCITTFaxStream::getWhiteCode() {
1261 code = look13Bits();
1262 if ((code >> 6) == 0)
1263 p = &whiteTab1[code >> 1];
1265 p = &whiteTab2[code >> 4];
1270 error(getPos(), "Bad white code (%04x) in CCITTFax stream", code);
1274 short CCITTFaxStream::getBlackCode() {
1278 code = look13Bits();
1279 if ((code >> 7) == 0)
1280 p = &blackTab1[code];
1281 else if ((code >> 9) == 0)
1282 p = &blackTab2[(code >> 1) - 64];
1284 p = &blackTab3[code >> 7];
1289 error(getPos(), "Bad black code (%04x) in CCITTFax stream", code);
1293 short CCITTFaxStream::look13Bits() {
1296 while (inputBits < 13) {
1297 if ((c = str->getChar()) == EOF) {
1302 inputBuf = (inputBuf << 8) + c;
1305 return (inputBuf >> (inputBits - 13)) & 0x1fff;
1308 GString *CCITTFaxStream::getPSFilter(char *indent) {
1312 s = str->getPSFilter(indent);
1313 s->append(indent)->append("<< ");
1314 if (encoding != 0) {
1315 sprintf(s1, "/K %d ", encoding);
1319 s->append("/EncodedByteAlign true ");
1320 sprintf(s1, "/Columns %d ", columns);
1323 sprintf(s1, "/Rows %d ", rows);
1327 s->append("/BlackIs1 true ");
1328 s->append(">> /CCITTFaxDecode filter\n");
1332 GBool CCITTFaxStream::isBinary(GBool last) {
1333 return str->isBinary(gTrue);
1336 //------------------------------------------------------------------------
1338 //------------------------------------------------------------------------
1340 // IDCT constants (20.12 fixed point format)
1342 #define dctCos1 4017 // cos(pi/16)
1343 #define dctSin1 799 // sin(pi/16)
1344 #define dctCos3 3406 // cos(3*pi/16)
1345 #define dctSin3 2276 // sin(3*pi/16)
1346 #define dctCos6 1567 // cos(6*pi/16)
1347 #define dctSin6 3784 // sin(6*pi/16)
1348 #define dctSqrt2 5793 // sqrt(2)
1349 #define dctSqrt1d2 2896 // sqrt(2) / 2
1354 #define dctCos1 0.98078528 // cos(pi/16)
1355 #define dctSin1 0.19509032 // sin(pi/16)
1356 #define dctCos3 0.83146961 // cos(3*pi/16)
1357 #define dctSin3 0.55557023 // sin(3*pi/16)
1358 #define dctCos6 0.38268343 // cos(6*pi/16)
1359 #define dctSin6 0.92387953 // sin(6*pi/16)
1360 #define dctSqrt2 1.41421356 // sqrt(2)
1361 #define dctSqrt1d2 0.70710678 // sqrt(2) / 2
1364 // color conversion parameters (16.16 fixed point format)
1365 #define dctCrToR 91881 // 1.4020
1366 #define dctCbToG -22553 // -0.3441363
1367 #define dctCrToG -46802 // -0.71413636
1368 #define dctCbToB 116130 // 1.772
1370 // clip [-256,511] --> [0,255]
1371 #define dctClipOffset 256
1372 static Guchar dctClip[768];
1373 static int dctClipInit = 0;
1375 // zig zag decode map
1376 static int dctZigZag[64] = {
1382 5, 12, 19, 26, 33, 40,
1383 48, 41, 34, 27, 20, 13, 6,
1384 7, 14, 21, 28, 35, 42, 49, 56,
1385 57, 50, 43, 36, 29, 22, 15,
1386 23, 30, 37, 44, 51, 58,
1394 DCTStream::DCTStream(Stream *str1) {
1399 mcuWidth = mcuHeight = 0;
1403 for (i = 0; i < 4; ++i)
1404 for (j = 0; j < 32; ++j)
1405 rowBuf[i][j] = NULL;
1408 for (i = -256; i < 0; ++i)
1409 dctClip[dctClipOffset + i] = 0;
1410 for (i = 0; i < 256; ++i)
1411 dctClip[dctClipOffset + i] = i;
1412 for (i = 256; i < 512; ++i)
1413 dctClip[dctClipOffset + i] = 255;
1418 DCTStream::~DCTStream() {
1422 for (i = 0; i < numComps; ++i)
1423 for (j = 0; j < mcuHeight; ++j)
1424 gfree(rowBuf[i][j]);
1427 void DCTStream::reset() {
1429 if (!readHeader()) {
1433 restartMarker = 0xd0;
1437 int DCTStream::getChar() {
1443 if (++comp == numComps) {
1456 int DCTStream::lookChar() {
1459 if (dy >= mcuHeight) {
1460 if (!readMCURow()) {
1468 return rowBuf[comp][dy][x];
1471 void DCTStream::restart() {
1475 restartCtr = restartInterval;
1476 for (i = 0; i < numComps; ++i)
1477 compInfo[i].prevDC = 0;
1480 GBool DCTStream::readMCURow() {
1483 int pY, pCb, pCr, pR, pG, pB;
1484 int h, v, horiz, vert, hSub, vSub;
1485 int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
1488 for (x1 = 0; x1 < width; x1 += mcuWidth) {
1490 // deal with restart marker
1491 if (restartInterval > 0 && restartCtr == 0) {
1493 if (c != restartMarker) {
1494 error(getPos(), "Bad DCT data: incorrect restart marker");
1497 if (++restartMarker == 0xd8)
1498 restartMarker = 0xd0;
1503 for (cc = 0; cc < numComps; ++cc) {
1504 h = compInfo[cc].hSample;
1505 v = compInfo[cc].vSample;
1506 horiz = mcuWidth / h;
1507 vert = mcuHeight / v;
1510 for (y2 = 0; y2 < mcuHeight; y2 += vert) {
1511 for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
1512 if (!readDataUnit(&dcHuffTables[compInfo[cc].dcHuffTable],
1513 &acHuffTables[compInfo[cc].acHuffTable],
1514 quantTables[compInfo[cc].quantTable],
1515 &compInfo[cc].prevDC,
1518 if (hSub == 1 && vSub == 1) {
1519 for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
1520 p1 = &rowBuf[cc][y2+y3][x1+x2];
1530 } else if (hSub == 2 && vSub == 2) {
1531 for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
1532 p1 = &rowBuf[cc][y2+y3][x1+x2];
1533 p2 = &rowBuf[cc][y2+y3+1][x1+x2];
1534 p1[0] = p1[1] = p2[0] = p2[1] = data[i];
1535 p1[2] = p1[3] = p2[2] = p2[3] = data[i+1];
1536 p1[4] = p1[5] = p2[4] = p2[5] = data[i+2];
1537 p1[6] = p1[7] = p2[6] = p2[7] = data[i+3];
1538 p1[8] = p1[9] = p2[8] = p2[9] = data[i+4];
1539 p1[10] = p1[11] = p2[10] = p2[11] = data[i+5];
1540 p1[12] = p1[13] = p2[12] = p2[13] = data[i+6];
1541 p1[14] = p1[15] = p2[14] = p2[15] = data[i+7];
1545 for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
1546 for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
1547 for (y5 = 0; y5 < vSub; ++y5)
1548 for (x5 = 0; x5 < hSub; ++x5)
1549 rowBuf[cc][y2+y4+y5][x1+x2+x4+x5] = data[i];
1559 // color space conversion
1561 // convert YCbCr to RGB
1562 if (numComps == 3) {
1563 for (y2 = 0; y2 < mcuHeight; ++y2) {
1564 for (x2 = 0; x2 < mcuWidth; ++x2) {
1565 pY = rowBuf[0][y2][x1+x2];
1566 pCb = rowBuf[1][y2][x1+x2] - 128;
1567 pCr = rowBuf[2][y2][x1+x2] - 128;
1568 pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
1569 rowBuf[0][y2][x1+x2] = dctClip[dctClipOffset + pR];
1570 pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32678) >> 16;
1571 rowBuf[1][y2][x1+x2] = dctClip[dctClipOffset + pG];
1572 pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
1573 rowBuf[2][y2][x1+x2] = dctClip[dctClipOffset + pB];
1576 // convert YCbCrK to CMYK (K is passed through unchanged)
1577 } else if (numComps == 4) {
1578 for (y2 = 0; y2 < mcuHeight; ++y2) {
1579 for (x2 = 0; x2 < mcuWidth; ++x2) {
1580 pY = rowBuf[0][y2][x1+x2];
1581 pCb = rowBuf[1][y2][x1+x2] - 128;
1582 pCr = rowBuf[2][y2][x1+x2] - 128;
1583 pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
1584 rowBuf[0][y2][x1+x2] = 255 - dctClip[dctClipOffset + pR];
1585 pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32678) >> 16;
1586 rowBuf[1][y2][x1+x2] = 255 - dctClip[dctClipOffset + pG];
1587 pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
1588 rowBuf[2][y2][x1+x2] = 255 - dctClip[dctClipOffset + pB];
1597 // This IDCT algorithm is taken from:
1598 // Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,
1599 // "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
1600 // IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
1602 // The stage numbers mentioned in the comments refer to Figure 1 in this
1605 GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
1606 DCTHuffTable *acHuffTable,
1607 Guchar quantTable[64], int *prevDC,
1610 int v0, v1, v2, v3, v4, v5, v6, v7, t;
1615 // Huffman decode and dequantize
1616 size = readHuffSym(dcHuffTable);
1620 amp = readAmp(size);
1626 tmp1[0] = (*prevDC += amp) * quantTable[0];
1627 for (i = 1; i < 64; ++i)
1632 while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30)
1639 run += (c >> 4) & 0x0f;
1641 amp = readAmp(size);
1646 tmp1[j] = amp * quantTable[j];
1650 // inverse DCT on rows
1651 for (i = 0; i < 64; i += 8) {
1654 v0 = (dctSqrt2 * tmp1[i+0] + 128) >> 8;
1655 v1 = (dctSqrt2 * tmp1[i+4] + 128) >> 8;
1658 v4 = (dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]) + 128) >> 8;
1659 v7 = (dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]) + 128) >> 8;
1660 v5 = tmp1[i+3] << 4;
1661 v6 = tmp1[i+5] << 4;
1664 t = (v0 - v1+ 1) >> 1;
1665 v0 = (v0 + v1 + 1) >> 1;
1667 t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8;
1668 v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8;
1670 t = (v4 - v6 + 1) >> 1;
1671 v4 = (v4 + v6 + 1) >> 1;
1673 t = (v7 + v5 + 1) >> 1;
1674 v5 = (v7 - v5 + 1) >> 1;
1678 t = (v0 - v3 + 1) >> 1;
1679 v0 = (v0 + v3 + 1) >> 1;
1681 t = (v1 - v2 + 1) >> 1;
1682 v1 = (v1 + v2 + 1) >> 1;
1684 t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
1685 v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
1687 t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
1688 v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
1692 tmp1[i+0] = v0 + v7;
1693 tmp1[i+7] = v0 - v7;
1694 tmp1[i+1] = v1 + v6;
1695 tmp1[i+6] = v1 - v6;
1696 tmp1[i+2] = v2 + v5;
1697 tmp1[i+5] = v2 - v5;
1698 tmp1[i+3] = v3 + v4;
1699 tmp1[i+4] = v3 - v4;
1702 // inverse DCT on columns
1703 for (i = 0; i < 8; ++i) {
1706 v0 = (dctSqrt2 * tmp1[0*8+i] + 2048) >> 12;
1707 v1 = (dctSqrt2 * tmp1[4*8+i] + 2048) >> 12;
1710 v4 = (dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]) + 2048) >> 12;
1711 v7 = (dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]) + 2048) >> 12;
1716 t = (v0 - v1 + 1) >> 1;
1717 v0 = (v0 + v1 + 1) >> 1;
1719 t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12;
1720 v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12;
1722 t = (v4 - v6 + 1) >> 1;
1723 v4 = (v4 + v6 + 1) >> 1;
1725 t = (v7 + v5 + 1) >> 1;
1726 v5 = (v7 - v5 + 1) >> 1;
1730 t = (v0 - v3 + 1) >> 1;
1731 v0 = (v0 + v3 + 1) >> 1;
1733 t = (v1 - v2 + 1) >> 1;
1734 v1 = (v1 + v2 + 1) >> 1;
1736 t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
1737 v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
1739 t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
1740 v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
1744 tmp1[0*8+i] = v0 + v7;
1745 tmp1[7*8+i] = v0 - v7;
1746 tmp1[1*8+i] = v1 + v6;
1747 tmp1[6*8+i] = v1 - v6;
1748 tmp1[2*8+i] = v2 + v5;
1749 tmp1[5*8+i] = v2 - v5;
1750 tmp1[3*8+i] = v3 + v4;
1751 tmp1[4*8+i] = v3 - v4;
1754 // convert to 8-bit integers
1755 for (i = 0; i < 64; ++i)
1756 data[i] = dctClip[dctClipOffset + 128 + ((tmp1[i] + 8) >> 4)];
1763 GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
1764 DCTHuffTable *acHuffTable,
1765 Guchar quantTable[64], int *prevDC,
1768 double v0, v1, v2, v3, v4, v5, v6, v7, t;
1773 // Huffman decode and dequantize
1774 size = readHuffSym(dcHuffTable);
1778 amp = readAmp(size);
1784 tmp1[0] = (*prevDC += amp) * quantTable[0];
1785 for (i = 1; i < 64; ++i)
1790 while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30)
1797 run += (c >> 4) & 0x0f;
1799 amp = readAmp(size);
1804 tmp1[j] = amp * quantTable[j];
1808 // inverse DCT on rows
1809 for (i = 0; i < 64; i += 8) {
1812 v0 = dctSqrt2 * tmp1[i+0];
1813 v1 = dctSqrt2 * tmp1[i+4];
1816 v4 = dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]);
1817 v7 = dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]);
1822 t = 0.5 * (v0 - v1);
1823 v0 = 0.5 * (v0 + v1);
1825 t = v2 * dctSin6 + v3 * dctCos6;
1826 v2 = v2 * dctCos6 - v3 * dctSin6;
1828 t = 0.5 * (v4 - v6);
1829 v4 = 0.5 * (v4 + v6);
1831 t = 0.5 * (v7 + v5);
1832 v5 = 0.5 * (v7 - v5);
1836 t = 0.5 * (v0 - v3);
1837 v0 = 0.5 * (v0 + v3);
1839 t = 0.5 * (v1 - v2);
1840 v1 = 0.5 * (v1 + v2);
1842 t = v4 * dctSin3 + v7 * dctCos3;
1843 v4 = v4 * dctCos3 - v7 * dctSin3;
1845 t = v5 * dctSin1 + v6 * dctCos1;
1846 v5 = v5 * dctCos1 - v6 * dctSin1;
1850 tmp1[i+0] = v0 + v7;
1851 tmp1[i+7] = v0 - v7;
1852 tmp1[i+1] = v1 + v6;
1853 tmp1[i+6] = v1 - v6;
1854 tmp1[i+2] = v2 + v5;
1855 tmp1[i+5] = v2 - v5;
1856 tmp1[i+3] = v3 + v4;
1857 tmp1[i+4] = v3 - v4;
1860 // inverse DCT on columns
1861 for (i = 0; i < 8; ++i) {
1864 v0 = dctSqrt2 * tmp1[0*8+i];
1865 v1 = dctSqrt2 * tmp1[4*8+i];
1868 v4 = dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]);
1869 v7 = dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]);
1874 t = 0.5 * (v0 - v1);
1875 v0 = 0.5 * (v0 + v1);
1877 t = v2 * dctSin6 + v3 * dctCos6;
1878 v2 = v2 * dctCos6 - v3 * dctSin6;
1880 t = 0.5 * (v4 - v6);
1881 v4 = 0.5 * (v4 + v6);
1883 t = 0.5 * (v7 + v5);
1884 v5 = 0.5 * (v7 - v5);
1888 t = 0.5 * (v0 - v3);
1889 v0 = 0.5 * (v0 + v3);
1891 t = 0.5 * (v1 - v2);
1892 v1 = 0.5 * (v1 + v2);
1894 t = v4 * dctSin3 + v7 * dctCos3;
1895 v4 = v4 * dctCos3 - v7 * dctSin3;
1897 t = v5 * dctSin1 + v6 * dctCos1;
1898 v5 = v5 * dctCos1 - v6 * dctSin1;
1902 tmp1[0*8+i] = v0 + v7;
1903 tmp1[7*8+i] = v0 - v7;
1904 tmp1[1*8+i] = v1 + v6;
1905 tmp1[6*8+i] = v1 - v6;
1906 tmp1[2*8+i] = v2 + v5;
1907 tmp1[5*8+i] = v2 - v5;
1908 tmp1[3*8+i] = v3 + v4;
1909 tmp1[4*8+i] = v3 - v4;
1912 // convert to 8-bit integers
1913 for (i = 0; i < 64; ++i)
1914 data[i] = dctClip[dctClipOffset + (int)(tmp1[i] + 128.5)];
1920 int DCTStream::readHuffSym(DCTHuffTable *table) {
1928 // add a bit to the code
1929 if ((bit = readBit()) == EOF)
1931 code = (code << 1) + bit;
1935 if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
1936 code -= table->firstCode[codeBits];
1937 return table->sym[table->firstSym[codeBits] + code];
1939 } while (codeBits < 16);
1941 error(getPos(), "Bad Huffman code in DCT stream");
1945 int DCTStream::readAmp(int size) {
1950 for (bits = 0; bits < size; ++bits) {
1951 if ((bit = readBit()) == EOF)
1953 amp = (amp << 1) + bit;
1955 if (amp < (1 << (size - 1)))
1956 amp -= (1 << size) - 1;
1960 int DCTStream::readBit() {
1964 if (inputBits == 0) {
1965 if ((c = str->getChar()) == EOF)
1969 c2 = str->getChar();
1970 } while (c2 == 0xff);
1972 error(getPos(), "Bad DCT data: missing 00 after ff");
1979 bit = (inputBuf >> (inputBits - 1)) & 1;
1984 GBool DCTStream::readHeader() {
1986 int minHSample, minVSample;
1995 numDCHuffTables = 0;
1996 numACHuffTables = 0;
1998 restartInterval = 0;
2006 if (!readFrameInfo())
2010 if (!readHuffmanTables())
2016 if (!readScanInfo())
2021 if (!readQuantTables())
2025 if (!readRestartInterval())
2029 if (!readAdobeMarker())
2033 error(getPos(), "Bad DCT header");
2036 // skip APPn / COM / etc.
2039 for (i = 0; i < n; ++i)
2042 error(getPos(), "Unknown DCT marker <%02x>", c);
2050 mcuWidth = minHSample = compInfo[0].hSample;
2051 mcuHeight = minVSample = compInfo[0].vSample;
2052 for (i = 1; i < numComps; ++i) {
2053 if (compInfo[i].hSample < minHSample)
2054 minHSample = compInfo[i].hSample;
2055 if (compInfo[i].vSample < minVSample)
2056 minVSample = compInfo[i].vSample;
2057 if (compInfo[i].hSample > mcuWidth)
2058 mcuWidth = compInfo[i].hSample;
2059 if (compInfo[i].vSample > mcuHeight)
2060 mcuHeight = compInfo[i].vSample;
2062 for (i = 0; i < numComps; ++i) {
2063 compInfo[i].hSample /= minHSample;
2064 compInfo[i].vSample /= minVSample;
2066 mcuWidth = (mcuWidth / minHSample) * 8;
2067 mcuHeight = (mcuHeight / minVSample) * 8;
2070 bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
2071 for (i = 0; i < numComps; ++i)
2072 for (j = 0; j < mcuHeight; ++j)
2073 rowBuf[i][j] = (Guchar *)gmalloc(bufWidth * sizeof(Guchar));
2075 // initialize counters
2084 GBool DCTStream::readFrameInfo() {
2090 length = read16() - 2;
2091 prec = str->getChar();
2094 numComps = str->getChar();
2097 error(getPos(), "Bad DCT precision %d", prec);
2100 for (i = 0; i < numComps; ++i) {
2101 compInfo[i].id = str->getChar();
2102 compInfo[i].inScan = gFalse;
2104 compInfo[i].hSample = (c >> 4) & 0x0f;
2105 compInfo[i].vSample = c & 0x0f;
2106 compInfo[i].quantTable = str->getChar();
2107 compInfo[i].dcHuffTable = 0;
2108 compInfo[i].acHuffTable = 0;
2113 GBool DCTStream::readScanInfo() {
2115 int scanComps, id, c;
2118 length = read16() - 2;
2119 scanComps = str->getChar();
2121 if (length != 2 * scanComps + 3) {
2122 error(getPos(), "Bad DCT scan info block");
2125 for (i = 0; i < scanComps; ++i) {
2126 id = str->getChar();
2127 for (j = 0; j < numComps; ++j) {
2128 if (id == compInfo[j].id)
2131 if (j == numComps) {
2132 error(getPos(), "Bad DCT component ID in scan info block");
2135 compInfo[j].inScan = gTrue;
2137 compInfo[j].dcHuffTable = (c >> 4) & 0x0f;
2138 compInfo[j].acHuffTable = c & 0x0f;
2146 GBool DCTStream::readQuantTables() {
2151 length = read16() - 2;
2152 while (length > 0) {
2153 index = str->getChar();
2154 if ((index & 0xf0) || index >= 4) {
2155 error(getPos(), "Bad DCT quantization table");
2158 if (index == numQuantTables)
2159 numQuantTables = index + 1;
2160 for (i = 0; i < 64; ++i)
2161 quantTables[index][dctZigZag[i]] = str->getChar();
2167 GBool DCTStream::readHuffmanTables() {
2176 length = read16() - 2;
2177 while (length > 0) {
2178 index = str->getChar();
2180 if ((index & 0x0f) >= 4) {
2181 error(getPos(), "Bad DCT Huffman table");
2186 if (index >= numACHuffTables)
2187 numACHuffTables = index+1;
2188 tbl = &acHuffTables[index];
2190 if (index >= numDCHuffTables)
2191 numDCHuffTables = index+1;
2192 tbl = &dcHuffTables[index];
2196 for (i = 1; i <= 16; ++i) {
2198 tbl->firstSym[i] = sym;
2199 tbl->firstCode[i] = code;
2200 tbl->numCodes[i] = c;
2202 code = (code + c) << 1;
2205 for (i = 0; i < sym; ++i)
2206 tbl->sym[i] = str->getChar();
2212 GBool DCTStream::readRestartInterval() {
2217 error(getPos(), "Bad DCT restart interval");
2220 restartInterval = read16();
2224 GBool DCTStream::readAdobeMarker() {
2232 for (i = 0; i < 12; ++i) {
2233 if ((c = str->getChar()) == EOF)
2237 if (strncmp(buf, "Adobe", 5))
2239 colorXform = buf[11];
2243 error(getPos(), "Bad DCT Adobe APP14 marker");
2247 GBool DCTStream::readTrailer() {
2251 if (c != 0xd9) { // EOI
2252 error(getPos(), "Bad DCT trailer");
2258 int DCTStream::readMarker() {
2264 } while (c != 0xff);
2267 } while (c == 0xff);
2268 } while (c == 0x00);
2272 int DCTStream::read16() {
2275 if ((c1 = str->getChar()) == EOF)
2277 if ((c2 = str->getChar()) == EOF)
2279 return (c1 << 8) + c2;
2282 GString *DCTStream::getPSFilter(char *indent) {
2285 s = str->getPSFilter(indent);
2286 s->append(indent)->append("<< >> /DCTDecode filter\n");
2290 GBool DCTStream::isBinary(GBool last) {
2291 return str->isBinary(gTrue);
2294 //------------------------------------------------------------------------
2296 //------------------------------------------------------------------------
2298 int FlateStream::codeLenCodeMap[flateMaxCodeLenCodes] = {
2299 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
2302 FlateDecode FlateStream::lengthDecode[flateMaxLitCodes-257] = {
2334 FlateDecode FlateStream::distDecode[flateMaxDistCodes] = {
2367 FlateStream::FlateStream(Stream *str1, int predictor1, int columns1,
2368 int colors1, int bits1) {
2370 predictor = predictor1;
2371 if (predictor1 > 1) {
2378 FlateStream::~FlateStream() {
2382 void FlateStream::reset() {
2388 //~ need to look at window size?
2389 endOfBlock = eof = gTrue;
2390 cmf = str->getChar();
2391 flg = str->getChar();
2392 if (cmf == EOF || flg == EOF)
2394 if ((cmf & 0x0f) != 0x08) {
2395 error(getPos(), "Unknown compression method in flate stream");
2398 if ((((cmf << 8) + flg) % 31) != 0) {
2399 error(getPos(), "Bad FCHECK in flate stream");
2403 error(getPos(), "FDICT bit set in flate stream");
2412 compressedBlock = gFalse;
2417 int FlateStream::getChar() {
2420 while (remain == 0) {
2421 if (endOfBlock && eof)
2426 index = (index + 1) & flateMask;
2431 int FlateStream::lookChar() {
2434 while (remain == 0) {
2435 if (endOfBlock && eof)
2443 GString *FlateStream::getPSFilter(char *indent) {
2447 GBool FlateStream::isBinary(GBool last) {
2448 return str->isBinary(gTrue);
2451 void FlateStream::readSome() {
2462 if (compressedBlock) {
2463 if ((code1 = getHuffmanCodeWord(&litCodeTab)) == EOF)
2468 } else if (code1 == 256) {
2473 code2 = lengthDecode[code1].bits;
2474 if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
2476 len = lengthDecode[code1].first + code2;
2477 if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF)
2479 code2 = distDecode[code1].bits;
2480 if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
2482 dist = distDecode[code1].first + code2;
2484 j = (index - dist) & flateMask;
2485 for (k = 0; k < len; ++k) {
2487 i = (i + 1) & flateMask;
2488 j = (j + 1) & flateMask;
2494 len = (blockLen < flateWindow) ? blockLen : flateWindow;
2495 for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) {
2496 if ((c = str->getChar()) == EOF) {
2497 endOfBlock = eof = gTrue;
2511 error(getPos(), "Unexpected end of file in flate stream");
2512 endOfBlock = eof = gTrue;
2516 GBool FlateStream::startBlock() {
2521 // read block header
2522 blockHdr = getCodeWord(3);
2527 // uncompressed block
2528 if (blockHdr == 0) {
2529 compressedBlock = gFalse;
2530 if ((c = str->getChar()) == EOF)
2532 blockLen = c & 0xff;
2533 if ((c = str->getChar()) == EOF)
2535 blockLen |= (c & 0xff) << 8;
2536 if ((c = str->getChar()) == EOF)
2539 if ((c = str->getChar()) == EOF)
2541 check |= (c & 0xff) << 8;
2542 if (check != (~blockLen & 0xffff))
2543 error(getPos(), "Bad uncompressed block length in flate stream");
2547 // compressed block with fixed codes
2548 } else if (blockHdr == 1) {
2549 compressedBlock = gTrue;
2552 // compressed block with dynamic codes
2553 } else if (blockHdr == 2) {
2554 compressedBlock = gTrue;
2555 if (!readDynamicCodes())
2558 // unknown block type
2563 endOfBlock = gFalse;
2567 error(getPos(), "Bad block header in flate stream");
2568 endOfBlock = eof = gTrue;
2572 void FlateStream::loadFixedCodes() {
2575 // set up code arrays
2576 litCodeTab.codes = allCodes;
2577 distCodeTab.codes = allCodes + flateMaxLitCodes;
2579 // initialize literal code table
2580 for (i = 0; i <= 143; ++i)
2581 litCodeTab.codes[i].len = 8;
2582 for (i = 144; i <= 255; ++i)
2583 litCodeTab.codes[i].len = 9;
2584 for (i = 256; i <= 279; ++i)
2585 litCodeTab.codes[i].len = 7;
2586 for (i = 280; i <= 287; ++i)
2587 litCodeTab.codes[i].len = 8;
2588 compHuffmanCodes(&litCodeTab, flateMaxLitCodes);
2590 // initialize distance code table
2591 for (i = 0; i < 5; ++i)
2592 distCodeTab.start[i] = 0;
2593 distCodeTab.start[5] = 0;
2594 for (i = 6; i <= flateMaxHuffman+1; ++i)
2595 distCodeTab.start[6] = flateMaxDistCodes;
2596 for (i = 0; i < flateMaxDistCodes; ++i) {
2597 distCodeTab.codes[i].len = 5;
2598 distCodeTab.codes[i].code = i;
2599 distCodeTab.codes[i].val = i;
2603 GBool FlateStream::readDynamicCodes() {
2604 int numCodeLenCodes;
2607 FlateCode codeLenCodes[flateMaxCodeLenCodes];
2608 FlateHuffmanTab codeLenCodeTab;
2609 int len, repeat, code;
2613 if ((numLitCodes = getCodeWord(5)) == EOF)
2616 if ((numDistCodes = getCodeWord(5)) == EOF)
2619 if ((numCodeLenCodes = getCodeWord(4)) == EOF)
2621 numCodeLenCodes += 4;
2622 if (numLitCodes > flateMaxLitCodes ||
2623 numDistCodes > flateMaxDistCodes ||
2624 numCodeLenCodes > flateMaxCodeLenCodes)
2627 // read code length code table
2628 codeLenCodeTab.codes = codeLenCodes;
2629 for (i = 0; i < flateMaxCodeLenCodes; ++i)
2630 codeLenCodes[i].len = 0;
2631 for (i = 0; i < numCodeLenCodes; ++i) {
2632 if ((codeLenCodes[codeLenCodeMap[i]].len = getCodeWord(3)) == -1)
2635 compHuffmanCodes(&codeLenCodeTab, flateMaxCodeLenCodes);
2637 // set up code arrays
2638 litCodeTab.codes = allCodes;
2639 distCodeTab.codes = allCodes + numLitCodes;
2641 // read literal and distance code tables
2645 while (i < numLitCodes + numDistCodes) {
2646 if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF)
2649 if ((repeat = getCodeWord(2)) == EOF)
2651 for (repeat += 3; repeat > 0; --repeat)
2652 allCodes[i++].len = len;
2653 } else if (code == 17) {
2654 if ((repeat = getCodeWord(3)) == EOF)
2657 for (repeat += 3; repeat > 0; --repeat)
2658 allCodes[i++].len = 0;
2659 } else if (code == 18) {
2660 if ((repeat = getCodeWord(7)) == EOF)
2663 for (repeat += 11; repeat > 0; --repeat)
2664 allCodes[i++].len = 0;
2666 allCodes[i++].len = len = code;
2669 compHuffmanCodes(&litCodeTab, numLitCodes);
2670 compHuffmanCodes(&distCodeTab, numDistCodes);
2675 error(getPos(), "Bad dynamic code table in flate stream");
2679 // On entry, the <tab->codes> array contains the lengths of each code,
2680 // stored in code value order. This function computes the code words.
2681 // The result is sorted in order of (1) code length and (2) code word.
2682 // The length values are no longer valid. The <tab->start> array is
2683 // filled with the indexes of the first code of each length.
2684 void FlateStream::compHuffmanCodes(FlateHuffmanTab *tab, int n) {
2685 int numLengths[flateMaxHuffman+1];
2686 int nextCode[flateMaxHuffman+1];
2687 int nextIndex[flateMaxHuffman+2];
2691 // count number of codes for each code length
2692 for (i = 0; i <= flateMaxHuffman; ++i)
2694 for (i = 0; i < n; ++i)
2695 ++numLengths[tab->codes[i].len];
2697 // compute first index for each length
2698 tab->start[0] = nextIndex[0] = 0;
2699 for (i = 1; i <= flateMaxHuffman + 1; ++i)
2700 tab->start[i] = nextIndex[i] = tab->start[i-1] + numLengths[i-1];
2702 // compute first code for each length
2705 for (i = 1; i <= flateMaxHuffman; ++i) {
2706 code = (code + numLengths[i-1]) << 1;
2710 // compute the codes -- this permutes the codes array from value
2711 // order to length/code order
2712 for (i = 0; i < n; ++i) {
2713 j = nextIndex[tab->codes[i].len]++;
2714 if (tab->codes[i].len == 0)
2715 tab->codes[j].code = 0;
2717 tab->codes[j].code = nextCode[tab->codes[i].len]++;
2718 tab->codes[j].val = i;
2722 int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) {
2729 for (len = 1; len <= flateMaxHuffman; ++len) {
2731 // add a bit to the code
2732 if (codeSize == 0) {
2733 if ((c = str->getChar()) == EOF)
2738 code = (code << 1) | (codeBuf & 1);
2743 i = tab->start[len];
2744 j = tab->start[len + 1];
2745 if (i < j && code >= tab->codes[i].code && code <= tab->codes[j-1].code) {
2746 i += code - tab->codes[i].code;
2747 return tab->codes[i].val;
2752 error(getPos(), "Bad code (%04x) in flate stream", code);
2756 int FlateStream::getCodeWord(int bits) {
2759 while (codeSize < bits) {
2760 if ((c = str->getChar()) == EOF)
2762 codeBuf |= (c & 0xff) << codeSize;
2765 c = codeBuf & ((1 << bits) - 1);
2771 //------------------------------------------------------------------------
2773 //------------------------------------------------------------------------
2775 EOFStream::EOFStream(Stream *str1) {
2779 EOFStream::~EOFStream() {
2783 //------------------------------------------------------------------------
2784 // FixedLengthEncoder
2785 //------------------------------------------------------------------------
2787 FixedLengthEncoder::FixedLengthEncoder(Stream *str1, int length1) {
2793 FixedLengthEncoder::~FixedLengthEncoder() {
2794 if (str->isEncoder())
2798 void FixedLengthEncoder::reset() {
2803 int FixedLengthEncoder::getChar() {
2804 if (length >= 0 && count >= length)
2807 return str->getChar();
2810 int FixedLengthEncoder::lookChar() {
2811 if (length >= 0 && count >= length)
2813 return str->getChar();
2816 //------------------------------------------------------------------------
2818 //------------------------------------------------------------------------
2820 ASCII85Encoder::ASCII85Encoder(Stream *str1) {
2822 bufPtr = bufEnd = buf;
2827 ASCII85Encoder::~ASCII85Encoder() {
2828 if (str->isEncoder())
2832 void ASCII85Encoder::reset() {
2834 bufPtr = bufEnd = buf;
2839 GBool ASCII85Encoder::fillBuf() {
2848 for (n = 0; n < 4; ++n) {
2849 if ((c = str->getChar()) == EOF)
2853 bufPtr = bufEnd = buf;
2855 if (n == 4 && t == 0) {
2857 if (++lineLen == 65) {
2864 for (i = 4; i >= 0; --i) {
2865 buf1[i] = (char)(t % 85 + 0x21);
2868 for (i = 0; i <= n; ++i) {
2869 *bufEnd++ = buf1[i];
2870 if (++lineLen == 65) {
2882 return bufPtr < bufEnd;
2885 //------------------------------------------------------------------------
2887 //------------------------------------------------------------------------
2889 RunLengthEncoder::RunLengthEncoder(Stream *str1) {
2891 bufPtr = bufEnd = nextEnd = buf;
2895 RunLengthEncoder::~RunLengthEncoder() {
2896 if (str->isEncoder())
2900 void RunLengthEncoder::reset() {
2902 bufPtr = bufEnd = nextEnd = buf;
2907 // When fillBuf finishes, buf[] looks like this:
2908 // +-----+--------------+-----------------+--
2909 // + tag | ... data ... | next 0, 1, or 2 |
2910 // +-----+--------------+-----------------+--
2912 // bufPtr bufEnd nextEnd
2914 GBool RunLengthEncoder::fillBuf() {
2923 if (nextEnd < bufEnd + 1) {
2924 if ((c1 = str->getChar()) == EOF) {
2929 c1 = bufEnd[0] & 0xff;
2931 if (nextEnd < bufEnd + 2) {
2932 if ((c2 = str->getChar()) == EOF) {
2941 c2 = bufEnd[1] & 0xff;
2947 while (n < 128 && (c = str->getChar()) == c1)
2949 buf[0] = (char)(257 - n);
2954 } else if (n < 128) {
2961 // get up to 128 chars
2967 if ((c = str->getChar()) == EOF) {
2973 if (buf[n] == buf[n-1])
2976 if (buf[n] == buf[n-1]) {
2977 buf[0] = (char)(n-2-1);
2979 nextEnd = &buf[n+1];
2981 buf[0] = (char)(n-1);
2982 bufEnd = nextEnd = &buf[n+1];