xref.cc
来自「source code: Covert TXT to PDF」· CC 代码 · 共 668 行 · 第 1/2 页
CC
668 行
return more; err1: obj.free(); err2: ok = gFalse; return gFalse;}// Attempt to construct an xref table for a damaged file.GBool XRef::constructXRef() { Parser *parser; Object obj; char buf[256]; Guint pos; int num, gen; int newSize; int streamEndsSize; char *p; int i; GBool gotRoot; error(0, "PDF file is damaged - attempting to reconstruct xref table..."); gotRoot = gFalse; streamEndsLen = streamEndsSize = 0; str->reset(); while (1) { pos = str->getPos(); if (!str->getLine(buf, 256)) { break; } p = buf; // got trailer dictionary if (!strncmp(p, "trailer", 7)) { obj.initNull(); parser = new Parser(NULL, new Lexer(NULL, str->makeSubStream(start + pos + 7, gFalse, 0, &obj))); if (!trailerDict.isNone()) trailerDict.free(); parser->getObj(&trailerDict); if (trailerDict.isDict()) { trailerDict.dictLookupNF("Root", &obj); if (obj.isRef()) { rootNum = obj.getRefNum(); rootGen = obj.getRefGen(); gotRoot = gTrue; } obj.free(); } else { pos = 0; } delete parser; // look for object } else if (isdigit(*p)) { num = atoi(p); 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; entries = (XRefEntry *) grealloc(entries, newSize * sizeof(XRefEntry)); for (i = size; i < newSize; ++i) { entries[i].offset = 0xffffffff; entries[i].used = gFalse; } size = newSize; } if (!entries[num].used || gen >= entries[num].gen) { entries[num].offset = pos - start; entries[num].gen = gen; entries[num].used = gTrue; } } } } } } else if (!strncmp(p, "endstream", 9)) { if (streamEndsLen == streamEndsSize) { streamEndsSize += 64; streamEnds = (Guint *)grealloc(streamEnds, streamEndsSize * sizeof(int)); } streamEnds[streamEndsLen++] = pos; } } if (gotRoot) return gTrue; error(-1, "Couldn't find trailer dictionary"); return gFalse;}#ifndef NO_DECRYPTIONGBool XRef::checkEncrypted(GString *ownerPassword, GString *userPassword) { Object encrypt, filterObj, versionObj, revisionObj, lengthObj; Object ownerKey, userKey, permissions, fileID, fileID1; GBool encrypted1; GBool ret; ret = gFalse; permFlags = defPermFlags; ownerPasswordOk = gFalse; trailerDict.dictLookup("Encrypt", &encrypt); if ((encrypted1 = encrypt.isDict())) { ret = gTrue; encrypt.dictLookup("Filter", &filterObj); if (filterObj.isName("Standard")) { encrypt.dictLookup("V", &versionObj); encrypt.dictLookup("R", &revisionObj); encrypt.dictLookup("Length", &lengthObj); encrypt.dictLookup("O", &ownerKey); encrypt.dictLookup("U", &userKey); encrypt.dictLookup("P", &permissions); trailerDict.dictLookup("ID", &fileID); if (versionObj.isInt() && revisionObj.isInt() && ownerKey.isString() && ownerKey.getString()->getLength() == 32 && userKey.isString() && userKey.getString()->getLength() == 32 && permissions.isInt() && fileID.isArray()) { encVersion = versionObj.getInt(); encRevision = revisionObj.getInt(); if (lengthObj.isInt()) { keyLength = lengthObj.getInt() / 8; } else { keyLength = 5; } permFlags = permissions.getInt(); if (encVersion >= 1 && encVersion <= 2 && encRevision >= 2 && encRevision <= 3) { fileID.arrayGet(0, &fileID1); if (fileID1.isString()) { if (Decrypt::makeFileKey(encVersion, encRevision, keyLength, ownerKey.getString(), userKey.getString(), permFlags, fileID1.getString(), ownerPassword, userPassword, fileKey, &ownerPasswordOk)) { if (ownerPassword && !ownerPasswordOk) { error(-1, "Incorrect owner password"); } ret = gFalse; } else { error(-1, "Incorrect password"); } } else { error(-1, "Weird encryption info"); } fileID1.free(); } else { error(-1, "Unsupported version/revision (%d/%d) of Standard security handler", encVersion, encRevision); } } else { error(-1, "Weird encryption info"); } fileID.free(); permissions.free(); userKey.free(); ownerKey.free(); lengthObj.free(); revisionObj.free(); versionObj.free(); } else { error(-1, "Unknown security handler '%s'", filterObj.isName() ? filterObj.getName() : "???"); } filterObj.free(); } encrypt.free(); // this flag has to be set *after* we read the O/U/P strings encrypted = encrypted1; return ret;}#elseGBool XRef::checkEncrypted(GString *ownerPassword, GString *userPassword) { Object obj; GBool encrypted; trailerDict.dictLookup("Encrypt", &obj); if ((encrypted = !obj.isNull())) { error(-1, "PDF file is encrypted and this version of the Xpdf tools"); error(-1, "was built without decryption support."); } obj.free(); return encrypted;}#endifGBool XRef::okToPrint(GBool ignoreOwnerPW) {#ifndef NO_DECRYPTION if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permPrint)) { return gFalse; }#endif return gTrue;}GBool XRef::okToChange(GBool ignoreOwnerPW) {#ifndef NO_DECRYPTION if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permChange)) { return gFalse; }#endif return gTrue;}GBool XRef::okToCopy(GBool ignoreOwnerPW) {#ifndef NO_DECRYPTION if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permCopy)) { return gFalse; }#endif return gTrue;}GBool XRef::okToAddNotes(GBool ignoreOwnerPW) {#ifndef NO_DECRYPTION if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permNotes)) { return gFalse; }#endif return gTrue;}Object *XRef::fetch(int num, int gen, Object *obj) { XRefEntry *e; Parser *parser; Object obj1, obj2, obj3; // check for bogus ref - this can happen in corrupted PDF files if (num < 0 || num >= size) { obj->initNull(); return obj; } e = &entries[num]; if (e->gen == gen && e->offset != 0xffffffff) { obj1.initNull(); parser = new Parser(this, 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")) {#ifndef NO_DECRYPTION parser->getObj(obj, encrypted ? fileKey : (Guchar *)NULL, keyLength, num, gen);#else parser->getObj(obj);#endif } else { obj->initNull(); } obj1.free(); obj2.free(); obj3.free(); delete parser; } else { obj->initNull(); } return obj;}Object *XRef::getDocInfo(Object *obj) { return trailerDict.dictLookup("Info", obj);}// Added for the pdftex project.Object *XRef::getDocInfoNF(Object *obj) { return trailerDict.dictLookupNF("Info", obj);}GBool XRef::getStreamEnd(Guint streamStart, Guint *streamEnd) { int a, b, m; if (streamEndsLen == 0 || streamStart > streamEnds[streamEndsLen - 1]) { return gFalse; } a = -1; b = streamEndsLen - 1; // invariant: streamEnds[a] < streamStart <= streamEnds[b] while (b - a > 1) { m = (a + b) / 2; if (streamStart <= streamEnds[m]) { b = m; } else { a = m; } } *streamEnd = streamEnds[b]; return gTrue;}Guint XRef::strToUnsigned(char *s) { Guint x; char *p; int i; x = 0; for (p = s, i = 0; *p && isdigit(*p) && i < 10; ++p, ++i) { x = 10 * x + (*p - '0'); } return x;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?