diff options
author | Tor Andersson <tor@ghostscript.com> | 2010-05-27 19:21:48 +0200 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2010-05-27 19:21:48 +0200 |
commit | d65bded0e788321bd09c0d3a9864ef7ee13dcddb (patch) | |
tree | 7350e8ae333a13e438e94788ced2d07ed39fd840 | |
parent | 5b09c0026585fe3063b467edde908e013e2be08b (diff) | |
download | mupdf-d65bded0e788321bd09c0d3a9864ef7ee13dcddb.tar.xz |
Add optimized function written in C that depends on integers being exactly 32-bit.
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | draw/archarm.c | 2 | ||||
-rw-r--r-- | draw/archport.c | 94 | ||||
-rw-r--r-- | draw/archx86.c | 2 | ||||
-rw-r--r-- | fitz/base_cpudep.c | 4 | ||||
-rw-r--r-- | fitz/fitz_draw.h | 1 | ||||
-rw-r--r-- | win32/draw/draw.vcproj | 4 |
7 files changed, 102 insertions, 7 deletions
@@ -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>
|