summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO4
-rw-r--r--filter/filew.c73
-rw-r--r--mupdf/interpret.c9
-rw-r--r--mupdf/page.c97
-rw-r--r--render/glyphcache.c31
-rw-r--r--render/rastport.c6
-rw-r--r--render/render.c4
7 files changed, 146 insertions, 78 deletions
diff --git a/TODO b/TODO
index 4c29ca87..38ad4720 100644
--- a/TODO
+++ b/TODO
@@ -20,7 +20,7 @@ rendering
- cpu-specific optims
parser
- - resource dict generate fake ids
+ - join content streams arrays (for split dicts)
- try to clean up colorspace/material handling in interpreter
- annotations and destinations (for links and outline)
@@ -30,9 +30,7 @@ fz_optimizetree()
- remove identity transforms
clean up
- - make source ansi c89 / pedantic
- reference count everything
- - standard cleanup mechanism
- design by contract
- split into private and public
- comments and documentation
diff --git a/filter/filew.c b/filter/filew.c
index 1ac446fe..f83399a2 100644
--- a/filter/filew.c
+++ b/filter/filew.c
@@ -93,10 +93,13 @@ fz_write(fz_file *f, unsigned char *buf, int n)
if (f->in->wp == f->in->ep)
{
- x = dowrite(f->in, f->fd);
- if (x < 0) {
- f->error = fz_throw("ioerror in write: %s", strerror(errno));
- return -1;
+ if (f->fd != -1)
+ {
+ x = dowrite(f->in, f->fd);
+ if (x < 0) {
+ f->error = fz_throw("ioerror in write: %s", strerror(errno));
+ return -1;
+ }
}
if (f->in->rp > f->in->bp)
@@ -134,10 +137,13 @@ fz_write(fz_file *f, unsigned char *buf, int n)
else if (reason == fz_ioneedout)
{
- x = dowrite(f->out, f->fd);
- if (x < 0) {
- f->error = fz_throw("ioerror in write: %s", strerror(errno));
- return -1;
+ if (f->fd != -1)
+ {
+ x = dowrite(f->out, f->fd);
+ if (x < 0) {
+ f->error = fz_throw("ioerror in write: %s", strerror(errno));
+ return -1;
+ }
}
if (f->out->rp > f->out->bp)
@@ -150,12 +156,15 @@ fz_write(fz_file *f, unsigned char *buf, int n)
else if (reason == fz_iodone)
{
- while (f->out->rp < f->out->wp)
+ if (f->fd != -1)
{
- x = dowrite(f->out, f->fd);
- if (x < 0) {
- f->error = fz_throw("ioerror in write: %s", strerror(errno));
- return -1;
+ while (f->out->rp < f->out->wp)
+ {
+ x = dowrite(f->out, f->fd);
+ if (x < 0) {
+ f->error = fz_throw("ioerror in write: %s", strerror(errno));
+ return -1;
+ }
}
}
break;
@@ -184,12 +193,15 @@ fz_flush(fz_file *f)
if (!f->filter)
{
- while (f->in->rp < f->in->wp)
+ if (f->fd != -1)
{
- n = dowrite(f->in, f->fd);
- if (n < 0) {
- f->error = fz_throw("ioerror in write: %s", strerror(errno));
- return -1;
+ while (f->in->rp < f->in->wp)
+ {
+ n = dowrite(f->in, f->fd);
+ if (n < 0) {
+ f->error = fz_throw("ioerror in write: %s", strerror(errno));
+ return -1;
+ }
}
}
return 0;
@@ -206,10 +218,13 @@ fz_flush(fz_file *f)
else if (reason == fz_ioneedout)
{
- n = dowrite(f->out, f->fd);
- if (n < 0) {
- f->error = fz_throw("ioerror in write: %s", strerror(errno));
- return -1;
+ if (f->fd != -1)
+ {
+ n = dowrite(f->out, f->fd);
+ if (n < 0) {
+ f->error = fz_throw("ioerror in write: %s", strerror(errno));
+ return -1;
+ }
}
if (f->out->rp > f->out->bp)
@@ -222,15 +237,19 @@ fz_flush(fz_file *f)
else if (reason == fz_iodone)
{
- n = dowrite(f->out, f->fd);
- if (n < 0) {
- f->error = fz_throw("ioerror in write: %s", strerror(errno));
- return -1;
+ if (f->fd != -1)
+ {
+ n = dowrite(f->out, f->fd);
+ if (n < 0) {
+ f->error = fz_throw("ioerror in write: %s", strerror(errno));
+ return -1;
+ }
}
break;
}
- else {
+ else
+ {
f->error = reason;
return -1;
}
diff --git a/mupdf/interpret.c b/mupdf/interpret.c
index 494404fc..c45c63e3 100644
--- a/mupdf/interpret.c
+++ b/mupdf/interpret.c
@@ -1101,19 +1101,12 @@ pdf_runcsi(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_file *file)
case PDF_TEOF:
return nil;
- /* we need to make array parsing be able to span files for
- those stupid pdf files that split TJ arrays across content
- streams...
- */
+ /* optimize text-object array parsing */
case PDF_TOARRAY:
error = fz_newarray(&csi->array, 8);
if (error) return error;
break;
- /* drop down to normal pdf object parsing for dictionaries,
- and pray that they are not split in the middle with the beginning
- and end in different streams
- */
case PDF_TODICT:
error = pdf_parsedict(&csi->stack[csi->top], file, buf, sizeof buf);
if (error) return error;
diff --git a/mupdf/page.c b/mupdf/page.c
index 8ae29541..b65378fd 100644
--- a/mupdf/page.c
+++ b/mupdf/page.c
@@ -2,7 +2,7 @@
#include <mupdf.h>
static fz_error *
-runcsi(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref)
+runone(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref)
{
fz_error *error;
@@ -17,13 +17,74 @@ runcsi(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref)
return error;
}
+/* we need to combine all sub-streams into one for pdf_runcsi
+ * to deal with split dictionaries etc.
+ */
+static fz_error *
+runmany(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_obj *list)
+{
+ fz_error *error;
+ fz_file *file;
+ fz_buffer *big;
+ fz_buffer *one;
+ fz_obj *stm;
+ int n;
+ int i;
+
+printf("joining content stream\n");
+
+ error = fz_newbuffer(&big, 32 * 1024);
+ if (error)
+ return error;
+
+ error = fz_openbuffer(&file, big, FZ_WRITE);
+ if (error)
+ goto cleanup0;
+
+ for (i = 0; i < fz_arraylen(list); i++)
+ {
+ stm = fz_arrayget(list, i);
+ error = pdf_loadstream(&one, xref, fz_tonum(stm), fz_togen(stm));
+ if (error)
+ goto cleanup1;
+
+ n = fz_write(file, one->rp, one->wp - one->rp);
+
+ fz_dropbuffer(one);
+
+ if (n == -1)
+ {
+ error = fz_ferror(file);
+ goto cleanup1;
+ }
+ }
+
+ fz_closefile(file);
+
+ error = fz_openbuffer(&file, big, FZ_READ);
+ if (error)
+ goto cleanup0;
+
+ error = pdf_runcsi(csi, xref, rdb, file);
+
+ fz_closefile(file);
+ fz_dropbuffer(big);
+
+ return error;
+
+cleanup1:
+ fz_closefile(file);
+cleanup0:
+ fz_dropbuffer(big);
+ return error;
+}
+
static fz_error *
loadpagecontents(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *ref)
{
fz_error *error;
fz_obj *obj;
pdf_csi *csi;
- int i;
error = pdf_newcsi(&csi, 0);
if (error)
@@ -37,35 +98,25 @@ loadpagecontents(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *ref)
if (fz_isarray(obj))
{
- for (i = 0; i < fz_arraylen(obj); i++)
- {
- error = runcsi(csi, xref, rdb, fz_arrayget(obj, i));
- if (error) {
- fz_dropobj(obj);
- goto cleanup;
- }
- }
+ if (fz_arraylen(obj) == 1)
+ error = runone(csi, xref, rdb, fz_arrayget(obj, 0));
+ else
+ error = runmany(csi, xref, rdb, obj);
}
else
- {
- error = runcsi(csi, xref, rdb, ref);
- if (error) {
- fz_dropobj(obj);
- goto cleanup;
- }
- }
+ error = runone(csi, xref, rdb, ref);
fz_dropobj(obj);
+ if (error)
+ goto cleanup;
}
else if (fz_isarray(ref))
{
- for (i = 0; i < fz_arraylen(ref); i++)
- {
- error = runcsi(csi, xref, rdb, fz_arrayget(ref, i));
- if (error)
- goto cleanup;
- }
+ if (fz_arraylen(ref) == 1)
+ error = runone(csi, xref, rdb, fz_arrayget(ref, 0));
+ else
+ error = runmany(csi, xref, rdb, ref);
}
*treep = csi->tree;
diff --git a/render/glyphcache.c b/render/glyphcache.c
index 57b2ce84..5364230b 100644
--- a/render/glyphcache.c
+++ b/render/glyphcache.c
@@ -285,7 +285,7 @@ evictlast(fz_glyphcache *arena)
arena->used -= e - s;
/* update lru pointers */
- for (i = 0; i < k; i++)
+ for (i = 0; i < k; i++) /* XXX this is DOG slow! XXX */
if (lru[i].samples >= e)
lru[i].samples -= e - s;
@@ -296,6 +296,17 @@ evictlast(fz_glyphcache *arena)
arena->load --;
}
+static void
+evictall(fz_glyphcache *arena)
+{
+printf("zap!\n");
+ memset(arena->hash, 0, sizeof(fz_hash) * arena->slots);
+ memset(arena->lru, 0, sizeof(fz_val) * arena->slots);
+ memset(arena->buffer, 0, arena->size);
+ arena->load = 0;
+ arena->used = 0;
+}
+
fz_error *
fz_renderglyph(fz_glyphcache *arena, fz_glyph *glyph, fz_font *font, int cid, fz_matrix ctm)
{
@@ -342,20 +353,16 @@ fz_renderglyph(fz_glyphcache *arena, fz_glyph *glyph, fz_font *font, int cid, fz
while (arena->load > arena->slots * 75 / 100)
{
- while (arena->load > arena->slots * 60 / 100)
- {
- covf ++;
- evictlast(arena);
- }
+ covf ++;
+// evictlast(arena);
+ evictall(arena);
}
- if (arena->used + size >= arena->size)
+ while (arena->used + size >= arena->size)
{
- while (arena->used + size >= arena->size * 80 / 100)
- {
- coos ++;
- evictlast(arena);
- }
+ coos ++;
+// evictlast(arena);
+ evictall(arena);
}
val = &arena->lru[arena->load++];
diff --git a/render/rastport.c b/render/rastport.c
index 6d6b3b8a..a6dedf05 100644
--- a/render/rastport.c
+++ b/render/rastport.c
@@ -396,9 +396,9 @@ static void img_w3i1o4(byte *rgb, FZ_PSRC, FZ_PDST, FZ_PCTM)
sa = samplemask(src, srcw, srch, u, v);
ssa = 255 - sa;
dstp[0] = sa + fz_mul255(dstp[0], ssa);
- dstp[1] = rgb[0] + fz_mul255(dstp[1], ssa);
- dstp[2] = rgb[1] + fz_mul255(dstp[2], ssa);
- dstp[3] = rgb[2] + fz_mul255(dstp[3], ssa);
+ dstp[1] = rgb[0] + fz_mul255((short)dstp[1] - rgb[0], ssa);
+ dstp[2] = rgb[1] + fz_mul255((short)dstp[2] - rgb[1], ssa);
+ dstp[3] = rgb[2] + fz_mul255((short)dstp[3] - rgb[2], ssa);
dstp += 4;
u += fa;
v += fb;
diff --git a/render/render.c b/render/render.c
index 77f04e22..b72f069e 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1,7 +1,7 @@
#include <fitz.h>
-#define DEBUG(args...) printf(args)
-#define noDEBUG(args...)
+#define noDEBUG(args...) printf(args)
+#define DEBUG(args...)
#define FNONE 0
#define FOVER 1