#include <string.h>
#include <ctype.h>
#include "gmem.h"
+#include "gfile.h"
#include "config.h"
#include "Error.h"
#include "Object.h"
+#ifndef NO_DECRYPTION
+#include "Decrypt.h"
+#endif
#include "Stream.h"
#include "Stream-CCITT.h"
-#ifdef _MSC_VER
-#define popen _popen
-#define pclose _pclose
-#endif
-
#ifdef __DJGPP__
static GBool setDJSYSFLAGS = gFalse;
#endif
#endif
#endif
+#ifdef MACOS
+#include "StuffItEngineLib.h"
+#endif
+
//------------------------------------------------------------------------
// Stream (base class)
//------------------------------------------------------------------------
Stream::~Stream() {
}
+void Stream::close() {
+}
+
int Stream::getRawChar() {
error(-1, "Internal: called getRawChar() on non-predictor stream");
return EOF;
BaseStream::BaseStream(Object *dict) {
this->dict = *dict;
+#ifndef NO_DECRYPTION
+ decrypt = NULL;
+#endif
}
BaseStream::~BaseStream() {
dict.free();
+#ifndef NO_DECRYPTION
+ if (decrypt)
+ delete decrypt;
+#endif
+}
+
+#ifndef NO_DECRYPTION
+void BaseStream::doDecryption(Guchar *fileKey, int objNum, int objGen) {
+ decrypt = new Decrypt(fileKey, objNum, objGen);
}
+#endif
//------------------------------------------------------------------------
// FilterStream
FilterStream::~FilterStream() {
}
+void FilterStream::close() {
+ str->close();
+}
+
void FilterStream::setPos(int pos) {
error(-1, "Internal: called setPos() on FilterStream");
}
}
FileStream::~FileStream() {
- if (savePos >= 0) {
- fseek(f, savePos, SEEK_SET);
- }
+ close();
}
Stream *FileStream::makeSubStream(int start, int length, Object *dict) {
fseek(f, start, SEEK_SET);
bufPtr = bufEnd = buf;
bufPos = start;
+#ifndef NO_DECRYPTION
+ if (decrypt)
+ decrypt->reset();
+#endif
+}
+
+void FileStream::close() {
+ if (savePos >= 0) {
+ fseek(f, savePos, SEEK_SET);
+ savePos = -1;
+ }
}
GBool FileStream::fillBuf() {
int n;
+#ifndef NO_DECRYPTION
+ char *p;
+#endif
bufPos += bufEnd - buf;
bufPtr = bufEnd = buf;
- if (length >= 0 && bufPos >= start + length)
+ if (length >= 0 && bufPos >= start + length) {
return gFalse;
- if (length >= 0 && bufPos + 256 > start + length)
+ }
+ if (length >= 0 && bufPos + fileStreamBufSize > start + length) {
n = start + length - bufPos;
- else
- n = 256;
+ } else {
+ n = fileStreamBufSize;
+ }
n = fread(buf, 1, n, f);
bufEnd = buf + n;
- if (bufPtr >= bufEnd)
+ if (bufPtr >= bufEnd) {
return gFalse;
+ }
+#ifndef NO_DECRYPTION
+ if (decrypt) {
+ for (p = buf; p < bufEnd; ++p) {
+ *p = (char)decrypt->decryptByte((Guchar)*p);
+ }
+ }
+#endif
return gTrue;
}
fclose(zPipe);
#endif
zPipe = NULL;
- unlink(zName);
+ unlink(zName->getCString());
+ delete zName;
}
if (pred) {
delete pred;
void LZWStream::reset() {
FILE *f;
+ GString *zCmd;
- str->reset();
- bufPtr = bufEnd = buf;
+ //----- close old LZW stream
if (zPipe) {
#ifdef HAVE_POPEN
pclose(zPipe);
fclose(zPipe);
#endif
zPipe = NULL;
- unlink(zName);
+ unlink(zName->getCString());
+ delete zName;
}
+
+ //----- tell Delorie runtime to spawn a new instance of COMMAND.COM
+ // to run gzip
#if __DJGPP__
if (!setDJSYSFLAGS) {
setenv("DJSYSFLAGS", "0x0002", 0);
setDJSYSFLAGS = gTrue;
}
#endif
- strcpy(zCmd, uncompressCmd);
- strcat(zCmd, " ");
- zName = zCmd + strlen(zCmd);
- tmpnam(zName);
-#ifdef _MSC_VER
- zName[strlen(zName) - 2] = '\0';
-#endif
- strcat(zName, ".Z");
- if (!(f = fopen(zName, "wb"))) {
- error(getPos(), "Couldn't open temporary file '%s'", zName);
+
+ //----- create the .Z file
+ if (!openTempFile(&zName, &f, "wb", ".Z")) {
+ error(getPos(), "Couldn't create temporary file for LZW stream");
return;
}
dumpFile(f);
fclose(f);
-#ifdef HAVE_POPEN
- if (!(zPipe = popen(zCmd, "r"))) {
- error(getPos(), "Couldn't popen '%s'", zCmd);
- unlink(zName);
+
+ //----- execute uncompress / gzip
+ zCmd = new GString(uncompressCmd);
+ zCmd->append(' ');
+ zCmd->append(zName);
+#if defined(MACOS)
+ long magicCookie;
+ // first we open the engine up
+ OSErr err = OpenSITEngine(kUseExternalEngine, &magicCookie);
+ // if we found it - let's use it!
+ if (!err && magicCookie) {
+ // make sure we have the correct version of the Engine
+ if (GetSITEngineVersion(magicCookie) >= kFirstSupportedEngine) {
+ FSSpec myFSS;
+ Str255 pName;
+ strcpy((char *)pName, zName->getCString());
+ c2pstr((char *)pName);
+ FSMakeFSSpec(0, 0, pName, &myFSS);
+ short ftype = DetermineFileType(magicCookie, &myFSS);
+ OSErr expandErr = ExpandFSSpec(magicCookie, ftype, &myFSS,
+ NULL, NULL, kCreateFolderNever,
+ kDeleteOriginal, kTextConvertSmart);
+ }
+ }
+#elif defined(HAVE_POPEN)
+ if (!(zPipe = popen(zCmd->getCString(), POPEN_READ_MODE))) {
+ error(getPos(), "Couldn't popen '%s'", zCmd->getCString());
+ unlink(zName->getCString());
+ delete zName;
return;
}
-#else
+#else // HAVE_POPEN
#ifdef VMS
- if (!system(zCmd)) {
+ if (!system(zCmd->getCString())) {
#else
- if (system(zCmd)) {
+ if (system(zCmd->getCString())) {
#endif
- error(getPos(), "Couldn't execute '%s'", zCmd);
- unlink(zName);
+ error(getPos(), "Couldn't execute '%s'", zCmd->getCString());
+ unlink(zName->getCString());
+ delete zName;
return;
}
- zName[strlen(zName) - 2] = '\0';
- if (!(zPipe = fopen(zName, "rb"))) {
- error(getPos(), "Couldn't open uncompress file '%s'", zName);
- unlink(zName);
+ zName->del(zName->getLength() - 2, 2);
+ if (!(zPipe = fopen(zName->getCString(), "rb"))) {
+ error(getPos(), "Couldn't open uncompress file '%s'", zName->getCString());
+ unlink(zName->getCString());
+ delete zName;
return;
}
-#endif
+#endif // HAVE_POPEN
+
+ //----- clean up
+ delete zCmd;
+
+ //----- initialize buffer
+ bufPtr = bufEnd = buf;
}
void LZWStream::dumpFile(FILE *f) {
GBool first; // indicates first code word after clear
int i, j;
+ str->reset();
+
// magic number
fputc(0x1f, f);
fputc(0x9d, f);
fclose(zPipe);
#endif
zPipe = NULL;
- unlink(zName);
+ unlink(zName->getCString());
+ delete zName;
}
bufPtr = buf;
bufEnd = buf + n;
this->rows = rows;
this->endOfBlock = endOfBlock;
this->black = black;
- refLine = (short *)gmalloc((columns + 2) * sizeof(short));
+ refLine = (short *)gmalloc((columns + 3) * sizeof(short));
codingLine = (short *)gmalloc((columns + 2) * sizeof(short));
eof = gFalse;
#if 0 //~
GBool err;
#endif
+ GBool gotEOL;
int ret;
- int bits, i, n;
+ int bits, i;
// if at eof just return EOF
if (eof && codingLine[a0] >= columns) {
inputBits &= ~7;
}
- // check for end-of-line marker, end-of-block marker, and
- // 2D encoding tag
- if (endOfBlock) {
+ // check for end-of-line marker, skipping over any extra zero bits
+ gotEOL = gFalse;
+ if (!endOfBlock && row == rows - 1) {
+ eof = gTrue;
+ } else {
code1 = lookBits(12);
- if (code1 == EOF) {
+ while (code1 == 0) {
+ eatBits(1);
+ code1 = lookBits(12);
+ }
+ if (code1 == 0x001) {
+ eatBits(12);
+ gotEOL = gTrue;
+ } else if (code1 == EOF) {
eof = gTrue;
- } else if (code1 == 0x001) {
+ }
+ }
+
+ // get 2D encoding tag
+ if (!eof && encoding > 0) {
+ nextLine2D = !lookBits(1);
+ eatBits(1);
+ }
+
+ // check for end-of-block marker
+ if (endOfBlock && gotEOL) {
+ code1 = lookBits(12);
+ if (code1 == 0x001) {
eatBits(12);
if (encoding > 0) {
- nextLine2D = !lookBits(1);
+ lookBits(1);
eatBits(1);
}
- code1 = lookBits(12);
- if (code1 == 0x001) {
- eatBits(12);
- if (encoding > 0) {
- lookBits(1);
- eatBits(1);
- }
- if (encoding >= 0) {
- for (i = 0; i < 4; ++i) {
- code1 = lookBits(12);
- if (code1 != 0x001) {
- error(getPos(), "Bad RTC code in CCITTFax stream");
- }
- eatBits(12);
- if (encoding > 0) {
- lookBits(1);
- eatBits(1);
- }
+ if (encoding >= 0) {
+ for (i = 0; i < 4; ++i) {
+ code1 = lookBits(12);
+ if (code1 != 0x001) {
+ error(getPos(), "Bad RTC code in CCITTFax stream");
+ }
+ eatBits(12);
+ if (encoding > 0) {
+ lookBits(1);
+ eatBits(1);
}
}
- eof = gTrue;
- }
- } else {
- if (encoding > 0) {
- nextLine2D = !lookBits(1);
- eatBits(1);
}
- }
- } else {
- if (row == rows - 1) {
eof = gTrue;
- } else {
- for (n = 0; n < 11 && lookBits(n) == 0; ++n) ;
- if (n == 11 && lookBits(12) == 0x001) {
- eatBits(12);
- }
- if (encoding > 0) {
- nextLine2D = !lookBits(1);
- eatBits(1);
- }
}
}
code = 0; // make gcc happy
if (endOfBlock) {
code = lookBits(12);
- if ((code >> 5) == 0)
+ if ((code >> 5) == 0) {
p = &whiteTab1[code];
- else
+ } else {
p = &whiteTab2[code >> 3];
+ }
if (p->bits > 0) {
eatBits(p->bits);
return p->n;
}
}
error(getPos(), "Bad white code (%04x) in CCITTFax stream", code);
- return EOF;
+ // eat a bit and return a positive number so that the caller doesn't
+ // go into an infinite loop
+ eatBits(1);
+ return 1;
}
short CCITTFaxStream::getBlackCode() {
code = 0; // make gcc happy
if (endOfBlock) {
code = lookBits(13);
- if ((code >> 7) == 0)
+ if ((code >> 7) == 0) {
p = &blackTab1[code];
- else if ((code >> 9) == 0)
+ } else if ((code >> 9) == 0) {
p = &blackTab2[(code >> 1) - 64];
- else
+ } else {
p = &blackTab3[code >> 7];
+ }
if (p->bits > 0) {
eatBits(p->bits);
return p->n;
}
}
error(getPos(), "Bad black code (%04x) in CCITTFax stream", code);
- return EOF;
+ // eat a bit and return a positive number so that the caller doesn't
+ // go into an infinite loop
+ eatBits(1);
+ return 1;
}
short CCITTFaxStream::lookBits(int n) {
while (inputBits < n) {
if ((c = str->getChar()) == EOF) {
- if (inputBits == 0)
+ if (inputBits == 0) {
return EOF;
- c = 0;
+ }
+ // near the end of the stream, the caller may ask for more bits
+ // than are available, but there may still be a valid code in
+ // however many bits are available -- we need to return correct
+ // data in this case
+ return (inputBuf << (n - inputBits)) & (0xffff >> (16 - n));
}
inputBuf = (inputBuf << 8) + c;
inputBits += 8;
void FlateStream::reset() {
int cmf, flg;
+ index = 0;
+ remain = 0;
+ codeBuf = 0;
+ codeSize = 0;
+ compressedBlock = gFalse;
+ endOfBlock = gTrue;
+ eof = gTrue;
+
str->reset();
// read header
return;
}
- // initialize
- index = 0;
- remain = 0;
- codeBuf = 0;
- codeSize = 0;
- compressedBlock = gFalse;
- endOfBlock = gTrue;
eof = gFalse;
}
compHuffmanCodes(&litCodeTab, flateMaxLitCodes);
// initialize distance code table
- for (i = 0; i < 5; ++i)
+ for (i = 0; i <= 5; ++i) {
distCodeTab.start[i] = 0;
- distCodeTab.start[5] = 0;
- for (i = 6; i <= flateMaxHuffman+1; ++i)
- distCodeTab.start[6] = flateMaxDistCodes;
+ }
+ for (i = 6; i <= flateMaxHuffman+1; ++i) {
+ distCodeTab.start[i] = flateMaxDistCodes;
+ }
for (i = 0; i < flateMaxDistCodes; ++i) {
distCodeTab.codes[i].len = 5;
distCodeTab.codes[i].code = i;
count = 0;
}
+void FixedLengthEncoder::close() {
+}
+
int FixedLengthEncoder::getChar() {
if (length >= 0 && count >= length)
return EOF;
eof = gFalse;
}
+void ASCII85Encoder::close() {
+}
+
GBool ASCII85Encoder::fillBuf() {
Gulong t;
char buf1[5];
eof = gFalse;
}
+void RunLengthEncoder::close() {
+}
+
//
// When fillBuf finishes, buf[] looks like this:
// +-----+--------------+-----------------+--
}
// check for repeat
+ c = 0; // make gcc happy
if (c1 == c2) {
n = 2;
while (n < 128 && (c = str->getChar()) == c1)