Index: poppler/Object.cc =================================================================== --- poppler/Object.cc (revision 52) +++ poppler/Object.cc (working copy) @@ -175,7 +175,7 @@ fprintf(f, "["); for (i = 0; i < arrayGetLength(); ++i) { if (i > 0) - fprintf(f, " "); + fprintf(f, " "); arrayGetNF(i, &obj); obj.print(f); obj.free(); @@ -225,7 +225,7 @@ fprintf(f, "Allocated objects:\n"); for (i = 0; i < numObjTypes; ++i) { if (numAlloc[i] > 0) - fprintf(f, " %-20s: %6d\n", objTypeNames[i], numAlloc[i]); + fprintf(f, " %-20s: %6d\n", objTypeNames[i], numAlloc[i]); } } #endif Index: poppler/UGooString.h =================================================================== --- poppler/UGooString.h (revision 52) +++ poppler/UGooString.h (working copy) @@ -47,6 +47,7 @@ // Compare two strings: -1:< 0:= +1:> int cmp(const UGooString *str) const; int cmp(const UGooString &str) const; + int cmp(const char *str, int strLen = CALC_STRING_LEN) const; // get the unicode Unicode *unicode() const { return s; } @@ -55,15 +56,16 @@ // ascii (non-Unicode) format. Caller has to delete [] the result char *getCString() const; + // a special value telling that the length of the string is not given + // so it must be calculated from the strings + static const int CALC_STRING_LEN = -1; + private: // you can tweak this number for a different speed/memory usage tradeoffs. // In libc malloc() rounding is 16 so it's best to choose a value that // results in sizeof(UGooString) be a multiple of 16. // 20 makes sizeof(UGooString) to be 48. static const int STR_STATIC_SIZE = 20; - // a special value telling that the length of the string is not given - // so it must be calculated from the strings - static const int CALC_STRING_LEN = -1; int roundedSize(int len); void initChar(const char *str, int strLen); Index: poppler/XRef.h =================================================================== --- poppler/XRef.h (revision 52) +++ poppler/XRef.h (working copy) @@ -54,8 +54,8 @@ // Set the encryption parameters. void setEncryption(int permFlagsA, GBool ownerPasswordOkA, - Guchar *fileKeyA, int keyLengthA, - int encVersionA, int encRevisionA); + Guchar *fileKeyA, int keyLengthA, + int encVersionA, int encRevisionA); // Is the file encrypted? GBool isEncrypted() { return encrypted; } @@ -106,7 +106,7 @@ BaseStream *str; // input stream Guint start; // offset in file (to allow for garbage - // at beginning of file) + // at beginning of file) XRefEntry *entries; // xref entries int size; // size of array int rootNum, rootGen; // catalog dict @@ -115,7 +115,7 @@ Object trailerDict; // trailer dictionary Guint lastXRefPos; // offset of last xref table Guint *streamEnds; // 'endstream' positions - only used in - // damaged files + // damaged files int streamEndsLen; // number of valid entries in streamEnds ObjectStream *objStr; // cached object stream GBool encrypted; // true if file is encrypted Index: poppler/Object.h =================================================================== --- poppler/Object.h (revision 52) +++ poppler/Object.h (working copy) @@ -18,12 +18,12 @@ #include "goo/gtypes.h" #include "goo/gmem.h" #include "goo/GooString.h" +#include "UGooString.h" class XRef; class Array; class Dict; class Stream; -class UGooString; //------------------------------------------------------------------------ // Ref @@ -168,6 +168,13 @@ GBool dictIs(char *dictType); Object *dictLookup(const UGooString &key, Object *obj); Object *dictLookupNF(const UGooString &key, Object *obj); + Object *dictLookupRefNoFetch(const UGooString &key); + Object *dictLookup(const char *key, Object *obj, int keyLen=UGooString::CALC_STRING_LEN); + Object *dictLookupNF(const char *key, Object *obj, int keyLen=UGooString::CALC_STRING_LEN); + Object *dictLookupRefNoFetch(const char *key, int keyLen=UGooString::CALC_STRING_LEN); + GBool dictLookupBool(const char *key, const char *alt_key, GBool *value); + GBool dictLookupInt(const char *key, const char *alt_key, int *value); + UGooString *dictGetKey(int i); Object *dictGetVal(int i, Object *obj); Object *dictGetValNF(int i, Object *obj); @@ -251,9 +258,27 @@ inline Object *Object::dictLookup(const UGooString &key, Object *obj) { return dict->lookup(key, obj); } +inline Object *Object::dictLookup(const char *key, Object *obj, int keyLen) + { return dict->lookup(key, obj, keyLen); } + inline Object *Object::dictLookupNF(const UGooString &key, Object *obj) { return dict->lookupNF(key, obj); } +inline Object *Object::dictLookupNF(const char *key, Object *obj, int keyLen) + { return dict->lookupNF(key, obj, keyLen); } + +inline Object *Object::dictLookupRefNoFetch(const UGooString &key) + { return dict->lookupRefNoFetch(key); } + +inline Object *Object::dictLookupRefNoFetch(const char *key, int keyLen) + { return dict->lookupRefNoFetch(key, keyLen); } + +inline GBool Object::dictLookupBool(const char *key, const char *alt_key, GBool *value) + { return dict->lookupBool(key, alt_key, value); } + +inline GBool Object::dictLookupInt(const char *key, const char *alt_key, int *value) + { return dict->lookupInt(key, alt_key, value); } + inline UGooString *Object::dictGetKey(int i) { return dict->getKey(i); } Index: poppler/Stream.cc =================================================================== --- poppler/Stream.cc (revision 52) +++ poppler/Stream.cc (working copy) @@ -86,7 +86,7 @@ break; if (c == '\r') { if ((c = lookChar()) == '\n') - getChar(); + getChar(); break; } buf[i] = c; @@ -122,14 +122,14 @@ for (i = 0; i < obj.arrayGetLength(); ++i) { obj.arrayGet(i, &obj2); if (params.isArray()) - params.arrayGet(i, ¶ms2); + params.arrayGet(i, ¶ms2); else - params2.initNull(); + params2.initNull(); if (obj2.isName()) { - str = makeFilter(obj2.getName(), str, ¶ms2); + str = makeFilter(obj2.getName(), str, ¶ms2); } else { - error(getPos(), "Bad filter name"); - str = new EOFStream(str); + error(getPos(), "Bad filter name"); + str = new EOFStream(str); } obj2.free(); params2.free(); @@ -164,26 +164,11 @@ bits = 8; early = 1; if (params->isDict()) { - params->dictLookup("Predictor", &obj); - if (obj.isInt()) - pred = obj.getInt(); - obj.free(); - params->dictLookup("Columns", &obj); - if (obj.isInt()) - columns = obj.getInt(); - obj.free(); - params->dictLookup("Colors", &obj); - if (obj.isInt()) - colors = obj.getInt(); - obj.free(); - params->dictLookup("BitsPerComponent", &obj); - if (obj.isInt()) - bits = obj.getInt(); - obj.free(); - params->dictLookup("EarlyChange", &obj); - if (obj.isInt()) - early = obj.getInt(); - obj.free(); + params->dictLookupInt("Predictor", NULL, &pred); + params->dictLookupInt("Columns", NULL, &columns); + params->dictLookupInt("Colors", NULL, &colors); + params->dictLookupInt("BitsPerComponent", NULL, &bits); + params->dictLookupInt("EarlyChange", NULL, &early); } str = new LZWStream(str, pred, columns, colors, bits, early); } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) { @@ -197,44 +182,16 @@ endOfBlock = gTrue; black = gFalse; if (params->isDict()) { - params->dictLookup("K", &obj); - if (obj.isInt()) { - encoding = obj.getInt(); - } - obj.free(); - params->dictLookup("EndOfLine", &obj); - if (obj.isBool()) { - endOfLine = obj.getBool(); - } - obj.free(); - params->dictLookup("EncodedByteAlign", &obj); - if (obj.isBool()) { - byteAlign = obj.getBool(); - } - obj.free(); - params->dictLookup("Columns", &obj); - if (obj.isInt()) { - columns = obj.getInt(); - } - obj.free(); - params->dictLookup("Rows", &obj); - if (obj.isInt()) { - rows = obj.getInt(); - } - obj.free(); - params->dictLookup("EndOfBlock", &obj); - if (obj.isBool()) { - endOfBlock = obj.getBool(); - } - obj.free(); - params->dictLookup("BlackIs1", &obj); - if (obj.isBool()) { - black = obj.getBool(); - } - obj.free(); + params->dictLookupInt("K", NULL, &encoding); + params->dictLookupBool("EndOfLine", NULL, &endOfLine); + params->dictLookupBool("EncodedByteAlign", NULL, &byteAlign); + params->dictLookupInt("Columns", NULL, &columns); + params->dictLookupInt("Rows", NULL, &rows); + params->dictLookupBool("EndOfBlock", NULL, &endOfBlock); + params->dictLookupBool("BlackIs1", NULL, &black); } str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign, - columns, rows, endOfBlock, black); + columns, rows, endOfBlock, black); } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) { str = new DCTStream(str); } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) { @@ -243,22 +200,10 @@ colors = 1; bits = 8; if (params->isDict()) { - params->dictLookup("Predictor", &obj); - if (obj.isInt()) - pred = obj.getInt(); - obj.free(); - params->dictLookup("Columns", &obj); - if (obj.isInt()) - columns = obj.getInt(); - obj.free(); - params->dictLookup("Colors", &obj); - if (obj.isInt()) - colors = obj.getInt(); - obj.free(); - params->dictLookup("BitsPerComponent", &obj); - if (obj.isInt()) - bits = obj.getInt(); - obj.free(); + params->dictLookupInt("Predictor", NULL, &pred); + params->dictLookupInt("Columns", NULL, &columns); + params->dictLookupInt("Colors", NULL, &colors); + params->dictLookupInt("BitsPerComponent", NULL, &bits); } str = new FlateStream(str, pred, columns, colors, bits); } else if (!strcmp(name, "JBIG2Decode")) { @@ -292,7 +237,7 @@ } void BaseStream::doDecryption(Guchar *fileKey, int keyLength, - int objNum, int objGen) { + int objNum, int objGen) { decrypt = new Decrypt(fileKey, keyLength, objNum, objGen); } @@ -386,8 +331,8 @@ bits = 0; for (i = 0; i < nVals; ++i) { if (bits < nBits) { - buf = (buf << 8) | (str->getChar() & 0xff); - bits += 8; + buf = (buf << 8) | (str->getChar() & 0xff); + bits += 8; } imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask); bits -= nBits; @@ -410,7 +355,7 @@ //------------------------------------------------------------------------ StreamPredictor::StreamPredictor(Stream *strA, int predictorA, - int widthA, int nCompsA, int nBitsA) { + int widthA, int nCompsA, int nBitsA) { int totalBits; str = strA; @@ -496,10 +441,10 @@ upLeftBuf[0] = predLine[i]; if ((c = str->getRawChar()) == EOF) { if (i > pixBytes) { - // this ought to return false, but some (broken) PDF files - // contain truncated image data, and Adobe apparently reads the - // last partial line - break; + // this ought to return false, but some (broken) PDF files + // contain truncated image data, and Adobe apparently reads the + // last partial line + break; } return gFalse; } @@ -512,7 +457,7 @@ break; case 13: // PNG average predLine[i] = ((predLine[i - pixBytes] + predLine[i]) >> 1) + - (Guchar)c; + (Guchar)c; break; case 14: // PNG Paeth left = predLine[i - pixBytes]; @@ -520,17 +465,17 @@ upLeft = upLeftBuf[pixBytes]; p = left + up - upLeft; if ((pa = p - left) < 0) - pa = -pa; + pa = -pa; if ((pb = p - up) < 0) - pb = -pb; + pb = -pb; if ((pc = p - upLeft) < 0) - pc = -pc; + pc = -pc; if (pa <= pb && pa <= pc) - predLine[i] = left + (Guchar)c; + predLine[i] = left + (Guchar)c; else if (pb <= pc) - predLine[i] = up + (Guchar)c; + predLine[i] = up + (Guchar)c; else - predLine[i] = upLeft + (Guchar)c; + predLine[i] = upLeft + (Guchar)c; break; case 10: // PNG none default: // no predictor or TIFF predictor @@ -544,13 +489,13 @@ if (nBits == 1) { inBuf = predLine[pixBytes - 1]; for (i = pixBytes; i < rowBytes; i += 8) { - // 1-bit add is just xor - inBuf = (inBuf << 8) | predLine[i]; - predLine[i] ^= inBuf >> nComps; + // 1-bit add is just xor + inBuf = (inBuf << 8) | predLine[i]; + predLine[i] ^= inBuf >> nComps; } } else if (nBits == 8) { for (i = pixBytes; i < rowBytes; ++i) { - predLine[i] += predLine[i - nComps]; + predLine[i] += predLine[i - nComps]; } } else { memset(upLeftBuf, 0, nComps + 1); @@ -559,25 +504,25 @@ inBits = outBits = 0; j = k = pixBytes; for (i = 0; i < width; ++i) { - for (kk = 0; kk < nComps; ++kk) { - if (inBits < nBits) { - inBuf = (inBuf << 8) | (predLine[j++] & 0xff); - inBits += 8; - } - upLeftBuf[kk] = (upLeftBuf[kk] + - (inBuf >> (inBits - nBits))) & bitMask; - inBits -= nBits; - outBuf = (outBuf << nBits) | upLeftBuf[kk]; - outBits += nBits; - if (outBits >= 8) { - predLine[k++] = (Guchar)(outBuf >> (outBits - 8)); - outBits -= 8; - } - } + for (kk = 0; kk < nComps; ++kk) { + if (inBits < nBits) { + inBuf = (inBuf << 8) | (predLine[j++] & 0xff); + inBits += 8; + } + upLeftBuf[kk] = (upLeftBuf[kk] + + (inBuf >> (inBits - nBits))) & bitMask; + inBits -= nBits; + outBuf = (outBuf << nBits) | upLeftBuf[kk]; + outBits += nBits; + if (outBits >= 8) { + predLine[k++] = (Guchar)(outBuf >> (outBits - 8)); + outBits -= 8; + } + } } if (outBits > 0) { - predLine[k++] = (Guchar)((outBuf << (8 - outBits)) + - (inBuf & ((1 << (8 - outBits)) - 1))); + predLine[k++] = (Guchar)((outBuf << (8 - outBits)) + + (inBuf & ((1 << (8 - outBits)) - 1))); } } } @@ -593,7 +538,7 @@ //------------------------------------------------------------------------ FileStream::FileStream(FILE *fA, Guint startA, GBool limitedA, - Guint lengthA, Object *dictA): + Guint lengthA, Object *dictA): BaseStream(dictA) { f = fA; start = startA; @@ -610,7 +555,7 @@ } Stream *FileStream::makeSubStream(Guint startA, GBool limitedA, - Guint lengthA, Object *dictA) { + Guint lengthA, Object *dictA) { return new FileStream(f, startA, limitedA, lengthA, dictA); } @@ -742,7 +687,7 @@ } Stream *MemStream::makeSubStream(Guint startA, GBool limited, - Guint lengthA, Object *dictA) { + Guint lengthA, Object *dictA) { MemStream *subStr; Guint newLength; @@ -788,7 +733,7 @@ } void MemStream::doDecryption(Guchar *fileKey, int keyLength, - int objNum, int objGen) { + int objNum, int objGen) { char *newBuf; char *p, *q; @@ -811,7 +756,7 @@ //------------------------------------------------------------------------ EmbedStream::EmbedStream(Stream *strA, Object *dictA, - GBool limitedA, Guint lengthA): + GBool limitedA, Guint lengthA): BaseStream(dictA) { str = strA; limited = limitedA; @@ -822,7 +767,7 @@ } Stream *EmbedStream::makeSubStream(Guint start, GBool limitedA, - Guint lengthA, Object *dictA) { + Guint lengthA, Object *dictA) { error(-1, "Internal: called makeSubStream() on EmbedStream"); return NULL; } @@ -985,24 +930,24 @@ n = 4; } else { for (k = 1; k < 5; ++k) { - do { - c[k] = str->getChar(); - } while (Lexer::isSpace(c[k])); - if (c[k] == '~' || c[k] == EOF) - break; + do { + c[k] = str->getChar(); + } while (Lexer::isSpace(c[k])); + if (c[k] == '~' || c[k] == EOF) + break; } n = k - 1; if (k < 5 && (c[k] == '~' || c[k] == EOF)) { - for (++k; k < 5; ++k) - c[k] = 0x21 + 84; - eof = gTrue; + for (++k; k < 5; ++k) + c[k] = 0x21 + 84; + eof = gTrue; } t = 0; for (k = 0; k < 5; ++k) - t = t * 85 + (c[k] - 0x21); + t = t * 85 + (c[k] - 0x21); for (k = 3; k >= 0; --k) { - b[k] = (int)(t & 0xff); - t >>= 8; + b[k] = (int)(t & 0xff); + t >>= 8; } } } @@ -1031,7 +976,7 @@ //------------------------------------------------------------------------ LZWStream::LZWStream(Stream *strA, int predictor, int columns, int colors, - int bits, int earlyA): + int bits, int earlyA): FilterStream(strA) { if (predictor != 1) { pred = new StreamPredictor(this, predictor, columns, colors, bits); @@ -1284,8 +1229,8 @@ //------------------------------------------------------------------------ CCITTFaxStream::CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA, - GBool byteAlignA, int columnsA, int rowsA, - GBool endOfBlockA, GBool blackA): + GBool byteAlignA, int columnsA, int rowsA, + GBool endOfBlockA, GBool blackA): FilterStream(strA) { encoding = encodingA; endOfLine = endOfLineA; @@ -1363,133 +1308,133 @@ // 2-D encoding if (nextLine2D) { for (i = 0; codingLine[i] < columns; ++i) - refLine[i] = codingLine[i]; + refLine[i] = codingLine[i]; refLine[i] = refLine[i + 1] = columns; b1 = 1; a0New = codingLine[a0 = 0] = 0; do { - code1 = getTwoDimCode(); - switch (code1) { - case twoDimPass: - if (refLine[b1] < columns) { - a0New = refLine[b1 + 1]; - b1 += 2; - } - break; - case twoDimHoriz: - if ((a0 & 1) == 0) { - code1 = code2 = 0; - do { - code1 += code3 = getWhiteCode(); - } while (code3 >= 64); - do { - code2 += code3 = getBlackCode(); - } while (code3 >= 64); - } else { - code1 = code2 = 0; - do { - code1 += code3 = getBlackCode(); - } while (code3 >= 64); - do { - code2 += code3 = getWhiteCode(); - } while (code3 >= 64); - } - if (code1 > 0 || code2 > 0) { - codingLine[a0 + 1] = a0New + code1; - ++a0; - a0New = codingLine[a0 + 1] = codingLine[a0] + code2; - ++a0; - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) - b1 += 2; - } - break; - case twoDimVert0: - a0New = codingLine[++a0] = refLine[b1]; - if (refLine[b1] < columns) { - ++b1; - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) - b1 += 2; - } - break; - case twoDimVertR1: - a0New = codingLine[++a0] = refLine[b1] + 1; - if (refLine[b1] < columns) { - ++b1; - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) - b1 += 2; - } - break; - case twoDimVertL1: - if (a0 == 0 || refLine[b1] - 1 > a0New) { - a0New = codingLine[++a0] = refLine[b1] - 1; - --b1; - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) - b1 += 2; - } - break; - case twoDimVertR2: - a0New = codingLine[++a0] = refLine[b1] + 2; - if (refLine[b1] < columns) { - ++b1; - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) - b1 += 2; - } - break; - case twoDimVertL2: - if (a0 == 0 || refLine[b1] - 2 > a0New) { - a0New = codingLine[++a0] = refLine[b1] - 2; - --b1; - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) - b1 += 2; - } - break; - case twoDimVertR3: - a0New = codingLine[++a0] = refLine[b1] + 3; - if (refLine[b1] < columns) { - ++b1; - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) - b1 += 2; - } - break; - case twoDimVertL3: - if (a0 == 0 || refLine[b1] - 3 > a0New) { - a0New = codingLine[++a0] = refLine[b1] - 3; - --b1; - while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) - b1 += 2; - } - break; - case EOF: - eof = gTrue; - codingLine[a0 = 0] = columns; - return EOF; - default: - error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1); - err = gTrue; - break; - } + code1 = getTwoDimCode(); + switch (code1) { + case twoDimPass: + if (refLine[b1] < columns) { + a0New = refLine[b1 + 1]; + b1 += 2; + } + break; + case twoDimHoriz: + if ((a0 & 1) == 0) { + code1 = code2 = 0; + do { + code1 += code3 = getWhiteCode(); + } while (code3 >= 64); + do { + code2 += code3 = getBlackCode(); + } while (code3 >= 64); + } else { + code1 = code2 = 0; + do { + code1 += code3 = getBlackCode(); + } while (code3 >= 64); + do { + code2 += code3 = getWhiteCode(); + } while (code3 >= 64); + } + if (code1 > 0 || code2 > 0) { + codingLine[a0 + 1] = a0New + code1; + ++a0; + a0New = codingLine[a0 + 1] = codingLine[a0] + code2; + ++a0; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVert0: + a0New = codingLine[++a0] = refLine[b1]; + if (refLine[b1] < columns) { + ++b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVertR1: + a0New = codingLine[++a0] = refLine[b1] + 1; + if (refLine[b1] < columns) { + ++b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVertL1: + if (a0 == 0 || refLine[b1] - 1 > a0New) { + a0New = codingLine[++a0] = refLine[b1] - 1; + --b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVertR2: + a0New = codingLine[++a0] = refLine[b1] + 2; + if (refLine[b1] < columns) { + ++b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVertL2: + if (a0 == 0 || refLine[b1] - 2 > a0New) { + a0New = codingLine[++a0] = refLine[b1] - 2; + --b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVertR3: + a0New = codingLine[++a0] = refLine[b1] + 3; + if (refLine[b1] < columns) { + ++b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVertL3: + if (a0 == 0 || refLine[b1] - 3 > a0New) { + a0New = codingLine[++a0] = refLine[b1] - 3; + --b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case EOF: + eof = gTrue; + codingLine[a0 = 0] = columns; + return EOF; + default: + error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1); + err = gTrue; + break; + } } while (codingLine[a0] < columns); // 1-D encoding } else { codingLine[a0 = 0] = 0; while (1) { - code1 = 0; - do { - code1 += code3 = getWhiteCode(); - } while (code3 >= 64); - codingLine[a0+1] = codingLine[a0] + code1; - ++a0; - 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) - break; + code1 = 0; + do { + code1 += code3 = getWhiteCode(); + } while (code3 >= 64); + codingLine[a0+1] = codingLine[a0] + code1; + ++a0; + 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) + break; } } @@ -1497,7 +1442,7 @@ error(getPos(), "CCITTFax row is wrong length (%d)", codingLine[a0]); // force the row to be the correct length while (codingLine[a0] > columns) { - --a0; + --a0; } codingLine[++a0] = columns; err = gTrue; @@ -1515,14 +1460,14 @@ } else { code1 = lookBits(12); while (code1 == 0) { - eatBits(1); - code1 = lookBits(12); + eatBits(1); + code1 = lookBits(12); } if (code1 == 0x001) { - eatBits(12); - gotEOL = gTrue; + eatBits(12); + gotEOL = gTrue; } else if (code1 == EOF) { - eof = gTrue; + eof = gTrue; } } @@ -1536,25 +1481,25 @@ if (endOfBlock && gotEOL) { 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); - } - } - } - eof = gTrue; + 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; } // look for an end-of-line marker after an error -- we only do @@ -1562,17 +1507,17 @@ // the "just plow on" technique tends to work better otherwise } else if (err && endOfLine) { do { - if (code1 == EOF) { - eof = gTrue; - return EOF; - } - eatBits(1); - code1 = lookBits(13); + if (code1 == EOF) { + eof = gTrue; + return EOF; + } + eatBits(1); + code1 = lookBits(13); } while ((code1 >> 1) != 0x001); eatBits(12); if (encoding > 0) { - eatBits(1); - nextLine2D = !(code1 & 1); + eatBits(1); + nextLine2D = !(code1 & 1); } } @@ -1592,7 +1537,7 @@ if ((outputBits -= 8) == 0) { ++a0; if (codingLine[a0] < columns) { - outputBits = codingLine[a0 + 1] - codingLine[a0]; + outputBits = codingLine[a0 + 1] - codingLine[a0]; } } } else { @@ -1600,23 +1545,23 @@ ret = 0; do { if (outputBits > bits) { - i = bits; - bits = 0; - if ((a0 & 1) == 0) { - ret |= 0xff >> (8 - i); - } - outputBits -= i; + i = bits; + bits = 0; + if ((a0 & 1) == 0) { + ret |= 0xff >> (8 - i); + } + outputBits -= i; } else { - i = outputBits; - bits -= outputBits; - if ((a0 & 1) == 0) { - ret |= (0xff >> (8 - i)) << bits; - } - outputBits = 0; - ++a0; - if (codingLine[a0] < columns) { - outputBits = codingLine[a0 + 1] - codingLine[a0]; - } + i = outputBits; + bits -= outputBits; + if ((a0 & 1) == 0) { + ret |= (0xff >> (8 - i)) << bits; + } + outputBits = 0; + ++a0; + if (codingLine[a0] < columns) { + outputBits = codingLine[a0 + 1] - codingLine[a0]; + } } } while (bits > 0 && codingLine[a0] < columns); } @@ -1641,12 +1586,12 @@ for (n = 1; n <= 7; ++n) { code = lookBits(n); if (n < 7) { - code <<= 7 - n; + code <<= 7 - n; } p = &twoDimTab1[code]; if (p->bits == n) { - eatBits(n); - return p->n; + eatBits(n); + return p->n; } } } @@ -1675,23 +1620,23 @@ for (n = 1; n <= 9; ++n) { code = lookBits(n); if (n < 9) { - code <<= 9 - n; + code <<= 9 - n; } p = &whiteTab2[code]; if (p->bits == n) { - eatBits(n); - return p->n; + eatBits(n); + return p->n; } } for (n = 11; n <= 12; ++n) { code = lookBits(n); if (n < 12) { - code <<= 12 - n; + code <<= 12 - n; } p = &whiteTab1[code]; if (p->bits == n) { - eatBits(n); - return p->n; + eatBits(n); + return p->n; } } } @@ -1725,36 +1670,36 @@ for (n = 2; n <= 6; ++n) { code = lookBits(n); if (n < 6) { - code <<= 6 - n; + code <<= 6 - n; } p = &blackTab3[code]; if (p->bits == n) { - eatBits(n); - return p->n; + eatBits(n); + return p->n; } } for (n = 7; n <= 12; ++n) { code = lookBits(n); if (n < 12) { - code <<= 12 - n; + code <<= 12 - n; } if (code >= 64) { - p = &blackTab2[code - 64]; - if (p->bits == n) { - eatBits(n); - return p->n; - } + p = &blackTab2[code - 64]; + if (p->bits == n) { + eatBits(n); + return p->n; + } } } for (n = 10; n <= 13; ++n) { code = lookBits(n); if (n < 13) { - code <<= 13 - n; + code <<= 13 - n; } p = &blackTab1[code]; if (p->bits == n) { - eatBits(n); - return p->n; + eatBits(n); + return p->n; } } } @@ -1771,7 +1716,7 @@ while (inputBits < n) { if ((c = str->getChar()) == EOF) { if (inputBits == 0) { - return EOF; + return EOF; } // 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 @@ -2362,8 +2307,8 @@ // Read one data unit from a sequential JPEG stream. GBool DCTStream::readProgressiveDataUnit(DCTHuffTable *dcHuffTable, - DCTHuffTable *acHuffTable, - int *prevDC, int data[64]) { + DCTHuffTable *acHuffTable, + int *prevDC, int data[64]) { int run, size, amp, bit, c; int i, j, k; @@ -2631,7 +2576,7 @@ // The stage numbers mentioned in the comments refer to Figure 1 in this // paper. void DCTStream::transformDataUnit(Gushort *quantTable, - int dataIn[64], Guchar dataOut[64]) { + int dataIn[64], Guchar dataOut[64]) { int v0, v1, v2, v3, v4, v5, v6, v7, t; int *p; int i; @@ -3874,7 +3819,7 @@ }; FlateStream::FlateStream(Stream *strA, int predictor, int columns, - int colors, int bits): + int colors, int bits): FilterStream(strA) { if (predictor != 1) { pred = new StreamPredictor(this, predictor, columns, colors, bits); @@ -4025,20 +3970,20 @@ code1 -= 257; code2 = lengthDecode[code1].bits; if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF) - goto err; + goto err; len = lengthDecode[code1].first + code2; if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF) - goto err; + goto err; code2 = distDecode[code1].bits; if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF) - goto err; + goto err; dist = distDecode[code1].first + code2; i = index; j = (index - dist) & flateMask; for (k = 0; k < len; ++k) { - buf[i] = buf[j]; - i = (i + 1) & flateMask; - j = (j + 1) & flateMask; + buf[i] = buf[j]; + i = (i + 1) & flateMask; + j = (j + 1) & flateMask; } remain = len; } @@ -4047,8 +3992,8 @@ len = (blockLen < flateWindow) ? blockLen : flateWindow; for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) { if ((c = str->getChar()) == EOF) { - endOfBlock = eof = gTrue; - break; + endOfBlock = eof = gTrue; + break; } buf[j] = c & 0xff; } @@ -4191,38 +4136,38 @@ } if (code == 16) { if ((repeat = getCodeWord(2)) == EOF) { - goto err; + goto err; } repeat += 3; if (i + repeat > numLitCodes + numDistCodes) { - goto err; + goto err; } for (; repeat > 0; --repeat) { - codeLengths[i++] = len; + codeLengths[i++] = len; } } else if (code == 17) { if ((repeat = getCodeWord(3)) == EOF) { - goto err; + goto err; } repeat += 3; if (i + repeat > numLitCodes + numDistCodes) { - goto err; + goto err; } len = 0; for (; repeat > 0; --repeat) { - codeLengths[i++] = 0; + codeLengths[i++] = 0; } } else if (code == 18) { if ((repeat = getCodeWord(7)) == EOF) { - goto err; + goto err; } repeat += 11; if (i + repeat > numLitCodes + numDistCodes) { - goto err; + goto err; } len = 0; for (; repeat > 0; --repeat) { - codeLengths[i++] = 0; + codeLengths[i++] = 0; } } else { codeLengths[i++] = len = code; @@ -4270,21 +4215,21 @@ for (val = 0; val < n; ++val) { if (lengths[val] == len) { - // bit-reverse the code - code2 = 0; - t = code; - for (i = 0; i < len; ++i) { - code2 = (code2 << 1) | (t & 1); - t >>= 1; - } + // bit-reverse the code + code2 = 0; + t = code; + for (i = 0; i < len; ++i) { + code2 = (code2 << 1) | (t & 1); + t >>= 1; + } - // fill in the table entries - for (i = code2; i < tabSize; i += skip) { - tab->codes[i].len = (Gushort)len; - tab->codes[i].val = (Gushort)val; - } + // fill in the table entries + for (i = code2; i < tabSize; i += skip) { + tab->codes[i].len = (Gushort)len; + tab->codes[i].val = (Gushort)val; + } - ++code; + ++code; } } } @@ -4464,22 +4409,22 @@ if (n == 4 && t == 0) { *bufEnd++ = 'z'; if (++lineLen == 65) { - *bufEnd++ = '\n'; - lineLen = 0; + *bufEnd++ = '\n'; + lineLen = 0; } } else { if (n < 4) - t <<= 8 * (4 - n); + t <<= 8 * (4 - n); for (i = 4; i >= 0; --i) { - buf1[i] = (char)(t % 85 + 0x21); - t /= 85; + 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++ = buf1[i]; + if (++lineLen == 65) { + *bufEnd++ = '\n'; + lineLen = 0; + } } } } @@ -4575,13 +4520,13 @@ n = 2; while (n < 128) { if ((c = str->getChar()) == EOF) { - eof = gTrue; - break; + eof = gTrue; + break; } ++n; buf[n] = c; if (buf[n] == buf[n-1]) - break; + break; } if (buf[n] == buf[n-1]) { buf[0] = (char)(n-2-1); Index: poppler/Stream.h =================================================================== --- poppler/Stream.h (revision 52) +++ poppler/Stream.h (working copy) @@ -107,7 +107,7 @@ // Get image parameters which are defined by the stream contents. virtual void getImageParams(int * /*bitsPerComponent*/, - StreamColorSpaceMode * /*csMode*/) {} + StreamColorSpaceMode * /*csMode*/) {} // Add filters to this stream according to the parameters in . // Returns the new stream. @@ -132,7 +132,7 @@ BaseStream(Object *dictA); virtual ~BaseStream(); virtual Stream *makeSubStream(Guint start, GBool limited, - Guint length, Object *dict) = 0; + Guint length, Object *dict) = 0; virtual void setPos(Guint pos, int dir = 0) = 0; virtual GBool isBinary(GBool last = gTrue) { return last; } virtual BaseStream *getBaseStream() { return this; } @@ -144,7 +144,7 @@ // Set decryption for this stream. virtual void doDecryption(Guchar *fileKey, int keyLength, - int objNum, int objGen); + int objNum, int objGen); protected: @@ -226,7 +226,7 @@ // Create a predictor object. Note that the parameters are for the // predictor, and may not match the actual image parameters. StreamPredictor(Stream *strA, int predictorA, - int widthA, int nCompsA, int nBitsA); + int widthA, int nCompsA, int nBitsA); ~StreamPredictor(); @@ -262,10 +262,10 @@ public: FileStream(FILE *fA, Guint startA, GBool limitedA, - Guint lengthA, Object *dictA); + Guint lengthA, Object *dictA); virtual ~FileStream(); virtual Stream *makeSubStream(Guint startA, GBool limitedA, - Guint lengthA, Object *dictA); + Guint lengthA, Object *dictA); virtual StreamKind getKind() { return strFile; } virtual void reset(); virtual void close(); @@ -304,7 +304,7 @@ MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA); virtual ~MemStream(); virtual Stream *makeSubStream(Guint start, GBool limited, - Guint lengthA, Object *dictA); + Guint lengthA, Object *dictA); virtual StreamKind getKind() { return strWeird; } virtual void reset(); virtual void close(); @@ -317,7 +317,7 @@ virtual Guint getStart() { return start; } virtual void moveStart(int delta); virtual void doDecryption(Guchar *fileKey, int keyLength, - int objNum, int objGen); + int objNum, int objGen); private: @@ -345,7 +345,7 @@ EmbedStream(Stream *strA, Object *dictA, GBool limitedA, Guint lengthA); virtual ~EmbedStream(); virtual Stream *makeSubStream(Guint start, GBool limitedA, - Guint lengthA, Object *dictA); + Guint lengthA, Object *dictA); virtual StreamKind getKind() { return str->getKind(); } virtual void reset() {} virtual int getChar(); @@ -418,7 +418,7 @@ public: LZWStream(Stream *strA, int predictor, int columns, int colors, - int bits, int earlyA); + int bits, int earlyA); virtual ~LZWStream(); virtual StreamKind getKind() { return strLZW; } virtual void reset(); @@ -492,8 +492,8 @@ public: CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA, - GBool byteAlignA, int columnsA, int rowsA, - GBool endOfBlockA, GBool blackA); + GBool byteAlignA, int columnsA, int rowsA, + GBool endOfBlockA, GBool blackA); virtual ~CCITTFaxStream(); virtual StreamKind getKind() { return strCCITTFax; } virtual void reset(); @@ -546,7 +546,7 @@ struct DCTScanInfo { GBool comp[4]; // comp[i] is set if component i is - // included in this scan + // included in this scan int numComps; // number of components in the scan int dcHuffTable[4]; // DC Huffman table numbers int acHuffTable[4]; // AC Huffman table numbers @@ -608,14 +608,14 @@ GBool readMCURow(); void readScan(); GBool readDataUnit(DCTHuffTable *dcHuffTable, - DCTHuffTable *acHuffTable, - int *prevDC, int data[64]); + DCTHuffTable *acHuffTable, + int *prevDC, int data[64]); GBool readProgressiveDataUnit(DCTHuffTable *dcHuffTable, - DCTHuffTable *acHuffTable, - int *prevDC, int data[64]); + DCTHuffTable *acHuffTable, + int *prevDC, int data[64]); void decodeImage(); void transformDataUnit(Gushort *quantTable, - int dataIn[64], Guchar dataOut[64]); + int dataIn[64], Guchar dataOut[64]); int readHuffSym(DCTHuffTable *table); int readAmp(int size); int readBit(); @@ -667,7 +667,7 @@ public: FlateStream(Stream *strA, int predictor, int columns, - int colors, int bits); + int colors, int bits); virtual ~FlateStream(); virtual StreamKind getKind() { return strFlate; } virtual void reset(); Index: poppler/UGooString.cc =================================================================== --- poppler/UGooString.cc (revision 52) +++ poppler/UGooString.cc (working copy) @@ -9,6 +9,7 @@ //======================================================================== #include +#include #include "goo/gmem.h" #include "goo/GooString.h" @@ -157,8 +158,37 @@ return n1 - n2; } +int UGooString::cmp(const char *str, int strLen) const +{ + int n1, n2, i, x; + Unicode u; + Unicode *p1, *p2; + + assert(str); + if (strLen == CALC_STRING_LEN) { + n2 = 0; + if (str) + n2 = strlen(str); + } else { + n2 = strLen; + } + + p2 = &u; + n1 = length; + for (i = 0, p1 = s; i < n1 && i < n2; ++i, ++p1) { + u = pdfDocEncoding[str[i] & 0xff]; + if (!u) + u = (unsigned char)str[i]; + x = *p1 - *p2; + if (x != 0) { + return x; + } + } + return n1 - n2; +} + // FIXME: -// a) this is confusing because GooString::getCSTring() returns a pointer +// a) this is confusing because GooString::getCString() returns a pointer // but UGooString returns a newly allocated copy. Should give this // a different name, like copyAsAscii() or copyAsGooString() // b) this interface requires copying. It should be changed to take a Index: poppler/XRef.cc =================================================================== --- poppler/XRef.cc (revision 52) +++ poppler/XRef.cc (working copy) @@ -30,7 +30,7 @@ //------------------------------------------------------------------------ #define xrefSearchSize 1024 // read this many bytes at end of file - // to look for 'startxref' + // to look for 'startxref' //------------------------------------------------------------------------ // Permission bits @@ -140,7 +140,7 @@ obj1.free(); obj2.free(); if (objNums[i] < 0 || offsets[i] < 0 || - (i > 0 && offsets[i] < offsets[i-1])) { + (i > 0 && offsets[i] < offsets[i-1])) { delete parser; gfree(offsets); goto err1; @@ -163,7 +163,7 @@ str = new EmbedStream(objStr.getStream(), &obj1, gFalse, 0); } else { str = new EmbedStream(objStr.getStream(), &obj1, gTrue, - offsets[i+1] - offsets[i]); + offsets[i+1] - offsets[i]); } parser = new Parser(xref, new Lexer(xref, str)); parser->getObj(&objs[i]); @@ -238,8 +238,8 @@ // try to reconstruct it if (!ok) { if (!(ok = constructXRef())) { - errCode = errDamaged; - return; + errCode = errDamaged; + return; } } } @@ -315,8 +315,8 @@ // start up a parser, parse one token obj.initNull(); parser = new Parser(NULL, - new Lexer(NULL, - str->makeSubStream(start + *pos, gFalse, 0, &obj))); + new Lexer(NULL, + str->makeSubStream(start + *pos, gFalse, 0, &obj))); parser->getObj(&obj); // parse an old-style xref table @@ -383,10 +383,10 @@ } if (first + n > size) { for (newSize = size ? 2 * size : 1024; - first + n > newSize && newSize > 0; - newSize <<= 1) ; + first + n > newSize && newSize > 0; + newSize <<= 1) ; if (newSize < 0) { - goto err1; + goto err1; } if (newSize*(int)sizeof(XRefEntry)/sizeof(XRefEntry) != newSize) { error(-1, "Invalid 'obj' parameters'"); @@ -395,43 +395,43 @@ entries = (XRefEntry *)greallocn(entries, newSize, sizeof(XRefEntry)); for (i = size; i < newSize; ++i) { - entries[i].offset = 0xffffffff; - entries[i].type = xrefEntryFree; + entries[i].offset = 0xffffffff; + entries[i].type = xrefEntryFree; } size = newSize; } for (i = first; i < first + n; ++i) { if (!parser->getObj(&obj)->isInt()) { - goto err1; + goto err1; } entry.offset = (Guint)obj.getInt(); obj.free(); if (!parser->getObj(&obj)->isInt()) { - goto err1; + goto err1; } entry.gen = obj.getInt(); obj.free(); parser->getObj(&obj); if (obj.isCmd("n")) { - entry.type = xrefEntryUncompressed; + entry.type = xrefEntryUncompressed; } else if (obj.isCmd("f")) { - entry.type = xrefEntryFree; + entry.type = xrefEntryFree; } else { - goto err1; + goto err1; } obj.free(); if (entries[i].offset == 0xffffffff) { - entries[i] = entry; - // PDF files of patents from the IBM Intellectual Property - // Network have a bug: the xref table claims to start at 1 - // instead of 0. - if (i == 1 && first == 1 && - entries[1].offset == 0 && entries[1].gen == 65535 && - entries[1].type == xrefEntryFree) { - i = first = 0; - entries[0] = entries[1]; - entries[1].offset = 0xffffffff; - } + entries[i] = entry; + // PDF files of patents from the IBM Intellectual Property + // Network have a bug: the xref table claims to start at 1 + // instead of 0. + if (i == 1 && first == 1 && + entries[1].offset == 0 && entries[1].gen == 65535 && + entries[1].type == xrefEntryFree) { + i = first = 0; + entries[0] = entries[1]; + entries[1].offset = 0xffffffff; + } } } } @@ -533,21 +533,21 @@ if (idx.isArray()) { for (i = 0; i+1 < idx.arrayGetLength(); i += 2) { if (!idx.arrayGet(i, &obj)->isInt()) { - idx.free(); - goto err1; + idx.free(); + goto err1; } first = obj.getInt(); obj.free(); if (!idx.arrayGet(i+1, &obj)->isInt()) { - idx.free(); - goto err1; + idx.free(); + goto err1; } n = obj.getInt(); obj.free(); if (first < 0 || n < 0 || - !readXRefStreamSection(xrefStr, w, first, n)) { - idx.free(); - goto err0; + !readXRefStreamSection(xrefStr, w, first, n)) { + idx.free(); + goto err0; } } } else { @@ -588,8 +588,8 @@ } if (first + n > size) { for (newSize = size ? 2 * size : 1024; - first + n > newSize && newSize > 0; - newSize <<= 1) ; + first + n > newSize && newSize > 0; + newSize <<= 1) ; if (newSize < 0) { return gFalse; } @@ -609,43 +609,43 @@ type = 1; } else { for (type = 0, j = 0; j < w[0]; ++j) { - if ((c = xrefStr->getChar()) == EOF) { - return gFalse; - } - type = (type << 8) + c; + if ((c = xrefStr->getChar()) == EOF) { + return gFalse; + } + type = (type << 8) + c; } } for (offset = 0, j = 0; j < w[1]; ++j) { if ((c = xrefStr->getChar()) == EOF) { - return gFalse; + return gFalse; } offset = (offset << 8) + c; } for (gen = 0, j = 0; j < w[2]; ++j) { if ((c = xrefStr->getChar()) == EOF) { - return gFalse; + return gFalse; } gen = (gen << 8) + c; } if (entries[i].offset == 0xffffffff) { switch (type) { case 0: - entries[i].offset = offset; - entries[i].gen = gen; - entries[i].type = xrefEntryFree; - break; + entries[i].offset = offset; + entries[i].gen = gen; + entries[i].type = xrefEntryFree; + break; case 1: - entries[i].offset = offset; - entries[i].gen = gen; - entries[i].type = xrefEntryUncompressed; - break; + entries[i].offset = offset; + entries[i].gen = gen; + entries[i].type = xrefEntryUncompressed; + break; case 2: - entries[i].offset = offset; - entries[i].gen = gen; - entries[i].type = xrefEntryCompressed; - break; + entries[i].offset = offset; + entries[i].gen = gen; + entries[i].type = xrefEntryCompressed; + break; default: - return gFalse; + return gFalse; } } } @@ -686,21 +686,21 @@ if (!strncmp(p, "trailer", 7)) { obj.initNull(); parser = new Parser(NULL, - new Lexer(NULL, - str->makeSubStream(pos + 7, gFalse, 0, &obj))); + new Lexer(NULL, + str->makeSubStream(pos + 7, gFalse, 0, &obj))); parser->getObj(&newTrailerDict); if (newTrailerDict.isDict()) { - newTrailerDict.dictLookupNF("Root", &obj); - if (obj.isRef()) { - rootNum = obj.getRefNum(); - rootGen = obj.getRefGen(); - if (!trailerDict.isNone()) { - trailerDict.free(); - } - newTrailerDict.copy(&trailerDict); - gotRoot = gTrue; - } - obj.free(); + newTrailerDict.dictLookupNF("Root", &obj); + if (obj.isRef()) { + rootNum = obj.getRefNum(); + rootGen = obj.getRefGen(); + if (!trailerDict.isNone()) { + trailerDict.free(); + } + newTrailerDict.copy(&trailerDict); + gotRoot = gTrue; + } + obj.free(); } newTrailerDict.free(); delete parser; @@ -709,62 +709,62 @@ } else if (isdigit(*p)) { num = atoi(p); if (num > 0) { - do { - ++p; - } while (*p && isdigit(*p)); - if (isspace(*p)) { - do { - ++p; - } while (*p && isspace(*p)); - if (isdigit(*p)) { - gen = atoi(p); - do { - ++p; - } while (*p && isdigit(*p)); - if (isspace(*p)) { - do { - ++p; - } while (*p && isspace(*p)); - if (!strncmp(p, "obj", 3)) { - if (num >= size) { - newSize = (num + 1 + 255) & ~255; - if (newSize < 0) { - error(-1, "Bad object number"); - return gFalse; - } + do { + ++p; + } while (*p && isdigit(*p)); + if (isspace(*p)) { + do { + ++p; + } while (*p && isspace(*p)); + if (isdigit(*p)) { + gen = atoi(p); + do { + ++p; + } while (*p && isdigit(*p)); + if (isspace(*p)) { + do { + ++p; + } while (*p && isspace(*p)); + if (!strncmp(p, "obj", 3)) { + if (num >= size) { + newSize = (num + 1 + 255) & ~255; + if (newSize < 0) { + error(-1, "Bad object number"); + return gFalse; + } if (newSize*(int)sizeof(XRefEntry)/sizeof(XRefEntry) != newSize) { error(-1, "Invalid 'obj' parameters."); return gFalse; } - entries = (XRefEntry *) - greallocn(entries, newSize, sizeof(XRefEntry)); - for (i = size; i < newSize; ++i) { - entries[i].offset = 0xffffffff; - entries[i].type = xrefEntryFree; - } - size = newSize; - } - if (entries[num].type == xrefEntryFree || - gen >= entries[num].gen) { - entries[num].offset = pos - start; - entries[num].gen = gen; - entries[num].type = xrefEntryUncompressed; - } - } - } - } - } + entries = (XRefEntry *) + greallocn(entries, newSize, sizeof(XRefEntry)); + for (i = size; i < newSize; ++i) { + entries[i].offset = 0xffffffff; + entries[i].type = xrefEntryFree; + } + size = newSize; + } + if (entries[num].type == xrefEntryFree || + gen >= entries[num].gen) { + entries[num].offset = pos - start; + entries[num].gen = gen; + entries[num].type = xrefEntryUncompressed; + } + } + } + } + } } } else if (!strncmp(p, "endstream", 9)) { if (streamEndsLen == streamEndsSize) { - streamEndsSize += 64; + streamEndsSize += 64; if (streamEndsSize*(int)sizeof(int)/sizeof(int) != streamEndsSize) { error(-1, "Invalid 'endstream' parameter."); return gFalse; } - streamEnds = (Guint *)greallocn(streamEnds, - streamEndsSize, sizeof(int)); + streamEnds = (Guint *)greallocn(streamEnds, + streamEndsSize, sizeof(int)); } streamEnds[streamEndsLen++] = pos; } @@ -778,8 +778,8 @@ } void XRef::setEncryption(int permFlagsA, GBool ownerPasswordOkA, - Guchar *fileKeyA, int keyLengthA, - int encVersionA, int encRevisionA) { + Guchar *fileKeyA, int keyLengthA, + int encVersionA, int encRevisionA) { int i; encrypted = gTrue; @@ -858,14 +858,14 @@ } obj1.initNull(); parser = new Parser(this, - new Lexer(this, - str->makeSubStream(start + e->offset, gFalse, 0, &obj1))); + new Lexer(this, + str->makeSubStream(start + e->offset, gFalse, 0, &obj1))); parser->getObj(&obj1); parser->getObj(&obj2); parser->getObj(&obj3); if (!obj1.isInt() || obj1.getInt() != num || - !obj2.isInt() || obj2.getInt() != gen || - !obj3.isCmd("obj")) { + !obj2.isInt() || obj2.getInt() != gen || + !obj3.isCmd("obj")) { obj1.free(); obj2.free(); obj3.free(); @@ -873,7 +873,7 @@ goto err; } parser->getObj(obj, encrypted ? fileKey : (Guchar *)NULL, keyLength, - num, gen); + num, gen); obj1.free(); obj2.free(); obj3.free(); @@ -886,7 +886,7 @@ } if (!objStr || objStr->getObjStrNum() != (int)e->offset) { if (objStr) { - delete objStr; + delete objStr; } objStr = new ObjectStream(this, e->offset); } Index: poppler/Gfx.cc =================================================================== --- poppler/Gfx.cc (revision 52) +++ poppler/Gfx.cc (working copy) @@ -3510,38 +3510,43 @@ Stream *Gfx::buildImageStream() { Object dict; Object obj; + Object dictObj; char *key; Stream *str; + GBool isEOF = gFalse; - // build dictionary dict.initDict(xref); - parser->getObj(&obj); - while (!obj.isCmd("ID") && !obj.isEOF()) { + while (1) { + parser->getObj(&obj); + isEOF = obj.isEOF(); + if (isEOF || obj.isCmd("ID")) + break; if (!obj.isName()) { error(getPos(), "Inline image dictionary key must be a name object"); - obj.free(); } else { - key = copyString(obj.getName()); - obj.free(); - parser->getObj(&obj); - if (obj.isEOF() || obj.isError()) { - gfree(key); - break; + parser->getObj(&dictObj); + isEOF = dictObj.isEOF(); + if (isEOF) + break; + if (dictObj.isError()) { + // FIXME: we probably should not build a stream in this case either + // but this behaviour was in poppler for a while so maybe it's ok + dictObj.free(); + break; } - dict.dictAdd(key, &obj); - gfree(key); + key = obj.getName(); + dict.dictAdd(key, &dictObj); } - parser->getObj(&obj); + obj.free(); } - if (obj.isEOF()) { + + obj.free(); + if (isEOF) { error(getPos(), "End of file in inline image"); - obj.free(); dict.free(); return NULL; } - obj.free(); - // make stream str = new EmbedStream(parser->getStream(), &dict, gFalse, 0); str = str->addFilters(&dict); Index: poppler/Dict.cc =================================================================== --- poppler/Dict.cc (revision 52) +++ poppler/Dict.cc (working copy) @@ -1,116 +1,203 @@ -//======================================================================== -// -// Dict.cc -// -// Copyright 1996-2003 Glyph & Cog, LLC -// -//======================================================================== - -#include - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include -#include -#include "goo/gmem.h" -#include "Object.h" -#include "UGooString.h" -#include "XRef.h" -#include "Dict.h" - -//------------------------------------------------------------------------ -// Dict -//------------------------------------------------------------------------ - -Dict::Dict(XRef *xrefA) { - xref = xrefA; - entries = NULL; - size = length = 0; - ref = 1; -} - -Dict::~Dict() { - int i; - - for (i = 0; i < length; ++i) { - delete entries[i].key; - entries[i].val.free(); - } - gfree(entries); -} - -void Dict::add(const UGooString &key, Object *val) { - if (length == size) { - if (length == 0) { - size = 8; - } else { - size *= 2; - } - entries = (DictEntry *)greallocn(entries, size, sizeof(DictEntry)); - } - entries[length].key = new UGooString(key); - entries[length].val = *val; - ++length; -} - -inline DictEntry *Dict::find(const UGooString &key) { - int i; - - for (i = 0; i < length; ++i) { - if (!key.cmp(entries[i].key)) - return &entries[i]; - } - return NULL; -} - -GBool Dict::is(char *type) { - DictEntry *e; - - return (e = find("Type")) && e->val.isName(type); -} - -Object *Dict::lookup(const UGooString &key, Object *obj) { - DictEntry *e; - - return (e = find(key)) ? e->val.fetch(xref, obj) : obj->initNull(); -} - -Object *Dict::lookupNF(const UGooString &key, Object *obj) { - DictEntry *e; - - return (e = find(key)) ? e->val.copy(obj) : obj->initNull(); -} - -GBool Dict::lookupInt(const char *key, const char *alt_key, int *value) -{ - Object obj1; - GBool success = gFalse; - - lookup ((char *) key, &obj1); - if (obj1.isNull () && alt_key != NULL) { - obj1.free (); - lookup ((char *) alt_key, &obj1); - } - if (obj1.isInt ()) { - *value = obj1.getInt (); - success = gTrue; - } - - obj1.free (); - - return success; -} - -UGooString *Dict::getKey(int i) { - return entries[i].key; -} - -Object *Dict::getVal(int i, Object *obj) { - return entries[i].val.fetch(xref, obj); -} - -Object *Dict::getValNF(int i, Object *obj) { - return entries[i].val.copy(obj); -} +//======================================================================== +// +// Dict.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include + +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + +#include +#include +#include +#include "goo/gmem.h" +#include "Error.h" +#include "Object.h" +#include "UGooString.h" +#include "XRef.h" +#include "Dict.h" + +//------------------------------------------------------------------------ +// Dict +//------------------------------------------------------------------------ + +Dict::Dict(XRef *xrefA) { + xref = xrefA; + entries = NULL; + size = length = 0; + ref = 1; +} + +Dict::~Dict() { + int i; + + for (i = 0; i < length; ++i) { + delete entries[i].key; + entries[i].val.free(); + } + gfree(entries); +} + +void Dict::add(const UGooString &key, Object *val) { + if (length == size) { + if (length == 0) { + size = 8; + } else { + size *= 2; + } + entries = (DictEntry *)greallocn(entries, size, sizeof(DictEntry)); + } + entries[length].key = new UGooString(key); + entries[length].val = *val; + ++length; +} + +inline DictEntry *Dict::find(const UGooString &key) const { + int i; + + for (i = 0; i < length; ++i) { + if (!key.cmp(entries[i].key)) + return &entries[i]; + } + return NULL; +} + +inline DictEntry *Dict::find(const char *key, int keyLen) const { + int i; + + for (i = 0; i < length; ++i) { + if (0 == entries[i].key->cmp(key, keyLen)) + return &entries[i]; + } + return NULL; +} + +// length of string "Type" +#define TYPE_STR_LEN 4 + +GBool Dict::is(char *type) const { + DictEntry *e = find("Type", TYPE_STR_LEN); + if (!e) + return gFalse; + return e->val.isName(type); +} + +Object *Dict::lookup(const char *key, Object *obj, int keyLen) const { + DictEntry *e = find(key, keyLen); + if (!e) + return obj->initNull(); + return e->val.fetch(xref, obj); +} + +Object *Dict::lookupNF(const char *key, Object *obj, int keyLen) const { + DictEntry *e = find(key, keyLen); + if (!e) + return obj->initNull(); + return e->val.copy(obj); +} + +Object *Dict::lookup(const UGooString &key, Object *obj) const { + DictEntry *e = find(key); + if (!e) + return obj->initNull(); + return e->val.fetch(xref, obj); +} + +Object *Dict::lookupNF(const UGooString &key, Object *obj) const { + DictEntry *e = find(key); + if (!e) + return obj->initNull(); + return e->val.copy(obj); +} + +Object *Dict::lookupRefNoFetch(const char *key, int keyLen) const { + DictEntry *e; + e = find(key); + if (!e) + return NULL; + return &(e->val); +} + +Object *Dict::lookupRefNoFetch(const UGooString &key) const { + DictEntry *e; + e = find(key); + if (!e) + return NULL; + return &(e->val); + +} + +GBool Dict::lookupBool(const char *key, const char *alt_key, GBool *value) const { + Object *obj; + + // FIXME: handle ref objects as well + obj = lookupRefNoFetch(key); + if (obj && obj->isRef()) { + error(-1, "ref object in Dict::lookupBool for %s", key); + assert(0); + } + if (obj && obj->isBool()) { + *value = obj->getBool(); + return gTrue; + } + + if (!alt_key) + return gFalse; + obj = lookupRefNoFetch(alt_key); + if (obj && obj->isRef()) { + error(-1, "ref object in Dict::lookupBool for %s", alt_key); + assert(0); + } + if (obj && obj->isBool()) { + *value = obj->getBool(); + return gTrue; + } + + return gFalse; +} + +GBool Dict::lookupInt(const char *key, const char *alt_key, int *value) const { + Object *obj; + + // FIXME: handle ref objects as well + obj = lookupRefNoFetch(key); + if (obj && obj->isRef()) { + error(-1, "ref object in Dict::lookupInt for %s", key); + assert(0); + } + if (obj && obj->isInt()) { + *value = obj->getInt(); + return gTrue; + } + + if (!alt_key) + return gFalse; + obj = lookupRefNoFetch(alt_key); + if (obj && obj->isRef()) { + error(-1, "ref object in Dict::lookupInt for %s", alt_key); + assert(0); + } + if (obj && obj->isInt()) { + *value = obj->getInt(); + return gTrue; + } + + return gFalse; +} + +UGooString *Dict::getKey(int i) const { + return entries[i].key; +} + +Object *Dict::getVal(int i, Object *obj) const { + return entries[i].val.fetch(xref, obj); +} + +Object *Dict::getValNF(int i, Object *obj) const { + return entries[i].val.copy(obj); +} Index: poppler/Dict.h =================================================================== --- poppler/Dict.h (revision 52) +++ poppler/Dict.h (working copy) @@ -14,8 +14,8 @@ #endif #include "Object.h" +#include "UGooString.h" -class UGooString; //------------------------------------------------------------------------ // Dict //------------------------------------------------------------------------ @@ -28,10 +28,8 @@ class Dict { public: - // Constructor. Dict(XRef *xrefA); - // Destructor. ~Dict(); // Reference counting. @@ -39,24 +37,30 @@ int decRef() { return --ref; } // Get number of entries. - int getLength() { return length; } + int getLength() const { return length; } // Add an entry void add(const UGooString &key, Object *val); // Check if dictionary is of specified type. - GBool is(char *type); + GBool is(char *type) const; // Look up an entry and return the value. Returns a null object // if is not in the dictionary. - Object *lookup(const UGooString &key, Object *obj); - Object *lookupNF(const UGooString &key, Object *obj); - GBool lookupInt(const char *key, const char *alt_key, int *value); + Object *lookup(const UGooString &key, Object *obj) const; + Object *lookupNF(const UGooString &key, Object *obj) const; + Object *lookupRefNoFetch(const UGooString &key) const; + Object *lookup(const char *key, Object *obj, int keyLen=UGooString::CALC_STRING_LEN) const; + Object *lookupNF(const char *key, Object *obj, int keyLen=UGooString::CALC_STRING_LEN) const; + Object *lookupRefNoFetch(const char *key, int keyLen=UGooString::CALC_STRING_LEN) const; + GBool lookupBool(const char *key, const char *alt_key, GBool *value) const; + GBool lookupInt(const char *key, const char *alt_key, int *value) const; + // Iterative accessors. - UGooString *getKey(int i); - Object *getVal(int i, Object *obj); - Object *getValNF(int i, Object *obj); + UGooString *getKey(int i) const; + Object *getVal(int i, Object *obj) const; + Object *getValNF(int i, Object *obj) const; // Set the xref pointer. This is only used in one special case: the // trailer dictionary, which is read before the xref table is @@ -71,7 +75,8 @@ int length; // number of entries in dictionary int ref; // reference count - DictEntry *find(const UGooString &key); + DictEntry *find(const UGooString &key) const; + DictEntry *find(const char *key, int keyLen) const; }; #endif