00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifdef __GNUC__
00010 #pragma implementation
00011 #endif
00012
00013 #include <aconf.h>
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <stddef.h>
00017 #ifndef WIN32
00018 #include <unistd.h>
00019 #endif
00020 #include <string.h>
00021 #include <ctype.h>
00022 #include "gmem.h"
00023 #include "gfile.h"
00024 #include "config.h"
00025 #include "Error.h"
00026 #include "Object.h"
00027 #ifndef NO_DECRYPTION
00028 #include "Decrypt.h"
00029 #endif
00030 #include "Stream.h"
00031 #include "Stream-CCITT.h"
00032
00033 #ifdef __DJGPP__
00034 static GBool setDJSYSFLAGS = gFalse;
00035 #endif
00036
00037 #ifdef VMS
00038 #if (__VMS_VER < 70000000)
00039 extern "C" int unlink(char *filename);
00040 #endif
00041 #ifdef __GNUC__
00042 #define SEEK_SET 0
00043 #define SEEK_CUR 1
00044 #define SEEK_END 2
00045 #endif
00046 #endif
00047
00048 #ifdef MACOS
00049 #include "StuffItEngineLib.h"
00050 #endif
00051
00052
00053
00054
00055
00056 Stream::Stream() {
00057 ref = 1;
00058 }
00059
00060 Stream::~Stream() {
00061 }
00062
00063 void Stream::close() {
00064 }
00065
00066 int Stream::getRawChar() {
00067 error(-1, "Internal: called getRawChar() on non-predictor stream");
00068 return EOF;
00069 }
00070
00071 char *Stream::getLine(char *buf, int size) {
00072 int i;
00073 int c;
00074
00075 if (lookChar() == EOF)
00076 return NULL;
00077 for (i = 0; i < size - 1; ++i) {
00078 c = getChar();
00079 if (c == EOF || c == '\n')
00080 break;
00081 if (c == '\r') {
00082 if ((c = lookChar()) == '\n')
00083 getChar();
00084 break;
00085 }
00086 buf[i] = c;
00087 }
00088 buf[i] = '\0';
00089 return buf;
00090 }
00091
00092 GString *Stream::getPSFilter(char *indent) {
00093 return new GString();
00094 }
00095
00096 Stream *Stream::addFilters(Object *dict) {
00097 Object obj, obj2;
00098 Object params, params2;
00099 Stream *str;
00100 int i;
00101
00102 str = this;
00103 dict->dictLookup("Filter", &obj);
00104 if (obj.isNull()) {
00105 obj.free();
00106 dict->dictLookup("F", &obj);
00107 }
00108 dict->dictLookup("DecodeParms", ¶ms);
00109 if (params.isNull()) {
00110 params.free();
00111 dict->dictLookup("DP", ¶ms);
00112 }
00113 if (obj.isName()) {
00114 str = makeFilter(obj.getName(), str, ¶ms);
00115 } else if (obj.isArray()) {
00116 for (i = 0; i < obj.arrayGetLength(); ++i) {
00117 obj.arrayGet(i, &obj2);
00118 if (params.isArray())
00119 params.arrayGet(i, ¶ms2);
00120 else
00121 params2.initNull();
00122 if (obj2.isName()) {
00123 str = makeFilter(obj2.getName(), str, ¶ms2);
00124 } else {
00125 error(getPos(), "Bad filter name");
00126 str = new EOFStream(str);
00127 }
00128 obj2.free();
00129 params2.free();
00130 }
00131 } else if (!obj.isNull()) {
00132 error(getPos(), "Bad 'Filter' attribute in stream");
00133 }
00134 obj.free();
00135 params.free();
00136
00137 return str;
00138 }
00139
00140 Stream *Stream::makeFilter(char *name, Stream *str, Object *params) {
00141 int pred;
00142 int colors;
00143 int bits;
00144 int early;
00145 int encoding;
00146 GBool endOfLine, byteAlign, endOfBlock, black;
00147 int columns, rows;
00148 Object obj;
00149
00150 if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) {
00151 str = new ASCIIHexStream(str);
00152 } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) {
00153 str = new ASCII85Stream(str);
00154 } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) {
00155 pred = 1;
00156 columns = 1;
00157 colors = 1;
00158 bits = 8;
00159 early = 1;
00160 if (params->isDict()) {
00161 params->dictLookup("Predictor", &obj);
00162 if (obj.isInt())
00163 pred = obj.getInt();
00164 obj.free();
00165 params->dictLookup("Columns", &obj);
00166 if (obj.isInt())
00167 columns = obj.getInt();
00168 obj.free();
00169 params->dictLookup("Colors", &obj);
00170 if (obj.isInt())
00171 colors = obj.getInt();
00172 obj.free();
00173 params->dictLookup("BitsPerComponent", &obj);
00174 if (obj.isInt())
00175 bits = obj.getInt();
00176 obj.free();
00177 params->dictLookup("EarlyChange", &obj);
00178 if (obj.isInt())
00179 early = obj.getInt();
00180 obj.free();
00181 }
00182 str = new LZWStream(str, pred, columns, colors, bits, early);
00183 } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) {
00184 str = new RunLengthStream(str);
00185 } else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) {
00186 encoding = 0;
00187 endOfLine = gFalse;
00188 byteAlign = gFalse;
00189 columns = 1728;
00190 rows = 0;
00191 endOfBlock = gTrue;
00192 black = gFalse;
00193 if (params->isDict()) {
00194 params->dictLookup("K", &obj);
00195 if (obj.isInt()) {
00196 encoding = obj.getInt();
00197 }
00198 obj.free();
00199 params->dictLookup("EndOfLine", &obj);
00200 if (obj.isBool()) {
00201 endOfLine = obj.getBool();
00202 }
00203 obj.free();
00204 params->dictLookup("EncodedByteAlign", &obj);
00205 if (obj.isBool()) {
00206 byteAlign = obj.getBool();
00207 }
00208 obj.free();
00209 params->dictLookup("Columns", &obj);
00210 if (obj.isInt()) {
00211 columns = obj.getInt();
00212 }
00213 obj.free();
00214 params->dictLookup("Rows", &obj);
00215 if (obj.isInt()) {
00216 rows = obj.getInt();
00217 }
00218 obj.free();
00219 params->dictLookup("EndOfBlock", &obj);
00220 if (obj.isBool()) {
00221 endOfBlock = obj.getBool();
00222 }
00223 obj.free();
00224 params->dictLookup("BlackIs1", &obj);
00225 if (obj.isBool()) {
00226 black = obj.getBool();
00227 }
00228 obj.free();
00229 }
00230 str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign,
00231 columns, rows, endOfBlock, black);
00232 } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) {
00233 str = new DCTStream(str);
00234 } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) {
00235 pred = 1;
00236 columns = 1;
00237 colors = 1;
00238 bits = 8;
00239 if (params->isDict()) {
00240 params->dictLookup("Predictor", &obj);
00241 if (obj.isInt())
00242 pred = obj.getInt();
00243 obj.free();
00244 params->dictLookup("Columns", &obj);
00245 if (obj.isInt())
00246 columns = obj.getInt();
00247 obj.free();
00248 params->dictLookup("Colors", &obj);
00249 if (obj.isInt())
00250 colors = obj.getInt();
00251 obj.free();
00252 params->dictLookup("BitsPerComponent", &obj);
00253 if (obj.isInt())
00254 bits = obj.getInt();
00255 obj.free();
00256 }
00257 str = new FlateStream(str, pred, columns, colors, bits);
00258 } else {
00259 error(getPos(), "Unknown filter '%s'", name);
00260 str = new EOFStream(str);
00261 }
00262 return str;
00263 }
00264
00265
00266
00267
00268
00269 BaseStream::BaseStream(Object *dictA) {
00270 dict = *dictA;
00271 #ifndef NO_DECRYPTION
00272 decrypt = NULL;
00273 #endif
00274 }
00275
00276 BaseStream::~BaseStream() {
00277 dict.free();
00278 #ifndef NO_DECRYPTION
00279 if (decrypt)
00280 delete decrypt;
00281 #endif
00282 }
00283
00284 #ifndef NO_DECRYPTION
00285 void BaseStream::doDecryption(Guchar *fileKey, int keyLength,
00286 int objNum, int objGen) {
00287 decrypt = new Decrypt(fileKey, keyLength, objNum, objGen);
00288 }
00289 #endif
00290
00291
00292
00293
00294
00295 FilterStream::FilterStream(Stream *strA) {
00296 str = strA;
00297 }
00298
00299 FilterStream::~FilterStream() {
00300 }
00301
00302 void FilterStream::close() {
00303 str->close();
00304 }
00305
00306 void FilterStream::setPos(Guint pos, int dir) {
00307 error(-1, "Internal: called setPos() on FilterStream");
00308 }
00309
00310
00311
00312
00313
00314 ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) {
00315 int imgLineSize;
00316
00317 str = strA;
00318 width = widthA;
00319 nComps = nCompsA;
00320 nBits = nBitsA;
00321
00322 nVals = width * nComps;
00323 if (nBits == 1) {
00324 imgLineSize = (nVals + 7) & ~7;
00325 } else {
00326 imgLineSize = nVals;
00327 }
00328 imgLine = (Guchar *)gmalloc(imgLineSize * sizeof(Guchar));
00329 imgIdx = nVals;
00330 }
00331
00332 ImageStream::~ImageStream() {
00333 gfree(imgLine);
00334 }
00335
00336 void ImageStream::reset() {
00337 str->reset();
00338 }
00339
00340 GBool ImageStream::getPixel(Guchar *pix) {
00341 Gulong buf, bitMask;
00342 int bits;
00343 int c;
00344 int i;
00345
00346 if (imgIdx >= nVals) {
00347
00348
00349 if (nBits == 1) {
00350 for (i = 0; i < nVals; i += 8) {
00351 c = str->getChar();
00352 imgLine[i+0] = (Guchar)((c >> 7) & 1);
00353 imgLine[i+1] = (Guchar)((c >> 6) & 1);
00354 imgLine[i+2] = (Guchar)((c >> 5) & 1);
00355 imgLine[i+3] = (Guchar)((c >> 4) & 1);
00356 imgLine[i+4] = (Guchar)((c >> 3) & 1);
00357 imgLine[i+5] = (Guchar)((c >> 2) & 1);
00358 imgLine[i+6] = (Guchar)((c >> 1) & 1);
00359 imgLine[i+7] = (Guchar)(c & 1);
00360 }
00361 } else if (nBits == 8) {
00362 for (i = 0; i < nVals; ++i) {
00363 imgLine[i] = str->getChar();
00364 }
00365 } else {
00366 bitMask = (1 << nBits) - 1;
00367 buf = 0;
00368 bits = 0;
00369 for (i = 0; i < nVals; ++i) {
00370 if (bits < nBits) {
00371 buf = (buf << 8) | (str->getChar() & 0xff);
00372 bits += 8;
00373 }
00374 imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask);
00375 bits -= nBits;
00376 }
00377 }
00378
00379
00380 imgIdx = 0;
00381 }
00382
00383 for (i = 0; i < nComps; ++i)
00384 pix[i] = imgLine[imgIdx++];
00385 return gTrue;
00386 }
00387
00388 void ImageStream::skipLine() {
00389 int n, i;
00390
00391 n = (nVals * nBits + 7) >> 3;
00392 for (i = 0; i < n; ++i) {
00393 str->getChar();
00394 }
00395 }
00396
00397
00398
00399
00400
00401 StreamPredictor::StreamPredictor(Stream *strA, int predictorA,
00402 int widthA, int nCompsA, int nBitsA) {
00403 str = strA;
00404 predictor = predictorA;
00405 width = widthA;
00406 nComps = nCompsA;
00407 nBits = nBitsA;
00408
00409 nVals = width * nComps;
00410 pixBytes = (nComps * nBits + 7) >> 3;
00411 rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes;
00412 predLine = (Guchar *)gmalloc(rowBytes);
00413 memset(predLine, 0, rowBytes);
00414 predIdx = rowBytes;
00415 }
00416
00417 StreamPredictor::~StreamPredictor() {
00418 gfree(predLine);
00419 }
00420
00421 int StreamPredictor::lookChar() {
00422 if (predIdx >= rowBytes) {
00423 if (!getNextLine()) {
00424 return EOF;
00425 }
00426 }
00427 return predLine[predIdx];
00428 }
00429
00430 int StreamPredictor::getChar() {
00431 if (predIdx >= rowBytes) {
00432 if (!getNextLine()) {
00433 return EOF;
00434 }
00435 }
00436 return predLine[predIdx++];
00437 }
00438
00439 GBool StreamPredictor::getNextLine() {
00440 int curPred;
00441 Guchar upLeftBuf[4];
00442 int left, up, upLeft, p, pa, pb, pc;
00443 int c;
00444 Gulong inBuf, outBuf, bitMask;
00445 int inBits, outBits;
00446 int i, j, k;
00447
00448
00449 if (predictor == 15) {
00450 if ((curPred = str->getRawChar()) == EOF) {
00451 return gFalse;
00452 }
00453 curPred += 10;
00454 } else {
00455 curPred = predictor;
00456 }
00457
00458
00459 upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0;
00460 for (i = pixBytes; i < rowBytes; ++i) {
00461 upLeftBuf[3] = upLeftBuf[2];
00462 upLeftBuf[2] = upLeftBuf[1];
00463 upLeftBuf[1] = upLeftBuf[0];
00464 upLeftBuf[0] = predLine[i];
00465 if ((c = str->getRawChar()) == EOF) {
00466 break;
00467 }
00468 switch (curPred) {
00469 case 11:
00470 predLine[i] = predLine[i - pixBytes] + (Guchar)c;
00471 break;
00472 case 12:
00473 predLine[i] = predLine[i] + (Guchar)c;
00474 break;
00475 case 13:
00476 predLine[i] = ((predLine[i - pixBytes] + predLine[i]) >> 1) +
00477 (Guchar)c;
00478 break;
00479 case 14:
00480 left = predLine[i - pixBytes];
00481 up = predLine[i];
00482 upLeft = upLeftBuf[pixBytes];
00483 p = left + up - upLeft;
00484 if ((pa = p - left) < 0)
00485 pa = -pa;
00486 if ((pb = p - up) < 0)
00487 pb = -pb;
00488 if ((pc = p - upLeft) < 0)
00489 pc = -pc;
00490 if (pa <= pb && pa <= pc)
00491 predLine[i] = left + (Guchar)c;
00492 else if (pb <= pc)
00493 predLine[i] = up + (Guchar)c;
00494 else
00495 predLine[i] = upLeft + (Guchar)c;
00496 break;
00497 case 10:
00498 default:
00499 predLine[i] = (Guchar)c;
00500 break;
00501 }
00502 }
00503
00504
00505
00506 if (predictor == 2) {
00507 if (nBits == 1) {
00508 inBuf = predLine[pixBytes - 1];
00509 for (i = pixBytes; i < rowBytes; i += 8) {
00510
00511 inBuf = (inBuf << 8) | predLine[i];
00512 predLine[i] ^= inBuf >> nComps;
00513 }
00514 } else if (nBits == 8) {
00515 for (i = pixBytes; i < rowBytes; ++i) {
00516 predLine[i] += predLine[i - nComps];
00517 }
00518 } else {
00519 upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0;
00520 bitMask = (1 << nBits) - 1;
00521 inBuf = outBuf = 0;
00522 inBits = outBits = 0;
00523 j = k = pixBytes;
00524 for (i = 0; i < nVals; ++i) {
00525 if (inBits < nBits) {
00526 inBuf = (inBuf << 8) | (predLine[j++] & 0xff);
00527 inBits += 8;
00528 }
00529 upLeftBuf[3] = upLeftBuf[2];
00530 upLeftBuf[2] = upLeftBuf[1];
00531 upLeftBuf[1] = upLeftBuf[0];
00532 upLeftBuf[0] = (upLeftBuf[nComps] +
00533 (inBuf >> (inBits - nBits))) & bitMask;
00534 outBuf = (outBuf << nBits) | upLeftBuf[0];
00535 inBits -= nBits;
00536 outBits += nBits;
00537 if (outBits > 8) {
00538 predLine[k++] = (Guchar)(outBuf >> (outBits - 8));
00539 }
00540 }
00541 if (outBits > 0) {
00542 predLine[k++] = (Guchar)(outBuf << (8 - outBits));
00543 }
00544 }
00545 }
00546
00547
00548 predIdx = pixBytes;
00549
00550 return gTrue;
00551 }
00552
00553
00554
00555
00556
00557 FileStream::FileStream(FILE *fA, Guint startA, GBool limitedA,
00558 Guint lengthA, Object *dictA):
00559 BaseStream(dictA) {
00560 f = fA;
00561 start = startA;
00562 limited = limitedA;
00563 length = lengthA;
00564 bufPtr = bufEnd = buf;
00565 bufPos = start;
00566 savePos = 0;
00567 saved = gFalse;
00568 }
00569
00570 FileStream::~FileStream() {
00571 close();
00572 }
00573
00574 Stream *FileStream::makeSubStream(Guint startA, GBool limitedA,
00575 Guint lengthA, Object *dictA) {
00576 return new FileStream(f, startA, limitedA, lengthA, dictA);
00577 }
00578
00579 void FileStream::reset() {
00580 #if HAVE_FSEEK64
00581 savePos = (Guint)ftell64(f);
00582 fseek64(f, start, SEEK_SET);
00583 #else
00584 savePos = (Guint)ftell(f);
00585 fseek(f, start, SEEK_SET);
00586 #endif
00587 saved = gTrue;
00588 bufPtr = bufEnd = buf;
00589 bufPos = start;
00590 #ifndef NO_DECRYPTION
00591 if (decrypt)
00592 decrypt->reset();
00593 #endif
00594 }
00595
00596 void FileStream::close() {
00597 if (saved) {
00598 #if HAVE_FSEEK64
00599 fseek64(f, savePos, SEEK_SET);
00600 #else
00601 fseek(f, savePos, SEEK_SET);
00602 #endif
00603 saved = gFalse;
00604 }
00605 }
00606
00607 GBool FileStream::fillBuf() {
00608 int n;
00609 #ifndef NO_DECRYPTION
00610 char *p;
00611 #endif
00612
00613 bufPos += bufEnd - buf;
00614 bufPtr = bufEnd = buf;
00615 if (limited && bufPos >= start + length) {
00616 return gFalse;
00617 }
00618 if (limited && bufPos + fileStreamBufSize > start + length) {
00619 n = start + length - bufPos;
00620 } else {
00621 n = fileStreamBufSize;
00622 }
00623 n = fread(buf, 1, n, f);
00624 bufEnd = buf + n;
00625 if (bufPtr >= bufEnd) {
00626 return gFalse;
00627 }
00628 #ifndef NO_DECRYPTION
00629 if (decrypt) {
00630 for (p = buf; p < bufEnd; ++p) {
00631 *p = (char)decrypt->decryptByte((Guchar)*p);
00632 }
00633 }
00634 #endif
00635 return gTrue;
00636 }
00637
00638 void FileStream::setPos(Guint pos, int dir) {
00639 Guint size;
00640
00641 if (dir >= 0) {
00642 #if HAVE_FSEEK64
00643 fseek64(f, pos, SEEK_SET);
00644 #else
00645 fseek(f, pos, SEEK_SET);
00646 #endif
00647 bufPos = pos;
00648 } else {
00649 #if HAVE_FSEEK64
00650 fseek64(f, 0, SEEK_END);
00651 size = (Guint)ftell64(f);
00652 #else
00653 fseek(f, 0, SEEK_END);
00654 size = (Guint)ftell(f);
00655 #endif
00656 if (pos > size)
00657 pos = (Guint)size;
00658 #ifdef __CYGWIN32__
00659
00660 rewind(f);
00661 #endif
00662 #if HAVE_FSEEK64
00663 fseek64(f, -(int)pos, SEEK_END);
00664 bufPos = (Guint)ftell64(f);
00665 #else
00666 fseek(f, -(int)pos, SEEK_END);
00667 bufPos = (Guint)ftell(f);
00668 #endif
00669 }
00670 bufPtr = bufEnd = buf;
00671 }
00672
00673 void FileStream::moveStart(int delta) {
00674 start += delta;
00675 bufPtr = bufEnd = buf;
00676 bufPos = start;
00677 }
00678
00679
00680
00681
00682
00683 MemStream::MemStream(char *bufA, Guint lengthA, Object *dictA):
00684 BaseStream(dictA) {
00685 buf = bufA;
00686 needFree = gFalse;
00687 length = lengthA;
00688 bufEnd = buf + length;
00689 bufPtr = buf;
00690 }
00691
00692 MemStream::~MemStream() {
00693 if (needFree) {
00694 gfree(buf);
00695 }
00696 }
00697
00698 Stream *MemStream::makeSubStream(Guint start, GBool limited,
00699 Guint lengthA, Object *dictA) {
00700 Guint newLength;
00701
00702 if (!limited || start + lengthA > length) {
00703 newLength = length - start;
00704 } else {
00705 newLength = lengthA;
00706 }
00707 return new MemStream(buf + start, newLength, dictA);
00708 }
00709
00710 void MemStream::reset() {
00711 bufPtr = buf;
00712 #ifndef NO_DECRYPTION
00713 if (decrypt) {
00714 decrypt->reset();
00715 }
00716 #endif
00717 }
00718
00719 void MemStream::close() {
00720 }
00721
00722 void MemStream::setPos(Guint pos, int dir) {
00723 if (dir >= 0) {
00724 if (pos > length) {
00725 bufPtr = bufEnd;
00726 } else {
00727 bufPtr = buf + pos;
00728 }
00729 } else {
00730 if (pos > length) {
00731 bufPtr = buf;
00732 } else {
00733 bufPtr = bufEnd - pos;
00734 }
00735 }
00736 }
00737
00738 void MemStream::moveStart(int delta) {
00739 buf += delta;
00740 bufPtr = buf;
00741 }
00742
00743 #ifndef NO_DECRYPTION
00744 void MemStream::doDecryption(Guchar *fileKey, int keyLength,
00745 int objNum, int objGen) {
00746 char *newBuf;
00747 char *p, *q;
00748
00749 this->BaseStream::doDecryption(fileKey, keyLength, objNum, objGen);
00750 if (decrypt) {
00751 newBuf = (char *)gmalloc(bufEnd - buf);
00752 for (p = buf, q = newBuf; p < bufEnd; ++p, ++q) {
00753 *q = (char)decrypt->decryptByte((Guchar)*p);
00754 }
00755 bufEnd = newBuf + (bufEnd - buf);
00756 bufPtr = newBuf + (bufPtr - buf);
00757 buf = newBuf;
00758 needFree = gTrue;
00759 }
00760 }
00761 #endif
00762
00763
00764
00765
00766
00767 EmbedStream::EmbedStream(Stream *strA, Object *dictA):
00768 BaseStream(dictA) {
00769 str = strA;
00770 }
00771
00772 EmbedStream::~EmbedStream() {
00773 }
00774
00775 Stream *EmbedStream::makeSubStream(Guint start, GBool limited,
00776 Guint length, Object *dictA) {
00777 error(-1, "Internal: called makeSubStream() on EmbedStream");
00778 return NULL;
00779 }
00780
00781 void EmbedStream::setPos(Guint pos, int dir) {
00782 error(-1, "Internal: called setPos() on EmbedStream");
00783 }
00784
00785 Guint EmbedStream::getStart() {
00786 error(-1, "Internal: called getStart() on EmbedStream");
00787 return 0;
00788 }
00789
00790 void EmbedStream::moveStart(int delta) {
00791 error(-1, "Internal: called moveStart() on EmbedStream");
00792 }
00793
00794
00795
00796
00797
00798 ASCIIHexStream::ASCIIHexStream(Stream *strA):
00799 FilterStream(strA) {
00800 buf = EOF;
00801 eof = gFalse;
00802 }
00803
00804 ASCIIHexStream::~ASCIIHexStream() {
00805 delete str;
00806 }
00807
00808 void ASCIIHexStream::reset() {
00809 str->reset();
00810 buf = EOF;
00811 eof = gFalse;
00812 }
00813
00814 int ASCIIHexStream::lookChar() {
00815 int c1, c2, x;
00816
00817 if (buf != EOF)
00818 return buf;
00819 if (eof) {
00820 buf = EOF;
00821 return EOF;
00822 }
00823 do {
00824 c1 = str->getChar();
00825 } while (isspace(c1));
00826 if (c1 == '>') {
00827 eof = gTrue;
00828 buf = EOF;
00829 return buf;
00830 }
00831 do {
00832 c2 = str->getChar();
00833 } while (isspace(c2));
00834 if (c2 == '>') {
00835 eof = gTrue;
00836 c2 = '0';
00837 }
00838 if (c1 >= '0' && c1 <= '9') {
00839 x = (c1 - '0') << 4;
00840 } else if (c1 >= 'A' && c1 <= 'F') {
00841 x = (c1 - 'A' + 10) << 4;
00842 } else if (c1 >= 'a' && c1 <= 'f') {
00843 x = (c1 - 'a' + 10) << 4;
00844 } else if (c1 == EOF) {
00845 eof = gTrue;
00846 x = 0;
00847 } else {
00848 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c1);
00849 x = 0;
00850 }
00851 if (c2 >= '0' && c2 <= '9') {
00852 x += c2 - '0';
00853 } else if (c2 >= 'A' && c2 <= 'F') {
00854 x += c2 - 'A' + 10;
00855 } else if (c2 >= 'a' && c2 <= 'f') {
00856 x += c2 - 'a' + 10;
00857 } else if (c2 == EOF) {
00858 eof = gTrue;
00859 x = 0;
00860 } else {
00861 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c2);
00862 }
00863 buf = x & 0xff;
00864 return buf;
00865 }
00866
00867 GString *ASCIIHexStream::getPSFilter(char *indent) {
00868 GString *s;
00869
00870 if (!(s = str->getPSFilter(indent))) {
00871 return NULL;
00872 }
00873 s->append(indent)->append("/ASCIIHexDecode filter\n");
00874 return s;
00875 }
00876
00877 GBool ASCIIHexStream::isBinary(GBool last) {
00878 return str->isBinary(gFalse);
00879 }
00880
00881
00882
00883
00884
00885 ASCII85Stream::ASCII85Stream(Stream *strA):
00886 FilterStream(strA) {
00887 index = n = 0;
00888 eof = gFalse;
00889 }
00890
00891 ASCII85Stream::~ASCII85Stream() {
00892 delete str;
00893 }
00894
00895 void ASCII85Stream::reset() {
00896 str->reset();
00897 index = n = 0;
00898 eof = gFalse;
00899 }
00900
00901 int ASCII85Stream::lookChar() {
00902 int k;
00903 Gulong t;
00904
00905 if (index >= n) {
00906 if (eof)
00907 return EOF;
00908 index = 0;
00909 do {
00910 c[0] = str->getChar();
00911 } while (c[0] == '\n' || c[0] == '\r');
00912 if (c[0] == '~' || c[0] == EOF) {
00913 eof = gTrue;
00914 n = 0;
00915 return EOF;
00916 } else if (c[0] == 'z') {
00917 b[0] = b[1] = b[2] = b[3] = 0;
00918 n = 4;
00919 } else {
00920 for (k = 1; k < 5; ++k) {
00921 do {
00922 c[k] = str->getChar();
00923 } while (c[k] == '\n' || c[k] == '\r');
00924 if (c[k] == '~' || c[k] == EOF)
00925 break;
00926 }
00927 n = k - 1;
00928 if (k < 5 && (c[k] == '~' || c[k] == EOF)) {
00929 for (++k; k < 5; ++k)
00930 c[k] = 0x21 + 84;
00931 eof = gTrue;
00932 }
00933 t = 0;
00934 for (k = 0; k < 5; ++k)
00935 t = t * 85 + (c[k] - 0x21);
00936 for (k = 3; k >= 0; --k) {
00937 b[k] = (int)(t & 0xff);
00938 t >>= 8;
00939 }
00940 }
00941 }
00942 return b[index];
00943 }
00944
00945 GString *ASCII85Stream::getPSFilter(char *indent) {
00946 GString *s;
00947
00948 if (!(s = str->getPSFilter(indent))) {
00949 return NULL;
00950 }
00951 s->append(indent)->append("/ASCII85Decode filter\n");
00952 return s;
00953 }
00954
00955 GBool ASCII85Stream::isBinary(GBool last) {
00956 return str->isBinary(gFalse);
00957 }
00958
00959
00960
00961
00962
00963 LZWStream::LZWStream(Stream *strA, int predictor, int columns, int colors,
00964 int bits, int earlyA):
00965 FilterStream(strA) {
00966 if (predictor != 1) {
00967 pred = new StreamPredictor(this, predictor, columns, colors, bits);
00968 } else {
00969 pred = NULL;
00970 }
00971 early = earlyA;
00972 zPipe = NULL;
00973 bufPtr = bufEnd = buf;
00974 }
00975
00976 LZWStream::~LZWStream() {
00977 if (zPipe) {
00978 #ifdef HAVE_POPEN
00979 pclose(zPipe);
00980 #else
00981 fclose(zPipe);
00982 #endif
00983 zPipe = NULL;
00984 unlink(zName->getCString());
00985 delete zName;
00986 }
00987 if (pred) {
00988 delete pred;
00989 }
00990 delete str;
00991 }
00992
00993 int LZWStream::getChar() {
00994 if (pred) {
00995 return pred->getChar();
00996 }
00997 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
00998 }
00999
01000 int LZWStream::lookChar() {
01001 if (pred) {
01002 return pred->lookChar();
01003 }
01004 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff);
01005 }
01006
01007 int LZWStream::getRawChar() {
01008 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
01009 }
01010
01011 void LZWStream::reset() {
01012 FILE *f;
01013 GString *zCmd;
01014
01015
01016 if (zPipe) {
01017 #ifdef HAVE_POPEN
01018 pclose(zPipe);
01019 #else
01020 fclose(zPipe);
01021 #endif
01022 zPipe = NULL;
01023 unlink(zName->getCString());
01024 delete zName;
01025 }
01026
01027
01028
01029 #if __DJGPP__
01030 if (!setDJSYSFLAGS) {
01031 setenv("DJSYSFLAGS", "0x0002", 0);
01032 setDJSYSFLAGS = gTrue;
01033 }
01034 #endif
01035
01036
01037 if (!openTempFile(&zName, &f, "wb", ".Z")) {
01038 error(getPos(), "Couldn't create temporary file for LZW stream");
01039 return;
01040 }
01041 dumpFile(f);
01042 fclose(f);
01043
01044
01045 zCmd = new GString(uncompressCmd);
01046 zCmd->append(' ');
01047 zCmd->append(zName);
01048 #if defined(MACOS)
01049 long magicCookie;
01050
01051 OSErr err = OpenSITEngine(kUseExternalEngine, &magicCookie);
01052
01053 if (!err && magicCookie) {
01054
01055 if (GetSITEngineVersion(magicCookie) >= kFirstSupportedEngine) {
01056 FSSpec myFSS;
01057 Str255 pName;
01058 strcpy((char *)pName, zName->getCString());
01059 c2pstr((char *)pName);
01060 FSMakeFSSpec(0, 0, pName, &myFSS);
01061 short ftype = DetermineFileType(magicCookie, &myFSS);
01062 OSErr expandErr = ExpandFSSpec(magicCookie, ftype, &myFSS,
01063 NULL, NULL, kCreateFolderNever,
01064 kDeleteOriginal, kTextConvertSmart);
01065 }
01066 }
01067 #elif defined(HAVE_POPEN)
01068 if (!(zPipe = popen(zCmd->getCString(), POPEN_READ_MODE))) {
01069 error(getPos(), "Couldn't popen '%s'", zCmd->getCString());
01070 unlink(zName->getCString());
01071 delete zName;
01072 return;
01073 }
01074 #else // HAVE_POPEN
01075 if (!executeCommand(zCmd->getCString())) {
01076 error(getPos(), "Couldn't execute '%s'", zCmd->getCString());
01077 unlink(zName->getCString());
01078 delete zName;
01079 return;
01080 }
01081 zName->del(zName->getLength() - 2, 2);
01082 if (!(zPipe = fopen(zName->getCString(), "rb"))) {
01083 error(getPos(), "Couldn't open uncompress file '%s'", zName->getCString());
01084 unlink(zName->getCString());
01085 delete zName;
01086 return;
01087 }
01088 #endif // HAVE_POPEN
01089
01090
01091 delete zCmd;
01092
01093
01094 bufPtr = bufEnd = buf;
01095 }
01096
01097 void LZWStream::dumpFile(FILE *f) {
01098 int outCodeBits;
01099 int outBits;
01100 int outBuf[8];
01101 int outData;
01102 int inCode, outCode;
01103 int nextCode;
01104 GBool eof;
01105 GBool clear;
01106 GBool first;
01107 int i, j;
01108
01109 str->reset();
01110
01111
01112 fputc(0x1f, f);
01113 fputc(0x9d, f);
01114
01115
01116 fputc(0x8c, f);
01117
01118
01119 inCodeBits = 9;
01120 inputBuf = 0;
01121 inputBits = 0;
01122 eof = gFalse;
01123
01124
01125 outCodeBits = 9;
01126
01127
01128 first = gTrue;
01129 nextCode = 258;
01130
01131 clear = gFalse;
01132 do {
01133 for (i = 0; i < 8; ++i) {
01134
01135 if (nextCode + early > 0x1001) {
01136 inCode = 256;
01137
01138
01139 } else {
01140 do {
01141 inCode = getCode();
01142 if (inCode == EOF) {
01143 eof = gTrue;
01144 inCode = 0;
01145 }
01146 } while (first && inCode == 256);
01147 }
01148
01149
01150 if (inCode < 256) {
01151 outCode = inCode;
01152 } else if (inCode == 256) {
01153 outCode = 256;
01154 clear = gTrue;
01155 } else if (inCode == 257) {
01156 outCode = 0;
01157 eof = gTrue;
01158 } else {
01159 outCode = inCode - 1;
01160 }
01161 outBuf[i] = outCode;
01162
01163
01164 if (first)
01165 first = gFalse;
01166 else
01167 ++nextCode;
01168
01169
01170 if (nextCode + early == 0x200)
01171 inCodeBits = 10;
01172 else if (nextCode + early == 0x400) {
01173 inCodeBits = 11;
01174 } else if (nextCode + early == 0x800) {
01175 inCodeBits = 12;
01176 }
01177
01178
01179 if (eof)
01180 break;
01181 if (clear) {
01182 i = 8;
01183 break;
01184 }
01185 }
01186
01187
01188 outData = 0;
01189 outBits = 0;
01190 j = 0;
01191 while (j < i || outBits > 0) {
01192 if (outBits < 8 && j < i) {
01193 outData = outData | (outBuf[j++] << outBits);
01194 outBits += outCodeBits;
01195 }
01196 fputc(outData & 0xff, f);
01197 outData >>= 8;
01198 outBits -= 8;
01199 }
01200
01201
01202 if (nextCode - 1 == 512 ||
01203 nextCode - 1 == 1024 ||
01204 nextCode - 1 == 2048 ||
01205 nextCode - 1 == 4096) {
01206 outCodeBits = inCodeBits;
01207 }
01208
01209
01210 if (clear) {
01211 inCodeBits = 9;
01212 outCodeBits = 9;
01213 first = gTrue;
01214 nextCode = 258;
01215 clear = gFalse;
01216 }
01217 } while (!eof);
01218 }
01219
01220 int LZWStream::getCode() {
01221 int c;
01222 int code;
01223
01224 while (inputBits < inCodeBits) {
01225 if ((c = str->getChar()) == EOF)
01226 return EOF;
01227 inputBuf = (inputBuf << 8) | (c & 0xff);
01228 inputBits += 8;
01229 }
01230 code = (inputBuf >> (inputBits - inCodeBits)) & ((1 << inCodeBits) - 1);
01231 inputBits -= inCodeBits;
01232 return code;
01233 }
01234
01235 GBool LZWStream::fillBuf() {
01236 int n;
01237
01238 if (!zPipe)
01239 return gFalse;
01240 if ((n = fread(buf, 1, 256, zPipe)) < 256) {
01241 #ifdef HAVE_POPEN
01242 pclose(zPipe);
01243 #else
01244 fclose(zPipe);
01245 #endif
01246 zPipe = NULL;
01247 unlink(zName->getCString());
01248 delete zName;
01249 }
01250 bufPtr = buf;
01251 bufEnd = buf + n;
01252 return n > 0;
01253 }
01254
01255 GString *LZWStream::getPSFilter(char *indent) {
01256 GString *s;
01257
01258 if (pred) {
01259 return NULL;
01260 }
01261 if (!(s = str->getPSFilter(indent))) {
01262 return NULL;
01263 }
01264 s->append(indent)->append("/LZWDecode filter\n");
01265 return s;
01266 }
01267
01268 GBool LZWStream::isBinary(GBool last) {
01269 return str->isBinary(gTrue);
01270 }
01271
01272
01273
01274
01275
01276 RunLengthStream::RunLengthStream(Stream *strA):
01277 FilterStream(strA) {
01278 bufPtr = bufEnd = buf;
01279 eof = gFalse;
01280 }
01281
01282 RunLengthStream::~RunLengthStream() {
01283 delete str;
01284 }
01285
01286 void RunLengthStream::reset() {
01287 str->reset();
01288 bufPtr = bufEnd = buf;
01289 eof = gFalse;
01290 }
01291
01292 GString *RunLengthStream::getPSFilter(char *indent) {
01293 GString *s;
01294
01295 if (!(s = str->getPSFilter(indent))) {
01296 return NULL;
01297 }
01298 s->append(indent)->append("/RunLengthDecode filter\n");
01299 return s;
01300 }
01301
01302 GBool RunLengthStream::isBinary(GBool last) {
01303 return str->isBinary(gTrue);
01304 }
01305
01306 GBool RunLengthStream::fillBuf() {
01307 int c;
01308 int n, i;
01309
01310 if (eof)
01311 return gFalse;
01312 c = str->getChar();
01313 if (c == 0x80 || c == EOF) {
01314 eof = gTrue;
01315 return gFalse;
01316 }
01317 if (c < 0x80) {
01318 n = c + 1;
01319 for (i = 0; i < n; ++i)
01320 buf[i] = (char)str->getChar();
01321 } else {
01322 n = 0x101 - c;
01323 c = str->getChar();
01324 for (i = 0; i < n; ++i)
01325 buf[i] = (char)c;
01326 }
01327 bufPtr = buf;
01328 bufEnd = buf + n;
01329 return gTrue;
01330 }
01331
01332
01333
01334
01335
01336 CCITTFaxStream::CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA,
01337 GBool byteAlignA, int columnsA, int rowsA,
01338 GBool endOfBlockA, GBool blackA):
01339 FilterStream(strA) {
01340 encoding = encodingA;
01341 endOfLine = endOfLineA;
01342 byteAlign = byteAlignA;
01343 columns = columnsA;
01344 rows = rowsA;
01345 endOfBlock = endOfBlockA;
01346 black = blackA;
01347 refLine = (short *)gmalloc((columns + 3) * sizeof(short));
01348 codingLine = (short *)gmalloc((columns + 2) * sizeof(short));
01349
01350 eof = gFalse;
01351 row = 0;
01352 nextLine2D = encoding < 0;
01353 inputBits = 0;
01354 codingLine[0] = 0;
01355 codingLine[1] = refLine[2] = columns;
01356 a0 = 1;
01357
01358 buf = EOF;
01359 }
01360
01361 CCITTFaxStream::~CCITTFaxStream() {
01362 delete str;
01363 gfree(refLine);
01364 gfree(codingLine);
01365 }
01366
01367 void CCITTFaxStream::reset() {
01368 int n;
01369
01370 str->reset();
01371 eof = gFalse;
01372 row = 0;
01373 nextLine2D = encoding < 0;
01374 inputBits = 0;
01375 codingLine[0] = 0;
01376 codingLine[1] = refLine[2] = columns;
01377 a0 = 1;
01378 buf = EOF;
01379
01380
01381 if (endOfBlock) {
01382 if (lookBits(12) == 0x001) {
01383 eatBits(12);
01384 }
01385 } else {
01386 for (n = 0; n < 11 && lookBits(n) == 0; ++n) ;
01387 if (n == 11 && lookBits(12) == 0x001) {
01388 eatBits(12);
01389 }
01390 }
01391 if (encoding > 0) {
01392 nextLine2D = !lookBits(1);
01393 eatBits(1);
01394 }
01395 }
01396
01397 int CCITTFaxStream::lookChar() {
01398 short code1, code2, code3;
01399 int a0New;
01400 #if 0
01401 GBool err;
01402 #endif
01403 GBool gotEOL;
01404 int ret;
01405 int bits, i;
01406
01407
01408 if (eof && codingLine[a0] >= columns) {
01409 return EOF;
01410 }
01411
01412
01413 #if 0
01414 err = gFalse;
01415 #endif
01416 if (codingLine[a0] >= columns) {
01417
01418
01419 if (nextLine2D) {
01420 for (i = 0; codingLine[i] < columns; ++i)
01421 refLine[i] = codingLine[i];
01422 refLine[i] = refLine[i + 1] = columns;
01423 b1 = 1;
01424 a0New = codingLine[a0 = 0] = 0;
01425 do {
01426 code1 = getTwoDimCode();
01427 switch (code1) {
01428 case twoDimPass:
01429 if (refLine[b1] < columns) {
01430 a0New = refLine[b1 + 1];
01431 b1 += 2;
01432 }
01433 break;
01434 case twoDimHoriz:
01435 if ((a0 & 1) == 0) {
01436 code1 = code2 = 0;
01437 do {
01438 code1 += code3 = getWhiteCode();
01439 } while (code3 >= 64);
01440 do {
01441 code2 += code3 = getBlackCode();
01442 } while (code3 >= 64);
01443 } else {
01444 code1 = code2 = 0;
01445 do {
01446 code1 += code3 = getBlackCode();
01447 } while (code3 >= 64);
01448 do {
01449 code2 += code3 = getWhiteCode();
01450 } while (code3 >= 64);
01451 }
01452 codingLine[a0 + 1] = a0New + code1;
01453 ++a0;
01454 a0New = codingLine[a0 + 1] = codingLine[a0] + code2;
01455 ++a0;
01456 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
01457 b1 += 2;
01458 break;
01459 case twoDimVert0:
01460 a0New = codingLine[++a0] = refLine[b1];
01461 if (refLine[b1] < columns) {
01462 ++b1;
01463 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
01464 b1 += 2;
01465 }
01466 break;
01467 case twoDimVertR1:
01468 a0New = codingLine[++a0] = refLine[b1] + 1;
01469 if (refLine[b1] < columns) {
01470 ++b1;
01471 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
01472 b1 += 2;
01473 }
01474 break;
01475 case twoDimVertL1:
01476 a0New = codingLine[++a0] = refLine[b1] - 1;
01477 --b1;
01478 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
01479 b1 += 2;
01480 break;
01481 case twoDimVertR2:
01482 a0New = codingLine[++a0] = refLine[b1] + 2;
01483 if (refLine[b1] < columns) {
01484 ++b1;
01485 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
01486 b1 += 2;
01487 }
01488 break;
01489 case twoDimVertL2:
01490 a0New = codingLine[++a0] = refLine[b1] - 2;
01491 --b1;
01492 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
01493 b1 += 2;
01494 break;
01495 case twoDimVertR3:
01496 a0New = codingLine[++a0] = refLine[b1] + 3;
01497 if (refLine[b1] < columns) {
01498 ++b1;
01499 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
01500 b1 += 2;
01501 }
01502 break;
01503 case twoDimVertL3:
01504 a0New = codingLine[++a0] = refLine[b1] - 3;
01505 --b1;
01506 while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns)
01507 b1 += 2;
01508 break;
01509 case EOF:
01510 eof = gTrue;
01511 codingLine[a0 = 0] = columns;
01512 return EOF;
01513 default:
01514 error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1);
01515 #if 0
01516 err = gTrue;
01517 break;
01518 #else
01519 eof = gTrue;
01520 return EOF;
01521 #endif
01522 }
01523 } while (codingLine[a0] < columns);
01524
01525
01526 } else {
01527 codingLine[a0 = 0] = 0;
01528 while (1) {
01529 code1 = 0;
01530 do {
01531 code1 += code3 = getWhiteCode();
01532 } while (code3 >= 64);
01533 codingLine[a0+1] = codingLine[a0] + code1;
01534 ++a0;
01535 if (codingLine[a0] >= columns)
01536 break;
01537 code2 = 0;
01538 do {
01539 code2 += code3 = getBlackCode();
01540 } while (code3 >= 64);
01541 codingLine[a0+1] = codingLine[a0] + code2;
01542 ++a0;
01543 if (codingLine[a0] >= columns)
01544 break;
01545 }
01546 }
01547
01548 if (codingLine[a0] != columns) {
01549 error(getPos(), "CCITTFax row is wrong length (%d)", codingLine[a0]);
01550 #if 0
01551 err = gTrue;
01552 #endif
01553 }
01554
01555
01556 if (byteAlign) {
01557 inputBits &= ~7;
01558 }
01559
01560
01561 gotEOL = gFalse;
01562 if (!endOfBlock && row == rows - 1) {
01563 eof = gTrue;
01564 } else {
01565 code1 = lookBits(12);
01566 while (code1 == 0) {
01567 eatBits(1);
01568 code1 = lookBits(12);
01569 }
01570 if (code1 == 0x001) {
01571 eatBits(12);
01572 gotEOL = gTrue;
01573 } else if (code1 == EOF) {
01574 eof = gTrue;
01575 }
01576 }
01577
01578
01579 if (!eof && encoding > 0) {
01580 nextLine2D = !lookBits(1);
01581 eatBits(1);
01582 }
01583
01584
01585 if (endOfBlock && gotEOL) {
01586 code1 = lookBits(12);
01587 if (code1 == 0x001) {
01588 eatBits(12);
01589 if (encoding > 0) {
01590 lookBits(1);
01591 eatBits(1);
01592 }
01593 if (encoding >= 0) {
01594 for (i = 0; i < 4; ++i) {
01595 code1 = lookBits(12);
01596 if (code1 != 0x001) {
01597 error(getPos(), "Bad RTC code in CCITTFax stream");
01598 }
01599 eatBits(12);
01600 if (encoding > 0) {
01601 lookBits(1);
01602 eatBits(1);
01603 }
01604 }
01605 }
01606 eof = gTrue;
01607 }
01608 }
01609
01610 #if 0
01611
01612
01613
01614
01615 else if (err) {
01616 do {
01617 if (code1 == EOF) {
01618 eof = gTrue;
01619 return EOF;
01620 }
01621 eatBits(1);
01622 code1 = look13Bits();
01623 } while ((code1 >> 1) != 0x001);
01624 eatBits(12);
01625 codingLine[++a0] = columns;
01626 if (encoding > 0) {
01627 eatBits(1);
01628 nextLine2D = !(code1 & 1);
01629 }
01630 }
01631 #endif
01632
01633 a0 = 0;
01634 outputBits = codingLine[1] - codingLine[0];
01635 if (outputBits == 0) {
01636 a0 = 1;
01637 outputBits = codingLine[2] - codingLine[1];
01638 }
01639
01640 ++row;
01641 }
01642
01643
01644 if (outputBits >= 8) {
01645 ret = ((a0 & 1) == 0) ? 0xff : 0x00;
01646 if ((outputBits -= 8) == 0) {
01647 ++a0;
01648 if (codingLine[a0] < columns) {
01649 outputBits = codingLine[a0 + 1] - codingLine[a0];
01650 }
01651 }
01652 } else {
01653 bits = 8;
01654 ret = 0;
01655 do {
01656 if (outputBits > bits) {
01657 i = bits;
01658 bits = 0;
01659 if ((a0 & 1) == 0) {
01660 ret |= 0xff >> (8 - i);
01661 }
01662 outputBits -= i;
01663 } else {
01664 i = outputBits;
01665 bits -= outputBits;
01666 if ((a0 & 1) == 0) {
01667 ret |= (0xff >> (8 - i)) << bits;
01668 }
01669 outputBits = 0;
01670 ++a0;
01671 if (codingLine[a0] < columns) {
01672 outputBits = codingLine[a0 + 1] - codingLine[a0];
01673 }
01674 }
01675 } while (bits > 0 && codingLine[a0] < columns);
01676 }
01677 buf = black ? (ret ^ 0xff) : ret;
01678 return buf;
01679 }
01680
01681 short CCITTFaxStream::getTwoDimCode() {
01682 short code;
01683 CCITTCode *p;
01684 int n;
01685
01686 code = 0;
01687 if (endOfBlock) {
01688 code = lookBits(7);
01689 p = &twoDimTab1[code];
01690 if (p->bits > 0) {
01691 eatBits(p->bits);
01692 return p->n;
01693 }
01694 } else {
01695 for (n = 1; n <= 7; ++n) {
01696 code = lookBits(n);
01697 if (n < 7) {
01698 code <<= 7 - n;
01699 }
01700 p = &twoDimTab1[code];
01701 if (p->bits == n) {
01702 eatBits(n);
01703 return p->n;
01704 }
01705 }
01706 }
01707 error(getPos(), "Bad two dim code (%04x) in CCITTFax stream", code);
01708 return EOF;
01709 }
01710
01711 short CCITTFaxStream::getWhiteCode() {
01712 short code;
01713 CCITTCode *p;
01714 int n;
01715
01716 code = 0;
01717 if (endOfBlock) {
01718 code = lookBits(12);
01719 if ((code >> 5) == 0) {
01720 p = &whiteTab1[code];
01721 } else {
01722 p = &whiteTab2[code >> 3];
01723 }
01724 if (p->bits > 0) {
01725 eatBits(p->bits);
01726 return p->n;
01727 }
01728 } else {
01729 for (n = 1; n <= 9; ++n) {
01730 code = lookBits(n);
01731 if (n < 9) {
01732 code <<= 9 - n;
01733 }
01734 p = &whiteTab2[code];
01735 if (p->bits == n) {
01736 eatBits(n);
01737 return p->n;
01738 }
01739 }
01740 for (n = 11; n <= 12; ++n) {
01741 code = lookBits(n);
01742 if (n < 12) {
01743 code <<= 12 - n;
01744 }
01745 p = &whiteTab1[code];
01746 if (p->bits == n) {
01747 eatBits(n);
01748 return p->n;
01749 }
01750 }
01751 }
01752 error(getPos(), "Bad white code (%04x) in CCITTFax stream", code);
01753
01754
01755 eatBits(1);
01756 return 1;
01757 }
01758
01759 short CCITTFaxStream::getBlackCode() {
01760 short code;
01761 CCITTCode *p;
01762 int n;
01763
01764 code = 0;
01765 if (endOfBlock) {
01766 code = lookBits(13);
01767 if ((code >> 7) == 0) {
01768 p = &blackTab1[code];
01769 } else if ((code >> 9) == 0) {
01770 p = &blackTab2[(code >> 1) - 64];
01771 } else {
01772 p = &blackTab3[code >> 7];
01773 }
01774 if (p->bits > 0) {
01775 eatBits(p->bits);
01776 return p->n;
01777 }
01778 } else {
01779 for (n = 2; n <= 6; ++n) {
01780 code = lookBits(n);
01781 if (n < 6) {
01782 code <<= 6 - n;
01783 }
01784 p = &blackTab3[code];
01785 if (p->bits == n) {
01786 eatBits(n);
01787 return p->n;
01788 }
01789 }
01790 for (n = 7; n <= 12; ++n) {
01791 code = lookBits(n);
01792 if (n < 12) {
01793 code <<= 12 - n;
01794 }
01795 if (code >= 64) {
01796 p = &blackTab2[code - 64];
01797 if (p->bits == n) {
01798 eatBits(n);
01799 return p->n;
01800 }
01801 }
01802 }
01803 for (n = 10; n <= 13; ++n) {
01804 code = lookBits(n);
01805 if (n < 13) {
01806 code <<= 13 - n;
01807 }
01808 p = &blackTab1[code];
01809 if (p->bits == n) {
01810 eatBits(n);
01811 return p->n;
01812 }
01813 }
01814 }
01815 error(getPos(), "Bad black code (%04x) in CCITTFax stream", code);
01816
01817
01818 eatBits(1);
01819 return 1;
01820 }
01821
01822 short CCITTFaxStream::lookBits(int n) {
01823 int c;
01824
01825 while (inputBits < n) {
01826 if ((c = str->getChar()) == EOF) {
01827 if (inputBits == 0) {
01828 return EOF;
01829 }
01830
01831
01832
01833
01834 return (inputBuf << (n - inputBits)) & (0xffff >> (16 - n));
01835 }
01836 inputBuf = (inputBuf << 8) + c;
01837 inputBits += 8;
01838 }
01839 return (inputBuf >> (inputBits - n)) & (0xffff >> (16 - n));
01840 }
01841
01842 GString *CCITTFaxStream::getPSFilter(char *indent) {
01843 GString *s;
01844 char s1[50];
01845
01846 if (!(s = str->getPSFilter(indent))) {
01847 return NULL;
01848 }
01849 s->append(indent)->append("<< ");
01850 if (encoding != 0) {
01851 sprintf(s1, "/K %d ", encoding);
01852 s->append(s1);
01853 }
01854 if (endOfLine) {
01855 s->append("/EndOfLine true ");
01856 }
01857 if (byteAlign) {
01858 s->append("/EncodedByteAlign true ");
01859 }
01860 sprintf(s1, "/Columns %d ", columns);
01861 s->append(s1);
01862 if (rows != 0) {
01863 sprintf(s1, "/Rows %d ", rows);
01864 s->append(s1);
01865 }
01866 if (!endOfBlock) {
01867 s->append("/EndOfBlock false ");
01868 }
01869 if (black) {
01870 s->append("/BlackIs1 true ");
01871 }
01872 s->append(">> /CCITTFaxDecode filter\n");
01873 return s;
01874 }
01875
01876 GBool CCITTFaxStream::isBinary(GBool last) {
01877 return str->isBinary(gTrue);
01878 }
01879
01880
01881
01882
01883
01884
01885 #ifndef FP_IDCT
01886 #define dctCos1 4017 // cos(pi/16)
01887 #define dctSin1 799 // sin(pi/16)
01888 #define dctCos3 3406 // cos(3*pi/16)
01889 #define dctSin3 2276 // sin(3*pi/16)
01890 #define dctCos6 1567 // cos(6*pi/16)
01891 #define dctSin6 3784 // sin(6*pi/16)
01892 #define dctSqrt2 5793 // sqrt(2)
01893 #define dctSqrt1d2 2896 // sqrt(2) / 2
01894 #endif
01895
01896
01897 #ifdef FP_IDCT
01898 #define dctCos1 0.98078528 // cos(pi/16)
01899 #define dctSin1 0.19509032 // sin(pi/16)
01900 #define dctCos3 0.83146961 // cos(3*pi/16)
01901 #define dctSin3 0.55557023 // sin(3*pi/16)
01902 #define dctCos6 0.38268343 // cos(6*pi/16)
01903 #define dctSin6 0.92387953 // sin(6*pi/16)
01904 #define dctSqrt2 1.41421356 // sqrt(2)
01905 #define dctSqrt1d2 0.70710678 // sqrt(2) / 2
01906 #endif
01907
01908
01909 #define dctCrToR 91881 // 1.4020
01910 #define dctCbToG -22553 // -0.3441363
01911 #define dctCrToG -46802 // -0.71413636
01912 #define dctCbToB 116130 // 1.772
01913
01914
01915 #define dctClipOffset 256
01916 static Guchar dctClip[768];
01917 static int dctClipInit = 0;
01918
01919
01920 static int dctZigZag[64] = {
01921 0,
01922 1, 8,
01923 16, 9, 2,
01924 3, 10, 17, 24,
01925 32, 25, 18, 11, 4,
01926 5, 12, 19, 26, 33, 40,
01927 48, 41, 34, 27, 20, 13, 6,
01928 7, 14, 21, 28, 35, 42, 49, 56,
01929 57, 50, 43, 36, 29, 22, 15,
01930 23, 30, 37, 44, 51, 58,
01931 59, 52, 45, 38, 31,
01932 39, 46, 53, 60,
01933 61, 54, 47,
01934 55, 62,
01935 63
01936 };
01937
01938 DCTStream::DCTStream(Stream *strA):
01939 FilterStream(strA) {
01940 int i, j;
01941
01942 width = height = 0;
01943 mcuWidth = mcuHeight = 0;
01944 numComps = 0;
01945 comp = 0;
01946 x = y = dy = 0;
01947 for (i = 0; i < 4; ++i)
01948 for (j = 0; j < 32; ++j)
01949 rowBuf[i][j] = NULL;
01950
01951 if (!dctClipInit) {
01952 for (i = -256; i < 0; ++i)
01953 dctClip[dctClipOffset + i] = 0;
01954 for (i = 0; i < 256; ++i)
01955 dctClip[dctClipOffset + i] = i;
01956 for (i = 256; i < 512; ++i)
01957 dctClip[dctClipOffset + i] = 255;
01958 dctClipInit = 1;
01959 }
01960 }
01961
01962 DCTStream::~DCTStream() {
01963 int i, j;
01964
01965 delete str;
01966 for (i = 0; i < numComps; ++i)
01967 for (j = 0; j < mcuHeight; ++j)
01968 gfree(rowBuf[i][j]);
01969 }
01970
01971 void DCTStream::reset() {
01972 str->reset();
01973 if (!readHeader()) {
01974 y = height;
01975 return;
01976 }
01977 restartMarker = 0xd0;
01978 restart();
01979 }
01980
01981 int DCTStream::getChar() {
01982 int c;
01983
01984 c = lookChar();
01985 if (c == EOF)
01986 return EOF;
01987 if (++comp == numComps) {
01988 comp = 0;
01989 if (++x == width) {
01990 x = 0;
01991 ++y;
01992 ++dy;
01993 }
01994 }
01995 if (y == height)
01996 readTrailer();
01997 return c;
01998 }
01999
02000 int DCTStream::lookChar() {
02001 if (y >= height)
02002 return EOF;
02003 if (dy >= mcuHeight) {
02004 if (!readMCURow()) {
02005 y = height;
02006 return EOF;
02007 }
02008 comp = 0;
02009 x = 0;
02010 dy = 0;
02011 }
02012 return rowBuf[comp][dy][x];
02013 }
02014
02015 void DCTStream::restart() {
02016 int i;
02017
02018 inputBits = 0;
02019 restartCtr = restartInterval;
02020 for (i = 0; i < numComps; ++i)
02021 compInfo[i].prevDC = 0;
02022 }
02023
02024 GBool DCTStream::readMCURow() {
02025 Guchar data[64];
02026 Guchar *p1, *p2;
02027 int pY, pCb, pCr, pR, pG, pB;
02028 int h, v, horiz, vert, hSub, vSub;
02029 int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i;
02030 int c;
02031
02032 for (x1 = 0; x1 < width; x1 += mcuWidth) {
02033
02034
02035 if (restartInterval > 0 && restartCtr == 0) {
02036 c = readMarker();
02037 if (c != restartMarker) {
02038 error(getPos(), "Bad DCT data: incorrect restart marker");
02039 return gFalse;
02040 }
02041 if (++restartMarker == 0xd8)
02042 restartMarker = 0xd0;
02043 restart();
02044 }
02045
02046
02047 for (cc = 0; cc < numComps; ++cc) {
02048 h = compInfo[cc].hSample;
02049 v = compInfo[cc].vSample;
02050 horiz = mcuWidth / h;
02051 vert = mcuHeight / v;
02052 hSub = horiz / 8;
02053 vSub = vert / 8;
02054 for (y2 = 0; y2 < mcuHeight; y2 += vert) {
02055 for (x2 = 0; x2 < mcuWidth; x2 += horiz) {
02056 if (!readDataUnit(&dcHuffTables[compInfo[cc].dcHuffTable],
02057 &acHuffTables[compInfo[cc].acHuffTable],
02058 quantTables[compInfo[cc].quantTable],
02059 &compInfo[cc].prevDC,
02060 data))
02061 return gFalse;
02062 if (hSub == 1 && vSub == 1) {
02063 for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) {
02064 p1 = &rowBuf[cc][y2+y3][x1+x2];
02065 p1[0] = data[i];
02066 p1[1] = data[i+1];
02067 p1[2] = data[i+2];
02068 p1[3] = data[i+3];
02069 p1[4] = data[i+4];
02070 p1[5] = data[i+5];
02071 p1[6] = data[i+6];
02072 p1[7] = data[i+7];
02073 }
02074 } else if (hSub == 2 && vSub == 2) {
02075 for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) {
02076 p1 = &rowBuf[cc][y2+y3][x1+x2];
02077 p2 = &rowBuf[cc][y2+y3+1][x1+x2];
02078 p1[0] = p1[1] = p2[0] = p2[1] = data[i];
02079 p1[2] = p1[3] = p2[2] = p2[3] = data[i+1];
02080 p1[4] = p1[5] = p2[4] = p2[5] = data[i+2];
02081 p1[6] = p1[7] = p2[6] = p2[7] = data[i+3];
02082 p1[8] = p1[9] = p2[8] = p2[9] = data[i+4];
02083 p1[10] = p1[11] = p2[10] = p2[11] = data[i+5];
02084 p1[12] = p1[13] = p2[12] = p2[13] = data[i+6];
02085 p1[14] = p1[15] = p2[14] = p2[15] = data[i+7];
02086 }
02087 } else {
02088 i = 0;
02089 for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) {
02090 for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) {
02091 for (y5 = 0; y5 < vSub; ++y5)
02092 for (x5 = 0; x5 < hSub; ++x5)
02093 rowBuf[cc][y2+y4+y5][x1+x2+x4+x5] = data[i];
02094 ++i;
02095 }
02096 }
02097 }
02098 }
02099 }
02100 }
02101 --restartCtr;
02102
02103
02104 if (colorXform) {
02105
02106 if (numComps == 3) {
02107 for (y2 = 0; y2 < mcuHeight; ++y2) {
02108 for (x2 = 0; x2 < mcuWidth; ++x2) {
02109 pY = rowBuf[0][y2][x1+x2];
02110 pCb = rowBuf[1][y2][x1+x2] - 128;
02111 pCr = rowBuf[2][y2][x1+x2] - 128;
02112 pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
02113 rowBuf[0][y2][x1+x2] = dctClip[dctClipOffset + pR];
02114 pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
02115 rowBuf[1][y2][x1+x2] = dctClip[dctClipOffset + pG];
02116 pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
02117 rowBuf[2][y2][x1+x2] = dctClip[dctClipOffset + pB];
02118 }
02119 }
02120
02121 } else if (numComps == 4) {
02122 for (y2 = 0; y2 < mcuHeight; ++y2) {
02123 for (x2 = 0; x2 < mcuWidth; ++x2) {
02124 pY = rowBuf[0][y2][x1+x2];
02125 pCb = rowBuf[1][y2][x1+x2] - 128;
02126 pCr = rowBuf[2][y2][x1+x2] - 128;
02127 pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16;
02128 rowBuf[0][y2][x1+x2] = 255 - dctClip[dctClipOffset + pR];
02129 pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16;
02130 rowBuf[1][y2][x1+x2] = 255 - dctClip[dctClipOffset + pG];
02131 pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16;
02132 rowBuf[2][y2][x1+x2] = 255 - dctClip[dctClipOffset + pB];
02133 }
02134 }
02135 }
02136 }
02137 }
02138 return gTrue;
02139 }
02140
02141
02142
02143
02144
02145
02146
02147
02148 #ifndef FP_IDCT
02149 GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
02150 DCTHuffTable *acHuffTable,
02151 Guchar quantTable[64], int *prevDC,
02152 Guchar data[64]) {
02153 int tmp1[64];
02154 int v0, v1, v2, v3, v4, v5, v6, v7, t;
02155 int run, size, amp;
02156 int c;
02157 int i, j;
02158
02159
02160 size = readHuffSym(dcHuffTable);
02161 if (size == 9999)
02162 return gFalse;
02163 if (size > 0) {
02164 amp = readAmp(size);
02165 if (amp == 9999)
02166 return gFalse;
02167 } else {
02168 amp = 0;
02169 }
02170 tmp1[0] = (*prevDC += amp) * quantTable[0];
02171 for (i = 1; i < 64; ++i)
02172 tmp1[i] = 0;
02173 i = 1;
02174 while (i < 64) {
02175 run = 0;
02176 while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30)
02177 run += 0x10;
02178 if (c == 9999)
02179 return gFalse;
02180 if (c == 0x00) {
02181 break;
02182 } else {
02183 run += (c >> 4) & 0x0f;
02184 size = c & 0x0f;
02185 amp = readAmp(size);
02186 if (amp == 9999)
02187 return gFalse;
02188 i += run;
02189 j = dctZigZag[i++];
02190 tmp1[j] = amp * quantTable[j];
02191 }
02192 }
02193
02194
02195 for (i = 0; i < 64; i += 8) {
02196
02197
02198 v0 = (dctSqrt2 * tmp1[i+0] + 128) >> 8;
02199 v1 = (dctSqrt2 * tmp1[i+4] + 128) >> 8;
02200 v2 = tmp1[i+2];
02201 v3 = tmp1[i+6];
02202 v4 = (dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]) + 128) >> 8;
02203 v7 = (dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]) + 128) >> 8;
02204 v5 = tmp1[i+3] << 4;
02205 v6 = tmp1[i+5] << 4;
02206
02207
02208 t = (v0 - v1+ 1) >> 1;
02209 v0 = (v0 + v1 + 1) >> 1;
02210 v1 = t;
02211 t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8;
02212 v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8;
02213 v3 = t;
02214 t = (v4 - v6 + 1) >> 1;
02215 v4 = (v4 + v6 + 1) >> 1;
02216 v6 = t;
02217 t = (v7 + v5 + 1) >> 1;
02218 v5 = (v7 - v5 + 1) >> 1;
02219 v7 = t;
02220
02221
02222 t = (v0 - v3 + 1) >> 1;
02223 v0 = (v0 + v3 + 1) >> 1;
02224 v3 = t;
02225 t = (v1 - v2 + 1) >> 1;
02226 v1 = (v1 + v2 + 1) >> 1;
02227 v2 = t;
02228 t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
02229 v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
02230 v7 = t;
02231 t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
02232 v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
02233 v6 = t;
02234
02235
02236 tmp1[i+0] = v0 + v7;
02237 tmp1[i+7] = v0 - v7;
02238 tmp1[i+1] = v1 + v6;
02239 tmp1[i+6] = v1 - v6;
02240 tmp1[i+2] = v2 + v5;
02241 tmp1[i+5] = v2 - v5;
02242 tmp1[i+3] = v3 + v4;
02243 tmp1[i+4] = v3 - v4;
02244 }
02245
02246
02247 for (i = 0; i < 8; ++i) {
02248
02249
02250 v0 = (dctSqrt2 * tmp1[0*8+i] + 2048) >> 12;
02251 v1 = (dctSqrt2 * tmp1[4*8+i] + 2048) >> 12;
02252 v2 = tmp1[2*8+i];
02253 v3 = tmp1[6*8+i];
02254 v4 = (dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]) + 2048) >> 12;
02255 v7 = (dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]) + 2048) >> 12;
02256 v5 = tmp1[3*8+i];
02257 v6 = tmp1[5*8+i];
02258
02259
02260 t = (v0 - v1 + 1) >> 1;
02261 v0 = (v0 + v1 + 1) >> 1;
02262 v1 = t;
02263 t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12;
02264 v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12;
02265 v3 = t;
02266 t = (v4 - v6 + 1) >> 1;
02267 v4 = (v4 + v6 + 1) >> 1;
02268 v6 = t;
02269 t = (v7 + v5 + 1) >> 1;
02270 v5 = (v7 - v5 + 1) >> 1;
02271 v7 = t;
02272
02273
02274 t = (v0 - v3 + 1) >> 1;
02275 v0 = (v0 + v3 + 1) >> 1;
02276 v3 = t;
02277 t = (v1 - v2 + 1) >> 1;
02278 v1 = (v1 + v2 + 1) >> 1;
02279 v2 = t;
02280 t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12;
02281 v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12;
02282 v7 = t;
02283 t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12;
02284 v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12;
02285 v6 = t;
02286
02287
02288 tmp1[0*8+i] = v0 + v7;
02289 tmp1[7*8+i] = v0 - v7;
02290 tmp1[1*8+i] = v1 + v6;
02291 tmp1[6*8+i] = v1 - v6;
02292 tmp1[2*8+i] = v2 + v5;
02293 tmp1[5*8+i] = v2 - v5;
02294 tmp1[3*8+i] = v3 + v4;
02295 tmp1[4*8+i] = v3 - v4;
02296 }
02297
02298
02299 for (i = 0; i < 64; ++i)
02300 data[i] = dctClip[dctClipOffset + 128 + ((tmp1[i] + 8) >> 4)];
02301
02302 return gTrue;
02303 }
02304 #endif
02305
02306 #ifdef FP_IDCT
02307 GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable,
02308 DCTHuffTable *acHuffTable,
02309 Guchar quantTable[64], int *prevDC,
02310 Guchar data[64]) {
02311 fouble tmp1[64];
02312 fouble v0, v1, v2, v3, v4, v5, v6, v7, t;
02313 int run, size, amp;
02314 int c;
02315 int i, j;
02316
02317
02318 size = readHuffSym(dcHuffTable);
02319 if (size == 9999)
02320 return gFalse;
02321 if (size > 0) {
02322 amp = readAmp(size);
02323 if (amp == 9999)
02324 return gFalse;
02325 } else {
02326 amp = 0;
02327 }
02328 tmp1[0] = (*prevDC += amp) * quantTable[0];
02329 for (i = 1; i < 64; ++i)
02330 tmp1[i] = 0;
02331 i = 1;
02332 while (i < 64) {
02333 run = 0;
02334 while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30)
02335 run += 0x10;
02336 if (c == 9999)
02337 return gFalse;
02338 if (c == 0x00) {
02339 break;
02340 } else {
02341 run += (c >> 4) & 0x0f;
02342 size = c & 0x0f;
02343 amp = readAmp(size);
02344 if (amp == 9999)
02345 return gFalse;
02346 i += run;
02347 j = dctZigZag[i++];
02348 tmp1[j] = amp * quantTable[j];
02349 }
02350 }
02351
02352
02353 for (i = 0; i < 64; i += 8) {
02354
02355
02356 v0 = dctSqrt2 * tmp1[i+0];
02357 v1 = dctSqrt2 * tmp1[i+4];
02358 v2 = tmp1[i+2];
02359 v3 = tmp1[i+6];
02360 v4 = dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]);
02361 v7 = dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]);
02362 v5 = tmp1[i+3];
02363 v6 = tmp1[i+5];
02364
02365
02366 t = 0.5 * (v0 - v1);
02367 v0 = 0.5 * (v0 + v1);
02368 v1 = t;
02369 t = v2 * dctSin6 + v3 * dctCos6;
02370 v2 = v2 * dctCos6 - v3 * dctSin6;
02371 v3 = t;
02372 t = 0.5 * (v4 - v6);
02373 v4 = 0.5 * (v4 + v6);
02374 v6 = t;
02375 t = 0.5 * (v7 + v5);
02376 v5 = 0.5 * (v7 - v5);
02377 v7 = t;
02378
02379
02380 t = 0.5 * (v0 - v3);
02381 v0 = 0.5 * (v0 + v3);
02382 v3 = t;
02383 t = 0.5 * (v1 - v2);
02384 v1 = 0.5 * (v1 + v2);
02385 v2 = t;
02386 t = v4 * dctSin3 + v7 * dctCos3;
02387 v4 = v4 * dctCos3 - v7 * dctSin3;
02388 v7 = t;
02389 t = v5 * dctSin1 + v6 * dctCos1;
02390 v5 = v5 * dctCos1 - v6 * dctSin1;
02391 v6 = t;
02392
02393
02394 tmp1[i+0] = v0 + v7;
02395 tmp1[i+7] = v0 - v7;
02396 tmp1[i+1] = v1 + v6;
02397 tmp1[i+6] = v1 - v6;
02398 tmp1[i+2] = v2 + v5;
02399 tmp1[i+5] = v2 - v5;
02400 tmp1[i+3] = v3 + v4;
02401 tmp1[i+4] = v3 - v4;
02402 }
02403
02404
02405 for (i = 0; i < 8; ++i) {
02406
02407
02408 v0 = dctSqrt2 * tmp1[0*8+i];
02409 v1 = dctSqrt2 * tmp1[4*8+i];
02410 v2 = tmp1[2*8+i];
02411 v3 = tmp1[6*8+i];
02412 v4 = dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]);
02413 v7 = dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]);
02414 v5 = tmp1[3*8+i];
02415 v6 = tmp1[5*8+i];
02416
02417
02418 t = 0.5 * (v0 - v1);
02419 v0 = 0.5 * (v0 + v1);
02420 v1 = t;
02421 t = v2 * dctSin6 + v3 * dctCos6;
02422 v2 = v2 * dctCos6 - v3 * dctSin6;
02423 v3 = t;
02424 t = 0.5 * (v4 - v6);
02425 v4 = 0.5 * (v4 + v6);
02426 v6 = t;
02427 t = 0.5 * (v7 + v5);
02428 v5 = 0.5 * (v7 - v5);
02429 v7 = t;
02430
02431
02432 t = 0.5 * (v0 - v3);
02433 v0 = 0.5 * (v0 + v3);
02434 v3 = t;
02435 t = 0.5 * (v1 - v2);
02436 v1 = 0.5 * (v1 + v2);
02437 v2 = t;
02438 t = v4 * dctSin3 + v7 * dctCos3;
02439 v4 = v4 * dctCos3 - v7 * dctSin3;
02440 v7 = t;
02441 t = v5 * dctSin1 + v6 * dctCos1;
02442 v5 = v5 * dctCos1 - v6 * dctSin1;
02443 v6 = t;
02444
02445
02446 tmp1[0*8+i] = v0 + v7;
02447 tmp1[7*8+i] = v0 - v7;
02448 tmp1[1*8+i] = v1 + v6;
02449 tmp1[6*8+i] = v1 - v6;
02450 tmp1[2*8+i] = v2 + v5;
02451 tmp1[5*8+i] = v2 - v5;
02452 tmp1[3*8+i] = v3 + v4;
02453 tmp1[4*8+i] = v3 - v4;
02454 }
02455
02456
02457 for (i = 0; i < 64; ++i)
02458 data[i] = dctClip[dctClipOffset + (int)(tmp1[i] + 128.5)];
02459
02460 return gTrue;
02461 }
02462 #endif
02463
02464 int DCTStream::readHuffSym(DCTHuffTable *table) {
02465 Gushort code;
02466 int bit;
02467 int codeBits;
02468
02469 code = 0;
02470 codeBits = 0;
02471 do {
02472
02473 if ((bit = readBit()) == EOF)
02474 return 9999;
02475 code = (code << 1) + bit;
02476 ++codeBits;
02477
02478
02479 if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) {
02480 code -= table->firstCode[codeBits];
02481 return table->sym[table->firstSym[codeBits] + code];
02482 }
02483 } while (codeBits < 16);
02484
02485 error(getPos(), "Bad Huffman code in DCT stream");
02486 return 9999;
02487 }
02488
02489 int DCTStream::readAmp(int size) {
02490 int amp, bit;
02491 int bits;
02492
02493 amp = 0;
02494 for (bits = 0; bits < size; ++bits) {
02495 if ((bit = readBit()) == EOF)
02496 return 9999;
02497 amp = (amp << 1) + bit;
02498 }
02499 if (amp < (1 << (size - 1)))
02500 amp -= (1 << size) - 1;
02501 return amp;
02502 }
02503
02504 int DCTStream::readBit() {
02505 int bit;
02506 int c, c2;
02507
02508 if (inputBits == 0) {
02509 if ((c = str->getChar()) == EOF)
02510 return EOF;
02511 if (c == 0xff) {
02512 do {
02513 c2 = str->getChar();
02514 } while (c2 == 0xff);
02515 if (c2 != 0x00) {
02516 error(getPos(), "Bad DCT data: missing 00 after ff");
02517 return EOF;
02518 }
02519 }
02520 inputBuf = c;
02521 inputBits = 8;
02522 }
02523 bit = (inputBuf >> (inputBits - 1)) & 1;
02524 --inputBits;
02525 return bit;
02526 }
02527
02528 GBool DCTStream::readHeader() {
02529 GBool doScan;
02530 int minHSample, minVSample;
02531 int bufWidth;
02532 int n;
02533 int c = 0;
02534 int i, j;
02535
02536 width = height = 0;
02537 numComps = 0;
02538 numQuantTables = 0;
02539 numDCHuffTables = 0;
02540 numACHuffTables = 0;
02541 colorXform = 0;
02542 gotAdobeMarker = gFalse;
02543 restartInterval = 0;
02544
02545
02546 doScan = gFalse;
02547 while (!doScan) {
02548 c = readMarker();
02549 switch (c) {
02550 case 0xc0:
02551 if (!readFrameInfo())
02552 return gFalse;
02553 break;
02554 case 0xc4:
02555 if (!readHuffmanTables())
02556 return gFalse;
02557 break;
02558 case 0xd8:
02559 break;
02560 case 0xda:
02561 if (!readScanInfo())
02562 return gFalse;
02563 doScan = gTrue;
02564 break;
02565 case 0xdb:
02566 if (!readQuantTables())
02567 return gFalse;
02568 break;
02569 case 0xdd:
02570 if (!readRestartInterval())
02571 return gFalse;
02572 break;
02573 case 0xee:
02574 if (!readAdobeMarker())
02575 return gFalse;
02576 break;
02577 case EOF:
02578 error(getPos(), "Bad DCT header");
02579 return gFalse;
02580 default:
02581
02582 if (c >= 0xe0) {
02583 n = read16() - 2;
02584 for (i = 0; i < n; ++i)
02585 str->getChar();
02586 } else {
02587 error(getPos(), "Unknown DCT marker <%02x>", c);
02588 return gFalse;
02589 }
02590 break;
02591 }
02592 }
02593
02594
02595 mcuWidth = minHSample = compInfo[0].hSample;
02596 mcuHeight = minVSample = compInfo[0].vSample;
02597 for (i = 1; i < numComps; ++i) {
02598 if (compInfo[i].hSample < minHSample)
02599 minHSample = compInfo[i].hSample;
02600 if (compInfo[i].vSample < minVSample)
02601 minVSample = compInfo[i].vSample;
02602 if (compInfo[i].hSample > mcuWidth)
02603 mcuWidth = compInfo[i].hSample;
02604 if (compInfo[i].vSample > mcuHeight)
02605 mcuHeight = compInfo[i].vSample;
02606 }
02607 for (i = 0; i < numComps; ++i) {
02608 compInfo[i].hSample /= minHSample;
02609 compInfo[i].vSample /= minVSample;
02610 }
02611 mcuWidth = (mcuWidth / minHSample) * 8;
02612 mcuHeight = (mcuHeight / minVSample) * 8;
02613
02614
02615 bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
02616 for (i = 0; i < numComps; ++i)
02617 for (j = 0; j < mcuHeight; ++j)
02618 rowBuf[i][j] = (Guchar *)gmalloc(bufWidth * sizeof(Guchar));
02619
02620
02621 if (!gotAdobeMarker && numComps == 3) {
02622 if (compInfo[0].id == 1 && compInfo[1].id == 2 && compInfo[2].id == 3) {
02623 colorXform = 1;
02624 }
02625 }
02626
02627
02628 comp = 0;
02629 x = 0;
02630 y = 0;
02631 dy = mcuHeight;
02632
02633 return gTrue;
02634 }
02635
02636 GBool DCTStream::readFrameInfo() {
02637 int length;
02638 int prec;
02639 int i;
02640 int c;
02641
02642 length = read16() - 2;
02643 prec = str->getChar();
02644 height = read16();
02645 width = read16();
02646 numComps = str->getChar();
02647 length -= 6;
02648 if (prec != 8) {
02649 error(getPos(), "Bad DCT precision %d", prec);
02650 return gFalse;
02651 }
02652 for (i = 0; i < numComps; ++i) {
02653 compInfo[i].id = str->getChar();
02654 compInfo[i].inScan = gFalse;
02655 c = str->getChar();
02656 compInfo[i].hSample = (c >> 4) & 0x0f;
02657 compInfo[i].vSample = c & 0x0f;
02658 compInfo[i].quantTable = str->getChar();
02659 compInfo[i].dcHuffTable = 0;
02660 compInfo[i].acHuffTable = 0;
02661 }
02662 return gTrue;
02663 }
02664
02665 GBool DCTStream::readScanInfo() {
02666 int length;
02667 int scanComps, id, c;
02668 int i, j;
02669
02670 length = read16() - 2;
02671 scanComps = str->getChar();
02672 --length;
02673 if (length != 2 * scanComps + 3) {
02674 error(getPos(), "Bad DCT scan info block");
02675 return gFalse;
02676 }
02677 for (i = 0; i < scanComps; ++i) {
02678 id = str->getChar();
02679 for (j = 0; j < numComps; ++j) {
02680 if (id == compInfo[j].id)
02681 break;
02682 }
02683 if (j == numComps) {
02684 error(getPos(), "Bad DCT component ID in scan info block");
02685 return gFalse;
02686 }
02687 compInfo[j].inScan = gTrue;
02688 c = str->getChar();
02689 compInfo[j].dcHuffTable = (c >> 4) & 0x0f;
02690 compInfo[j].acHuffTable = c & 0x0f;
02691 }
02692 str->getChar();
02693 str->getChar();
02694 str->getChar();
02695 return gTrue;
02696 }
02697
02698 GBool DCTStream::readQuantTables() {
02699 int length;
02700 int i;
02701 int index;
02702
02703 length = read16() - 2;
02704 while (length > 0) {
02705 index = str->getChar();
02706 if ((index & 0xf0) || index >= 4) {
02707 error(getPos(), "Bad DCT quantization table");
02708 return gFalse;
02709 }
02710 if (index == numQuantTables)
02711 numQuantTables = index + 1;
02712 for (i = 0; i < 64; ++i)
02713 quantTables[index][dctZigZag[i]] = str->getChar();
02714 length -= 65;
02715 }
02716 return gTrue;
02717 }
02718
02719 GBool DCTStream::readHuffmanTables() {
02720 DCTHuffTable *tbl;
02721 int length;
02722 int index;
02723 Gushort code;
02724 Guchar sym;
02725 int i;
02726 int c;
02727
02728 length = read16() - 2;
02729 while (length > 0) {
02730 index = str->getChar();
02731 --length;
02732 if ((index & 0x0f) >= 4) {
02733 error(getPos(), "Bad DCT Huffman table");
02734 return gFalse;
02735 }
02736 if (index & 0x10) {
02737 index &= 0x0f;
02738 if (index >= numACHuffTables)
02739 numACHuffTables = index+1;
02740 tbl = &acHuffTables[index];
02741 } else {
02742 if (index >= numDCHuffTables)
02743 numDCHuffTables = index+1;
02744 tbl = &dcHuffTables[index];
02745 }
02746 sym = 0;
02747 code = 0;
02748 for (i = 1; i <= 16; ++i) {
02749 c = str->getChar();
02750 tbl->firstSym[i] = sym;
02751 tbl->firstCode[i] = code;
02752 tbl->numCodes[i] = c;
02753 sym += c;
02754 code = (code + c) << 1;
02755 }
02756 length -= 16;
02757 for (i = 0; i < sym; ++i)
02758 tbl->sym[i] = str->getChar();
02759 length -= sym;
02760 }
02761 return gTrue;
02762 }
02763
02764 GBool DCTStream::readRestartInterval() {
02765 int length;
02766
02767 length = read16();
02768 if (length != 4) {
02769 error(getPos(), "Bad DCT restart interval");
02770 return gFalse;
02771 }
02772 restartInterval = read16();
02773 return gTrue;
02774 }
02775
02776 GBool DCTStream::readAdobeMarker() {
02777 int length, i;
02778 char buf[12];
02779 int c;
02780
02781 length = read16();
02782 if (length != 14)
02783 goto err;
02784 for (i = 0; i < 12; ++i) {
02785 if ((c = str->getChar()) == EOF)
02786 goto err;
02787 buf[i] = c;
02788 }
02789 if (strncmp(buf, "Adobe", 5))
02790 goto err;
02791 colorXform = buf[11];
02792 gotAdobeMarker = gTrue;
02793 return gTrue;
02794
02795 err:
02796 error(getPos(), "Bad DCT Adobe APP14 marker");
02797 return gFalse;
02798 }
02799
02800 GBool DCTStream::readTrailer() {
02801 int c;
02802
02803 c = readMarker();
02804 if (c != 0xd9) {
02805 error(getPos(), "Bad DCT trailer");
02806 return gFalse;
02807 }
02808 return gTrue;
02809 }
02810
02811 int DCTStream::readMarker() {
02812 int c;
02813
02814 do {
02815 do {
02816 c = str->getChar();
02817 } while (c != 0xff);
02818 do {
02819 c = str->getChar();
02820 } while (c == 0xff);
02821 } while (c == 0x00);
02822 return c;
02823 }
02824
02825 int DCTStream::read16() {
02826 int c1, c2;
02827
02828 if ((c1 = str->getChar()) == EOF)
02829 return EOF;
02830 if ((c2 = str->getChar()) == EOF)
02831 return EOF;
02832 return (c1 << 8) + c2;
02833 }
02834
02835 GString *DCTStream::getPSFilter(char *indent) {
02836 GString *s;
02837
02838 if (!(s = str->getPSFilter(indent))) {
02839 return NULL;
02840 }
02841 s->append(indent)->append("<< >> /DCTDecode filter\n");
02842 return s;
02843 }
02844
02845 GBool DCTStream::isBinary(GBool last) {
02846 return str->isBinary(gTrue);
02847 }
02848
02849
02850
02851
02852
02853 int FlateStream::codeLenCodeMap[flateMaxCodeLenCodes] = {
02854 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
02855 };
02856
02857 FlateDecode FlateStream::lengthDecode[flateMaxLitCodes-257] = {
02858 {0, 3},
02859 {0, 4},
02860 {0, 5},
02861 {0, 6},
02862 {0, 7},
02863 {0, 8},
02864 {0, 9},
02865 {0, 10},
02866 {1, 11},
02867 {1, 13},
02868 {1, 15},
02869 {1, 17},
02870 {2, 19},
02871 {2, 23},
02872 {2, 27},
02873 {2, 31},
02874 {3, 35},
02875 {3, 43},
02876 {3, 51},
02877 {3, 59},
02878 {4, 67},
02879 {4, 83},
02880 {4, 99},
02881 {4, 115},
02882 {5, 131},
02883 {5, 163},
02884 {5, 195},
02885 {5, 227},
02886 {0, 258}
02887 };
02888
02889 FlateDecode FlateStream::distDecode[flateMaxDistCodes] = {
02890 { 0, 1},
02891 { 0, 2},
02892 { 0, 3},
02893 { 0, 4},
02894 { 1, 5},
02895 { 1, 7},
02896 { 2, 9},
02897 { 2, 13},
02898 { 3, 17},
02899 { 3, 25},
02900 { 4, 33},
02901 { 4, 49},
02902 { 5, 65},
02903 { 5, 97},
02904 { 6, 129},
02905 { 6, 193},
02906 { 7, 257},
02907 { 7, 385},
02908 { 8, 513},
02909 { 8, 769},
02910 { 9, 1025},
02911 { 9, 1537},
02912 {10, 2049},
02913 {10, 3073},
02914 {11, 4097},
02915 {11, 6145},
02916 {12, 8193},
02917 {12, 12289},
02918 {13, 16385},
02919 {13, 24577}
02920 };
02921
02922 FlateStream::FlateStream(Stream *strA, int predictor, int columns,
02923 int colors, int bits):
02924 FilterStream(strA) {
02925 if (predictor != 1) {
02926 pred = new StreamPredictor(this, predictor, columns, colors, bits);
02927 } else {
02928 pred = NULL;
02929 }
02930 }
02931
02932 FlateStream::~FlateStream() {
02933 if (pred) {
02934 delete pred;
02935 }
02936 delete str;
02937 }
02938
02939 void FlateStream::reset() {
02940 int cmf, flg;
02941
02942 index = 0;
02943 remain = 0;
02944 codeBuf = 0;
02945 codeSize = 0;
02946 compressedBlock = gFalse;
02947 endOfBlock = gTrue;
02948 eof = gTrue;
02949
02950 str->reset();
02951
02952
02953
02954 endOfBlock = eof = gTrue;
02955 cmf = str->getChar();
02956 flg = str->getChar();
02957 if (cmf == EOF || flg == EOF)
02958 return;
02959 if ((cmf & 0x0f) != 0x08) {
02960 error(getPos(), "Unknown compression method in flate stream");
02961 return;
02962 }
02963 if ((((cmf << 8) + flg) % 31) != 0) {
02964 error(getPos(), "Bad FCHECK in flate stream");
02965 return;
02966 }
02967 if (flg & 0x20) {
02968 error(getPos(), "FDICT bit set in flate stream");
02969 return;
02970 }
02971
02972 eof = gFalse;
02973 }
02974
02975 int FlateStream::getChar() {
02976 int c;
02977
02978 if (pred) {
02979 return pred->getChar();
02980 }
02981 while (remain == 0) {
02982 if (endOfBlock && eof)
02983 return EOF;
02984 readSome();
02985 }
02986 c = buf[index];
02987 index = (index + 1) & flateMask;
02988 --remain;
02989 return c;
02990 }
02991
02992 int FlateStream::lookChar() {
02993 int c;
02994
02995 if (pred) {
02996 return pred->lookChar();
02997 }
02998 while (remain == 0) {
02999 if (endOfBlock && eof)
03000 return EOF;
03001 readSome();
03002 }
03003 c = buf[index];
03004 return c;
03005 }
03006
03007 int FlateStream::getRawChar() {
03008 int c;
03009
03010 while (remain == 0) {
03011 if (endOfBlock && eof)
03012 return EOF;
03013 readSome();
03014 }
03015 c = buf[index];
03016 index = (index + 1) & flateMask;
03017 --remain;
03018 return c;
03019 }
03020
03021 GString *FlateStream::getPSFilter(char *indent) {
03022 return NULL;
03023 }
03024
03025 GBool FlateStream::isBinary(GBool last) {
03026 return str->isBinary(gTrue);
03027 }
03028
03029 void FlateStream::readSome() {
03030 int code1, code2;
03031 int len, dist;
03032 int i, j, k;
03033 int c;
03034
03035 if (endOfBlock) {
03036 if (!startBlock())
03037 return;
03038 }
03039
03040 if (compressedBlock) {
03041 if ((code1 = getHuffmanCodeWord(&litCodeTab)) == EOF)
03042 goto err;
03043 if (code1 < 256) {
03044 buf[index] = code1;
03045 remain = 1;
03046 } else if (code1 == 256) {
03047 endOfBlock = gTrue;
03048 remain = 0;
03049 } else {
03050 code1 -= 257;
03051 code2 = lengthDecode[code1].bits;
03052 if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
03053 goto err;
03054 len = lengthDecode[code1].first + code2;
03055 if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF)
03056 goto err;
03057 code2 = distDecode[code1].bits;
03058 if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF)
03059 goto err;
03060 dist = distDecode[code1].first + code2;
03061 i = index;
03062 j = (index - dist) & flateMask;
03063 for (k = 0; k < len; ++k) {
03064 buf[i] = buf[j];
03065 i = (i + 1) & flateMask;
03066 j = (j + 1) & flateMask;
03067 }
03068 remain = len;
03069 }
03070
03071 } else {
03072 len = (blockLen < flateWindow) ? blockLen : flateWindow;
03073 for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) {
03074 if ((c = str->getChar()) == EOF) {
03075 endOfBlock = eof = gTrue;
03076 break;
03077 }
03078 buf[j] = c & 0xff;
03079 }
03080 remain = i;
03081 blockLen -= len;
03082 if (blockLen == 0)
03083 endOfBlock = gTrue;
03084 }
03085
03086 return;
03087
03088 err:
03089 error(getPos(), "Unexpected end of file in flate stream");
03090 endOfBlock = eof = gTrue;
03091 remain = 0;
03092 }
03093
03094 GBool FlateStream::startBlock() {
03095 int blockHdr;
03096 int c;
03097 int check;
03098
03099
03100 blockHdr = getCodeWord(3);
03101 if (blockHdr & 1)
03102 eof = gTrue;
03103 blockHdr >>= 1;
03104
03105
03106 if (blockHdr == 0) {
03107 compressedBlock = gFalse;
03108 if ((c = str->getChar()) == EOF)
03109 goto err;
03110 blockLen = c & 0xff;
03111 if ((c = str->getChar()) == EOF)
03112 goto err;
03113 blockLen |= (c & 0xff) << 8;
03114 if ((c = str->getChar()) == EOF)
03115 goto err;
03116 check = c & 0xff;
03117 if ((c = str->getChar()) == EOF)
03118 goto err;
03119 check |= (c & 0xff) << 8;
03120 if (check != (~blockLen & 0xffff))
03121 error(getPos(), "Bad uncompressed block length in flate stream");
03122 codeBuf = 0;
03123 codeSize = 0;
03124
03125
03126 } else if (blockHdr == 1) {
03127 compressedBlock = gTrue;
03128 loadFixedCodes();
03129
03130
03131 } else if (blockHdr == 2) {
03132 compressedBlock = gTrue;
03133 if (!readDynamicCodes())
03134 goto err;
03135
03136
03137 } else {
03138 goto err;
03139 }
03140
03141 endOfBlock = gFalse;
03142 return gTrue;
03143
03144 err:
03145 error(getPos(), "Bad block header in flate stream");
03146 endOfBlock = eof = gTrue;
03147 return gFalse;
03148 }
03149
03150 void FlateStream::loadFixedCodes() {
03151 int i;
03152
03153
03154 litCodeTab.codes = allCodes;
03155 distCodeTab.codes = allCodes + flateMaxLitCodes;
03156
03157
03158 for (i = 0; i <= 143; ++i)
03159 litCodeTab.codes[i].len = 8;
03160 for (i = 144; i <= 255; ++i)
03161 litCodeTab.codes[i].len = 9;
03162 for (i = 256; i <= 279; ++i)
03163 litCodeTab.codes[i].len = 7;
03164 for (i = 280; i <= 287; ++i)
03165 litCodeTab.codes[i].len = 8;
03166 compHuffmanCodes(&litCodeTab, flateMaxLitCodes);
03167
03168
03169 for (i = 0; i <= 5; ++i) {
03170 distCodeTab.start[i] = 0;
03171 }
03172 for (i = 6; i <= flateMaxHuffman+1; ++i) {
03173 distCodeTab.start[i] = flateMaxDistCodes;
03174 }
03175 for (i = 0; i < flateMaxDistCodes; ++i) {
03176 distCodeTab.codes[i].len = 5;
03177 distCodeTab.codes[i].code = i;
03178 distCodeTab.codes[i].val = i;
03179 }
03180 }
03181
03182 GBool FlateStream::readDynamicCodes() {
03183 int numCodeLenCodes;
03184 int numLitCodes;
03185 int numDistCodes;
03186 FlateCode codeLenCodes[flateMaxCodeLenCodes];
03187 FlateHuffmanTab codeLenCodeTab;
03188 int len, repeat, code;
03189 int i;
03190
03191
03192 if ((numLitCodes = getCodeWord(5)) == EOF)
03193 goto err;
03194 numLitCodes += 257;
03195 if ((numDistCodes = getCodeWord(5)) == EOF)
03196 goto err;
03197 numDistCodes += 1;
03198 if ((numCodeLenCodes = getCodeWord(4)) == EOF)
03199 goto err;
03200 numCodeLenCodes += 4;
03201 if (numLitCodes > flateMaxLitCodes ||
03202 numDistCodes > flateMaxDistCodes ||
03203 numCodeLenCodes > flateMaxCodeLenCodes)
03204 goto err;
03205
03206
03207 codeLenCodeTab.codes = codeLenCodes;
03208 for (i = 0; i < flateMaxCodeLenCodes; ++i)
03209 codeLenCodes[i].len = 0;
03210 for (i = 0; i < numCodeLenCodes; ++i) {
03211 if ((codeLenCodes[codeLenCodeMap[i]].len = getCodeWord(3)) == -1)
03212 goto err;
03213 }
03214 compHuffmanCodes(&codeLenCodeTab, flateMaxCodeLenCodes);
03215
03216
03217 litCodeTab.codes = allCodes;
03218 distCodeTab.codes = allCodes + numLitCodes;
03219
03220
03221 len = 0;
03222 repeat = 0;
03223 i = 0;
03224 while (i < numLitCodes + numDistCodes) {
03225 if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF)
03226 goto err;
03227 if (code == 16) {
03228 if ((repeat = getCodeWord(2)) == EOF)
03229 goto err;
03230 for (repeat += 3; repeat > 0; --repeat)
03231 allCodes[i++].len = len;
03232 } else if (code == 17) {
03233 if ((repeat = getCodeWord(3)) == EOF)
03234 goto err;
03235 len = 0;
03236 for (repeat += 3; repeat > 0; --repeat)
03237 allCodes[i++].len = 0;
03238 } else if (code == 18) {
03239 if ((repeat = getCodeWord(7)) == EOF)
03240 goto err;
03241 len = 0;
03242 for (repeat += 11; repeat > 0; --repeat)
03243 allCodes[i++].len = 0;
03244 } else {
03245 allCodes[i++].len = len = code;
03246 }
03247 }
03248 compHuffmanCodes(&litCodeTab, numLitCodes);
03249 compHuffmanCodes(&distCodeTab, numDistCodes);
03250
03251 return gTrue;
03252
03253 err:
03254 error(getPos(), "Bad dynamic code table in flate stream");
03255 return gFalse;
03256 }
03257
03258
03259
03260
03261
03262
03263 void FlateStream::compHuffmanCodes(FlateHuffmanTab *tab, int n) {
03264 int numLengths[flateMaxHuffman+1];
03265 int nextCode[flateMaxHuffman+1];
03266 int nextIndex[flateMaxHuffman+2];
03267 int code;
03268 int i, j;
03269
03270
03271 for (i = 0; i <= flateMaxHuffman; ++i)
03272 numLengths[i] = 0;
03273 for (i = 0; i < n; ++i)
03274 ++numLengths[tab->codes[i].len];
03275
03276
03277 tab->start[0] = nextIndex[0] = 0;
03278 for (i = 1; i <= flateMaxHuffman + 1; ++i)
03279 tab->start[i] = nextIndex[i] = tab->start[i-1] + numLengths[i-1];
03280
03281
03282 code = 0;
03283 numLengths[0] = 0;
03284 for (i = 1; i <= flateMaxHuffman; ++i) {
03285 code = (code + numLengths[i-1]) << 1;
03286 nextCode[i] = code;
03287 }
03288
03289
03290
03291 for (i = 0; i < n; ++i) {
03292 j = nextIndex[tab->codes[i].len]++;
03293 if (tab->codes[i].len == 0)
03294 tab->codes[j].code = 0;
03295 else
03296 tab->codes[j].code = nextCode[tab->codes[i].len]++;
03297 tab->codes[j].val = i;
03298 }
03299 }
03300
03301 int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) {
03302 int len;
03303 int code;
03304 int c;
03305 int i, j;
03306
03307 code = 0;
03308 for (len = 1; len <= flateMaxHuffman; ++len) {
03309
03310
03311 if (codeSize == 0) {
03312 if ((c = str->getChar()) == EOF)
03313 return EOF;
03314 codeBuf = c & 0xff;
03315 codeSize = 8;
03316 }
03317 code = (code << 1) | (codeBuf & 1);
03318 codeBuf >>= 1;
03319 --codeSize;
03320
03321
03322 i = tab->start[len];
03323 j = tab->start[len + 1];
03324 if (i < j && code >= tab->codes[i].code && code <= tab->codes[j-1].code) {
03325 i += code - tab->codes[i].code;
03326 return tab->codes[i].val;
03327 }
03328 }
03329
03330
03331 error(getPos(), "Bad code (%04x) in flate stream", code);
03332 return EOF;
03333 }
03334
03335 int FlateStream::getCodeWord(int bits) {
03336 int c;
03337
03338 while (codeSize < bits) {
03339 if ((c = str->getChar()) == EOF)
03340 return EOF;
03341 codeBuf |= (c & 0xff) << codeSize;
03342 codeSize += 8;
03343 }
03344 c = codeBuf & ((1 << bits) - 1);
03345 codeBuf >>= bits;
03346 codeSize -= bits;
03347 return c;
03348 }
03349
03350
03351
03352
03353
03354 EOFStream::EOFStream(Stream *strA):
03355 FilterStream(strA) {
03356 }
03357
03358 EOFStream::~EOFStream() {
03359 delete str;
03360 }
03361
03362
03363
03364
03365
03366 FixedLengthEncoder::FixedLengthEncoder(Stream *strA, int lengthA):
03367 FilterStream(strA) {
03368 length = lengthA;
03369 count = 0;
03370 }
03371
03372 FixedLengthEncoder::~FixedLengthEncoder() {
03373 if (str->isEncoder())
03374 delete str;
03375 }
03376
03377 void FixedLengthEncoder::reset() {
03378 str->reset();
03379 count = 0;
03380 }
03381
03382 void FixedLengthEncoder::close() {
03383 }
03384
03385 int FixedLengthEncoder::getChar() {
03386 if (length >= 0 && count >= length)
03387 return EOF;
03388 ++count;
03389 return str->getChar();
03390 }
03391
03392 int FixedLengthEncoder::lookChar() {
03393 if (length >= 0 && count >= length)
03394 return EOF;
03395 return str->getChar();
03396 }
03397
03398
03399
03400
03401
03402 ASCIIHexEncoder::ASCIIHexEncoder(Stream *strA):
03403 FilterStream(strA) {
03404 bufPtr = bufEnd = buf;
03405 lineLen = 0;
03406 eof = gFalse;
03407 }
03408
03409 ASCIIHexEncoder::~ASCIIHexEncoder() {
03410 if (str->isEncoder()) {
03411 delete str;
03412 }
03413 }
03414
03415 void ASCIIHexEncoder::reset() {
03416 str->reset();
03417 bufPtr = bufEnd = buf;
03418 lineLen = 0;
03419 eof = gFalse;
03420 }
03421
03422 void ASCIIHexEncoder::close() {
03423 }
03424
03425 GBool ASCIIHexEncoder::fillBuf() {
03426 static char *hex = "0123456789abcdef";
03427 int c;
03428
03429 if (eof) {
03430 return gFalse;
03431 }
03432 bufPtr = bufEnd = buf;
03433 if ((c = str->getChar()) == EOF) {
03434 *bufEnd++ = '>';
03435 eof = gTrue;
03436 } else {
03437 if (lineLen >= 64) {
03438 *bufEnd++ = '\n';
03439 lineLen = 0;
03440 }
03441 *bufEnd++ = hex[(c >> 4) & 0x0f];
03442 *bufEnd++ = hex[c & 0x0f];
03443 lineLen += 2;
03444 }
03445 return gTrue;
03446 }
03447
03448
03449
03450
03451
03452 ASCII85Encoder::ASCII85Encoder(Stream *strA):
03453 FilterStream(strA) {
03454 bufPtr = bufEnd = buf;
03455 lineLen = 0;
03456 eof = gFalse;
03457 }
03458
03459 ASCII85Encoder::~ASCII85Encoder() {
03460 if (str->isEncoder())
03461 delete str;
03462 }
03463
03464 void ASCII85Encoder::reset() {
03465 str->reset();
03466 bufPtr = bufEnd = buf;
03467 lineLen = 0;
03468 eof = gFalse;
03469 }
03470
03471 void ASCII85Encoder::close() {
03472 }
03473
03474 GBool ASCII85Encoder::fillBuf() {
03475 Gulong t;
03476 char buf1[5];
03477 int c;
03478 int n, i;
03479
03480 if (eof)
03481 return gFalse;
03482 t = 0;
03483 for (n = 0; n < 4; ++n) {
03484 if ((c = str->getChar()) == EOF)
03485 break;
03486 t = (t << 8) + c;
03487 }
03488 bufPtr = bufEnd = buf;
03489 if (n > 0) {
03490 if (n == 4 && t == 0) {
03491 *bufEnd++ = 'z';
03492 if (++lineLen == 65) {
03493 *bufEnd++ = '\n';
03494 lineLen = 0;
03495 }
03496 } else {
03497 if (n < 4)
03498 t <<= 8 * (4 - n);
03499 for (i = 4; i >= 0; --i) {
03500 buf1[i] = (char)(t % 85 + 0x21);
03501 t /= 85;
03502 }
03503 for (i = 0; i <= n; ++i) {
03504 *bufEnd++ = buf1[i];
03505 if (++lineLen == 65) {
03506 *bufEnd++ = '\n';
03507 lineLen = 0;
03508 }
03509 }
03510 }
03511 }
03512 if (n < 4) {
03513 *bufEnd++ = '~';
03514 *bufEnd++ = '>';
03515 eof = gTrue;
03516 }
03517 return bufPtr < bufEnd;
03518 }
03519
03520
03521
03522
03523
03524 RunLengthEncoder::RunLengthEncoder(Stream *strA):
03525 FilterStream(strA) {
03526 bufPtr = bufEnd = nextEnd = buf;
03527 eof = gFalse;
03528 }
03529
03530 RunLengthEncoder::~RunLengthEncoder() {
03531 if (str->isEncoder())
03532 delete str;
03533 }
03534
03535 void RunLengthEncoder::reset() {
03536 str->reset();
03537 bufPtr = bufEnd = nextEnd = buf;
03538 eof = gFalse;
03539 }
03540
03541 void RunLengthEncoder::close() {
03542 }
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552 GBool RunLengthEncoder::fillBuf() {
03553 int c, c1, c2;
03554 int n;
03555
03556
03557 if (eof)
03558 return gFalse;
03559
03560
03561 if (nextEnd < bufEnd + 1) {
03562 if ((c1 = str->getChar()) == EOF) {
03563 eof = gTrue;
03564 return gFalse;
03565 }
03566 } else {
03567 c1 = bufEnd[0] & 0xff;
03568 }
03569 if (nextEnd < bufEnd + 2) {
03570 if ((c2 = str->getChar()) == EOF) {
03571 eof = gTrue;
03572 buf[0] = 0;
03573 buf[1] = c1;
03574 bufPtr = buf;
03575 bufEnd = &buf[2];
03576 return gTrue;
03577 }
03578 } else {
03579 c2 = bufEnd[1] & 0xff;
03580 }
03581
03582
03583 c = 0;
03584 if (c1 == c2) {
03585 n = 2;
03586 while (n < 128 && (c = str->getChar()) == c1)
03587 ++n;
03588 buf[0] = (char)(257 - n);
03589 buf[1] = c1;
03590 bufEnd = &buf[2];
03591 if (c == EOF) {
03592 eof = gTrue;
03593 } else if (n < 128) {
03594 buf[2] = c;
03595 nextEnd = &buf[3];
03596 } else {
03597 nextEnd = bufEnd;
03598 }
03599
03600
03601 } else {
03602 buf[1] = c1;
03603 buf[2] = c2;
03604 n = 2;
03605 while (n < 128) {
03606 if ((c = str->getChar()) == EOF) {
03607 eof = gTrue;
03608 break;
03609 }
03610 ++n;
03611 buf[n] = c;
03612 if (buf[n] == buf[n-1])
03613 break;
03614 }
03615 if (buf[n] == buf[n-1]) {
03616 buf[0] = (char)(n-2-1);
03617 bufEnd = &buf[n-1];
03618 nextEnd = &buf[n+1];
03619 } else {
03620 buf[0] = (char)(n-1);
03621 bufEnd = nextEnd = &buf[n+1];
03622 }
03623 }
03624 bufPtr = buf;
03625 return gTrue;
03626 }