summaryrefslogtreecommitdiff
path: root/pdf/pdf_function.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-02-23 15:07:04 +0000
committerRobin Watts <robin.watts@artifex.com>2012-02-25 08:14:40 -0800
commit9ef2a68e77842456ab30594a9a8d2c0535314715 (patch)
tree630c1b23b64ed15984b6c065635929f08bf613e8 /pdf/pdf_function.c
parentd28129c2ff6a78c50877426f90167d63334ab18a (diff)
downloadmupdf-9ef2a68e77842456ab30594a9a8d2c0535314715.tar.xz
Revamp pdf lexing code
A huge amount (20%+ on some files) of our runtime is spent in fz_atof. A survey of results on the net suggests we will get much better speed by writing our own atof. Part of the job of doing this involves parsing the string to identify the component parts of the number - ludicrously, we are already doing this as part of the lexing process, so it would make sense to do the atoi/atof as part of this process. In order to do this, we need somewhere to store the lexed results; rather than add a float * and an int * to every single pdf_lex call, we generalise the calls to pass a pdf_lexbuf * pointer instead of separate buffer/max/string length pointers. This should help us overall.
Diffstat (limited to 'pdf/pdf_function.c')
-rw-r--r--pdf/pdf_function.c33
1 files changed, 17 insertions, 16 deletions
diff --git a/pdf/pdf_function.c b/pdf/pdf_function.c
index 4478827c..17373f42 100644
--- a/pdf/pdf_function.c
+++ b/pdf/pdf_function.c
@@ -683,18 +683,18 @@ resize_code(fz_context *ctx, pdf_function *func, int newsize)
static void
parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
{
- char buf[64];
- int len;
+ pdf_lexbuf buf;
int tok;
int opptr, elseptr, ifptr;
int a, b, mid, cmp;
fz_context *ctx = stream->ctx;
- memset(buf, 0, sizeof(buf));
+ buf.size = PDF_LEXBUF_SMALL;
+ memset(buf.scratch, 0, sizeof(buf.scratch));
while (1)
{
- tok = pdf_lex(stream, buf, sizeof buf, &len);
+ tok = pdf_lex(stream, &buf);
/* RJW: "calculator function lexical error" */
switch(tok)
@@ -705,7 +705,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
case PDF_TOK_INT:
resize_code(ctx, func, *codeptr);
func->u.p.code[*codeptr].type = PS_INT;
- func->u.p.code[*codeptr].u.i = atoi(buf);
+ func->u.p.code[*codeptr].u.i = buf.i;
++*codeptr;
break;
@@ -726,7 +726,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
case PDF_TOK_REAL:
resize_code(ctx, func, *codeptr);
func->u.p.code[*codeptr].type = PS_REAL;
- func->u.p.code[*codeptr].u.f = fz_atof(buf);
+ func->u.p.code[*codeptr].u.f = buf.f;
++*codeptr;
break;
@@ -740,7 +740,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
parse_code(func, stream, codeptr);
/* RJW: "error in 'if' branch" */
- tok = pdf_lex(stream, buf, sizeof buf, &len);
+ tok = pdf_lex(stream, &buf);
/* RJW: "calculator function syntax error" */
if (tok == PDF_TOK_OPEN_BRACE)
@@ -749,7 +749,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
parse_code(func, stream, codeptr);
/* RJW: "error in 'else' branch" */
- tok = pdf_lex(stream, buf, sizeof buf, &len);
+ tok = pdf_lex(stream, &buf);
/* RJW: "calculator function syntax error" */
}
else
@@ -760,7 +760,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
if (tok != PDF_TOK_KEYWORD)
fz_throw(ctx, "missing keyword in 'if-else' context");
- if (!strcmp(buf, "if"))
+ if (!strcmp(buf.scratch, "if"))
{
if (elseptr >= 0)
fz_throw(ctx, "too many branches for 'if'");
@@ -771,7 +771,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
func->u.p.code[opptr+3].type = PS_BLOCK;
func->u.p.code[opptr+3].u.block = *codeptr;
}
- else if (!strcmp(buf, "ifelse"))
+ else if (!strcmp(buf.scratch, "ifelse"))
{
if (elseptr < 0)
fz_throw(ctx, "not enough branches for 'ifelse'");
@@ -786,7 +786,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
}
else
{
- fz_throw(ctx, "unknown keyword in 'if-else' context: '%s'", buf);
+ fz_throw(ctx, "unknown keyword in 'if-else' context: '%s'", buf.scratch);
}
break;
@@ -804,7 +804,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
while (b - a > 1)
{
mid = (a + b) / 2;
- cmp = strcmp(buf, ps_op_names[mid]);
+ cmp = strcmp(buf.scratch, ps_op_names[mid]);
if (cmp > 0)
a = mid;
else if (cmp < 0)
@@ -813,7 +813,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
a = b = mid;
}
if (cmp != 0)
- fz_throw(ctx, "unknown operator: '%s'", buf);
+ fz_throw(ctx, "unknown operator: '%s'", buf.scratch);
resize_code(ctx, func, *codeptr);
func->u.p.code[*codeptr].type = PS_OPERATOR;
@@ -832,12 +832,13 @@ load_postscript_func(pdf_function *func, pdf_document *xref, fz_obj *dict, int n
{
fz_stream *stream = NULL;
int codeptr;
- char buf[64];
+ pdf_lexbuf buf;
int tok;
- int len;
fz_context *ctx = xref->ctx;
int locked = 0;
+ buf.size = PDF_LEXBUF_SMALL;
+
fz_var(stream);
fz_var(locked);
@@ -846,7 +847,7 @@ load_postscript_func(pdf_function *func, pdf_document *xref, fz_obj *dict, int n
stream = pdf_open_stream(xref, num, gen);
/* RJW: "cannot open calculator function stream" */
- tok = pdf_lex(stream, buf, sizeof buf, &len);
+ tok = pdf_lex(stream, &buf);
if (tok != PDF_TOK_OPEN_BRACE)
{
fz_throw(ctx, "stream is not a calculator function");