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;
}
Exemplo n.º 3
0
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;
}