diff options
Diffstat (limited to 'Build/source/libs/xpdf/xpdf/Stream.cc')
-rw-r--r-- | Build/source/libs/xpdf/xpdf/Stream.cc | 280 |
1 files changed, 157 insertions, 123 deletions
diff --git a/Build/source/libs/xpdf/xpdf/Stream.cc b/Build/source/libs/xpdf/xpdf/Stream.cc index 5fa7791c436..68abafa7b8d 100644 --- a/Build/source/libs/xpdf/xpdf/Stream.cc +++ b/Build/source/libs/xpdf/xpdf/Stream.cc @@ -27,7 +27,6 @@ #include "Error.h" #include "Object.h" #include "Lexer.h" -#include "Decrypt.h" #include "GfxState.h" #include "Stream.h" #include "JBIG2Stream.h" @@ -142,6 +141,7 @@ Stream *Stream::makeFilter(char *name, Stream *str, Object *params) { int encoding; GBool endOfLine, byteAlign, endOfBlock, black; int columns, rows; + int colorXform; Object globals, obj; if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) { @@ -227,7 +227,14 @@ Stream *Stream::makeFilter(char *name, Stream *str, Object *params) { str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign, columns, rows, endOfBlock, black); } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) { - str = new DCTStream(str); + colorXform = -1; + if (params->isDict()) { + if (params->dictLookup("ColorTransform", &obj)->isInt()) { + colorXform = obj.getInt(); + } + obj.free(); + } + str = new DCTStream(str, colorXform); } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) { pred = 1; columns = 1; @@ -273,18 +280,10 @@ Stream *Stream::makeFilter(char *name, Stream *str, Object *params) { BaseStream::BaseStream(Object *dictA) { dict = *dictA; - decrypt = NULL; } BaseStream::~BaseStream() { dict.free(); - if (decrypt) - delete decrypt; -} - -void BaseStream::doDecryption(Guchar *fileKey, int keyLength, - int objNum, int objGen) { - decrypt = new Decrypt(fileKey, keyLength, objNum, objGen); } //------------------------------------------------------------------------ @@ -402,8 +401,6 @@ void ImageStream::skipLine() { StreamPredictor::StreamPredictor(Stream *strA, int predictorA, int widthA, int nCompsA, int nBitsA) { - int totalBits; - str = strA; predictor = predictorA; width = widthA; @@ -413,7 +410,6 @@ StreamPredictor::StreamPredictor(Stream *strA, int predictorA, ok = gFalse; nVals = width * nComps; - totalBits = nVals * nBits; if (width <= 0 || nComps <= 0 || nBits <= 0 || nComps >= INT_MAX / nBits || width >= INT_MAX / nComps / nBits || @@ -421,8 +417,8 @@ StreamPredictor::StreamPredictor(Stream *strA, int predictorA, return; } pixBytes = (nComps * nBits + 7) >> 3; - rowBytes = ((totalBits + 7) >> 3) + pixBytes; - if (rowBytes < 0) { + rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes; + if (rowBytes <= 0) { return; } predLine = (Guchar *)gmalloc(rowBytes); @@ -550,8 +546,8 @@ GBool StreamPredictor::getNextLine() { inBuf = (inBuf << 8) | (predLine[j++] & 0xff); inBits += 8; } - upLeftBuf[kk] = (upLeftBuf[kk] + - (inBuf >> (inBits - nBits))) & bitMask; + upLeftBuf[kk] = (Guchar)((upLeftBuf[kk] + + (inBuf >> (inBits - nBits))) & bitMask); inBits -= nBits; outBuf = (outBuf << nBits) | upLeftBuf[kk]; outBits += nBits; @@ -614,8 +610,6 @@ void FileStream::reset() { saved = gTrue; bufPtr = bufEnd = buf; bufPos = start; - if (decrypt) - decrypt->reset(); } void FileStream::close() { @@ -633,7 +627,6 @@ void FileStream::close() { GBool FileStream::fillBuf() { int n; - char *p; bufPos += bufEnd - buf; bufPtr = bufEnd = buf; @@ -650,11 +643,6 @@ GBool FileStream::fillBuf() { if (bufPtr >= bufEnd) { return gFalse; } - if (decrypt) { - for (p = buf; p < bufEnd; ++p) { - *p = (char)decrypt->decryptByte((Guchar)*p); - } - } return gTrue; } @@ -743,9 +731,6 @@ Stream *MemStream::makeSubStream(Guint startA, GBool limited, void MemStream::reset() { bufPtr = buf + start; - if (decrypt) { - decrypt->reset(); - } } void MemStream::close() { @@ -773,25 +758,6 @@ void MemStream::moveStart(int delta) { bufPtr = buf + start; } -void MemStream::doDecryption(Guchar *fileKey, int keyLength, - int objNum, int objGen) { - char *newBuf; - char *p, *q; - - this->BaseStream::doDecryption(fileKey, keyLength, objNum, objGen); - if (decrypt) { - newBuf = (char *)gmalloc(length); - for (p = buf + start, q = newBuf; p < bufEnd; ++p, ++q) { - *q = (char)decrypt->decryptByte((Guchar)*p); - } - bufEnd = newBuf + length; - bufPtr = newBuf + (bufPtr - (buf + start)); - start = 0; - buf = newBuf; - needFree = gTrue; - } -} - //------------------------------------------------------------------------ // EmbedStream //------------------------------------------------------------------------ @@ -1286,8 +1252,8 @@ CCITTFaxStream::CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA, rows = rowsA; endOfBlock = endOfBlockA; black = blackA; - refLine = (short *)gmallocn(columns + 4, sizeof(short)); - codingLine = (short *)gmallocn(columns + 3, sizeof(short)); + refLine = (short *)gmallocn(columns + 3, sizeof(short)); + codingLine = (short *)gmallocn(columns + 2, sizeof(short)); eof = gFalse; row = 0; @@ -1315,7 +1281,7 @@ void CCITTFaxStream::reset() { nextLine2D = encoding < 0; inputBits = 0; codingLine[0] = 0; - codingLine[1] = refLine[2] = columns; + codingLine[1] = columns; a0 = 1; buf = EOF; @@ -1351,8 +1317,27 @@ int CCITTFaxStream::lookChar() { // 2-D encoding if (nextLine2D) { - for (i = 0; codingLine[i] < columns; ++i) + // state: + // a0New = current position in coding line (0 <= a0New <= columns) + // codingLine[a0] = last change in coding line + // (black-to-white if a0 is even, + // white-to-black if a0 is odd) + // refLine[b1] = next change in reference line of opposite color + // to a0 + // invariants: + // 0 <= codingLine[a0] <= a0New + // <= refLine[b1] <= refLine[b1+1] <= columns + // 0 <= a0 <= columns+1 + // refLine[0] = 0 + // refLine[n] = refLine[n+1] = columns + // -- for some 1 <= n <= columns+1 + // end condition: + // 0 = codingLine[0] <= codingLine[1] < codingLine[2] < ... + // < codingLine[n-1] < codingLine[n] = columns + // -- where 1 <= n <= columns+1 + for (i = 0; codingLine[i] < columns; ++i) { refLine[i] = codingLine[i]; + } refLine[i] = refLine[i + 1] = columns; b1 = 1; a0New = codingLine[a0 = 0] = 0; @@ -1384,68 +1369,93 @@ int CCITTFaxStream::lookChar() { } while (code3 >= 64); } if (code1 > 0 || code2 > 0) { - codingLine[a0 + 1] = a0New + code1; + if (a0New + code1 <= columns) { + codingLine[a0 + 1] = a0New + code1; + } else { + codingLine[a0 + 1] = columns; + } ++a0; - a0New = codingLine[a0 + 1] = codingLine[a0] + code2; + if (codingLine[a0] + code2 <= columns) { + codingLine[a0 + 1] = codingLine[a0] + code2; + } else { + codingLine[a0 + 1] = columns; + } ++a0; - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + a0New = codingLine[a0]; + while (refLine[b1] <= a0New && refLine[b1] < columns) { b1 += 2; + } } break; case twoDimVert0: - a0New = codingLine[++a0] = refLine[b1]; if (refLine[b1] < columns) { + a0New = codingLine[++a0] = refLine[b1]; ++b1; - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + while (refLine[b1] <= a0New && refLine[b1] < columns) { b1 += 2; + } + } else { + a0New = codingLine[++a0] = columns; } break; case twoDimVertR1: - a0New = codingLine[++a0] = refLine[b1] + 1; - if (refLine[b1] < columns) { + if (refLine[b1] + 1 < columns) { + a0New = codingLine[++a0] = refLine[b1] + 1; ++b1; - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + while (refLine[b1] <= a0New && refLine[b1] < columns) { b1 += 2; + } + } else { + a0New = codingLine[++a0] = columns; } break; case twoDimVertL1: - if (a0 == 0 || refLine[b1] - 1 > a0New) { + if (refLine[b1] - 1 > a0New || (a0 == 0 && refLine[b1] == 1)) { a0New = codingLine[++a0] = refLine[b1] - 1; --b1; - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + while (refLine[b1] <= a0New && refLine[b1] < columns) { b1 += 2; + } } break; case twoDimVertR2: - a0New = codingLine[++a0] = refLine[b1] + 2; - if (refLine[b1] < columns) { + if (refLine[b1] + 2 < columns) { + a0New = codingLine[++a0] = refLine[b1] + 2; ++b1; - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + while (refLine[b1] <= a0New && refLine[b1] < columns) { b1 += 2; + } + } else { + a0New = codingLine[++a0] = columns; } break; case twoDimVertL2: - if (a0 == 0 || refLine[b1] - 2 > a0New) { + if (refLine[b1] - 2 > a0New || (a0 == 0 && refLine[b1] == 2)) { a0New = codingLine[++a0] = refLine[b1] - 2; --b1; - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + while (refLine[b1] <= a0New && refLine[b1] < columns) { b1 += 2; + } } break; case twoDimVertR3: - a0New = codingLine[++a0] = refLine[b1] + 3; - if (refLine[b1] < columns) { + if (refLine[b1] + 3 < columns) { + a0New = codingLine[++a0] = refLine[b1] + 3; ++b1; - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + while (refLine[b1] <= a0New && refLine[b1] < columns) { b1 += 2; + } + } else { + a0New = codingLine[++a0] = columns; } break; case twoDimVertL3: - if (a0 == 0 || refLine[b1] - 3 > a0New) { + if (refLine[b1] - 3 > a0New || (a0 == 0 && refLine[b1] == 3)) { a0New = codingLine[++a0] = refLine[b1] - 3; --b1; - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + while (refLine[b1] <= a0New && refLine[b1] < columns) { b1 += 2; + } } break; case EOF: @@ -1469,16 +1479,18 @@ int CCITTFaxStream::lookChar() { } while (code3 >= 64); codingLine[a0+1] = codingLine[a0] + code1; ++a0; - if (codingLine[a0] >= columns) + if (codingLine[a0] >= columns) { break; + } code2 = 0; do { code2 += code3 = getBlackCode(); } while (code3 >= 64); codingLine[a0+1] = codingLine[a0] + code2; ++a0; - if (codingLine[a0] >= columns) + if (codingLine[a0] >= columns) { break; + } } } @@ -1859,10 +1871,11 @@ static int dctZigZag[64] = { 63 }; -DCTStream::DCTStream(Stream *strA): +DCTStream::DCTStream(Stream *strA, GBool colorXformA): FilterStream(strA) { int i, j; + colorXform = colorXformA; progressive = interleaved = gFalse; width = height = 0; mcuWidth = mcuHeight = 0; @@ -1888,20 +1901,8 @@ DCTStream::DCTStream(Stream *strA): } DCTStream::~DCTStream() { - int i, j; - + close(); delete str; - if (progressive || !interleaved) { - for (i = 0; i < numComps; ++i) { - gfree(frameBuf[i]); - } - } else { - for (i = 0; i < numComps; ++i) { - for (j = 0; j < mcuHeight; ++j) { - gfree(rowBuf[i][j]); - } - } - } } void DCTStream::reset() { @@ -1915,7 +1916,6 @@ void DCTStream::reset() { numQuantTables = 0; numDCHuffTables = 0; numACHuffTables = 0; - colorXform = 0; gotJFIFMarker = gFalse; gotAdobeMarker = gFalse; restartInterval = 0; @@ -1943,14 +1943,18 @@ void DCTStream::reset() { mcuHeight *= 8; // figure out color transform - if (!gotAdobeMarker && numComps == 3) { - if (gotJFIFMarker) { - colorXform = 1; - } else if (compInfo[0].id == 82 && compInfo[1].id == 71 && - compInfo[2].id == 66) { // ASCII "RGB" - colorXform = 0; + if (colorXform == -1) { + if (numComps == 3) { + if (gotJFIFMarker) { + colorXform = 1; + } else if (compInfo[0].id == 82 && compInfo[1].id == 71 && + compInfo[2].id == 66) { // ASCII "RGB" + colorXform = 0; + } else { + colorXform = 1; + } } else { - colorXform = 1; + colorXform = 0; } } @@ -2000,6 +2004,20 @@ void DCTStream::reset() { } } +void DCTStream::close() { + int i, j; + + for (i = 0; i < 4; ++i) { + for (j = 0; j < 32; ++j) { + gfree(rowBuf[i][j]); + rowBuf[i][j] = NULL; + } + gfree(frameBuf[i]); + frameBuf[i] = NULL; + } + FilterStream::close(); +} + int DCTStream::getChar() { int c; @@ -2924,11 +2942,8 @@ GBool DCTStream::readBaselineSOF() { width = read16(); numComps = str->getChar(); if (numComps <= 0 || numComps > 4) { - error(getPos(), "Bad number of components in DCT stream", prec); - return gFalse; - } - if (numComps <= 0 || numComps > 4) { - error(getPos(), "Bad number of components in DCT stream", prec); + error(getPos(), "Bad number of components in DCT stream"); + numComps = 0; return gFalse; } if (prec != 8) { @@ -2962,11 +2977,6 @@ GBool DCTStream::readProgressiveSOF() { numComps = 0; return gFalse; } - if (numComps <= 0 || numComps > 4) { - error(getPos(), "Bad number of components in DCT stream"); - numComps = 0; - return gFalse; - } if (prec != 8) { error(getPos(), "Bad DCT precision %d", prec); return gFalse; @@ -3884,6 +3894,7 @@ FlateStream::FlateStream(Stream *strA, int predictor, int columns, } litCodeTab.codes = NULL; distCodeTab.codes = NULL; + memset(buf, 0, flateWindow); } FlateStream::~FlateStream() { @@ -4444,33 +4455,61 @@ void ASCII85Encoder::reset() { GBool ASCII85Encoder::fillBuf() { Gulong t; char buf1[5]; - int c; + int c0, c1, c2, c3; int n, i; - if (eof) + if (eof) { return gFalse; - t = 0; - for (n = 0; n < 4; ++n) { - if ((c = str->getChar()) == EOF) - break; - t = (t << 8) + c; } + c0 = str->getChar(); + c1 = str->getChar(); + c2 = str->getChar(); + c3 = str->getChar(); bufPtr = bufEnd = buf; - if (n > 0) { - if (n == 4 && t == 0) { + if (c3 == EOF) { + if (c0 == EOF) { + n = 0; + t = 0; + } else { + if (c1 == EOF) { + n = 1; + t = c0 << 24; + } else if (c2 == EOF) { + n = 2; + t = (c0 << 24) | (c1 << 16); + } else { + n = 3; + t = (c0 << 24) | (c1 << 16) | (c2 << 8); + } + for (i = 4; i >= 0; --i) { + buf1[i] = (char)(t % 85 + 0x21); + t /= 85; + } + for (i = 0; i <= n; ++i) { + *bufEnd++ = buf1[i]; + if (++lineLen == 65) { + *bufEnd++ = '\n'; + lineLen = 0; + } + } + } + *bufEnd++ = '~'; + *bufEnd++ = '>'; + eof = gTrue; + } else { + t = (c0 << 24) | (c1 << 16) | (c2 << 8) | c3; + if (t == 0) { *bufEnd++ = 'z'; if (++lineLen == 65) { *bufEnd++ = '\n'; lineLen = 0; } } else { - if (n < 4) - t <<= 8 * (4 - n); for (i = 4; i >= 0; --i) { buf1[i] = (char)(t % 85 + 0x21); t /= 85; } - for (i = 0; i <= n; ++i) { + for (i = 0; i <= 4; ++i) { *bufEnd++ = buf1[i]; if (++lineLen == 65) { *bufEnd++ = '\n'; @@ -4479,12 +4518,7 @@ GBool ASCII85Encoder::fillBuf() { } } } - if (n < 4) { - *bufEnd++ = '~'; - *bufEnd++ = '>'; - eof = gTrue; - } - return bufPtr < bufEnd; + return gTrue; } //------------------------------------------------------------------------ |