diff options
Diffstat (limited to 'draw/archport.c')
-rw-r--r-- | draw/archport.c | 94 |
1 files changed, 94 insertions, 0 deletions
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 +} |