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