summaryrefslogtreecommitdiff
path: root/source/fitz
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2016-02-11 16:00:36 +0000
committerRobin Watts <robin.watts@artifex.com>2016-02-12 16:52:52 +0000
commit4b6c0ab659b3feb5f8e3683e393d61ccfdc09c3c (patch)
tree7c2210beb8858171e8f72388444c06d69ebf383e /source/fitz
parent16e82693f89d2b1d176fb7b2f5718d5270ad0239 (diff)
downloadmupdf-4b6c0ab659b3feb5f8e3683e393d61ccfdc09c3c.tar.xz
Bug 696580: Speed up fz_write_pnm_band.
Writing individual bytes using fwrite is VERY slow (profile of debug code shows 93% of runtime is in system fwrite). Fix this by collating into a buffer and writing (now 2.5%).
Diffstat (limited to 'source/fitz')
-rw-r--r--source/fitz/pixmap.c61
1 files changed, 46 insertions, 15 deletions
diff --git a/source/fitz/pixmap.c b/source/fitz/pixmap.c
index d2086d6f..8bdb5cb9 100644
--- a/source/fitz/pixmap.c
+++ b/source/fitz/pixmap.c
@@ -582,6 +582,7 @@ fz_write_pnm_header(fz_context *ctx, fz_output *out, int w, int h, int n)
void
fz_write_pnm_band(fz_context *ctx, fz_output *out, int w, int h, int n, int band, int bandheight, unsigned char *p)
{
+ char buffer[2*3*4*5*6]; /* Buffer must be a multiple of 2 and 3 at least. */
int len;
int start = band * bandheight;
int end = start + bandheight;
@@ -592,26 +593,56 @@ fz_write_pnm_band(fz_context *ctx, fz_output *out, int w, int h, int n, int band
len = w * end;
- switch (n)
+ /* Tests show that writing single bytes out at a time
+ * is appallingly slow. We get a huge improvement
+ * by collating stuff into buffers first. */
+
+ while (len)
{
- case 1:
- fz_write(ctx, out, p, len);
- break;
- case 2:
- while (len--)
+ int num_written = len;
+
+ switch (n)
+ {
+ case 1:
+ /* No collation required */
+ fz_write(ctx, out, p, num_written);
+ break;
+ case 2:
{
- fz_putc(ctx, out, p[0]);
- p += 2;
+ char *o = buffer;
+ int count;
+
+ if (num_written > sizeof(buffer))
+ num_written = sizeof(buffer);
+
+ for (count = num_written; count; count--)
+ {
+ *o++ = *p;
+ p += 2;
+ }
+ fz_write(ctx, out, buffer, num_written);
+ break;
}
- break;
- case 4:
- while (len--)
+ case 4:
{
- fz_putc(ctx, out, p[0]);
- fz_putc(ctx, out, p[1]);
- fz_putc(ctx, out, p[2]);
- p += 4;
+ char *o = buffer;
+ int count;
+
+ if (num_written > sizeof(buffer)/3)
+ num_written = sizeof(buffer)/3;
+
+ for (count = num_written; count; count--)
+ {
+ *o++ = p[0];
+ *o++ = p[1];
+ *o++ = p[2];
+ p += 4;
+ }
+ fz_write(ctx, out, buffer, num_written * 3);
+ break;
+ }
}
+ len -= num_written;
}
}