summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--draw/imageunpack.c149
-rw-r--r--fitz/fitz.h4
-rw-r--r--mupdf/pdf_image.c19
3 files changed, 142 insertions, 30 deletions
diff --git a/draw/imageunpack.c b/draw/imageunpack.c
index b899a8ad..577eac21 100644
--- a/draw/imageunpack.c
+++ b/draw/imageunpack.c
@@ -10,38 +10,151 @@
#define get8(buf,x) (buf[x])
#define get16(buf,x) (buf[x << 1])
+static unsigned char get1tab1[256][8];
+static unsigned char get1tab1p[256][16];
+static unsigned char get1tab255[256][8];
+static unsigned char get1tab255p[256][16];
+
+static void
+initget1tables(void)
+{
+ static int once = 0;
+ unsigned char bits[1];
+ int i, k, x;
+
+ /* TODO: mutex lock here */
+
+ if (once)
+ return;
+
+ for (i = 0; i < 256; i++)
+ {
+ bits[0] = i;
+ for (k = 0; k < 8; k++)
+ {
+ x = get1(bits, k);
+
+ get1tab1[i][k] = x;
+ get1tab1p[i][k * 2] = x;
+ get1tab1p[i][k * 2 + 1] = 1;
+
+ get1tab255[i][k] = x * 255;
+ get1tab255p[i][k * 2] = x * 255;
+ get1tab255p[i][k * 2 + 1] = 255;
+ }
+ }
+
+ once = 1;
+}
+
void
-fz_unpacktile(fz_pixmap *dst, unsigned char * restrict src, int n, int depth, int stride)
+fz_unpacktile(fz_pixmap *dst, unsigned char * restrict src, int n, int depth, int stride, int scale)
{
int pad, x, y, k;
+ int w = dst->w;
pad = 0;
if (dst->n > n)
- pad = (1 << depth) - 1;
+ pad = ((1 << depth) - 1) * scale;
- /* TODO: reinsert Robin Watts' specialized loops here */
+ initget1tables();
for (y = 0; y < dst->h; y++)
{
unsigned char *sp = src + y * stride;
unsigned char *dp = dst->samples + y * (dst->w * dst->n);
- int b = 0;
- for (x = 0; x < dst->w; x++)
+
+ /* Specialized loops */
+
+ if (n == 1 && depth == 1 && scale == 1 && !pad)
+ {
+ int w3 = w >> 3;
+ for (x = 0; x < w3; x++)
+ {
+ memcpy(dp, get1tab1[*sp++], 8);
+ dp += 8;
+ }
+ x = x << 3;
+ if (x < w)
+ memcpy(dp, get1tab1[*sp], w - x);
+ }
+
+ else if (n == 1 && depth == 1 && scale == 255 && !pad)
+ {
+ int w3 = w >> 3;
+ for (x = 0; x < w3; x++)
+ {
+ memcpy(dp, get1tab255[*sp++], 8);
+ dp += 8;
+ }
+ x = x << 3;
+ if (x < w)
+ memcpy(dp, get1tab255[*sp], w - x);
+ }
+
+ else if (n == 1 && depth == 1 && scale == 1 && pad == 1)
+ {
+ int w3 = w >> 3;
+ for (x = 0; x < w3; x++)
+ {
+ memcpy(dp, get1tab1p[*sp++], 16);
+ dp += 16;
+ }
+ x = x << 3;
+ if (x < w)
+ memcpy(dp, get1tab1p[*sp], (w - x) << 1);
+ }
+
+ else if (n == 1 && depth == 1 && scale == 255 && pad == 255)
+ {
+ int w3 = w >> 3;
+ for (x = 0; x < w3; x++)
+ {
+ memcpy(dp, get1tab255p[*sp++], 16);
+ dp += 16;
+ }
+ x = x << 3;
+ if (x < w)
+ memcpy(dp, get1tab255p[*sp], (w - x) << 1);
+ }
+
+ else if (depth == 8 && !pad)
+ {
+ int len = w * n;
+ while (len--)
+ *dp++ = *sp++;
+ }
+
+ else if (depth == 8 && pad == 255)
+ {
+ for (x = 0; x < w; x++)
+ {
+ for (k = 0; k < n; k++)
+ *dp++ = *sp++;
+ *dp++ = 255;
+ }
+ }
+
+ else
{
- for (k = 0; k < n; k++)
+ int b = 0;
+ for (x = 0; x < w; x++)
{
- switch (depth)
+ for (k = 0; k < n; k++)
{
- case 1: *dp++ = get1(sp, b); break;
- case 2: *dp++ = get2(sp, b); break;
- case 4: *dp++ = get4(sp, b); break;
- case 8: *dp++ = get8(sp, b); break;
- case 16: *dp++ = get16(sp, b); break;
+ switch (depth)
+ {
+ case 1: *dp++ = get1(sp, b) * scale; break;
+ case 2: *dp++ = get2(sp, b) * scale; break;
+ case 4: *dp++ = get4(sp, b) * scale; break;
+ case 8: *dp++ = get8(sp, b); break;
+ case 16: *dp++ = get16(sp, b); break;
+ }
+ b++;
}
- b++;
+ if (pad)
+ *dp++ = pad;
}
- if (pad)
- *dp++ = pad;
}
}
}
@@ -51,7 +164,7 @@ fz_unpacktile(fz_pixmap *dst, unsigned char * restrict src, int n, int depth, in
*/
void
-fz_decodetile(fz_pixmap *pix, float *decode, int scale)
+fz_decodetile(fz_pixmap *pix, float *decode)
{
int min[FZ_MAXCOLORS + 2];
int max[FZ_MAXCOLORS + 2];
@@ -62,7 +175,7 @@ fz_decodetile(fz_pixmap *pix, float *decode, int scale)
int needed;
int k;
- needed = scale != 1;
+ needed = 0;
for (k = 0; k < n; k++)
{
min[k] = decode[k * 2] * 255;
@@ -77,7 +190,7 @@ fz_decodetile(fz_pixmap *pix, float *decode, int scale)
while (len--)
{
for (k = 0; k < n; k++)
- p[k] = min[k] + fz_mul255(sub[k], p[k] * scale);
+ p[k] = min[k] + fz_mul255(sub[k], p[k]);
p += n;
}
}
diff --git a/fitz/fitz.h b/fitz/fitz.h
index 517e001e..9dbbafdc 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -1112,8 +1112,8 @@ void fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix ctm);
extern void fz_accelerate(void);
extern void fz_acceleratearch(void);
-extern void fz_decodetile(fz_pixmap *pix, float *decode, int scale);
-extern void fz_unpacktile(fz_pixmap *dst, unsigned char * restrict src, int n, int depth, int stride);
+extern void fz_decodetile(fz_pixmap *pix, float *decode);
+extern void fz_unpacktile(fz_pixmap *dst, unsigned char * restrict src, int n, int depth, int stride, int scale);
extern void (*fz_duff_ni1on)(unsigned char*restrict,int,int,unsigned char*restrict,int,unsigned char*restrict,int,int,int);
extern void (*fz_duff_1i1o1)(unsigned char*restrict,int,unsigned char*restrict,int,unsigned char*restrict,int,int,int);
diff --git a/mupdf/pdf_image.c b/mupdf/pdf_image.c
index 221dd507..9724b1ef 100644
--- a/mupdf/pdf_image.c
+++ b/mupdf/pdf_image.c
@@ -249,7 +249,7 @@ pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict)
}
static void
-pdf_maskcolorkey(fz_pixmap *pix, int n, int *colorkey)
+pdf_maskcolorkey(fz_pixmap *pix, int n, int *colorkey, int scale)
{
unsigned char *p = pix->samples;
int len = pix->w * pix->h;
@@ -258,7 +258,7 @@ pdf_maskcolorkey(fz_pixmap *pix, int n, int *colorkey)
{
t = 1;
for (k = 0; k < n; k++)
- if (p[k] < colorkey[k * 2] || p[k] > colorkey[k * 2 + 1])
+ if (p[k] < colorkey[k * 2] * scale || p[k] > colorkey[k * 2 + 1] * scale)
t = 0;
if (t)
for (k = 0; k < pix->n; k++)
@@ -283,15 +283,10 @@ pdf_loadtile(pdf_image *img /* ...bbox/y+h should go here... */)
case 4: scale = 17; break;
}
- fz_unpacktile(tile, img->samples->bp, img->n, img->bpc, img->stride);
+ fz_unpacktile(tile, img->samples->bp, img->n, img->bpc, img->stride, scale);
if (img->usecolorkey)
- pdf_maskcolorkey(tile, img->n, img->colorkey);
-
- if (!img->indexed)
- {
- fz_decodetile(tile, img->decode, scale);
- }
+ pdf_maskcolorkey(tile, img->n, img->colorkey, scale);
if (img->indexed)
{
@@ -303,12 +298,16 @@ pdf_loadtile(pdf_image *img /* ...bbox/y+h should go here... */)
decode[2] = img->decode[2];
decode[3] = img->decode[3];
- fz_decodetile(tile, decode, scale);
+ fz_decodetile(tile, decode);
conv = pdf_expandindexedpixmap(tile);
fz_droppixmap(tile);
tile = conv;
}
+ else
+ {
+ fz_decodetile(tile, img->decode);
+ }
return tile;
}