1 //========================================================================
5 // Copyright 1996-2003 Glyph & Cog, LLC
7 //========================================================================
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
32 #include "JBIG2Stream.h"
33 #include "Stream-CCITT.h"
36 static GBool setDJSYSFLAGS = gFalse;
47 //------------------------------------------------------------------------
48 // Stream (base class)
49 //------------------------------------------------------------------------
58 void Stream::close() {
61 int Stream::getRawChar() {
62 error(-1, "Internal: called getRawChar() on non-predictor stream");
66 char *Stream::getLine(char *buf, int size) {
70 if (lookChar() == EOF)
72 for (i = 0; i < size - 1; ++i) {
74 if (c == EOF || c == '\n')
77 if ((c = lookChar()) == '\n')
87 GString *Stream::getPSFilter(int psLevel, char *indent) {
91 Stream *Stream::addFilters(Object *dict) {
93 Object params, params2;
98 dict->dictLookup("Filter", &obj);
101 dict->dictLookup("F", &obj);
103 dict->dictLookup("DecodeParms", ¶ms);
104 if (params.isNull()) {
106 dict->dictLookup("DP", ¶ms);
109 str = makeFilter(obj.getName(), str, ¶ms);
110 } else if (obj.isArray()) {
111 for (i = 0; i < obj.arrayGetLength(); ++i) {
112 obj.arrayGet(i, &obj2);
113 if (params.isArray())
114 params.arrayGet(i, ¶ms2);
118 str = makeFilter(obj2.getName(), str, ¶ms2);
120 error(getPos(), "Bad filter name");
121 str = new EOFStream(str);
126 } else if (!obj.isNull()) {
127 error(getPos(), "Bad 'Filter' attribute in stream");
135 Stream *Stream::makeFilter(char *name, Stream *str, Object *params) {
136 int pred; // parameters
141 GBool endOfLine, byteAlign, endOfBlock, black;
145 if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) {
146 str = new ASCIIHexStream(str);
147 } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) {
148 str = new ASCII85Stream(str);
149 } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) {
155 if (params->isDict()) {
156 params->dictLookup("Predictor", &obj);
160 params->dictLookup("Columns", &obj);
162 columns = obj.getInt();
164 params->dictLookup("Colors", &obj);
166 colors = obj.getInt();
168 params->dictLookup("BitsPerComponent", &obj);
172 params->dictLookup("EarlyChange", &obj);
174 early = obj.getInt();
177 str = new LZWStream(str, pred, columns, colors, bits, early);
178 } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) {
179 str = new RunLengthStream(str);
180 } else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) {
188 if (params->isDict()) {
189 params->dictLookup("K", &obj);
191 encoding = obj.getInt();
194 params->dictLookup("EndOfLine", &obj);
196 endOfLine = obj.getBool();
199 params->dictLookup("EncodedByteAlign", &obj);
201 byteAlign = obj.getBool();
204 params->dictLookup("Columns", &obj);
206 columns = obj.getInt();
209 params->dictLookup("Rows", &obj);
214 params->dictLookup("EndOfBlock", &obj);
216 endOfBlock = obj.getBool();
219 params->dictLookup("BlackIs1", &obj);
221 black = obj.getBool();
225 str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign,
226 columns, rows, endOfBlock, black);
227 } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) {
228 str = new DCTStream(str);
229 } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) {
234 if (params->isDict()) {
235 params->dictLookup("Predictor", &obj);
239 params->dictLookup("Columns", &obj);
241 columns = obj.getInt();
243 params->dictLookup("Colors", &obj);
245 colors = obj.getInt();
247 params->dictLookup("BitsPerComponent", &obj);
252 str = new FlateStream(str, pred, columns, colors, bits);
253 } else if (!strcmp(name, "JBIG2Decode")) {
254 if (params->isDict()) {
255 params->dictLookup("JBIG2Globals", &globals);
257 str = new JBIG2Stream(str, &globals);
260 error(getPos(), "Unknown filter '%s'", name);
261 str = new EOFStream(str);
266 //------------------------------------------------------------------------
268 //------------------------------------------------------------------------
270 BaseStream::BaseStream(Object *dictA) {
272 #ifndef NO_DECRYPTION
277 BaseStream::~BaseStream() {
279 #ifndef NO_DECRYPTION
285 #ifndef NO_DECRYPTION
286 void BaseStream::doDecryption(Guchar *fileKey, int keyLength,
287 int objNum, int objGen) {
288 decrypt = new Decrypt(fileKey, keyLength, objNum, objGen);
292 //------------------------------------------------------------------------
294 //------------------------------------------------------------------------
296 FilterStream::FilterStream(Stream *strA) {
300 FilterStream::~FilterStream() {
303 void FilterStream::close() {
307 void FilterStream::setPos(Guint pos, int dir) {
308 error(-1, "Internal: called setPos() on FilterStream");
311 //------------------------------------------------------------------------
313 //------------------------------------------------------------------------
315 ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) {
323 nVals = width * nComps;
325 imgLineSize = (nVals + 7) & ~7;
329 imgLine = (Guchar *)gmalloc(imgLineSize * sizeof(Guchar));
333 ImageStream::~ImageStream() {
337 void ImageStream::reset() {
341 GBool ImageStream::getPixel(Guchar *pix) {
344 if (imgIdx >= nVals) {
348 for (i = 0; i < nComps; ++i) {
349 pix[i] = imgLine[imgIdx++];
354 Guchar *ImageStream::getLine() {
361 for (i = 0; i < nVals; i += 8) {
363 imgLine[i+0] = (Guchar)((c >> 7) & 1);
364 imgLine[i+1] = (Guchar)((c >> 6) & 1);
365 imgLine[i+2] = (Guchar)((c >> 5) & 1);
366 imgLine[i+3] = (Guchar)((c >> 4) & 1);
367 imgLine[i+4] = (Guchar)((c >> 3) & 1);
368 imgLine[i+5] = (Guchar)((c >> 2) & 1);
369 imgLine[i+6] = (Guchar)((c >> 1) & 1);
370 imgLine[i+7] = (Guchar)(c & 1);
372 } else if (nBits == 8) {
373 for (i = 0; i < nVals; ++i) {
374 imgLine[i] = str->getChar();
377 bitMask = (1 << nBits) - 1;
380 for (i = 0; i < nVals; ++i) {
382 buf = (buf << 8) | (str->getChar() & 0xff);
385 imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask);
392 void ImageStream::skipLine() {
395 n = (nVals * nBits + 7) >> 3;
396 for (i = 0; i < n; ++i) {
401 //------------------------------------------------------------------------
403 //------------------------------------------------------------------------
405 StreamPredictor::StreamPredictor(Stream *strA, int predictorA,
406 int widthA, int nCompsA, int nBitsA) {
408 predictor = predictorA;
413 nVals = width * nComps;
414 pixBytes = (nComps * nBits + 7) >> 3;
415 rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes;
416 predLine = (Guchar *)gmalloc(rowBytes);
417 memset(predLine, 0, rowBytes);
421 StreamPredictor::~StreamPredictor() {
425 int StreamPredictor::lookChar() {
426 if (predIdx >= rowBytes) {
427 if (!getNextLine()) {
431 return predLine[predIdx];
434 int StreamPredictor::getChar() {
435 if (predIdx >= rowBytes) {
436 if (!getNextLine()) {
440 return predLine[predIdx++];
443 GBool StreamPredictor::getNextLine() {
446 int left, up, upLeft, p, pa, pb, pc;
448 Gulong inBuf, outBuf, bitMask;
452 // get PNG optimum predictor number
453 if (predictor == 15) {
454 if ((curPred = str->getRawChar()) == EOF) {
462 // read the raw line, apply PNG (byte) predictor
463 upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0;
464 for (i = pixBytes; i < rowBytes; ++i) {
465 upLeftBuf[3] = upLeftBuf[2];
466 upLeftBuf[2] = upLeftBuf[1];
467 upLeftBuf[1] = upLeftBuf[0];
468 upLeftBuf[0] = predLine[i];
469 if ((c = str->getRawChar()) == EOF) {
474 predLine[i] = predLine[i - pixBytes] + (Guchar)c;
477 predLine[i] = predLine[i] + (Guchar)c;
479 case 13: // PNG average
480 predLine[i] = ((predLine[i - pixBytes] + predLine[i]) >> 1) +
483 case 14: // PNG Paeth
484 left = predLine[i - pixBytes];
486 upLeft = upLeftBuf[pixBytes];
487 p = left + up - upLeft;
488 if ((pa = p - left) < 0)
490 if ((pb = p - up) < 0)
492 if ((pc = p - upLeft) < 0)
494 if (pa <= pb && pa <= pc)
495 predLine[i] = left + (Guchar)c;
497 predLine[i] = up + (Guchar)c;
499 predLine[i] = upLeft + (Guchar)c;
502 default: // no predictor or TIFF predictor
503 predLine[i] = (Guchar)c;
508 // apply TIFF (component) predictor
509 if (predictor == 2) {
511 inBuf = predLine[pixBytes - 1];
512 for (i = pixBytes; i < rowBytes; i += 8) {
513 // 1-bit add is just xor
514 inBuf = (inBuf << 8) | predLine[i];
515 predLine[i] ^= inBuf >> nComps;
517 } else if (nBits == 8) {
518 for (i = pixBytes; i < rowBytes; ++i) {
519 predLine[i] += predLine[i - nComps];
522 upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0;
523 bitMask = (1 << nBits) - 1;
525 inBits = outBits = 0;
527 for (i = 0; i < nVals; ++i) {
528 if (inBits < nBits) {
529 inBuf = (inBuf << 8) | (predLine[j++] & 0xff);
532 upLeftBuf[3] = upLeftBuf[2];
533 upLeftBuf[2] = upLeftBuf[1];
534 upLeftBuf[1] = upLeftBuf[0];
535 upLeftBuf[0] = (upLeftBuf[nComps] +
536 (inBuf >> (inBits - nBits))) & bitMask;
537 outBuf = (outBuf << nBits) | upLeftBuf[0];
541 predLine[k++] = (Guchar)(outBuf >> (outBits - 8));
545 predLine[k++] = (Guchar)(outBuf << (8 - outBits));
550 // reset to start of line
556 //------------------------------------------------------------------------
558 //------------------------------------------------------------------------
560 FileStream::FileStream(FILE *fA, Guint startA, GBool limitedA,
561 Guint lengthA, Object *dictA):
567 bufPtr = bufEnd = buf;
573 FileStream::~FileStream() {
577 Stream *FileStream::makeSubStream(Guint startA, GBool limitedA,
578 Guint lengthA, Object *dictA) {
579 return new FileStream(f, startA, limitedA, lengthA, dictA);
582 void FileStream::reset() {
584 savePos = (Guint)ftello(f);
585 fseeko(f, start, SEEK_SET);
587 savePos = (Guint)ftell64(f);
588 fseek64(f, start, SEEK_SET);
590 savePos = (Guint)ftell(f);
591 fseek(f, start, SEEK_SET);
594 bufPtr = bufEnd = buf;
596 #ifndef NO_DECRYPTION
602 void FileStream::close() {
605 fseeko(f, savePos, SEEK_SET);
607 fseek64(f, savePos, SEEK_SET);
609 fseek(f, savePos, SEEK_SET);
615 GBool FileStream::fillBuf() {
617 #ifndef NO_DECRYPTION
621 bufPos += bufEnd - buf;
622 bufPtr = bufEnd = buf;
623 if (limited && bufPos >= start + length) {
626 if (limited && bufPos + fileStreamBufSize > start + length) {
627 n = start + length - bufPos;
629 n = fileStreamBufSize;
631 n = fread(buf, 1, n, f);
633 if (bufPtr >= bufEnd) {
636 #ifndef NO_DECRYPTION
638 for (p = buf; p < bufEnd; ++p) {
639 *p = (char)decrypt->decryptByte((Guchar)*p);
646 void FileStream::setPos(Guint pos, int dir) {
651 fseeko(f, pos, SEEK_SET);
653 fseek64(f, pos, SEEK_SET);
655 fseek(f, pos, SEEK_SET);
660 fseeko(f, 0, SEEK_END);
661 size = (Guint)ftello(f);
663 fseek64(f, 0, SEEK_END);
664 size = (Guint)ftell64(f);
666 fseek(f, 0, SEEK_END);
667 size = (Guint)ftell(f);
672 //~ work around a bug in cygwin's implementation of fseek
676 fseeko(f, -(int)pos, SEEK_END);
677 bufPos = (Guint)ftello(f);
679 fseek64(f, -(int)pos, SEEK_END);
680 bufPos = (Guint)ftell64(f);
682 fseek(f, -(int)pos, SEEK_END);
683 bufPos = (Guint)ftell(f);
686 bufPtr = bufEnd = buf;
689 void FileStream::moveStart(int delta) {
691 bufPtr = bufEnd = buf;
695 //------------------------------------------------------------------------
697 //------------------------------------------------------------------------
699 MemStream::MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA):
704 bufEnd = buf + start + length;
705 bufPtr = buf + start;
709 MemStream::~MemStream() {
715 Stream *MemStream::makeSubStream(Guint startA, GBool limited,
716 Guint lengthA, Object *dictA) {
720 if (!limited || startA + lengthA > start + length) {
721 newLength = start + length - startA;
725 subStr = new MemStream(buf, startA, newLength, dictA);
729 void MemStream::reset() {
730 bufPtr = buf + start;
731 #ifndef NO_DECRYPTION
738 void MemStream::close() {
741 void MemStream::setPos(Guint pos, int dir) {
747 i = start + length - pos;
751 } else if (i > start + length) {
757 void MemStream::moveStart(int delta) {
759 bufPtr = buf + start;
762 #ifndef NO_DECRYPTION
763 void MemStream::doDecryption(Guchar *fileKey, int keyLength,
764 int objNum, int objGen) {
768 this->BaseStream::doDecryption(fileKey, keyLength, objNum, objGen);
770 newBuf = (char *)gmalloc(length);
771 for (p = buf + start, q = newBuf; p < bufEnd; ++p, ++q) {
772 *q = (char)decrypt->decryptByte((Guchar)*p);
774 bufEnd = newBuf + length;
775 bufPtr = newBuf + (bufPtr - (buf + start));
783 //------------------------------------------------------------------------
785 //------------------------------------------------------------------------
787 EmbedStream::EmbedStream(Stream *strA, Object *dictA):
792 EmbedStream::~EmbedStream() {
795 Stream *EmbedStream::makeSubStream(Guint start, GBool limited,
796 Guint length, Object *dictA) {
797 error(-1, "Internal: called makeSubStream() on EmbedStream");
801 void EmbedStream::setPos(Guint pos, int dir) {
802 error(-1, "Internal: called setPos() on EmbedStream");
805 Guint EmbedStream::getStart() {
806 error(-1, "Internal: called getStart() on EmbedStream");
810 void EmbedStream::moveStart(int delta) {
811 error(-1, "Internal: called moveStart() on EmbedStream");
814 //------------------------------------------------------------------------
816 //------------------------------------------------------------------------
818 ASCIIHexStream::ASCIIHexStream(Stream *strA):
824 ASCIIHexStream::~ASCIIHexStream() {
828 void ASCIIHexStream::reset() {
834 int ASCIIHexStream::lookChar() {
845 } while (isspace(c1));
853 } while (isspace(c2));
858 if (c1 >= '0' && c1 <= '9') {
860 } else if (c1 >= 'A' && c1 <= 'F') {
861 x = (c1 - 'A' + 10) << 4;
862 } else if (c1 >= 'a' && c1 <= 'f') {
863 x = (c1 - 'a' + 10) << 4;
864 } else if (c1 == EOF) {
868 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c1);
871 if (c2 >= '0' && c2 <= '9') {
873 } else if (c2 >= 'A' && c2 <= 'F') {
875 } else if (c2 >= 'a' && c2 <= 'f') {
877 } else if (c2 == EOF) {
881 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c2);
887 GString *ASCIIHexStream::getPSFilter(int psLevel, char *indent) {
893 if (!(s = str->getPSFilter(psLevel, indent))) {
896 s->append(indent)->append("/ASCIIHexDecode filter\n");
900 GBool ASCIIHexStream::isBinary(GBool last) {
901 return str->isBinary(gFalse);
904 //------------------------------------------------------------------------
906 //------------------------------------------------------------------------
908 ASCII85Stream::ASCII85Stream(Stream *strA):
914 ASCII85Stream::~ASCII85Stream() {
918 void ASCII85Stream::reset() {
924 int ASCII85Stream::lookChar() {
933 c[0] = str->getChar();
934 } while (c[0] == '\n' || c[0] == '\r');
935 if (c[0] == '~' || c[0] == EOF) {
939 } else if (c[0] == 'z') {
940 b[0] = b[1] = b[2] = b[3] = 0;
943 for (k = 1; k < 5; ++k) {
945 c[k] = str->getChar();
946 } while (c[k] == '\n' || c[k] == '\r');
947 if (c[k] == '~' || c[k] == EOF)
951 if (k < 5 && (c[k] == '~' || c[k] == EOF)) {
952 for (++k; k < 5; ++k)
957 for (k = 0; k < 5; ++k)
958 t = t * 85 + (c[k] - 0x21);
959 for (k = 3; k >= 0; --k) {
960 b[k] = (int)(t & 0xff);
968 GString *ASCII85Stream::getPSFilter(int psLevel, char *indent) {
974 if (!(s = str->getPSFilter(psLevel, indent))) {
977 s->append(indent)->append("/ASCII85Decode filter\n");
981 GBool ASCII85Stream::isBinary(GBool last) {
982 return str->isBinary(gFalse);
985 //------------------------------------------------------------------------
987 //------------------------------------------------------------------------
989 LZWStream::LZWStream(Stream *strA, int predictor, int columns, int colors,
990 int bits, int earlyA):
992 if (predictor != 1) {
993 pred = new StreamPredictor(this, predictor, columns, colors, bits);
1003 LZWStream::~LZWStream() {
1010 int LZWStream::getChar() {
1012 return pred->getChar();
1017 if (seqIndex >= seqLength) {
1018 if (!processNextCode()) {
1022 return seqBuf[seqIndex++];
1025 int LZWStream::lookChar() {
1027 return pred->lookChar();
1032 if (seqIndex >= seqLength) {
1033 if (!processNextCode()) {
1037 return seqBuf[seqIndex];
1040 int LZWStream::getRawChar() {
1044 if (seqIndex >= seqLength) {
1045 if (!processNextCode()) {
1049 return seqBuf[seqIndex++];
1052 void LZWStream::reset() {
1059 GBool LZWStream::processNextCode() {
1069 // check for eod and clear-table codes
1072 if (code == EOF || code == 257) {
1080 if (nextCode >= 4097) {
1081 error(getPos(), "Bad LZW stream - expected clear-table code");
1085 // process the next code
1086 nextLength = seqLength + 1;
1090 } else if (code < nextCode) {
1091 seqLength = table[code].length;
1092 for (i = seqLength - 1, j = code; i > 0; --i) {
1093 seqBuf[i] = table[j].tail;
1097 } else if (code == nextCode) {
1098 seqBuf[seqLength] = newChar;
1101 error(getPos(), "Bad LZW stream - unexpected code");
1105 newChar = seqBuf[0];
1109 table[nextCode].length = nextLength;
1110 table[nextCode].head = prevCode;
1111 table[nextCode].tail = newChar;
1113 if (nextCode + early == 512)
1115 else if (nextCode + early == 1024)
1117 else if (nextCode + early == 2048)
1128 void LZWStream::clearTable() {
1131 seqIndex = seqLength = 0;
1135 int LZWStream::getCode() {
1139 while (inputBits < nextBits) {
1140 if ((c = str->getChar()) == EOF)
1142 inputBuf = (inputBuf << 8) | (c & 0xff);
1145 code = (inputBuf >> (inputBits - nextBits)) & ((1 << nextBits) - 1);
1146 inputBits -= nextBits;
1150 GString *LZWStream::getPSFilter(int psLevel, char *indent) {
1153 if (psLevel < 2 || pred) {
1156 if (!(s = str->getPSFilter(psLevel, indent))) {
1159 s->append(indent)->append("/LZWDecode filter\n");
1163 GBool LZWStream::isBinary(GBool last) {
1164 return str->isBinary(gTrue);
1167 //------------------------------------------------------------------------
1169 //------------------------------------------------------------------------
1171 RunLengthStream::RunLengthStream(Stream *strA):
1172 FilterStream(strA) {
1173 bufPtr = bufEnd = buf;
1177 RunLengthStream::~RunLengthStream() {
1181 void RunLengthStream::reset() {
1183 bufPtr = bufEnd = buf;
1187 GString *RunLengthStream::getPSFilter(int psLevel, char *indent) {
1193 if (!(s = str->getPSFilter(psLevel, indent))) {
1196 s->append(indent)->append("/RunLengthDecode filter\n");
1200 GBool RunLengthStream::isBinary(GBool last) {
1201 return str->isBinary(gTrue);
1204 GBool RunLengthStream::fillBuf() {
1211 if (c == 0x80 || c == EOF) {
1217 for (i = 0; i < n; ++i)
1218 buf[i] = (char)str->getChar();
1222 for (i = 0; i < n; ++i)
1230 //------------------------------------------------------------------------
1232 //------------------------------------------------------------------------
1234 CCITTFaxStream::CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA,
1235 GBool byteAlignA, int columnsA, int rowsA,
1236 GBool endOfBlockA, GBool blackA):
1237 FilterStream(strA) {
1238 encoding = encodingA;
1239 endOfLine = endOfLineA;
1240 byteAlign = byteAlignA;
1243 endOfBlock = endOfBlockA;
1245 refLine = (short *)gmalloc((columns + 3) * sizeof(short));
1246 codingLine = (short *)gmalloc((columns + 2) * sizeof(short));
1250 nextLine2D = encoding < 0;
1253 codingLine[1] = refLine[2] = columns;
1259 CCITTFaxStream::~CCITTFaxStream() {
1265 void CCITTFaxStream::reset() {
1271 nextLine2D = encoding < 0;
1274 codingLine[1] = refLine[2] = columns;
1278 // get initial end-of-line marker and 2D encoding tag
1280 if (lookBits(12) == 0x001) {
1284 for (n = 0; n < 11 && lookBits(n) == 0; ++n) ;
1285 if (n == 11 && lookBits(12) == 0x001) {
1290 nextLine2D = !lookBits(1);
1295 int CCITTFaxStream::lookChar() {
1296 short code1, code2, code3;
1305 // if at eof just return EOF
1306 if (eof && codingLine[a0] >= columns) {
1310 // read the next row
1314 if (codingLine[a0] >= columns) {
1318 for (i = 0; codingLine[i] < columns; ++i)
1319 refLine[i] = codingLine[i];
1320 refLine[i] = refLine[i + 1] = columns;
1322 a0New = codingLine[a0 = 0] = 0;
1324 code1 = getTwoDimCode();
1327 if (refLine[b1] < columns) {
1328 a0New = refLine[b1 + 1];
1333 if ((a0 & 1) == 0) {
1336 code1 += code3 = getWhiteCode();
1337 } while (code3 >= 64);
1339 code2 += code3 = getBlackCode();
1340 } while (code3 >= 64);
1344 code1 += code3 = getBlackCode();
1345 } while (code3 >= 64);
1347 code2 += code3 = getWhiteCode();
1348 } while (code3 >= 64);
1350 if (code1 > 0 || code2 > 0) {
1351 codingLine[a0 + 1] = a0New + code1;
1353 a0New = codingLine[a0 + 1] = codingLine[a0] + code2;
1355 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1360 a0New = codingLine[++a0] = refLine[b1];
1361 if (refLine[b1] < columns) {
1363 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1368 a0New = codingLine[++a0] = refLine[b1] + 1;
1369 if (refLine[b1] < columns) {
1371 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1376 a0New = codingLine[++a0] = refLine[b1] - 1;
1378 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1382 a0New = codingLine[++a0] = refLine[b1] + 2;
1383 if (refLine[b1] < columns) {
1385 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1390 a0New = codingLine[++a0] = refLine[b1] - 2;
1392 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1396 a0New = codingLine[++a0] = refLine[b1] + 3;
1397 if (refLine[b1] < columns) {
1399 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1404 a0New = codingLine[++a0] = refLine[b1] - 3;
1406 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
1411 codingLine[a0 = 0] = columns;
1414 error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1);
1423 } while (codingLine[a0] < columns);
1427 codingLine[a0 = 0] = 0;
1431 code1 += code3 = getWhiteCode();
1432 } while (code3 >= 64);
1433 codingLine[a0+1] = codingLine[a0] + code1;
1435 if (codingLine[a0] >= columns)
1439 code2 += code3 = getBlackCode();
1440 } while (code3 >= 64);
1441 codingLine[a0+1] = codingLine[a0] + code2;
1443 if (codingLine[a0] >= columns)
1448 if (codingLine[a0] != columns) {
1449 error(getPos(), "CCITTFax row is wrong length (%d)", codingLine[a0]);
1455 // byte-align the row
1460 // check for end-of-line marker, skipping over any extra zero bits
1462 if (!endOfBlock && row == rows - 1) {
1465 code1 = lookBits(12);
1466 while (code1 == 0) {
1468 code1 = lookBits(12);
1470 if (code1 == 0x001) {
1473 } else if (code1 == EOF) {
1478 // get 2D encoding tag
1479 if (!eof && encoding > 0) {
1480 nextLine2D = !lookBits(1);
1484 // check for end-of-block marker
1485 if (endOfBlock && gotEOL) {
1486 code1 = lookBits(12);
1487 if (code1 == 0x001) {
1493 if (encoding >= 0) {
1494 for (i = 0; i < 4; ++i) {
1495 code1 = lookBits(12);
1496 if (code1 != 0x001) {
1497 error(getPos(), "Bad RTC code in CCITTFax stream");
1511 // This looks for an end-of-line marker after an error, however
1512 // some (most?) CCITT streams in PDF files don't use end-of-line
1513 // markers, and the just-plow-on technique works better in those
1522 code1 = lookBits(13);
1523 } while ((code1 >> 1) != 0x001);
1525 codingLine[++a0] = columns;
1528 nextLine2D = !(code1 & 1);
1534 outputBits = codingLine[1] - codingLine[0];
1535 if (outputBits == 0) {
1537 outputBits = codingLine[2] - codingLine[1];
1544 if (outputBits >= 8) {
1545 ret = ((a0 & 1) == 0) ? 0xff : 0x00;
1546 if ((outputBits -= 8) == 0) {
1548 if (codingLine[a0] < columns) {
1549 outputBits = codingLine[a0 + 1] - codingLine[a0];
1556 if (outputBits > bits) {
1559 if ((a0 & 1) == 0) {
1560 ret |= 0xff >> (8 - i);
1566 if ((a0 & 1) == 0) {
1567 ret |= (0xff >> (8 - i)) << bits;
1571 if (codingLine[a0] < columns) {
1572 outputBits = codingLine[a0 + 1] - codingLine[a0];
1575 } while (bits > 0 && codingLine[a0] < columns);
1577 buf = black ? (ret ^ 0xff) : ret;
1581 short CCITTFaxStream::getTwoDimCode() {
1586 code = 0; // make gcc happy
1589 p = &twoDimTab1[code];
1595 for (n = 1; n <= 7; ++n) {
1600 p = &twoDimTab1[code];
1607 error(getPos(), "Bad two dim code (%04x) in CCITTFax stream", code);
1611 short CCITTFaxStream::getWhiteCode() {
1616 code = 0; // make gcc happy
1618 code = lookBits(12);
1619 if ((code >> 5) == 0) {
1620 p = &whiteTab1[code];
1622 p = &whiteTab2[code >> 3];
1629 for (n = 1; n <= 9; ++n) {
1634 p = &whiteTab2[code];
1640 for (n = 11; n <= 12; ++n) {
1645 p = &whiteTab1[code];
1652 error(getPos(), "Bad white code (%04x) in CCITTFax stream", code);
1653 // eat a bit and return a positive number so that the caller doesn't
1654 // go into an infinite loop
1659 short CCITTFaxStream::getBlackCode() {
1664 code = 0; // make gcc happy
1666 code = lookBits(13);
1667 if ((code >> 7) == 0) {
1668 p = &blackTab1[code];
1669 } else if ((code >> 9) == 0) {
1670 p = &blackTab2[(code >> 1) - 64];
1672 p = &blackTab3[code >> 7];
1679 for (n = 2; n <= 6; ++n) {
1684 p = &blackTab3[code];
1690 for (n = 7; n <= 12; ++n) {
1696 p = &blackTab2[code - 64];
1703 for (n = 10; n <= 13; ++n) {
1708 p = &blackTab1[code];
1715 error(getPos(), "Bad black code (%04x) in CCITTFax stream", code);
1716 // eat a bit and return a positive number so that the caller doesn't
1717 // go into an infinite loop
1722 short CCITTFaxStream::lookBits(int n) {
1725 while (inputBits < n) {
1726 if ((c = str->getChar()) == EOF) {
1727 if (inputBits == 0) {
1730 // near the end of the stream, the caller may ask for more bits
1731 // than are available, but there may still be a valid code in
1732 // however many bits are available -- we need to return correct
1733 // data in this case
1734 return (inputBuf << (n - inputBits)) & (0xffff >> (16 - n));
1736 inputBuf = (inputBuf << 8) + c;
1739 return (inputBuf >> (inputBits - n)) & (0xffff >> (16 - n));
1742 GString *CCITTFaxStream::getPSFilter(int psLevel, char *indent) {
1749 if (!(s = str->getPSFilter(psLevel, indent))) {
1752 s->append(indent)->append("<< ");
1753 if (encoding != 0) {
1754 sprintf(s1, "/K %d ", encoding);
1758 s->append("/EndOfLine true ");
1761 s->append("/EncodedByteAlign true ");
1763 sprintf(s1, "/Columns %d ", columns);
1766 sprintf(s1, "/Rows %d ", rows);
1770 s->append("/EndOfBlock false ");
1773 s->append("/BlackIs1 true ");
1775 s->append(">> /CCITTFaxDecode filter\n");
1779 GBool CCITTFaxStream::isBinary(GBool last) {
1780 return str->isBinary(gTrue);
1783 //------------------------------------------------------------------------
1785 //------------------------------------------------------------------------
1787 // IDCT constants (20.12 fixed point format)
1788 #define dctCos1 4017 // cos(pi/16)
1789 #define dctSin1 799 // sin(pi/16)
1790 #define dctCos3 3406 // cos(3*pi/16)
1791 #define dctSin3 2276 // sin(3*pi/16)
1792 #define dctCos6 1567 // cos(6*pi/16)
1793 #define dctSin6 3784 // sin(6*pi/16)
1794 #define dctSqrt2 5793 // sqrt(2)
1795 #define dctSqrt1d2 2896 // sqrt(2) / 2
1797 // color conversion parameters (16.16 fixed point format)
1798 #define dctCrToR 91881 // 1.4020
1799 #define dctCbToG -22553 // -0.3441363
1800 #define dctCrToG -46802 // -0.71413636
1801 #define dctCbToB 116130 // 1.772
1803 // clip [-256,511] --> [0,255]
1804 #define dctClipOffset 256
1805 static Guchar dctClip[768];
1806 static int dctClipInit = 0;
1808 // zig zag decode map
1809 static int dctZigZag[64] = {
1815 5, 12, 19, 26, 33, 40,
1816 48, 41, 34, 27, 20, 13, 6,
1817 7, 14, 21, 28, 35, 42, 49, 56,
1818 57, 50, 43, 36, 29, 22, 15,
1819 23, 30, 37, 44, 51, 58,
1827 DCTStream::DCTStream(Stream *strA):
1828 FilterStream(strA) {
1831 progressive = interleaved = gFalse;
1833 mcuWidth = mcuHeight = 0;
1837 for (i = 0; i < 4; ++i) {
1838 for (j = 0; j < 32; ++j) {
1839 rowBuf[i][j] = NULL;
1845 for (i = -256; i < 0; ++i)
1846 dctClip[dctClipOffset + i] = 0;
1847 for (i = 0; i < 256; ++i)
1848 dctClip[dctClipOffset + i] = i;
1849 for (i = 256; i < 512; ++i)
1850 dctClip[dctClipOffset + i] = 255;
1855 DCTStream::~DCTStream() {
1859 if (progressive || !interleaved) {
1860 for (i = 0; i < numComps; ++i) {
1864 for (i = 0; i < numComps; ++i) {
1865 for (j = 0; j < mcuHeight; ++j) {
1866 gfree(rowBuf[i][j]);
1872 void DCTStream::reset() {
1873 int minHSample, minVSample;
1878 progressive = interleaved = gFalse;
1882 numDCHuffTables = 0;
1883 numACHuffTables = 0;
1885 gotJFIFMarker = gFalse;
1886 gotAdobeMarker = gFalse;
1887 restartInterval = 0;
1889 if (!readHeader()) {
1895 mcuWidth = minHSample = compInfo[0].hSample;
1896 mcuHeight = minVSample = compInfo[0].vSample;
1897 for (i = 1; i < numComps; ++i) {
1898 if (compInfo[i].hSample < minHSample)
1899 minHSample = compInfo[i].hSample;
1900 if (compInfo[i].vSample < minVSample)
1901 minVSample = compInfo[i].vSample;
1902 if (compInfo[i].hSample > mcuWidth)
1903 mcuWidth = compInfo[i].hSample;
1904 if (compInfo[i].vSample > mcuHeight)
1905 mcuHeight = compInfo[i].vSample;
1907 for (i = 0; i < numComps; ++i) {
1908 compInfo[i].hSample /= minHSample;
1909 compInfo[i].vSample /= minVSample;
1911 mcuWidth = (mcuWidth / minHSample) * 8;
1912 mcuHeight = (mcuHeight / minVSample) * 8;
1914 // figure out color transform
1915 if (!gotAdobeMarker && numComps == 3) {
1916 if (gotJFIFMarker) {
1918 } else if (compInfo[0].id == 82 && compInfo[1].id == 71 &&
1919 compInfo[2].id == 66) { // ASCII "RGB"
1926 if (progressive || !interleaved) {
1928 // allocate a buffer for the whole image
1929 bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
1930 bufHeight = ((height + mcuHeight - 1) / mcuHeight) * mcuHeight;
1931 for (i = 0; i < numComps; ++i) {
1932 frameBuf[i] = (int *)gmalloc(bufWidth * bufHeight * sizeof(int));
1933 memset(frameBuf[i], 0, bufWidth * bufHeight * sizeof(int));
1936 // read the image data
1938 restartMarker = 0xd0;
1941 } while (readHeader());
1946 // initialize counters
1953 // allocate a buffer for one row of MCUs
1954 bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
1955 for (i = 0; i < numComps; ++i) {
1956 for (j = 0; j < mcuHeight; ++j) {
1957 rowBuf[i][j] = (Guchar *)gmalloc(bufWidth * sizeof(Guchar));
1961 // initialize counters
1967 restartMarker = 0xd0;
1972 int DCTStream::getChar() {
1978 if (progressive || !interleaved) {
1979 c = frameBuf[comp][y * bufWidth + x];
1980 if (++comp == numComps) {
1988 if (dy >= mcuHeight) {
1989 if (!readMCURow()) {
1997 c = rowBuf[comp][dy][x];
1998 if (++comp == numComps) {
2013 int DCTStream::lookChar() {
2017 if (progressive || !interleaved) {
2018 return frameBuf[comp][y * bufWidth + x];
2020 if (dy >= mcuHeight) {
2021 if (!readMCURow()) {
2029 return rowBuf[comp][dy][x];
2033 void DCTStream::restart() {
2037 restartCtr = restartInterval;
2038 for (i = 0; i < numComps; ++i) {
2039 compInfo[i].prevDC = 0;
2044 // Read one row of MCUs from a sequential JPEG stream.
2045 GBool DCTStream::readMCURow() {
2049 int pY, pCb, pCr, pR, pG, pB;
2050 int h, v, horiz, vert, hSub, vSub;
2051 int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
2054 for (x1 = 0; x1 < width; x1 += mcuWidth) {
2056 // deal with restart marker
2057 if (restartInterval > 0 && restartCtr == 0) {
2059 if (c != restartMarker) {
2060 error(getPos(), "Bad DCT data: incorrect restart marker");
2063 if (++restartMarker == 0xd8)
2064 restartMarker = 0xd0;
2069 for (cc = 0; cc < numComps; ++cc) {
2070 h = compInfo[cc].hSample;
2071 v = compInfo[cc].vSample;
2072 horiz = mcuWidth / h;
2073 vert = mcuHeight / v;
2076 for (y2 = 0; y2 < mcuHeight; y2 += vert) {
2077 for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
2078 if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]],
2079 &acHuffTables[scanInfo.acHuffTable[cc]],
2080 &compInfo[cc].prevDC,
2084 transformDataUnit(quantTables[compInfo[cc].quantTable],
2086 if (hSub == 1 && vSub == 1) {
2087 for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2088 p1 = &rowBuf[cc][y2+y3][x1+x2];
2098 } else if (hSub == 2 && vSub == 2) {
2099 for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
2100 p1 = &rowBuf[cc][y2+y3][x1+x2];
2101 p2 = &rowBuf[cc][y2+y3+1][x1+x2];
2102 p1[0] = p1[1] = p2[0] = p2[1] = data2[i];
2103 p1[2] = p1[3] = p2[2] = p2[3] = data2[i+1];
2104 p1[4] = p1[5] = p2[4] = p2[5] = data2[i+2];
2105 p1[6] = p1[7] = p2[6] = p2[7] = data2[i+3];
2106 p1[8] = p1[9] = p2[8] = p2[9] = data2[i+4];
2107 p1[10] = p1[11] = p2[10] = p2[11] = data2[i+5];
2108 p1[12] = p1[13] = p2[12] = p2[13] = data2[i+6];
2109 p1[14] = p1[15] = p2[14] = p2[15] = data2[i+7];
2113 for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
2114 for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
2115 for (y5 = 0; y5 < vSub; ++y5)
2116 for (x5 = 0; x5 < hSub; ++x5)
2117 rowBuf[cc][y2+y4+y5][x1+x2+x4+x5] = data2[i];
2127 // color space conversion
2129 // convert YCbCr to RGB
2130 if (numComps == 3) {
2131 for (y2 = 0; y2 < mcuHeight; ++y2) {
2132 for (x2 = 0; x2 < mcuWidth; ++x2) {
2133 pY = rowBuf[0][y2][x1+x2];
2134 pCb = rowBuf[1][y2][x1+x2] - 128;
2135 pCr = rowBuf[2][y2][x1+x2] - 128;
2136 pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2137 rowBuf[0][y2][x1+x2] = dctClip[dctClipOffset + pR];
2138 pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
2139 rowBuf[1][y2][x1+x2] = dctClip[dctClipOffset + pG];
2140 pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2141 rowBuf[2][y2][x1+x2] = dctClip[dctClipOffset + pB];
2144 // convert YCbCrK to CMYK (K is passed through unchanged)
2145 } else if (numComps == 4) {
2146 for (y2 = 0; y2 < mcuHeight; ++y2) {
2147 for (x2 = 0; x2 < mcuWidth; ++x2) {
2148 pY = rowBuf[0][y2][x1+x2];
2149 pCb = rowBuf[1][y2][x1+x2] - 128;
2150 pCr = rowBuf[2][y2][x1+x2] - 128;
2151 pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2152 rowBuf[0][y2][x1+x2] = 255 - dctClip[dctClipOffset + pR];
2153 pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
2154 rowBuf[1][y2][x1+x2] = 255 - dctClip[dctClipOffset + pG];
2155 pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2156 rowBuf[2][y2][x1+x2] = 255 - dctClip[dctClipOffset + pB];
2165 // Read one scan from a progressive or non-interleaved JPEG stream.
2166 void DCTStream::readScan() {
2168 int x1, y1, dx1, dy1, x2, y2, y3, cc, i;
2169 int h, v, horiz, vert, vSub;
2173 if (scanInfo.numComps == 1) {
2174 for (cc = 0; cc < numComps; ++cc) {
2175 if (scanInfo.comp[cc]) {
2179 dx1 = mcuWidth / compInfo[cc].hSample;
2180 dy1 = mcuHeight / compInfo[cc].vSample;
2186 for (y1 = 0; y1 < height; y1 += dy1) {
2187 for (x1 = 0; x1 < width; x1 += dx1) {
2189 // deal with restart marker
2190 if (restartInterval > 0 && restartCtr == 0) {
2192 if (c != restartMarker) {
2193 error(getPos(), "Bad DCT data: incorrect restart marker");
2196 if (++restartMarker == 0xd8) {
2197 restartMarker = 0xd0;
2203 for (cc = 0; cc < numComps; ++cc) {
2204 if (!scanInfo.comp[cc]) {
2208 h = compInfo[cc].hSample;
2209 v = compInfo[cc].vSample;
2210 horiz = mcuWidth / h;
2211 vert = mcuHeight / v;
2213 for (y2 = 0; y2 < dy1; y2 += vert) {
2214 for (x2 = 0; x2 < dx1; x2 += horiz) {
2216 // pull out the current values
2217 p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
2218 for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2227 p1 += bufWidth * vSub;
2230 // read one data unit
2232 if (!readProgressiveDataUnit(
2233 &dcHuffTables[scanInfo.dcHuffTable[cc]],
2234 &acHuffTables[scanInfo.acHuffTable[cc]],
2235 &compInfo[cc].prevDC,
2240 if (!readDataUnit(&dcHuffTables[scanInfo.dcHuffTable[cc]],
2241 &acHuffTables[scanInfo.acHuffTable[cc]],
2242 &compInfo[cc].prevDC,
2248 // add the data unit into frameBuf
2249 p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
2250 for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2259 p1 += bufWidth * vSub;
2269 // Read one data unit from a sequential JPEG stream.
2270 GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
2271 DCTHuffTable *acHuffTable,
2272 int *prevDC, int data[64]) {
2277 if ((size = readHuffSym(dcHuffTable)) == 9999) {
2281 if ((amp = readAmp(size)) == 9999) {
2287 data[0] = *prevDC += amp;
2288 for (i = 1; i < 64; ++i) {
2294 while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30) {
2303 run += (c >> 4) & 0x0f;
2305 amp = readAmp(size);
2319 // Read one data unit from a sequential JPEG stream.
2320 GBool DCTStream::readProgressiveDataUnit(DCTHuffTable *dcHuffTable,
2321 DCTHuffTable *acHuffTable,
2322 int *prevDC, int data[64]) {
2323 int run, size, amp, bit, c;
2326 // get the DC coefficient
2327 i = scanInfo.firstCoeff;
2329 if (scanInfo.ah == 0) {
2330 if ((size = readHuffSym(dcHuffTable)) == 9999) {
2334 if ((amp = readAmp(size)) == 9999) {
2340 data[0] += (*prevDC += amp) << scanInfo.al;
2342 if ((bit = readBit()) == 9999) {
2345 data[0] += bit << scanInfo.al;
2349 if (scanInfo.lastCoeff == 0) {
2353 // check for an EOB run
2355 while (i <= scanInfo.lastCoeff) {
2358 if ((bit = readBit()) == EOF) {
2362 data[j] += 1 << scanInfo.al;
2370 // read the AC coefficients
2371 while (i <= scanInfo.lastCoeff) {
2372 if ((c = readHuffSym(acHuffTable)) == 9999) {
2384 if ((bit = readBit()) == EOF) {
2388 data[j] += 1 << scanInfo.al;
2394 } else if ((c & 0x0f) == 0x00) {
2397 for (k = 0; k < j; ++k) {
2398 if ((bit = readBit()) == EOF) {
2401 eobRun = (eobRun << 1) | bit;
2404 while (i <= scanInfo.lastCoeff) {
2407 if ((bit = readBit()) == EOF) {
2411 data[j] += 1 << scanInfo.al;
2418 // zero run and one AC coefficient
2420 run = (c >> 4) & 0x0f;
2422 if ((amp = readAmp(size)) == 9999) {
2428 while (data[j] != 0) {
2429 if ((bit = readBit()) == EOF) {
2433 data[j] += 1 << scanInfo.al;
2439 data[j] = amp << scanInfo.al;
2446 // Decode a progressive JPEG image.
2447 void DCTStream::decodeImage() {
2451 int pY, pCb, pCr, pR, pG, pB;
2452 int x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
2453 int h, v, horiz, vert, hSub, vSub;
2456 for (y1 = 0; y1 < bufHeight; y1 += mcuHeight) {
2457 for (x1 = 0; x1 < bufWidth; x1 += mcuWidth) {
2458 for (cc = 0; cc < numComps; ++cc) {
2459 quantTable = quantTables[compInfo[cc].quantTable];
2460 h = compInfo[cc].hSample;
2461 v = compInfo[cc].vSample;
2462 horiz = mcuWidth / h;
2463 vert = mcuHeight / v;
2466 for (y2 = 0; y2 < mcuHeight; y2 += vert) {
2467 for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
2469 // pull out the coded data unit
2470 p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
2471 for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2473 dataIn[i+1] = p1[1];
2474 dataIn[i+2] = p1[2];
2475 dataIn[i+3] = p1[3];
2476 dataIn[i+4] = p1[4];
2477 dataIn[i+5] = p1[5];
2478 dataIn[i+6] = p1[6];
2479 dataIn[i+7] = p1[7];
2480 p1 += bufWidth * vSub;
2484 transformDataUnit(quantTable, dataIn, dataOut);
2486 // store back into frameBuf, doing replication for
2487 // subsampled components
2488 p1 = &frameBuf[cc][(y1+y2) * bufWidth + (x1+x2)];
2489 if (hSub == 1 && vSub == 1) {
2490 for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
2491 p1[0] = dataOut[i] & 0xff;
2492 p1[1] = dataOut[i+1] & 0xff;
2493 p1[2] = dataOut[i+2] & 0xff;
2494 p1[3] = dataOut[i+3] & 0xff;
2495 p1[4] = dataOut[i+4] & 0xff;
2496 p1[5] = dataOut[i+5] & 0xff;
2497 p1[6] = dataOut[i+6] & 0xff;
2498 p1[7] = dataOut[i+7] & 0xff;
2501 } else if (hSub == 2 && vSub == 2) {
2503 for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
2504 p1[0] = p1[1] = p2[0] = p2[1] = dataOut[i] & 0xff;
2505 p1[2] = p1[3] = p2[2] = p2[3] = dataOut[i+1] & 0xff;
2506 p1[4] = p1[5] = p2[4] = p2[5] = dataOut[i+2] & 0xff;
2507 p1[6] = p1[7] = p2[6] = p2[7] = dataOut[i+3] & 0xff;
2508 p1[8] = p1[9] = p2[8] = p2[9] = dataOut[i+4] & 0xff;
2509 p1[10] = p1[11] = p2[10] = p2[11] = dataOut[i+5] & 0xff;
2510 p1[12] = p1[13] = p2[12] = p2[13] = dataOut[i+6] & 0xff;
2511 p1[14] = p1[15] = p2[14] = p2[15] = dataOut[i+7] & 0xff;
2517 for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
2518 for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
2520 for (y5 = 0; y5 < vSub; ++y5) {
2521 for (x5 = 0; x5 < hSub; ++x5) {
2522 p2[x5] = dataOut[i] & 0xff;
2528 p1 += bufWidth * vSub;
2535 // color space conversion
2537 // convert YCbCr to RGB
2538 if (numComps == 3) {
2539 for (y2 = 0; y2 < mcuHeight; ++y2) {
2540 p0 = &frameBuf[0][(y1+y2) * bufWidth + x1];
2541 p1 = &frameBuf[1][(y1+y2) * bufWidth + x1];
2542 p2 = &frameBuf[2][(y1+y2) * bufWidth + x1];
2543 for (x2 = 0; x2 < mcuWidth; ++x2) {
2547 pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2548 *p0++ = dctClip[dctClipOffset + pR];
2549 pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr +
2551 *p1++ = dctClip[dctClipOffset + pG];
2552 pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2553 *p2++ = dctClip[dctClipOffset + pB];
2556 // convert YCbCrK to CMYK (K is passed through unchanged)
2557 } else if (numComps == 4) {
2558 for (y2 = 0; y2 < mcuHeight; ++y2) {
2559 p0 = &frameBuf[0][(y1+y2) * bufWidth + x1];
2560 p1 = &frameBuf[1][(y1+y2) * bufWidth + x1];
2561 p2 = &frameBuf[2][(y1+y2) * bufWidth + x1];
2562 for (x2 = 0; x2 < mcuWidth; ++x2) {
2566 pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
2567 *p0++ = 255 - dctClip[dctClipOffset + pR];
2568 pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr +
2570 *p1++ = 255 - dctClip[dctClipOffset + pG];
2571 pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
2572 *p2++ = 255 - dctClip[dctClipOffset + pB];
2581 // Transform one data unit -- this performs the dequantization and
2582 // IDCT steps. This IDCT algorithm is taken from:
2583 // Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,
2584 // "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
2585 // IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
2587 // The stage numbers mentioned in the comments refer to Figure 1 in this
2589 void DCTStream::transformDataUnit(Guchar *quantTable,
2590 int dataIn[64], Guchar dataOut[64]) {
2591 int v0, v1, v2, v3, v4, v5, v6, v7, t;
2596 for (i = 0; i < 64; ++i) {
2597 dataIn[i] *= quantTable[i];
2600 // inverse DCT on rows
2601 for (i = 0; i < 64; i += 8) {
2604 // check for all-zero AC coefficients
2605 if (p[1] == 0 && p[2] == 0 && p[3] == 0 &&
2606 p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] == 0) {
2607 t = (dctSqrt2 * p[0] + 512) >> 10;
2620 v0 = (dctSqrt2 * p[0] + 128) >> 8;
2621 v1 = (dctSqrt2 * p[4] + 128) >> 8;
2624 v4 = (dctSqrt1d2 * (p[1] - p[7]) + 128) >> 8;
2625 v7 = (dctSqrt1d2 * (p[1] + p[7]) + 128) >> 8;
2630 t = (v0 - v1+ 1) >> 1;
2631 v0 = (v0 + v1 + 1) >> 1;
2633 t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8;
2634 v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8;
2636 t = (v4 - v6 + 1) >> 1;
2637 v4 = (v4 + v6 + 1) >> 1;
2639 t = (v7 + v5 + 1) >> 1;
2640 v5 = (v7 - v5 + 1) >> 1;
2644 t = (v0 - v3 + 1) >> 1;
2645 v0 = (v0 + v3 + 1) >> 1;
2647 t = (v1 - v2 + 1) >> 1;
2648 v1 = (v1 + v2 + 1) >> 1;
2650 t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
2651 v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
2653 t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
2654 v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
2668 // inverse DCT on columns
2669 for (i = 0; i < 8; ++i) {
2672 // check for all-zero AC coefficients
2673 if (p[1*8] == 0 && p[2*8] == 0 && p[3*8] == 0 &&
2674 p[4*8] == 0 && p[5*8] == 0 && p[6*8] == 0 && p[7*8] == 0) {
2675 t = (dctSqrt2 * dataIn[i+0] + 8192) >> 14;
2688 v0 = (dctSqrt2 * p[0*8] + 2048) >> 12;
2689 v1 = (dctSqrt2 * p[4*8] + 2048) >> 12;
2692 v4 = (dctSqrt1d2 * (p[1*8] - p[7*8]) + 2048) >> 12;
2693 v7 = (dctSqrt1d2 * (p[1*8] + p[7*8]) + 2048) >> 12;
2698 t = (v0 - v1 + 1) >> 1;
2699 v0 = (v0 + v1 + 1) >> 1;
2701 t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12;
2702 v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12;
2704 t = (v4 - v6 + 1) >> 1;
2705 v4 = (v4 + v6 + 1) >> 1;
2707 t = (v7 + v5 + 1) >> 1;
2708 v5 = (v7 - v5 + 1) >> 1;
2712 t = (v0 - v3 + 1) >> 1;
2713 v0 = (v0 + v3 + 1) >> 1;
2715 t = (v1 - v2 + 1) >> 1;
2716 v1 = (v1 + v2 + 1) >> 1;
2718 t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
2719 v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
2721 t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
2722 v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
2736 // convert to 8-bit integers
2737 for (i = 0; i < 64; ++i) {
2738 dataOut[i] = dctClip[dctClipOffset + 128 + ((dataIn[i] + 8) >> 4)];
2742 int DCTStream::readHuffSym(DCTHuffTable *table) {
2750 // add a bit to the code
2751 if ((bit = readBit()) == EOF)
2753 code = (code << 1) + bit;
2757 if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
2758 code -= table->firstCode[codeBits];
2759 return table->sym[table->firstSym[codeBits] + code];
2761 } while (codeBits < 16);
2763 error(getPos(), "Bad Huffman code in DCT stream");
2767 int DCTStream::readAmp(int size) {
2772 for (bits = 0; bits < size; ++bits) {
2773 if ((bit = readBit()) == EOF)
2775 amp = (amp << 1) + bit;
2777 if (amp < (1 << (size - 1)))
2778 amp -= (1 << size) - 1;
2782 int DCTStream::readBit() {
2786 if (inputBits == 0) {
2787 if ((c = str->getChar()) == EOF)
2791 c2 = str->getChar();
2792 } while (c2 == 0xff);
2794 error(getPos(), "Bad DCT data: missing 00 after ff");
2801 bit = (inputBuf >> (inputBits - 1)) & 1;
2806 GBool DCTStream::readHeader() {
2818 if (!readBaselineSOF()) {
2823 if (!readProgressiveSOF()) {
2828 if (!readHuffmanTables()) {
2837 if (!readScanInfo()) {
2843 if (!readQuantTables()) {
2848 if (!readRestartInterval()) {
2853 if (!readJFIFMarker()) {
2858 if (!readAdobeMarker()) {
2863 error(getPos(), "Bad DCT header");
2866 // skip APPn / COM / etc.
2869 for (i = 0; i < n; ++i) {
2873 error(getPos(), "Unknown DCT marker <%02x>", c);
2883 GBool DCTStream::readBaselineSOF() {
2890 prec = str->getChar();
2893 numComps = str->getChar();
2895 error(getPos(), "Bad DCT precision %d", prec);
2898 for (i = 0; i < numComps; ++i) {
2899 compInfo[i].id = str->getChar();
2901 compInfo[i].hSample = (c >> 4) & 0x0f;
2902 compInfo[i].vSample = c & 0x0f;
2903 compInfo[i].quantTable = str->getChar();
2905 progressive = gFalse;
2909 GBool DCTStream::readProgressiveSOF() {
2916 prec = str->getChar();
2919 numComps = str->getChar();
2921 error(getPos(), "Bad DCT precision %d", prec);
2924 for (i = 0; i < numComps; ++i) {
2925 compInfo[i].id = str->getChar();
2927 compInfo[i].hSample = (c >> 4) & 0x0f;
2928 compInfo[i].vSample = c & 0x0f;
2929 compInfo[i].quantTable = str->getChar();
2931 progressive = gTrue;
2935 GBool DCTStream::readScanInfo() {
2940 length = read16() - 2;
2941 scanInfo.numComps = str->getChar();
2943 if (length != 2 * scanInfo.numComps + 3) {
2944 error(getPos(), "Bad DCT scan info block");
2947 interleaved = scanInfo.numComps == numComps;
2948 for (j = 0; j < numComps; ++j) {
2949 scanInfo.comp[j] = gFalse;
2951 for (i = 0; i < scanInfo.numComps; ++i) {
2952 id = str->getChar();
2953 // some (broken) DCT streams reuse ID numbers, but at least they
2954 // keep the components in order, so we check compInfo[i] first to
2955 // work around the problem
2956 if (id == compInfo[i].id) {
2959 for (j = 0; j < numComps; ++j) {
2960 if (id == compInfo[j].id) {
2964 if (j == numComps) {
2965 error(getPos(), "Bad DCT component ID in scan info block");
2969 scanInfo.comp[j] = gTrue;
2971 scanInfo.dcHuffTable[j] = (c >> 4) & 0x0f;
2972 scanInfo.acHuffTable[j] = c & 0x0f;
2974 scanInfo.firstCoeff = str->getChar();
2975 scanInfo.lastCoeff = str->getChar();
2977 scanInfo.ah = (c >> 4) & 0x0f;
2978 scanInfo.al = c & 0x0f;
2982 GBool DCTStream::readQuantTables() {
2987 length = read16() - 2;
2988 while (length > 0) {
2989 index = str->getChar();
2990 if ((index & 0xf0) || index >= 4) {
2991 error(getPos(), "Bad DCT quantization table");
2994 if (index == numQuantTables)
2995 numQuantTables = index + 1;
2996 for (i = 0; i < 64; ++i)
2997 quantTables[index][dctZigZag[i]] = str->getChar();
3003 GBool DCTStream::readHuffmanTables() {
3012 length = read16() - 2;
3013 while (length > 0) {
3014 index = str->getChar();
3016 if ((index & 0x0f) >= 4) {
3017 error(getPos(), "Bad DCT Huffman table");
3022 if (index >= numACHuffTables)
3023 numACHuffTables = index+1;
3024 tbl = &acHuffTables[index];
3026 if (index >= numDCHuffTables)
3027 numDCHuffTables = index+1;
3028 tbl = &dcHuffTables[index];
3032 for (i = 1; i <= 16; ++i) {
3034 tbl->firstSym[i] = sym;
3035 tbl->firstCode[i] = code;
3036 tbl->numCodes[i] = c;
3038 code = (code + c) << 1;
3041 for (i = 0; i < sym; ++i)
3042 tbl->sym[i] = str->getChar();
3048 GBool DCTStream::readRestartInterval() {
3053 error(getPos(), "Bad DCT restart interval");
3056 restartInterval = read16();
3060 GBool DCTStream::readJFIFMarker() {
3068 for (i = 0; i < 5; ++i) {
3069 if ((c = str->getChar()) == EOF) {
3070 error(getPos(), "Bad DCT APP0 marker");
3076 if (!memcmp(buf, "JFIF\0", 5)) {
3077 gotJFIFMarker = gTrue;
3080 while (length > 0) {
3081 if (str->getChar() == EOF) {
3082 error(getPos(), "Bad DCT APP0 marker");
3090 GBool DCTStream::readAdobeMarker() {
3099 for (i = 0; i < 12; ++i) {
3100 if ((c = str->getChar()) == EOF) {
3105 if (strncmp(buf, "Adobe", 5)) {
3108 colorXform = buf[11];
3109 gotAdobeMarker = gTrue;
3110 for (i = 14; i < length; ++i) {
3111 if (str->getChar() == EOF) {
3118 error(getPos(), "Bad DCT Adobe APP14 marker");
3122 GBool DCTStream::readTrailer() {
3126 if (c != 0xd9) { // EOI
3127 error(getPos(), "Bad DCT trailer");
3133 int DCTStream::readMarker() {
3139 } while (c != 0xff);
3142 } while (c == 0xff);
3143 } while (c == 0x00);
3147 int DCTStream::read16() {
3150 if ((c1 = str->getChar()) == EOF)
3152 if ((c2 = str->getChar()) == EOF)
3154 return (c1 << 8) + c2;
3157 GString *DCTStream::getPSFilter(int psLevel, char *indent) {
3163 if (!(s = str->getPSFilter(psLevel, indent))) {
3166 s->append(indent)->append("<< >> /DCTDecode filter\n");
3170 GBool DCTStream::isBinary(GBool last) {
3171 return str->isBinary(gTrue);
3174 //------------------------------------------------------------------------
3176 //------------------------------------------------------------------------
3178 int FlateStream::codeLenCodeMap[flateMaxCodeLenCodes] = {
3179 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
3182 FlateDecode FlateStream::lengthDecode[flateMaxLitCodes-257] = {
3214 FlateDecode FlateStream::distDecode[flateMaxDistCodes] = {
3247 FlateStream::FlateStream(Stream *strA, int predictor, int columns,
3248 int colors, int bits):
3249 FilterStream(strA) {
3250 if (predictor != 1) {
3251 pred = new StreamPredictor(this, predictor, columns, colors, bits);
3255 litCodeTab.codes = NULL;
3256 distCodeTab.codes = NULL;
3259 FlateStream::~FlateStream() {
3260 gfree(litCodeTab.codes);
3261 gfree(distCodeTab.codes);
3268 void FlateStream::reset() {
3275 compressedBlock = gFalse;
3282 //~ need to look at window size?
3283 endOfBlock = eof = gTrue;
3284 cmf = str->getChar();
3285 flg = str->getChar();
3286 if (cmf == EOF || flg == EOF)
3288 if ((cmf & 0x0f) != 0x08) {
3289 error(getPos(), "Unknown compression method in flate stream");
3292 if ((((cmf << 8) + flg) % 31) != 0) {
3293 error(getPos(), "Bad FCHECK in flate stream");
3297 error(getPos(), "FDICT bit set in flate stream");
3304 int FlateStream::getChar() {
3308 return pred->getChar();
3310 while (remain == 0) {
3311 if (endOfBlock && eof)
3316 index = (index + 1) & flateMask;
3321 int FlateStream::lookChar() {
3325 return pred->lookChar();
3327 while (remain == 0) {
3328 if (endOfBlock && eof)
3336 int FlateStream::getRawChar() {
3339 while (remain == 0) {
3340 if (endOfBlock && eof)
3345 index = (index + 1) & flateMask;
3350 GString *FlateStream::getPSFilter(int psLevel, char *indent) {
3353 if (psLevel < 3 || pred) {
3356 if (!(s = str->getPSFilter(psLevel, indent))) {
3359 s->append(indent)->append("<< >> /FlateDecode filter\n");
3363 GBool FlateStream::isBinary(GBool last) {
3364 return str->isBinary(gTrue);
3367 void FlateStream::readSome() {
3378 if (compressedBlock) {
3379 if ((code1 = getHuffmanCodeWord(&litCodeTab)) == EOF)
3384 } else if (code1 == 256) {
3389 code2 = lengthDecode[code1].bits;
3390 if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
3392 len = lengthDecode[code1].first + code2;
3393 if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF)
3395 code2 = distDecode[code1].bits;
3396 if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
3398 dist = distDecode[code1].first + code2;
3400 j = (index - dist) & flateMask;
3401 for (k = 0; k < len; ++k) {
3403 i = (i + 1) & flateMask;
3404 j = (j + 1) & flateMask;
3410 len = (blockLen < flateWindow) ? blockLen : flateWindow;
3411 for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) {
3412 if ((c = str->getChar()) == EOF) {
3413 endOfBlock = eof = gTrue;
3427 error(getPos(), "Unexpected end of file in flate stream");
3428 endOfBlock = eof = gTrue;
3432 GBool FlateStream::startBlock() {
3437 // free the code tables from the previous block
3438 gfree(litCodeTab.codes);
3439 litCodeTab.codes = NULL;
3440 gfree(distCodeTab.codes);
3441 distCodeTab.codes = NULL;
3443 // read block header
3444 blockHdr = getCodeWord(3);
3449 // uncompressed block
3450 if (blockHdr == 0) {
3451 compressedBlock = gFalse;
3452 if ((c = str->getChar()) == EOF)
3454 blockLen = c & 0xff;
3455 if ((c = str->getChar()) == EOF)
3457 blockLen |= (c & 0xff) << 8;
3458 if ((c = str->getChar()) == EOF)
3461 if ((c = str->getChar()) == EOF)
3463 check |= (c & 0xff) << 8;
3464 if (check != (~blockLen & 0xffff))
3465 error(getPos(), "Bad uncompressed block length in flate stream");
3469 // compressed block with fixed codes
3470 } else if (blockHdr == 1) {
3471 compressedBlock = gTrue;
3474 // compressed block with dynamic codes
3475 } else if (blockHdr == 2) {
3476 compressedBlock = gTrue;
3477 if (!readDynamicCodes()) {
3481 // unknown block type
3486 endOfBlock = gFalse;
3490 error(getPos(), "Bad block header in flate stream");
3491 endOfBlock = eof = gTrue;
3495 void FlateStream::loadFixedCodes() {
3498 // build the literal code table
3499 for (i = 0; i <= 143; ++i) {
3502 for (i = 144; i <= 255; ++i) {
3505 for (i = 256; i <= 279; ++i) {
3508 for (i = 280; i <= 287; ++i) {
3511 compHuffmanCodes(codeLengths, flateMaxLitCodes, &litCodeTab);
3513 // build the distance code table
3514 for (i = 0; i < flateMaxDistCodes; ++i) {
3517 compHuffmanCodes(codeLengths, flateMaxDistCodes, &distCodeTab);
3520 GBool FlateStream::readDynamicCodes() {
3521 int numCodeLenCodes;
3524 int codeLenCodeLengths[flateMaxCodeLenCodes];
3525 FlateHuffmanTab codeLenCodeTab;
3526 int len, repeat, code;
3529 codeLenCodeTab.codes = NULL;
3532 if ((numLitCodes = getCodeWord(5)) == EOF) {
3536 if ((numDistCodes = getCodeWord(5)) == EOF) {
3540 if ((numCodeLenCodes = getCodeWord(4)) == EOF) {
3543 numCodeLenCodes += 4;
3544 if (numLitCodes > flateMaxLitCodes ||
3545 numDistCodes > flateMaxDistCodes ||
3546 numCodeLenCodes > flateMaxCodeLenCodes) {
3550 // build the code length code table
3551 for (i = 0; i < flateMaxCodeLenCodes; ++i) {
3552 codeLenCodeLengths[i] = 0;
3554 for (i = 0; i < numCodeLenCodes; ++i) {
3555 if ((codeLenCodeLengths[codeLenCodeMap[i]] = getCodeWord(3)) == -1) {
3559 compHuffmanCodes(codeLenCodeLengths, flateMaxCodeLenCodes, &codeLenCodeTab);
3561 // build the literal and distance code tables
3565 while (i < numLitCodes + numDistCodes) {
3566 if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF) {
3570 if ((repeat = getCodeWord(2)) == EOF) {
3574 if (i + repeat > numLitCodes + numDistCodes) {
3577 for (; repeat > 0; --repeat) {
3578 codeLengths[i++] = len;
3580 } else if (code == 17) {
3581 if ((repeat = getCodeWord(3)) == EOF) {
3585 if (i + repeat > numLitCodes + numDistCodes) {
3589 for (; repeat > 0; --repeat) {
3590 codeLengths[i++] = 0;
3592 } else if (code == 18) {
3593 if ((repeat = getCodeWord(7)) == EOF) {
3597 if (i + repeat > numLitCodes + numDistCodes) {
3601 for (; repeat > 0; --repeat) {
3602 codeLengths[i++] = 0;
3605 codeLengths[i++] = len = code;
3608 compHuffmanCodes(codeLengths, numLitCodes, &litCodeTab);
3609 compHuffmanCodes(codeLengths + numLitCodes, numDistCodes, &distCodeTab);
3611 gfree(codeLenCodeTab.codes);
3615 error(getPos(), "Bad dynamic code table in flate stream");
3616 gfree(codeLenCodeTab.codes);
3620 // Convert an array <lengths> of <n> lengths, in value order, into a
3621 // Huffman code lookup table.
3622 void FlateStream::compHuffmanCodes(int *lengths, int n, FlateHuffmanTab *tab) {
3623 int tabSize, len, code, code2, skip, val, i, t;
3625 // find max code length
3627 for (val = 0; val < n; ++val) {
3628 if (lengths[val] > tab->maxLen) {
3629 tab->maxLen = lengths[val];
3633 // allocate the table
3634 tabSize = 1 << tab->maxLen;
3635 tab->codes = (FlateCode *)gmalloc(tabSize * sizeof(FlateCode));
3638 for (i = 0; i < tabSize; ++i) {
3639 tab->codes[i].len = 0;
3640 tab->codes[i].val = 0;
3644 for (len = 1, code = 0, skip = 2;
3646 ++len, code <<= 1, skip <<= 1) {
3647 for (val = 0; val < n; ++val) {
3648 if (lengths[val] == len) {
3650 // bit-reverse the code
3653 for (i = 0; i < len; ++i) {
3654 code2 = (code2 << 1) | (t & 1);
3658 // fill in the table entries
3659 for (i = code2; i < tabSize; i += skip) {
3660 tab->codes[i].len = (Gushort)len;
3661 tab->codes[i].val = (Gushort)val;
3670 int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) {
3674 while (codeSize < tab->maxLen) {
3675 if ((c = str->getChar()) == EOF) {
3678 codeBuf |= (c & 0xff) << codeSize;
3681 code = &tab->codes[codeBuf & ((1 << tab->maxLen) - 1)];
3682 if (codeSize == 0 || codeSize < code->len || code->len == 0) {
3685 codeBuf >>= code->len;
3686 codeSize -= code->len;
3687 return (int)code->val;
3690 int FlateStream::getCodeWord(int bits) {
3693 while (codeSize < bits) {
3694 if ((c = str->getChar()) == EOF)
3696 codeBuf |= (c & 0xff) << codeSize;
3699 c = codeBuf & ((1 << bits) - 1);
3705 //------------------------------------------------------------------------
3707 //------------------------------------------------------------------------
3709 EOFStream::EOFStream(Stream *strA):
3710 FilterStream(strA) {
3713 EOFStream::~EOFStream() {
3717 //------------------------------------------------------------------------
3718 // FixedLengthEncoder
3719 //------------------------------------------------------------------------
3721 FixedLengthEncoder::FixedLengthEncoder(Stream *strA, int lengthA):
3722 FilterStream(strA) {
3727 FixedLengthEncoder::~FixedLengthEncoder() {
3728 if (str->isEncoder())
3732 void FixedLengthEncoder::reset() {
3737 int FixedLengthEncoder::getChar() {
3738 if (length >= 0 && count >= length)
3741 return str->getChar();
3744 int FixedLengthEncoder::lookChar() {
3745 if (length >= 0 && count >= length)
3747 return str->getChar();
3750 //------------------------------------------------------------------------
3752 //------------------------------------------------------------------------
3754 ASCIIHexEncoder::ASCIIHexEncoder(Stream *strA):
3755 FilterStream(strA) {
3756 bufPtr = bufEnd = buf;
3761 ASCIIHexEncoder::~ASCIIHexEncoder() {
3762 if (str->isEncoder()) {
3767 void ASCIIHexEncoder::reset() {
3769 bufPtr = bufEnd = buf;
3774 GBool ASCIIHexEncoder::fillBuf() {
3775 static char *hex = "0123456789abcdef";
3781 bufPtr = bufEnd = buf;
3782 if ((c = str->getChar()) == EOF) {
3786 if (lineLen >= 64) {
3790 *bufEnd++ = hex[(c >> 4) & 0x0f];
3791 *bufEnd++ = hex[c & 0x0f];
3797 //------------------------------------------------------------------------
3799 //------------------------------------------------------------------------
3801 ASCII85Encoder::ASCII85Encoder(Stream *strA):
3802 FilterStream(strA) {
3803 bufPtr = bufEnd = buf;
3808 ASCII85Encoder::~ASCII85Encoder() {
3809 if (str->isEncoder())
3813 void ASCII85Encoder::reset() {
3815 bufPtr = bufEnd = buf;
3820 GBool ASCII85Encoder::fillBuf() {
3829 for (n = 0; n < 4; ++n) {
3830 if ((c = str->getChar()) == EOF)
3834 bufPtr = bufEnd = buf;
3836 if (n == 4 && t == 0) {
3838 if (++lineLen == 65) {
3845 for (i = 4; i >= 0; --i) {
3846 buf1[i] = (char)(t % 85 + 0x21);
3849 for (i = 0; i <= n; ++i) {
3850 *bufEnd++ = buf1[i];
3851 if (++lineLen == 65) {
3863 return bufPtr < bufEnd;
3866 //------------------------------------------------------------------------
3868 //------------------------------------------------------------------------
3870 RunLengthEncoder::RunLengthEncoder(Stream *strA):
3871 FilterStream(strA) {
3872 bufPtr = bufEnd = nextEnd = buf;
3876 RunLengthEncoder::~RunLengthEncoder() {
3877 if (str->isEncoder())
3881 void RunLengthEncoder::reset() {
3883 bufPtr = bufEnd = nextEnd = buf;
3888 // When fillBuf finishes, buf[] looks like this:
3889 // +-----+--------------+-----------------+--
3890 // + tag | ... data ... | next 0, 1, or 2 |
3891 // +-----+--------------+-----------------+--
3893 // bufPtr bufEnd nextEnd
3895 GBool RunLengthEncoder::fillBuf() {
3904 if (nextEnd < bufEnd + 1) {
3905 if ((c1 = str->getChar()) == EOF) {
3910 c1 = bufEnd[0] & 0xff;
3912 if (nextEnd < bufEnd + 2) {
3913 if ((c2 = str->getChar()) == EOF) {
3922 c2 = bufEnd[1] & 0xff;
3926 c = 0; // make gcc happy
3929 while (n < 128 && (c = str->getChar()) == c1)
3931 buf[0] = (char)(257 - n);
3936 } else if (n < 128) {
3943 // get up to 128 chars
3949 if ((c = str->getChar()) == EOF) {
3955 if (buf[n] == buf[n-1])
3958 if (buf[n] == buf[n-1]) {
3959 buf[0] = (char)(n-2-1);
3961 nextEnd = &buf[n+1];
3963 buf[0] = (char)(n-1);
3964 bufEnd = nextEnd = &buf[n+1];