static fz_error pdf_readoldtrailer(pdf_xref *xref, char *buf, int cap) { fz_error error; int len; char *s; int n; int t; pdf_token_e tok; int c; pdf_logxref("load old xref format trailer\n"); fz_readline(xref->file, buf, cap); if (strncmp(buf, "xref", 4) != 0) return fz_throw("cannot find xref marker"); while (1) { c = fz_peekbyte(xref->file); if (!(c >= '0' && c <= '9')) break; fz_readline(xref->file, buf, cap); s = buf; fz_strsep(&s, " "); /* ignore ofs */ if (!s) return fz_throw("invalid range marker in xref"); len = atoi(fz_strsep(&s, " ")); /* broken pdfs where the section is not on a separate line */ if (s && *s != '\0') fz_seek(xref->file, -(2 + (int)strlen(s)), 1); t = fz_tell(xref->file); if (t < 0) return fz_throw("cannot tell in file"); fz_seek(xref->file, t + 20 * len, 0); } error = pdf_lex(&tok, xref->file, buf, cap, &n); if (error) return fz_rethrow(error, "cannot parse trailer"); if (tok != PDF_TTRAILER) return fz_throw("expected trailer marker"); error = pdf_lex(&tok, xref->file, buf, cap, &n); if (error) return fz_rethrow(error, "cannot parse trailer"); if (tok != PDF_TODICT) return fz_throw("expected trailer dictionary"); error = pdf_parsedict(&xref->trailer, xref, xref->file, buf, cap); if (error) return fz_rethrow(error, "cannot parse trailer"); return fz_okay; }
static fz_error pdf_loadversion(pdf_xref *xref) { char buf[20]; fz_seek(xref->file, 0, 0); fz_readline(xref->file, buf, sizeof buf); if (memcmp(buf, "%PDF-", 5) != 0) return fz_throw("cannot recognize version marker"); xref->version = atof(buf + 5) * 10; pdf_logxref("version %d.%d\n", xref->version / 10, xref->version % 10); return fz_okay; }
static fz_error loadversion(pdf_xref *xref) { fz_error error; char buf[20]; error = fz_seek(xref->file, 0, 0); if (error) return fz_rethrow(error, "cannot seek to beginning of file"); error = fz_readline(xref->file, buf, sizeof buf); if (error) return fz_rethrow(error, "cannot read version marker"); if (memcmp(buf, "%PDF-", 5) != 0) return fz_throw("cannot recognize version marker"); xref->version = (int) (atof(buf + 5) * 10.0 + 0.5); pdf_logxref("version %d.%d\n", xref->version / 10, xref->version % 10); return fz_okay; }
static fz_error pdf_readoldxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap) { fz_error error; int ofs, len; char *s; int n; pdf_token_e tok; int i; int c; pdf_logxref("load old xref format\n"); fz_readline(xref->file, buf, cap); if (strncmp(buf, "xref", 4) != 0) return fz_throw("cannot find xref marker"); while (1) { c = fz_peekbyte(xref->file); if (!(c >= '0' && c <= '9')) break; fz_readline(xref->file, buf, cap); s = buf; ofs = atoi(fz_strsep(&s, " ")); len = atoi(fz_strsep(&s, " ")); /* broken pdfs where the section is not on a separate line */ if (s && *s != '\0') { fz_warn("broken xref section. proceeding anyway."); fz_seek(xref->file, -(2 + (int)strlen(s)), 1); } /* broken pdfs where size in trailer undershoots entries in xref sections */ if (ofs + len > xref->cap) { fz_warn("broken xref section, proceeding anyway."); xref->cap = ofs + len; xref->table = fz_realloc(xref->table, xref->cap * sizeof(pdf_xrefentry)); } if ((ofs + len) > xref->len) { for (i = xref->len; i < (ofs + len); i++) { xref->table[i].ofs = 0; xref->table[i].gen = 0; xref->table[i].stmofs = 0; xref->table[i].obj = nil; xref->table[i].type = 0; } xref->len = ofs + len; } for (i = ofs; i < ofs + len; i++) { n = fz_read(xref->file, (unsigned char *) buf, 20); if (n < 0) return fz_rethrow(n, "cannot read xref table"); if (!xref->table[i].type) { s = buf; /* broken pdfs where line start with white space */ while (*s != '\0' && iswhite(*s)) s++; xref->table[i].ofs = atoi(s); xref->table[i].gen = atoi(s + 11); xref->table[i].type = s[17]; } } } error = pdf_lex(&tok, xref->file, buf, cap, &n); if (error) return fz_rethrow(error, "cannot parse trailer"); if (tok != PDF_TTRAILER) return fz_throw("expected trailer marker"); error = pdf_lex(&tok, xref->file, buf, cap, &n); if (error) return fz_rethrow(error, "cannot parse trailer"); if (tok != PDF_TODICT) return fz_throw("expected trailer dictionary"); error = pdf_parsedict(trailerp, xref, xref->file, buf, cap); if (error) return fz_rethrow(error, "cannot parse trailer"); return fz_okay; }