summaryrefslogtreecommitdiff
path: root/draw
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2010-07-11 16:02:39 +0200
committerTor Andersson <tor@ghostscript.com>2010-07-11 16:02:39 +0200
commit2420b5d3aecb9aa286436215f975513f83828fc5 (patch)
treea222a2769cdc5dd78a358efc12c5ca57451df4e4 /draw
parent92c206d6adc86ae645d54612b20e3de2df6afc45 (diff)
downloadmupdf-2420b5d3aecb9aa286436215f975513f83828fc5.tar.xz
Refactor image pixel unpacking.
Diffstat (limited to 'draw')
-rw-r--r--draw/imageunpack.c333
1 files changed, 54 insertions, 279 deletions
diff --git a/draw/imageunpack.c b/draw/imageunpack.c
index 6e5467ad..b899a8ad 100644
--- a/draw/imageunpack.c
+++ b/draw/imageunpack.c
@@ -1,308 +1,83 @@
#include "fitz.h"
-typedef unsigned char byte;
-
/*
- * Apply decode parameters
+ * Unpack image samples and optionally pad pixels with opaque alpha
*/
-static void decodetile(fz_pixmap *pix, int imagemask, float *decode)
-{
- int min[FZ_MAXCOLORS];
- int max[FZ_MAXCOLORS];
- int sub[FZ_MAXCOLORS];
- int needed = 0;
- int n = pix->n;
- byte *p = pix->samples;
- int wh = pix->w * pix->h;
- int i;
- int justinvert = 1;
+#define get1(buf,x) ((buf[x >> 3] >> ( 7 - (x & 7) ) ) & 1 )
+#define get2(buf,x) ((buf[x >> 2] >> ( ( 3 - (x & 3) ) << 1 ) ) & 3 )
+#define get4(buf,x) ((buf[x >> 1] >> ( ( 1 - (x & 1) ) << 2 ) ) & 15 )
+#define get8(buf,x) (buf[x])
+#define get16(buf,x) (buf[x << 1])
- for (i = 0; i < n - imagemask; i++)
- {
- min[i] = decode[i * 2] * 255;
- max[i] = decode[i * 2 + 1] * 255;
- sub[i] = max[i] - min[i];
- needed |= (min[i] != 0) | (max[i] != 255);
- justinvert &= min[i] == 255 && max[i] == 0 && sub[i] == -255;
- }
+void
+fz_unpacktile(fz_pixmap *dst, unsigned char * restrict src, int n, int depth, int stride)
+{
+ int pad, x, y, k;
- if (imagemask)
- {
- min[i] = 0;
- max[i] = 255;
- sub[i] = 255;
- }
+ pad = 0;
+ if (dst->n > n)
+ pad = (1 << depth) - 1;
- if (!needed)
- return;
+ /* TODO: reinsert Robin Watts' specialized loops here */
- switch (n) {
- case 1:
- while (wh--)
- {
- p[0] = min[0] + fz_mul255(sub[0], p[0]);
- p ++;
- }
- break;
- case 2:
- if (justinvert)
- {
- unsigned mask = fz_isbigendian() ? 0x00ff00ff : 0xff00ff00;
- unsigned *wp = (unsigned *)p;
- if ((((char *)wp - (char *)0) & 3) == 0) {
- int hwh = wh / 2;
- wh = wh - 2 * hwh;
- while(hwh--) {
- unsigned in = *wp;
- unsigned out = in ^ mask;
- *wp++ = out;
- }
- p = (byte *)wp;
- }
- if (wh--) {
- p[0] = p[0];
- p[1] = 255 - p[1];
- p += 2;
- }
- }
- else
+ 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++)
{
- while (wh--)
+ for (k = 0; k < n; k++)
{
- p[0] = min[0] + fz_mul255(sub[0], p[0]);
- p[1] = min[1] + fz_mul255(sub[1], p[1]);
- p += 2;
+ switch (depth)
+ {
+ 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;
+ }
+ b++;
}
- }
- break;
- default:
- while (wh--)
- {
- for (i = 0; i < n; i++)
- p[i] = min[i] + fz_mul255(sub[i], p[i]);
- p += n;
+ if (pad)
+ *dp++ = pad;
}
}
}
/*
- * Unpack image samples and optionally pad pixels with opaque alpha
+ * Apply decode parameters and scale integers
*/
-#define tbit(buf,x) ((buf[x >> 3] >> ( 7 - (x & 7) ) ) & 1 ) * 255
-#define ttwo(buf,x) ((buf[x >> 2] >> ( ( 3 - (x & 3) ) << 1 ) ) & 3 ) * 85
-#define tnib(buf,x) ((buf[x >> 1] >> ( ( 1 - (x & 1) ) << 2 ) ) & 15 ) * 17
-#define toct(buf,x) (buf[x])
-#define thex(buf,x) (buf[x << 1])
-
-static byte t1pad0[256][8];
-static byte t1pad1[256][16];
-
-static void init1(void)
-{
- static int inited = 0;
- byte bits[1];
- int i, k, x;
-
- if (inited)
- return;
-
- for (i = 0; i < 256; i++)
- {
- bits[0] = i;
- for (k = 0; k < 8; k++)
- {
- x = tbit(bits, k);
- t1pad0[i][k] = x;
- t1pad1[i][k * 2 + 0] = x;
- t1pad1[i][k * 2 + 1] = 255;
- }
- }
-
- inited = 1;
-}
-
-static void loadtile1(byte * restrict src, int sw, byte * restrict dst, int dw, int w, int h, int pad)
+void
+fz_decodetile(fz_pixmap *pix, float *decode, int scale)
{
- byte *sp;
- byte *dp;
- int x;
-
- init1();
-
- if (pad == 0)
- {
- int w3 = w >> 3;
- while (h--)
- {
- sp = src;
- dp = dst;
- for (x = 0; x < w3; x++)
- {
- memcpy(dp, t1pad0[*sp++], 8);
- dp += 8;
- }
- x = x << 3;
- if (x < w)
- memcpy(dp, t1pad0[*sp], w - x);
- src += sw;
- dst += dw;
- }
- }
+ int min[FZ_MAXCOLORS + 2];
+ int max[FZ_MAXCOLORS + 2];
+ int sub[FZ_MAXCOLORS + 2];
+ unsigned char *p = pix->samples;
+ int len = pix->w * pix->h;
+ int n = pix->n;
+ int needed;
+ int k;
- else if (pad == 1)
+ needed = scale != 1;
+ for (k = 0; k < n; k++)
{
- int w3 = w >> 3;
- while (h--)
- {
- sp = src;
- dp = dst;
- for (x = 0; x < w3; x++)
- {
- memcpy(dp, t1pad1[*sp++], 16);
- dp += 16;
- }
- x = x << 3;
- if (x < w)
- memcpy(dp, t1pad1[*sp], (w - x) << 1);
- src += sw;
- dst += dw;
- }
+ min[k] = decode[k * 2] * 255;
+ max[k] = decode[k * 2 + 1] * 255;
+ sub[k] = max[k] - min[k];
+ needed |= min[k] != 0 || max[k] != 255;
}
- else
- {
- while (h--)
- {
- dp = dst;
- for (x = 0; x < w; x++)
- {
- if ((x % pad) == pad-1)
- *dp++ = 255;
- *dp++ = tbit(src, x);
- }
- src += sw;
- dst += dw;
- }
- }
-}
-
-#define TILE(getf) \
-{ \
- int x; \
- if (!pad) \
- while (h--) \
- { \
- for (x = 0; x < w; x++) \
- dst[x] = getf(src, x); \
- src += sw; \
- dst += dw; \
- } \
- else { \
- int tpad; \
- while (h--) \
- { \
- byte *dp = dst; \
- tpad = pad; \
- for (x = 0; x < w; x++) \
- { \
- *dp++ = getf(src, x); \
- if (--tpad == 0) { \
- tpad = pad; \
- *dp++ = 255; \
- } \
- } \
- src += sw; \
- dst += dw; \
- } \
- } \
-}
-
-static void loadtile2(byte * restrict src, int sw, byte * restrict dst, int dw, int w, int h, int pad)
-TILE(ttwo)
-static void loadtile4(byte * restrict src, int sw, byte * restrict dst, int dw, int w, int h, int pad)
-TILE(tnib)
-static void loadtile8(byte * restrict src, int sw, byte * restrict dst, int dw, int w, int h, int pad)
-{
- if ((h == 0) || (w == 0))
+ if (!needed)
return;
- switch (pad)
+ while (len--)
{
- case 0:
- while (h--)
- {
- memcpy(dst, src, w);
- src += sw;
- dst += dw;
- }
- break;
-
- case 1:
- sw -= w;
- dw -= w<<1;
- while (h--)
- {
- int x;
- for (x = w; x > 0; x --)
- {
- *dst++ = *src++;
- *dst++ = 255;
- }
- src += sw;
- dst += dw;
- }
- break;
-
- case 3:
- sw -= w;
- while (h--)
- {
- byte *dp = dst;
- int x;
- for (x = w; x > 0; x -= 3)
- {
- *dp++ = *src++;
- *dp++ = *src++;
- *dp++ = *src++;
- *dp++ = 255;
- }
- src += sw;
- dst += dw;
- }
- break;
-
- default:
- sw -= w;
- while (h--)
- {
- byte *dp = dst;
- int tpad = pad;
- int x;
- for (x = w; x > 0; x--)
- {
- *dp++ = *src++;
- tpad--;
- if (tpad == 0) {
- tpad = pad;
- *dp++ = 255;
- }
- }
- src += sw;
- dst += dw;
- }
- break;
+ for (k = 0; k < n; k++)
+ p[k] = min[k] + fz_mul255(sub[k], p[k] * scale);
+ p += n;
}
}
-
-static void loadtile16(byte * restrict src, int sw, byte * restrict dst, int dw, int w, int h, int pad)
-TILE(thex)
-
-void (*fz_decodetile)(fz_pixmap *pix, int skip, float *decode) = decodetile;
-void (*fz_loadtile1)(byte*restrict, int sw, byte*restrict, int dw, int w, int h, int pad) = loadtile1;
-void (*fz_loadtile2)(byte*restrict, int sw, byte*restrict, int dw, int w, int h, int pad) = loadtile2;
-void (*fz_loadtile4)(byte*restrict, int sw, byte*restrict, int dw, int w, int h, int pad) = loadtile4;
-void (*fz_loadtile8)(byte*restrict, int sw, byte*restrict, int dw, int w, int h, int pad) = loadtile8;
-void (*fz_loadtile16)(byte*restrict, int sw, byte*restrict, int dw, int w, int h, int pad) = loadtile16;
-