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