📄 pdf_open.c
字号:
else { fz_dropobj(trailer); return fz_throw("object id (%d %d R) out of range (0..%d)", oid, gen, xref->len - 1); } } xref->table[oid].type = 'n'; xref->table[oid].gen = gen; xref->table[oid].obj = fz_keepobj(trailer); xref->table[oid].stmofs = stmofs; obj = fz_dictgets(trailer, "Size"); if (!obj) { fz_dropobj(trailer); return fz_throw("xref stream missing Size entry"); } size = fz_toint(obj); obj = fz_dictgets(trailer, "W"); if (!obj) { fz_dropobj(trailer); return fz_throw("xref stream missing W entry"); } w0 = fz_toint(fz_arrayget(obj, 0)); w1 = fz_toint(fz_arrayget(obj, 1)); w2 = fz_toint(fz_arrayget(obj, 2)); index = fz_dictgets(trailer, "Index"); error = pdf_openstream(&stm, xref, oid, gen); if (error) { fz_dropobj(trailer); return fz_rethrow(error, "cannot open compressed xref stream"); } if (!index) { error = readnewxrefsection(xref, stm, 0, size, w0, w1, w2); if (error) { fz_dropstream(stm); fz_dropobj(trailer); return fz_rethrow(error, "cannot read xref stream"); } } else { for (t = 0; t < fz_arraylen(index); t += 2) { int i0 = fz_toint(fz_arrayget(index, t + 0)); int i1 = fz_toint(fz_arrayget(index, t + 1)); error = readnewxrefsection(xref, stm, i0, i1, w0, w1, w2); if (error) { fz_dropstream(stm); fz_dropobj(trailer); return fz_rethrow(error, "cannot read xref stream section"); } } } fz_dropstream(stm); *trailerp = trailer; return fz_okay;}static fz_error *readxref(fz_obj **trailerp, pdf_xref *xref, int ofs, char *buf, int cap){ fz_error *error; int c; error = fz_seek(xref->file, ofs, 0); if (error) return fz_rethrow(error, "cannot seek to xref"); c = fz_peekbyte(xref->file); error = fz_readerror(xref->file); if (error) return fz_rethrow(error, "cannot read trailer"); if (c == 'x') { error = readoldxref(trailerp, xref, buf, cap); if (error) return fz_rethrow(error, "cannot read xref (ofs=%d)", ofs); } else if (c >= '0' && c <= '9') { error = readnewxref(trailerp, xref, buf, cap); if (error) return fz_rethrow(error, "cannot read xref (ofs=%d)", ofs); } else { return fz_throw("cannot recognize xref format"); } return fz_okay;}static fz_error *readxrefsections(pdf_xref *xref, int ofs, char *buf, int cap){ fz_error *error; fz_obj *trailer; fz_obj *prev; fz_obj *xrefstm; error = readxref(&trailer, xref, ofs, buf, cap); if (error) return fz_rethrow(error, "cannot read xref section"); /* FIXME: do we overwrite free entries properly? */ xrefstm = fz_dictgets(trailer, "XRefStm"); if (xrefstm) { pdf_logxref("load xrefstm\n"); error = readxrefsections(xref, fz_toint(xrefstm), buf, cap); if (error) { fz_dropobj(trailer); return fz_rethrow(error, "cannot read /XRefStm xref section"); } } prev = fz_dictgets(trailer, "Prev"); if (prev) { pdf_logxref("load prev\n"); error = readxrefsections(xref, fz_toint(prev), buf, cap); if (error) { fz_dropobj(trailer); return fz_rethrow(error, "cannot read /Prev xref section"); } } fz_dropobj(trailer); return fz_okay;}/* * compressed object streams */fz_error *pdf_loadobjstm(pdf_xref *xref, int oid, int gen, char *buf, int cap){ fz_error *error; fz_stream *stm; fz_obj *objstm; int *oidbuf; int *ofsbuf; fz_obj *obj; int first; int count; int i, n; pdf_token_e tok; pdf_logxref("loadobjstm (%d %d R)\n", oid, gen); error = pdf_loadobject(&objstm, xref, oid, gen); if (error) return fz_rethrow(error, "cannot load object stream object"); count = fz_toint(fz_dictgets(objstm, "N")); first = fz_toint(fz_dictgets(objstm, "First")); pdf_logxref(" count %d\n", count); oidbuf = fz_malloc(count * sizeof(int)); if (!oidbuf) { error = fz_throw("outofmem: object id buffer"); goto cleanupobj; } ofsbuf = fz_malloc(count * sizeof(int)); if (!ofsbuf) { error = fz_throw("outofmem: offset buffer"); goto cleanupoid; } error = pdf_openstream(&stm, xref, oid, gen); if (error) { error = fz_rethrow(error, "cannot open object stream"); goto cleanupofs; } for (i = 0; i < count; i++) { error = pdf_lex(&tok, stm, buf, cap, &n); if (error || tok != PDF_TINT) { error = fz_rethrow(error, "corrupt object stream"); goto cleanupstm; } oidbuf[i] = atoi(buf); error = pdf_lex(&tok, stm, buf, cap, &n); if (error || tok != PDF_TINT) { error = fz_rethrow(error, "corrupt object stream"); goto cleanupstm; } ofsbuf[i] = atoi(buf); } error = fz_seek(stm, first, 0); if (error) { error = fz_rethrow(error, "cannot seek in object stream"); goto cleanupstm; } for (i = 0; i < count; i++) { /* FIXME: seek to first + ofsbuf[i] */ error = pdf_parsestmobj(&obj, stm, buf, cap); if (error) { error = fz_rethrow(error, "cannot parse object %d in stream", i); goto cleanupstm; } if (oidbuf[i] < 1 || oidbuf[i] >= xref->len) { error = fz_throw("object id (%d 0 R) out of range (0..%d)", oidbuf[i], xref->len - 1); goto cleanupstm; } if (xref->table[oidbuf[i]].obj) fz_dropobj(xref->table[oidbuf[i]].obj); xref->table[oidbuf[i]].obj = obj; } fz_dropstream(stm); fz_free(ofsbuf); fz_free(oidbuf); fz_dropobj(objstm); return fz_okay;cleanupstm: fz_dropstream(stm);cleanupofs: fz_free(ofsbuf);cleanupoid: fz_free(oidbuf);cleanupobj: fz_dropobj(objstm); return error; /* already rethrown */}/* * open and load xref tables from pdf */static fz_error *pdf_loadxref2(pdf_xref *xref){ fz_error *error; fz_obj *size; int i; char buf[65536]; /* yeowch! */ error = loadversion(xref); if (error) { error = fz_rethrow(error, "cannot read version marker"); goto cleanup; } error = readstartxref(xref); if (error) { error = fz_rethrow(error, "cannot read startxref"); goto cleanup; } error = readtrailer(xref, buf, sizeof buf); if (error) { error = fz_rethrow(error, "cannot read trailer"); goto cleanup; } size = fz_dictgets(xref->trailer, "Size"); if (!size) { error = fz_throw("trailer missing Size entry"); goto cleanup; } pdf_logxref(" size %d\n", fz_toint(size)); assert(xref->table == nil); xref->len = fz_toint(size); xref->cap = xref->len + 1; /* for hack to allow broken pdf generators with off-by-one errors */ xref->table = fz_malloc(xref->cap * sizeof(pdf_xrefentry)); if (!xref->table) { error = fz_throw("outofmem: xref table"); goto cleanup; } for (i = 0; i < xref->cap; i++) { xref->table[i].ofs = 0; xref->table[i].gen = 0; xref->table[i].type = 0; xref->table[i].mark = 0; xref->table[i].stmbuf = nil; xref->table[i].stmofs = 0; xref->table[i].obj = nil; } error = readxrefsections(xref, xref->startxref, buf, sizeof buf); if (error) { error = fz_rethrow(error, "cannot read xref"); goto cleanup; } return fz_okay;cleanup: fz_dropstream(xref->file); xref->file = nil; free(xref->table); xref->table = nil; return error;}fz_error *pdf_loadxref(pdf_xref *xref, char *filename){ fz_error * error; pdf_logxref("loadxref '%s' %p\n", filename, xref); error = fz_openrfile(&xref->file, filename); if (error) { return fz_rethrow(error, "cannot open file: '%s'", filename); } return pdf_loadxref2(xref);}#ifdef WIN32_UNICODE_HACKfz_error *pdf_loadxrefw(pdf_xref *xref, const wchar_t *filename){ fz_error * error = fz_openrfilew(&xref->file, filename); if (error) { return fz_rethrow(error, "cannot open file"); } return pdf_loadxref2(xref);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -