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