summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2010-05-27 19:21:48 +0200
committerTor Andersson <tor@ghostscript.com>2010-05-27 19:21:48 +0200
commitd65bded0e788321bd09c0d3a9864ef7ee13dcddb (patch)
tree7350e8ae333a13e438e94788ced2d07ed39fd840
parent5b09c0026585fe3063b467edde908e013e2be08b (diff)
downloadmupdf-d65bded0e788321bd09c0d3a9864ef7ee13dcddb.tar.xz
Add optimized function written in C that depends on integers being exactly 32-bit.
-rw-r--r--Makefile2
-rw-r--r--draw/archarm.c2
-rw-r--r--draw/archport.c94
-rw-r--r--draw/archx86.c2
-rw-r--r--fitz/base_cpudep.c4
-rw-r--r--fitz/fitz_draw.h1
-rw-r--r--win32/draw/draw.vcproj4
7 files changed, 102 insertions, 7 deletions
diff --git a/Makefile b/Makefile
index cb98ed38..2623963a 100644
--- a/Makefile
+++ b/Makefile
@@ -75,7 +75,7 @@ FITZ_OBJ=$(FITZ_SRC:fitz/%.c=$(OBJDIR)/%.o)
$(FITZ_OBJ): $(FITZ_HDR)
DRAW_SRC=$(addprefix draw/, $(ARCH_SRC) \
- blendmodes.c glyphcache.c imagedraw.c imagescale.c imageunpack.c meshdraw.c \
+ archport.c blendmodes.c glyphcache.c imagedraw.c imagescale.c imageunpack.c meshdraw.c \
pathfill.c pathscan.c pathstroke.c porterduff.c )
DRAW_OBJ=$(DRAW_SRC:draw/%.c=$(OBJDIR)/%.o)
$(DRAW_OBJ): $(FITZ_HDR)
diff --git a/draw/archarm.c b/draw/archarm.c
index 609a1b90..c5f9d13c 100644
--- a/draw/archarm.c
+++ b/draw/archarm.c
@@ -98,7 +98,7 @@ path_w4i1o4arm(byte * restrict argb, byte * restrict src, byte cov, int len, byt
}
void
-fz_accelerate(void)
+fz_acceleratearch(void)
{
fz_path_w4i1o4 = path_w4i1o4arm;
}
diff --git a/draw/archport.c b/draw/archport.c
new file mode 100644
index 00000000..2b45b7c0
--- /dev/null
+++ b/draw/archport.c
@@ -0,0 +1,94 @@
+#include "fitz.h"
+
+/* This C implementation was a prototype of the algorithm used
+ * in the ARM code in draw/archarm.c. It is conceivable that on some
+ * architectures/compilers this may be preferable to the vanilla
+ * version below. */
+
+static void
+path_w4i1o4_32bit(unsigned char * restrict argb,
+ unsigned char * restrict src, unsigned char cov, int len,
+ unsigned char * restrict dst)
+{
+ /* COLOR * coverage + DST * (256-coverage) = (COLOR - DST)*coverage + DST*256 */
+ unsigned int *dst32 = (unsigned int *)(void *)dst;
+ int alpha = argb[0];
+ unsigned int rb = argb[1] | argb[3] << 16;
+ unsigned int ag = 255 | argb[2] << 16;
+ const int MASK = 0xFF00FF00;
+
+ /* sanity test */
+ if (sizeof(int) != 4 || sizeof(unsigned int) != 4)
+ abort();
+
+ if (alpha != 255)
+ {
+ alpha += alpha>>7; /* alpha is now in the 0...256 range */
+ while (len--)
+ {
+ unsigned int ca, drb, dag, crb, cag;
+ cov += *src; *src++ = 0;
+ ca = cov+(cov>>7); /* ca is in 0...256 range */
+ ca = (ca*alpha)>>8; /* ca is is in 0...256 range */
+ dag = *dst32++;
+ if (ca != 0)
+ {
+ drb = dag & MASK;
+ dag = (dag<<8) & MASK;
+ crb = rb - (drb>>8);
+ cag = ag - (dag>>8);
+ drb += crb * ca;
+ dag += cag * ca;
+ drb = drb & MASK;
+ dag = dag & MASK;
+ dag = drb | (dag>>8);
+ dst32[-1] = dag;
+ }
+ }
+ }
+ else
+ {
+ while (len--)
+ {
+ unsigned int ca, drb, dag, crb, cag;
+ cov += *src; *src++ = 0;
+ ca = cov+(cov>>7); /* ca is in 0...256 range */
+ dag = *dst32++;
+ if (ca == 0)
+ continue;
+ if (ca == 255)
+ {
+ dag = (rb<<8) | ag;
+ }
+ else
+ {
+ drb = dag & MASK;
+ dag = (dag<<8) & MASK;
+ crb = rb - (drb>>8);
+ cag = ag - (dag>>8);
+ drb += crb * ca;
+ dag += cag * ca;
+ drb = drb & MASK;
+ dag = dag & MASK;
+ dag = drb | (dag>>8);
+ }
+ dst32[-1] = dag;
+ }
+ }
+}
+
+void fz_accelerate(void)
+{
+ if (sizeof(int) == 4)
+ {
+ fz_path_w4i1o4 = path_w4i1o4_32bit;
+ }
+
+ if (sizeof(int) == 8)
+ {
+ }
+
+#ifdef HAVE_CPUDEP
+ fz_acceleratearch();
+#endif
+}
diff --git a/draw/archx86.c b/draw/archx86.c
index b75fb28f..0c313f33 100644
--- a/draw/archx86.c
+++ b/draw/archx86.c
@@ -220,7 +220,7 @@ static void img_4o4mmx(FZ_PSRC, FZ_PDST, FZ_PCTM)
#if defined (ARCH_X86) || defined(ARCH_X86_64)
void
-fz_accelerate(void)
+fz_acceleratearch(void)
{
# ifdef HAVE_MMX
if (fz_cpuflags & HAVE_MMX)
diff --git a/fitz/base_cpudep.c b/fitz/base_cpudep.c
index bc9bee91..980bc9d8 100644
--- a/fitz/base_cpudep.c
+++ b/fitz/base_cpudep.c
@@ -12,10 +12,6 @@ unsigned fz_cpuflags = 0;
#ifndef HAVE_CPUDEP
-void fz_accelerate(void)
-{
-}
-
void fz_cpudetect(void)
{
}
diff --git a/fitz/fitz_draw.h b/fitz/fitz_draw.h
index 0e53401f..cd155712 100644
--- a/fitz/fitz_draw.h
+++ b/fitz/fitz_draw.h
@@ -452,6 +452,7 @@ void fz_dashpath(fz_gel *gel, fz_path *path, fz_strokestate *stroke, fz_matrix c
*/
extern void fz_accelerate(void);
+extern void fz_acceleratearch(void);
extern void (*fz_duff_non)(unsigned char*,int,int,unsigned char*,int,int,int);
extern void (*fz_duff_nimon)(unsigned char*,int,int,unsigned char*,int,int,unsigned char*,int,int,int);
diff --git a/win32/draw/draw.vcproj b/win32/draw/draw.vcproj
index af1280dc..45954e31 100644
--- a/win32/draw/draw.vcproj
+++ b/win32/draw/draw.vcproj
@@ -147,6 +147,10 @@
Name="draw"
>
<File
+ RelativePath="..\..\draw\archport.c"
+ >
+ </File>
+ <File
RelativePath="..\..\draw\archx86.c"
>
</File>