summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2004-11-29 16:15:08 +0100
committerTor Andersson <tor@ghostscript.com>2004-11-29 16:15:08 +0100
commit9a36550815c3d874ce62650bf06ee85a3f705f1c (patch)
treecc45ee69f0eca20520b388c44909703142c9196a
parentfa0b09e3a0c696069033195a394b09d30a8c0573 (diff)
downloadmupdf-9a36550815c3d874ce62650bf06ee85a3f705f1c.tar.xz
shift things about a bit
-rw-r--r--Jamfile25
-rw-r--r--TODO5
-rw-r--r--base/cpudep.c6
-rw-r--r--filter/dctd.c4
-rw-r--r--include/fitz.h2
-rw-r--r--include/fitz/cpudep.h4
-rw-r--r--include/fitz/pathscan.h (renamed from include/fitz/scanconv.h)2
-rw-r--r--include/fitz/render.h81
-rw-r--r--mupdf/colorspace1.c5
-rw-r--r--mupdf/image.c (renamed from mupdf/image1.c)76
-rw-r--r--mupdf/image2.c255
-rw-r--r--mupdf/resources.c2
-rw-r--r--render/archppc.c65
-rw-r--r--render/archsparc.c (renamed from render/rastsparc.c)2
-rw-r--r--render/archx86.c (renamed from render/rastx86.c)9
-rw-r--r--render/optduff.c324
-rw-r--r--render/optimage.c238
-rw-r--r--render/optscale.c191
-rw-r--r--render/optunpack.c183
-rw-r--r--render/pathfill.c (renamed from render/fill.c)0
-rw-r--r--render/pathscan.c (renamed from render/edgelist.c)162
-rw-r--r--render/pathstroke.c (renamed from render/stroke.c)0
-rw-r--r--render/rastport.c570
-rw-r--r--render/rastppc.c23
-rw-r--r--render/render.c60
-rw-r--r--render/scale.c225
-rw-r--r--render/scanconv.c152
-rw-r--r--test/pdfrip.c3
-rw-r--r--test/x11pdf.c3
-rw-r--r--test/ximage.c4
-rw-r--r--tree/optimize.c8
31 files changed, 1360 insertions, 1329 deletions
diff --git a/Jamfile b/Jamfile
index 6357a47d..3745d795 100644
--- a/Jamfile
+++ b/Jamfile
@@ -86,17 +86,19 @@ Library libfitz :
# render
render/glyphcache.c
render/pixmap.c
- render/edgelist.c
- render/scanconv.c
- render/fill.c
- render/stroke.c
- render/scale.c
render/rastshade.c
- render/rastport.c
- render/rastppc.c
- render/rastsparc.c
- render/rastx86.c
+ render/pathscan.c
+ render/pathfill.c
+ render/pathstroke.c
+ render/optduff.c
+ render/optimage.c
+ render/optunpack.c
+ render/optscale.c
render/render.c
+
+ render/archppc.c
+ render/archsparc.c
+ render/archx86.c
;
Library libmupdf :
@@ -120,13 +122,14 @@ Library libmupdf :
mupdf/fontagl.c
mupdf/fontenc.c
mupdf/fontfile.c
+# mupdf/fontfilefc.c
+# mupdf/fontfilems.c
mupdf/unicode.c
mupdf/font.c
mupdf/type3.c
mupdf/colorspace1.c
mupdf/colorspace2.c
- mupdf/image1.c
- mupdf/image2.c
+ mupdf/image.c
mupdf/xobject.c
mupdf/pattern.c
mupdf/shade.c
diff --git a/TODO b/TODO
index 85462d64..7e845aac 100644
--- a/TODO
+++ b/TODO
@@ -28,16 +28,19 @@ shadings
- ... jeong ...
rendering
+ - fix glyphcache evictlast
- bbox culling per glyph
- optimize image load/decode/scale
- cpu-specific optims
+ - font focus
parser
+ - image color key transparency
+ - rewrite 1x1 images as fillrect
- try to clean up colorspace/material handling in interpreter
- annotations and destinations (for links and outline)
fz_optimizetree()
- - remove white fills at beginning of page
- concatenate chained transforms
- remove identity transforms
diff --git a/base/cpudep.c b/base/cpudep.c
index c7af38b9..d4bd1a6c 100644
--- a/base/cpudep.c
+++ b/base/cpudep.c
@@ -7,6 +7,12 @@ Glenn Kennard <d98gk@efd.lth.se>
#include <fitz.h>
+#ifdef WIN32
+#define sigjmp_buf jmp_buf
+#define sigsetjmp setjmp
+#define siglongjmp longjmp
+#endif
+
typedef struct {
void (*test)(void);
const unsigned flag;
diff --git a/filter/dctd.c b/filter/dctd.c
index 0c0b072e..750f7893 100644
--- a/filter/dctd.c
+++ b/filter/dctd.c
@@ -91,6 +91,10 @@ fz_newdctd(fz_filter **fp, fz_obj *params)
d->src.super.next_input_byte = nil;
d->src.skip = 0;
+ /* speed up jpeg decoding a bit */
+ d->cinfo.dct_method = JDCT_FASTEST;
+ d->cinfo.do_fancy_upsampling = FALSE;
+
return nil;
}
diff --git a/include/fitz.h b/include/fitz.h
index 8c38652f..4c9756a0 100644
--- a/include/fitz.h
+++ b/include/fitz.h
@@ -29,6 +29,6 @@
#include "fitz/path.h"
#include "fitz/text.h"
-#include "fitz/scanconv.h"
+#include "fitz/pathscan.h"
#include "fitz/render.h"
diff --git a/include/fitz/cpudep.h b/include/fitz/cpudep.h
index 261c3c79..fc07393d 100644
--- a/include/fitz/cpudep.h
+++ b/include/fitz/cpudep.h
@@ -21,6 +21,10 @@
/* call this before using fitz */
extern void fz_cpudetect();
+#ifndef HAVE_CPUDEP
+#define fz_accelerate()
+#endif
+
/* treat as constant! */
extern unsigned fz_cpuflags;
diff --git a/include/fitz/scanconv.h b/include/fitz/pathscan.h
index 675d6806..109d16b6 100644
--- a/include/fitz/scanconv.h
+++ b/include/fitz/pathscan.h
@@ -35,8 +35,6 @@ void fz_sortgel(fz_gel *gel);
void fz_dropgel(fz_gel *gel);
fz_error *fz_newael(fz_ael **aelp);
-fz_error *fz_insertael(fz_ael *ael, fz_gel *gel, int y, int *e);
-void fz_advanceael(fz_ael *ael);
void fz_dropael(fz_ael *ael);
fz_error *fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, int y0, int y1,
diff --git a/include/fitz/render.h b/include/fitz/render.h
index d951b3da..5c2c7a67 100644
--- a/include/fitz/render.h
+++ b/include/fitz/render.h
@@ -1,9 +1,7 @@
typedef struct fz_renderer_s fz_renderer;
-typedef struct fz_rastfuncs_s fz_rastfuncs;
#define FZ_BYTE unsigned char
-/* TODO: use 'restrict' on pointers - they never alias, do they? */
#define FZ_PSRC \
unsigned char *src, int srcw, int srch
#define FZ_PDST \
@@ -11,33 +9,52 @@ typedef struct fz_rastfuncs_s fz_rastfuncs;
#define FZ_PCTM \
int u0, int v0, int fa, int fb, int fc, int fd, int w0, int h
-struct fz_rastfuncs_s
-{
- void (*duff_NoN)(FZ_BYTE*,int,int,FZ_BYTE*,int,int,int);
- void (*duff_NiMcN)(FZ_BYTE*,int,int,FZ_BYTE*,int,int,FZ_BYTE*,int,int,int);
- void (*duff_NiMoN)(FZ_BYTE*,int,int,FZ_BYTE*,int,int,FZ_BYTE*,int,int,int);
- void (*duff_1o1)(FZ_BYTE*,int,FZ_BYTE*,int,int,int);
- void (*duff_4o4)(FZ_BYTE*,int,FZ_BYTE*,int,int,int);
- void (*duff_1i1c1)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
- void (*duff_4i1c4)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
- void (*duff_1i1o1)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
- void (*duff_4i1o4)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
-
- void (*msk_1c1)(FZ_BYTE*,FZ_BYTE*,int);
- void (*msk_1o1)(FZ_BYTE*,FZ_BYTE*,int);
- void (*msk_w3i1o4)(FZ_BYTE*,FZ_BYTE*,FZ_BYTE*,int);
-
- void (*glf_1c1)(FZ_BYTE*,int,FZ_BYTE*,int,int,int);
- void (*glf_1o1)(FZ_BYTE*,int,FZ_BYTE*,int,int,int);
- void (*glf_w3i1o4)(FZ_BYTE*,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
-
- void (*img_NcN)(FZ_PSRC, int sn, FZ_PDST, FZ_PCTM);
- void (*img_1c1)(FZ_PSRC, FZ_PDST, FZ_PCTM);
- void (*img_4c4)(FZ_PSRC, FZ_PDST, FZ_PCTM);
- void (*img_1o1)(FZ_PSRC, FZ_PDST, FZ_PCTM);
- void (*img_4o4)(FZ_PSRC, FZ_PDST, FZ_PCTM);
- void (*img_w3i1o4)(FZ_BYTE*,FZ_PSRC,FZ_PDST,FZ_PCTM);
-};
+/*
+ * Function pointers -- they can be replaced by cpu-optimized versions
+ */
+
+extern void (*fz_duff_non)(FZ_BYTE*,int,int,FZ_BYTE*,int,int,int);
+extern void (*fz_duff_nimcn)(FZ_BYTE*,int,int,FZ_BYTE*,int,int,FZ_BYTE*,int,int,int);
+extern void (*fz_duff_nimon)(FZ_BYTE*,int,int,FZ_BYTE*,int,int,FZ_BYTE*,int,int,int);
+extern void (*fz_duff_1o1)(FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+extern void (*fz_duff_4o4)(FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+extern void (*fz_duff_1i1c1)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+extern void (*fz_duff_4i1c4)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+extern void (*fz_duff_1i1o1)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+extern void (*fz_duff_4i1o4)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+
+extern void (*fz_path_1c1)(FZ_BYTE*,FZ_BYTE*,int);
+extern void (*fz_path_1o1)(FZ_BYTE*,FZ_BYTE*,int);
+extern void (*fz_path_w3i1o4)(FZ_BYTE*,FZ_BYTE*,FZ_BYTE*,int);
+
+extern void (*fz_text_1c1)(FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+extern void (*fz_text_1o1)(FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+extern void (*fz_text_w3i1o4)(FZ_BYTE*,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+
+extern void (*fz_img_ncn)(FZ_PSRC, int sn, FZ_PDST, FZ_PCTM);
+extern void (*fz_img_1c1)(FZ_PSRC, FZ_PDST, FZ_PCTM);
+extern void (*fz_img_4c4)(FZ_PSRC, FZ_PDST, FZ_PCTM);
+extern void (*fz_img_1o1)(FZ_PSRC, FZ_PDST, FZ_PCTM);
+extern void (*fz_img_4o4)(FZ_PSRC, FZ_PDST, FZ_PCTM);
+extern void (*fz_img_w3i1o4)(FZ_BYTE*,FZ_PSRC,FZ_PDST,FZ_PCTM);
+
+extern void (*fz_decodetile)(fz_pixmap *pix, int skip, float *decode);
+extern void (*fz_loadtile1)(FZ_BYTE*, int sw, FZ_BYTE*, int dw, int w, int h, int pad);
+extern void (*fz_loadtile2)(FZ_BYTE*, int sw, FZ_BYTE*, int dw, int w, int h, int pad);
+extern void (*fz_loadtile4)(FZ_BYTE*, int sw, FZ_BYTE*, int dw, int w, int h, int pad);
+extern void (*fz_loadtile8)(FZ_BYTE*, int sw, FZ_BYTE*, int dw, int w, int h, int pad);
+
+extern void (*fz_srown)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom, int n);
+extern void (*fz_srow1)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom);
+extern void (*fz_srow2)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom);
+extern void (*fz_srow4)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom);
+extern void (*fz_srow5)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom);
+
+extern void (*fz_scoln)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom, int n);
+extern void (*fz_scol1)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom);
+extern void (*fz_scol2)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom);
+extern void (*fz_scol4)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom);
+extern void (*fz_scol5)(FZ_BYTE *src, FZ_BYTE *dst, int w, int denom);
#undef FZ_BYTE
@@ -49,8 +66,6 @@ struct fz_renderer_s
fz_gel *gel;
fz_ael *ael;
- fz_rastfuncs rast;
-
fz_irect clip;
fz_pixmap *dest;
fz_pixmap *over;
@@ -58,11 +73,9 @@ struct fz_renderer_s
int flag;
};
-extern void fz_loadrastfuncs(fz_rastfuncs *);
-extern void fz_accelrastfuncs(fz_rastfuncs *);
+extern void fz_accelerate();
fz_error *fz_newrenderer(fz_renderer **gcp, fz_colorspace *pcm, int maskonly, int gcmem);
void fz_droprenderer(fz_renderer *gc);
-
fz_error *fz_rendertree(fz_pixmap **out, fz_renderer *gc, fz_tree *tree, fz_matrix ctm, fz_irect bbox, int white);
diff --git a/mupdf/colorspace1.c b/mupdf/colorspace1.c
index b1608740..08569cc4 100644
--- a/mupdf/colorspace1.c
+++ b/mupdf/colorspace1.c
@@ -515,6 +515,7 @@ loadseparation(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
* Indexed
*/
+#if 0
static void
indexedtoxyz(fz_colorspace *fzcs, float *ind, float *xyz)
{
@@ -523,11 +524,11 @@ indexedtoxyz(fz_colorspace *fzcs, float *ind, float *xyz)
int i, k;
i = ind[0] * 255;
i = CLAMP(i, 0, cs->high);
-printf("indexedtoxyz: %d\n", i);
for (k = 0; k < cs->base->n; k++)
alt[k] = cs->lookup[i * cs->base->n + k] / 255.0;
cs->base->toxyz(cs->base, alt, xyz);
}
+#endif
static void
dropindexed(fz_colorspace *fzcs)
@@ -563,7 +564,7 @@ loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
return fz_outofmem;
}
- initcs((fz_colorspace*)cs, "Indexed", 1, indexedtoxyz, nil, dropindexed);
+ initcs((fz_colorspace*)cs, "Indexed", 1, nil, nil, dropindexed);
cs->base = base;
cs->high = fz_toint(highobj);
diff --git a/mupdf/image1.c b/mupdf/image.c
index ee1ff5b3..2b4242e5 100644
--- a/mupdf/image1.c
+++ b/mupdf/image.c
@@ -217,7 +217,6 @@ pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
obj = fz_dictgets(dict, "SMask");
if (fz_isindirect(obj))
{
- puts(" smask");
error = pdf_loadindirect(&sub, xref, obj);
if (error)
return error;
@@ -248,7 +247,6 @@ pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
}
else
{
- puts(" mask");
error = pdf_loadimage(&mask, xref, sub, obj);
if (error)
return error;
@@ -338,3 +336,77 @@ pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
return nil;
}
+fz_error *
+pdf_loadtile(fz_image *img, fz_pixmap *tile)
+{
+ pdf_image *src = (pdf_image*)img;
+ void (*tilefunc)(unsigned char*,int,unsigned char*, int, int, int, int);
+ fz_error *error;
+
+ assert(tile->n == img->n + 1);
+ assert(tile->x >= 0);
+ assert(tile->y >= 0);
+ assert(tile->x + tile->w <= img->w);
+ assert(tile->y + tile->h <= img->h);
+
+ switch (src->bpc)
+ {
+ case 1: tilefunc = fz_loadtile1; break;
+ case 2: tilefunc = fz_loadtile2; break;
+ case 4: tilefunc = fz_loadtile4; break;
+ case 8: tilefunc = fz_loadtile8; break;
+ default:
+ return fz_throw("rangecheck: unsupported bit depth: %d", src->bpc);
+ }
+
+ if (src->indexed)
+ {
+ fz_pixmap *tmp;
+ int x, y, k, i;
+ int bpcfact = 1;
+
+ error = fz_newpixmap(&tmp, tile->x, tile->y, tile->w, tile->h, 1);
+ if (error)
+ return error;
+
+ switch (src->bpc)
+ {
+ case 1: bpcfact = 255; break;
+ case 2: bpcfact = 85; break;
+ case 4: bpcfact = 17; break;
+ case 8: bpcfact = 1; break;
+ }
+
+ tilefunc(src->samples->rp, src->stride,
+ tmp->samples, tmp->w,
+ tmp->w, tmp->h, 0);
+
+ for (y = 0; y < tile->h; y++)
+ {
+ for (x = 0; x < tile->w; x++)
+ {
+ tile->samples[(y * tile->w + x) * tile->n] = 255;
+ i = tmp->samples[y * tile->w + x] / bpcfact;
+ i = CLAMP(i, 0, src->indexed->high);
+ for (k = 0; k < src->indexed->base->n; k++)
+ {
+ tile->samples[(y * tile->w + x) * tile->n + k + 1] =
+ src->indexed->lookup[i * src->indexed->base->n + k];
+ }
+ }
+ }
+
+ fz_droppixmap(tmp);
+ }
+
+ else
+ {
+ tilefunc(src->samples->rp, src->stride,
+ tile->samples, tile->w * tile->n,
+ img->w * (img->n + img->a), img->h, img->a ? 0 : img->n);
+ fz_decodetile(tile, !img->a, src->decode);
+ }
+
+ return nil;
+}
+
diff --git a/mupdf/image2.c b/mupdf/image2.c
deleted file mode 100644
index ad07e6bc..00000000
--- a/mupdf/image2.c
+++ /dev/null
@@ -1,255 +0,0 @@
-#include <fitz.h>
-#include <mupdf.h>
-
-static inline int getbit(const unsigned char *buf, int x)
-{
- return ( buf[x >> 3] >> ( 7 - (x & 7) ) ) & 1;
-}
-
-static inline int gettwo(const unsigned char *buf, int x)
-{
- return ( buf[x >> 2] >> ( ( 3 - (x & 3) ) << 1 ) ) & 3;
-}
-
-static inline int getnib(const unsigned char *buf, int x)
-{
- return ( buf[x >> 1] >> ( ( 1 - (x & 1) ) << 2 ) ) & 0xf;
-}
-
-static void loadtile1(pdf_image *src, fz_pixmap *dst, int n)
-{
- int x, y, k;
- for (y = dst->y; y < dst->y + dst->h; y++)
- {
- unsigned char *s = src->samples->bp + y * src->stride;
- unsigned char *d = dst->samples + y * dst->w * dst->n;
- for (x = dst->x; x < dst->x + dst->w; x++)
- {
- for (k = 0; k < n; k++)
- d[x * n + k] = getbit(s, x * n + k);
- }
- }
-}
-
-static void loadtile1a(pdf_image *src, fz_pixmap *dst, int n)
-{
- int x, y, k;
- for (y = dst->y; y < dst->y + dst->h; y++)
- {
- unsigned char *s = src->samples->bp + y * src->stride;
- unsigned char *d = dst->samples + y * dst->w * dst->n;
- for (x = dst->x; x < dst->x + dst->w; x++)
- {
- d[x * (n+1) + 0] = 1;
- for (k = 0; k < n; k++)
- d[x * (n+1) + k + 1] = getbit(s, x * n + k);
- }
- }
-}
-
-static void loadtile2(pdf_image *src, fz_pixmap *dst, int n)
-{
- int x, y, k;
- for (y = dst->y; y < dst->y + dst->h; y++)
- {
- unsigned char *s = src->samples->bp + y * src->stride;
- unsigned char *d = dst->samples + y * dst->w * dst->n;
- for (x = dst->x; x < dst->x + dst->w; x++)
- {
- for (k = 0; k < n; k++)
- d[x * n + k] = gettwo(s, x * n + k);
- }
- }
-}
-
-static void loadtile2a(pdf_image *src, fz_pixmap *dst, int n)
-{
- int x, y, k;
- for (y = dst->y; y < dst->y + dst->h; y++)
- {
- unsigned char *s = src->samples->bp + y * src->stride;
- unsigned char *d = dst->samples + y * dst->w * dst->n;
- for (x = dst->x; x < dst->x + dst->w; x++)
- {
- d[x * (n+1) + 0] = 1;
- for (k = 0; k < n; k++)
- d[x * (n+1) + k + 1] = gettwo(s, x * n + k);
- }
- }
-}
-
-static void loadtile4(pdf_image *src, fz_pixmap *dst, int n)
-{
- int x, y, k;
- for (y = dst->y; y < dst->y + dst->h; y++)
- {
- unsigned char *s = src->samples->bp + y * src->stride;
- unsigned char *d = dst->samples + y * dst->w * dst->n;
- for (x = dst->x; x < dst->x + dst->w; x++)
- {
- for (k = 0; k < n; k++)
- d[x * n + k] = getnib(s, x * n + k);
- }
- }
-}
-
-static void loadtile4a(pdf_image *src, fz_pixmap *dst, int n)
-{
- int x, y, k;
- for (y = dst->y; y < dst->y + dst->h; y++)
- {
- unsigned char *s = src->samples->bp + y * src->stride;
- unsigned char *d = dst->samples + y * dst->w * dst->n;
- for (x = dst->x; x < dst->x + dst->w; x++)
- {
- d[x * (n+1) + 0] = 1;
- for (k = 0; k < n; k++)
- d[x * (n+1) + k + 1] = getnib(s, x * n + k);
- }
- }
-}
-
-static void loadtile8(pdf_image *src, fz_pixmap *dst, int n)
-{
- int x, y, k;
- for (y = dst->y; y < dst->y + dst->h; y++)
- {
- unsigned char *s = src->samples->bp + y * src->stride;
- unsigned char *d = dst->samples + y * dst->w * dst->n;
- for (x = dst->x; x < dst->x + dst->w; x++)
- for (k = 0; k < n; k++)
- *d++ = *s++;
- }
-}
-
-static void loadtile8a(pdf_image *src, fz_pixmap *dst, int n)
-{
- int x, y, k;
- for (y = dst->y; y < dst->y + dst->h; y++)
- {
- unsigned char *s = src->samples->bp + y * src->stride;
- unsigned char *d = dst->samples + y * dst->w * dst->n;
- for (x = dst->x; x < dst->x + dst->w; x++)
- {
- *d++ = 255;
- for (k = 0; k < n; k++)
- *d++ = *s++;
- }
- }
-}
-
-static void
-decodetile(fz_pixmap *pix, int bpc, int skip, float *decode)
-{
- unsigned char table[FZ_MAXCOLORS][256];
- float invtwon = 1.0 / ((1 << bpc) - 1);
- int x, y, k, i;
-
- for (i = 0; i < (1 << bpc); i++)
- {
- if (skip)
- table[0][i] = (i * 255) * invtwon;
- for (k = skip; k < pix->n; k++)
- {
- float min = decode[(k - skip) * 2 + 0];
- float max = decode[(k - skip) * 2 + 1];
- float f = min + i * (max - min) * invtwon;
- table[k][i] = f * 255;
- }
- }
-
- for (y = 0; y < pix->h; y++)
- {
- for (x = 0; x < pix->w; x++)
- {
- for (k = 0; k < pix->n; k++)
- {
- i = pix->samples[ (y * pix->w + x) * pix->n + k];
- pix->samples[ (y * pix->w + x) * pix->n + k] = table[k][i];
- }
- }
- }
-}
-
-fz_error *
-pdf_loadtile(fz_image *img, fz_pixmap *tile)
-{
- pdf_image *src = (pdf_image*)img;
- fz_error *error;
-
- assert(tile->n == img->n + 1);
- assert(tile->x >= 0);
- assert(tile->y >= 0);
- assert(tile->x + tile->w <= img->w);
- assert(tile->y + tile->h <= img->h);
-
- if (src->indexed)
- {
- fz_pixmap *tmp;
- int x, y, k, i;
-
- error = fz_newpixmap(&tmp, tile->x, tile->y, tile->w, tile->h, 1);
- if (error)
- return error;
-
- switch (src->bpc)
- {
- case 1: loadtile1(src, tmp, 1); break;
- case 2: loadtile2(src, tmp, 1); break;
- case 4: loadtile4(src, tmp, 1); break;
- case 8: loadtile8(src, tmp, 1); break;
- default:
- return fz_throw("rangecheck: unsupported bit depth: %d", src->bpc);
- }
-
- for (y = 0; y < tile->h; y++)
- {
- for (x = 0; x < tile->w; x++)
- {
- tile->samples[(y * tile->w + x) * tile->n] = 255;
- i = tmp->samples[y * tile->w + x];
- i = CLAMP(i, 0, src->indexed->high);
- for (k = 0; k < src->indexed->base->n; k++)
- {
- tile->samples[(y * tile->w + x) * tile->n + k + 1] =
- src->indexed->lookup[i * src->indexed->base->n + k];
- }
- }
- }
-
- fz_droppixmap(tmp);
- }
-
- else
- {
- if (img->a)
- {
- switch (src->bpc)
- {
- case 1: loadtile1(src, tile, img->n + img->a); break;
- case 2: loadtile2(src, tile, img->n + img->a); break;
- case 4: loadtile4(src, tile, img->n + img->a); break;
- case 8: loadtile8(src, tile, img->n + img->a); break;
- default:
- return fz_throw("rangecheck: unsupported bit depth: %d", src->bpc);
- }
- }
- else
- {
- switch (src->bpc)
- {
- case 1: loadtile1a(src, tile, img->n); break;
- case 2: loadtile2a(src, tile, img->n); break;
- case 4: loadtile4a(src, tile, img->n); break;
- case 8: loadtile8a(src, tile, img->n); break;
- default:
- return fz_throw("rangecheck: unsupported bit depth: %d", src->bpc);
- }
- }
-
- decodetile(tile, src->bpc, !img->a, src->decode);
- }
-
- return nil;
-}
-
diff --git a/mupdf/resources.c b/mupdf/resources.c
index 3d962a43..10d7de43 100644
--- a/mupdf/resources.c
+++ b/mupdf/resources.c
@@ -4,6 +4,8 @@
void *
pdf_findresource(pdf_rsrc *rsrc, fz_obj *key)
{
+ if (key == nil)
+ return nil;
while (rsrc)
{
if (!fz_cmpobj(rsrc->key, key))
diff --git a/render/archppc.c b/render/archppc.c
new file mode 100644
index 00000000..2d0fee1d
--- /dev/null
+++ b/render/archppc.c
@@ -0,0 +1,65 @@
+/*
+ * PowerPC specific render optims live here
+ */
+
+#include <fitz.h>
+
+typedef unsigned char byte;
+
+#ifdef HAVE_ALTIVEC
+
+static void srow1ppc(byte *src, byte *dst, int w, int denom)
+{
+ int x, left;
+ int sum;
+
+ left = 0;
+ sum = 0;
+
+ for (x = 0; x < w; x++)
+ {
+ sum += *src++;
+ if (++left == denom)
+ {
+ left = 0;
+ *dst++ = sum / denom;
+ sum = 0;
+ }
+ }
+
+ if (left)
+ *dst++ = sum / left;
+}
+
+static void scol1ppc(byte *src, byte *dst, int w, int denom)
+{
+ int x, y;
+ unsigned char *s;
+ int sum;
+
+ for (x = 0; x < w; x++)
+ {
+ s = src + x;
+ sum = 0;
+ for (y = 0; y < denom; y++)
+ sum += s[y * w];
+ *dst++ = sum / denom;
+ }
+}
+
+#endif /* HAVE_ALTIVEC */
+
+#if defined (ARCH_PPC)
+void
+fz_accelerate(void)
+{
+# ifdef HAVE_ALTIVEC
+ if (fz_cpuflags & HAVE_ALTIVEC)
+ {
+ fz_srow1 = srow1ppc;
+ fz_scol1 = scol1ppc;
+ }
+# endif
+}
+#endif
+
diff --git a/render/rastsparc.c b/render/archsparc.c
index c18db9a5..32e142c3 100644
--- a/render/rastsparc.c
+++ b/render/archsparc.c
@@ -9,7 +9,7 @@ SPARC specific render optims live here
#if defined (ARCH_SPARC)
void
-fz_accelrastfuncs(fz_rastfuncs *tab)
+fz_accelerate(void)
{
# ifdef HAVE_VIS
if (fz_cpuflags & HAVE_VIS)
diff --git a/render/rastx86.c b/render/archx86.c
index 9360b5e2..9754214f 100644
--- a/render/rastx86.c
+++ b/render/archx86.c
@@ -40,7 +40,7 @@ static void duff_4i1o4mmx(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int d
int ts = *s++;
int ma = *mp++ + 1;
int sa = ((ts & 0xff) * ma) >> 8;
- int ssa = 254 - sa;
+ int ssa = 256 - sa;
__m64 d0 = _mm_cvtsi32_si64(*d);
__m64 s0 = _mm_cvtsi32_si64(ts);
@@ -212,14 +212,15 @@ static void img_4o4mmx(FZ_PSRC, FZ_PDST, FZ_PCTM)
#if defined (ARCH_X86) || defined(ARCH_X86_64)
void
-fz_accelrastfuncs(fz_rastfuncs *tab)
+fz_accelerate(void)
{
# ifdef HAVE_MMX
if (fz_cpuflags & HAVE_MMX)
{
- tab->duff_4i1o4 = duff_4i1o4mmx;
- tab->img_4o4 = img_4o4mmx;
+ fz_duff_4i1o4 = duff_4i1o4mmx;
+ fz_img_4o4 = img_4o4mmx;
}
# endif
}
#endif
+
diff --git a/render/optduff.c b/render/optduff.c
new file mode 100644
index 00000000..75d305ba
--- /dev/null
+++ b/render/optduff.c
@@ -0,0 +1,324 @@
+#include <fitz.h>
+
+typedef unsigned char byte;
+
+/*
+ * Blend pixmap regions
+ */
+
+/* dst = src over dst */
+static void
+duff_non(byte *sp0, int sw, int sn, byte *dp0, int dw, int w0, int h)
+{
+ int k;
+ while (h--)
+ {
+ byte *sp = sp0;
+ byte *dp = dp0;
+ int w = w0;
+ while (w--)
+ {
+ byte sa = sp[0];
+ byte ssa = 255 - sa;
+ for (k = 0; k < sn; k++)
+ {
+ dp[k] = sp[k] + fz_mul255(dp[k], ssa);
+ }
+ sp += sn;
+ dp += sn;
+ }
+ sp0 += sw;
+ dp0 += dw;
+ }
+}
+
+/* dst = src in msk */
+static void
+duff_nimcn(byte *sp0, int sw, int sn, byte *mp0, int mw, int mn, byte *dp0, int dw, int w0, int h)
+{
+ int k;
+ while (h--)
+ {
+ byte *sp = sp0;
+ byte *mp = mp0;
+ byte *dp = dp0;
+ int w = w0;
+ while (w--)
+ {
+ byte ma = mp[0];
+ for (k = 0; k < sn; k++)
+ dp[k] = fz_mul255(sp[k], ma);
+ sp += sn;
+ mp += mn;
+ dp += sn;
+ }
+ sp0 += sw;
+ mp0 += mw;
+ dp0 += dw;
+ }
+}
+
+/* dst = src in msk over dst */
+static void
+duff_nimon(byte *sp0, int sw, int sn, byte *mp0, int mw, int mn, byte *dp0, int dw, int w0, int h)
+{
+ int k;
+ while (h--)
+ {
+ byte *sp = sp0;
+ byte *mp = mp0;
+ byte *dp = dp0;
+ int w = w0;
+ while (w--)
+ {
+ /* TODO: validate this */
+ byte ma = mp[0];
+ byte sa = fz_mul255(sp[0], ma);
+ byte ssa = 255 - sa;
+ for (k = 0; k < sn; k++)
+ {
+ dp[k] = fz_mul255(sp[k], ma) + fz_mul255(dp[k], ssa);
+ }
+ sp += sn;
+ mp += mn;
+ dp += sn;
+ }
+ sp0 += sw;
+ mp0 += mw;
+ dp0 += dw;
+ }
+}
+
+static void duff_1o1(byte *sp0, int sw, byte *dp0, int dw, int w0, int h)
+{
+ /* duff_non(sp0, sw, 1, dp0, dw, w0, h); */
+ while (h--)
+ {
+ byte *sp = sp0;
+ byte *dp = dp0;
+ int w = w0;
+ while (w--)
+ {
+ dp[0] = sp[0] + fz_mul255(dp[0], 255 - sp[0]);
+ sp ++;
+ dp ++;
+ }
+ sp0 += sw;
+ dp0 += dw;
+ }
+}
+
+static void duff_4o4(byte *sp0, int sw, byte *dp0, int dw, int w0, int h)
+{
+ /* duff_non(sp0, sw, 4, dp0, dw, w0, h); */
+ while (h--)
+ {
+ byte *sp = sp0;
+ byte *dp = dp0;
+ int w = w0;
+ while (w--)
+ {
+ byte ssa = 255 - sp[0];
+ dp[0] = sp[0] + fz_mul255(dp[0], ssa);
+ dp[1] = sp[1] + fz_mul255(dp[1], ssa);
+ dp[2] = sp[2] + fz_mul255(dp[2], ssa);
+ dp[3] = sp[3] + fz_mul255(dp[3], ssa);
+ sp += 4;
+ dp += 4;
+ }
+ sp0 += sw;
+ dp0 += dw;
+ }
+}
+
+static void duff_1i1c1(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw, int w0, int h)
+{
+ /* duff_nimcn(sp0, sw, 1, mp0, mw, 1, dp0, dw, w0, h); */
+ while (h--)
+ {
+ byte *sp = sp0;
+ byte *mp = mp0;
+ byte *dp = dp0;
+ int w = w0;
+ while (w--)
+ {
+ dp[0] = fz_mul255(sp[0], mp[0]);
+ sp ++;
+ mp ++;
+ dp ++;
+ }
+ sp0 += sw;
+ mp0 += mw;
+ dp0 += dw;
+ }
+}
+
+static void duff_4i1c4(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw, int w0, int h)
+{
+ /* duff_nimcn(sp0, sw, 4, mp0, mw, 1, dp0, dw, w0, h); */
+ while (h--)
+ {
+ byte *sp = sp0;
+ byte *mp = mp0;
+ byte *dp = dp0;
+ int w = w0;
+ while (w--)
+ {
+ byte ma = mp[0];
+ dp[0] = fz_mul255(sp[0], ma);
+ dp[1] = fz_mul255(sp[1], ma);
+ dp[2] = fz_mul255(sp[2], ma);
+ dp[3] = fz_mul255(sp[3], ma);
+ sp += 4;
+ mp += 1;
+ dp += 4;
+ }
+ sp0 += sw;
+ mp0 += mw;
+ dp0 += dw;
+ }
+}
+
+static void duff_1i1o1(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw, int w0, int h)
+{
+ /* duff_nimon(sp0, sw, 1, mp0, mw, 1, dp0, dw, w0, h); */
+ while (h--)
+ {
+ byte *sp = sp0;
+ byte *mp = mp0;
+ byte *dp = dp0;
+ int w = w0;
+ while (w--)
+ {
+ byte ma = mp[0];
+ byte sa = fz_mul255(sp[0], ma);
+ byte ssa = 255 - sa;
+ dp[0] = fz_mul255(sp[0], ma) + fz_mul255(dp[0], ssa);
+ sp ++;
+ mp ++;
+ dp ++;
+ }
+ sp0 += sw;
+ mp0 += mw;
+ dp0 += dw;
+ }
+}
+
+static void duff_4i1o4(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw, int w0, int h)
+{
+ /* duff_nimon(sp0, sw, 4, mp0, mw, 1, dp0, dw, w0, h); */
+ while (h--)
+ {
+ byte *sp = sp0;
+ byte *mp = mp0;
+ byte *dp = dp0;
+ int w = w0;
+ while (w--)
+ {
+ byte ma = mp[0];
+ byte sa = fz_mul255(sp[0], ma);
+ byte ssa = 255 - sa;
+ dp[0] = fz_mul255(sp[0], ma) + fz_mul255(dp[0], ssa);
+ dp[1] = fz_mul255(sp[1], ma) + fz_mul255(dp[1], ssa);
+ dp[2] = fz_mul255(sp[2], ma) + fz_mul255(dp[2], ssa);
+ dp[3] = fz_mul255(sp[3], ma) + fz_mul255(dp[3], ssa);
+ sp += 4;
+ mp += 1;
+ dp += 4;
+ }
+ sp0 += sw;
+ mp0 += mw;
+ dp0 += dw;
+ }
+}
+
+/*
+ * Path and text masks
+ */
+
+static void path_1c1(byte *src, byte *dst, int w)
+{
+ memcpy(dst, src, w);
+}
+
+static void path_1o1(byte *src, byte *dst, int w)
+{
+ while (w--)
+ {
+ dst[0] = src[0] + fz_mul255(dst[0], 255 - src[0]);
+ src++;
+ dst++;
+ }
+}
+
+static void path_w3i1o4(byte *rgb, byte *src, byte *dst, int n)
+{
+ byte rgb0 = rgb[0];
+ byte rgb1 = rgb[1];
+ byte rgb2 = rgb[2];
+ byte sa, ssa;
+ while (n--)
+ {
+ sa = src[0];
+ ssa = 255 - sa;
+ dst[0] = sa + fz_mul255(dst[0], ssa);
+ dst[1] = rgb0 + fz_mul255((short)dst[1] - rgb0, ssa);
+ dst[2] = rgb1 + fz_mul255((short)dst[2] - rgb1, ssa);
+ dst[3] = rgb2 + fz_mul255((short)dst[3] - rgb2, ssa);
+ src ++;
+ dst += 4;
+ }
+}
+
+static void text_1c1(byte *src, int srcw, byte *dst, int dstw, int w0, int h)
+{
+ while (h--)
+ {
+ path_1c1(src, dst, w0);
+ src += srcw;
+ dst += dstw;
+ }
+}
+
+static void text_1o1(byte *src, int srcw, byte *dst, int dstw, int w0, int h)
+{
+ while (h--)
+ {
+ path_1o1(src, dst, w0);
+ src += srcw;
+ dst += dstw;
+ }
+}
+
+static void text_w3i1o4(byte *rgb, byte *src, int srcw, byte *dst, int dstw, int w0, int h)
+{
+ while (h--)
+ {
+ path_w3i1o4(rgb, src, dst, w0);
+ src += srcw;
+ dst += dstw;
+ }
+}
+
+/*
+ * ... and the function pointers
+ */
+
+void (*fz_duff_non)(byte*,int,int,byte*,int,int,int) = duff_non;
+void (*fz_duff_nimcn)(byte*,int,int,byte*,int,int,byte*,int,int,int) = duff_nimcn;
+void (*fz_duff_nimon)(byte*,int,int,byte*,int,int,byte*,int,int,int) = duff_nimon;
+void (*fz_duff_1o1)(byte*,int,byte*,int,int,int) = duff_1o1;
+void (*fz_duff_4o4)(byte*,int,byte*,int,int,int) = duff_4o4;
+void (*fz_duff_1i1c1)(byte*,int,byte*,int,byte*,int,int,int) = duff_1i1c1;
+void (*fz_duff_4i1c4)(byte*,int,byte*,int,byte*,int,int,int) = duff_4i1c4;
+void (*fz_duff_1i1o1)(byte*,int,byte*,int,byte*,int,int,int) = duff_1i1o1;
+void (*fz_duff_4i1o4)(byte*,int,byte*,int,byte*,int,int,int) = duff_4i1o4;
+
+void (*fz_path_1c1)(byte*,byte*,int) = path_1c1;
+void (*fz_path_1o1)(byte*,byte*,int) = path_1o1;
+void (*fz_path_w3i1o4)(byte*,byte*,byte*,int) = path_w3i1o4;
+
+void (*fz_text_1c1)(byte*,int,byte*,int,int,int) = text_1c1;
+void (*fz_text_1o1)(byte*,int,byte*,int,int,int) = text_1o1;
+void (*fz_text_w3i1o4)(byte*,byte*,int,byte*,int,int,int) = text_w3i1o4;
+
diff --git a/render/optimage.c b/render/optimage.c
new file mode 100644
index 00000000..0654b006
--- /dev/null
+++ b/render/optimage.c
@@ -0,0 +1,238 @@
+#include <fitz.h>
+
+typedef unsigned char byte;
+
+#define lerp(a,b,t) (a + (((b - a) * t) >> 16))
+
+static inline byte getcomp(byte *s, int w, int h, int u, int v, int n, int k)
+{
+ if (u < 0 || u >= w) return 0;
+ if (v < 0 || v >= h) return 0;
+ return s[(w * v + u) * n + k];
+}
+
+static inline int samplecomp(byte *s, int w, int h, int u, int v, int n, int k)
+{
+ int ui = u >> 16;
+ int vi = v >> 16;
+ int ud = u & 0xFFFF;
+ int vd = v & 0xFFFF;
+ int a = getcomp(s, w, h, ui, vi, n, k);
+ int b = getcomp(s, w, h, ui+1, vi, n, k);
+ int c = getcomp(s, w, h, ui, vi+1, n, k);
+ int d = getcomp(s, w, h, ui+1, vi+1, n, k);
+ int ab = lerp(a, b, ud);
+ int cd = lerp(c, d, ud);
+ return lerp(ab, cd, vd);
+}
+
+static inline byte getmask(byte *s, int w, int h, int u, int v)
+{
+ if (u < 0 || u >= w) return 0;
+ if (v < 0 || v >= h) return 0;
+ return s[w * v + u];
+}
+
+static inline int samplemask(byte *s, int w, int h, int u, int v)
+{
+ int ui = u >> 16;
+ int vi = v >> 16;
+ int ud = u & 0xFFFF;
+ int vd = v & 0xFFFF;
+ int a = getmask(s, w, h, ui, vi);
+ int b = getmask(s, w, h, ui+1, vi);
+ int c = getmask(s, w, h, ui, vi+1);
+ int d = getmask(s, w, h, ui+1, vi+1);
+ int ab = lerp(a, b, ud);
+ int cd = lerp(c, d, ud);
+ return lerp(ab, cd, vd);
+}
+
+static inline void lerpargb(byte *dst, byte *a, byte *b, int t)
+{
+ dst[0] = lerp(a[0], b[0], t);
+ dst[1] = lerp(a[1], b[1], t);
+ dst[2] = lerp(a[2], b[2], t);
+ dst[3] = lerp(a[3], b[3], t);
+}
+
+static inline byte *getargb(byte *s, int w, int h, int u, int v)
+{
+ static byte zero[4] = { 0, 0, 0, 0 };
+ if (u < 0 || u >= w) return zero;
+ if (v < 0 || v >= h) return zero;
+ return s + ((w * v + u) << 2);
+}
+
+static inline void sampleargb(byte *s, int w, int h, int u, int v, byte *abcd)
+{
+ byte ab[4];
+ byte cd[4];
+ int ui = u >> 16;
+ int vi = v >> 16;
+ int ud = u & 0xFFFF;
+ int vd = v & 0xFFFF;
+ byte *a = getargb(s, w, h, ui, vi);
+ byte *b = getargb(s, w, h, ui+1, vi);
+ byte *c = getargb(s, w, h, ui, vi+1);
+ byte *d = getargb(s, w, h, ui+1, vi+1);
+ lerpargb(ab, a, b, ud);
+ lerpargb(cd, c, d, ud);
+ lerpargb(abcd, ab, cd, vd);
+}
+
+static void img_ncn(FZ_PSRC, int srcn, FZ_PDST, FZ_PCTM)
+{
+ int k;
+ while (h--)
+ {
+ byte *dstp = dst0;
+ int u = u0;
+ int v = v0;
+ int w = w0;
+ while (w--)
+ {
+ for (k = 0; k < srcn; k++)
+ {
+ dstp[k] = samplecomp(src, srcw, srch, u, v, srcn, k);
+ dstp += srcn;
+ u += fa;
+ v += fb;
+ }
+ }
+ dst0 += dstw;
+ u0 += fc;
+ v0 += fd;
+ }
+}
+
+static void img_1c1(FZ_PSRC, FZ_PDST, FZ_PCTM)
+{
+ while (h--)
+ {
+ byte *dstp = dst0;
+ int u = u0;
+ int v = v0;
+ int w = w0;
+ while (w--)
+ {
+ dstp[0] = samplemask(src, srcw, srch, u, v);
+ dstp ++;
+ u += fa;
+ v += fb;
+ }
+ dst0 += dstw;
+ u0 += fc;
+ v0 += fd;
+ }
+}
+
+static void img_4c4(FZ_PSRC, FZ_PDST, FZ_PCTM)
+{
+ while (h--)
+ {
+ byte *dstp = dst0;
+ int u = u0;
+ int v = v0;
+ int w = w0;
+ while (w--)
+ {
+ sampleargb(src, srcw, srch, u, v, dstp);
+ dstp += 4;
+ u += fa;
+ v += fb;
+ }
+ dst0 += dstw;
+ u0 += fc;
+ v0 += fd;
+ }
+}
+
+static void img_1o1(FZ_PSRC, FZ_PDST, FZ_PCTM)
+{
+ byte srca;
+ while (h--)
+ {
+ byte *dstp = dst0;
+ int u = u0;
+ int v = v0;
+ int w = w0;
+ while (w--)
+ {
+ srca = samplemask(src, srcw, srch, u, v);
+ dstp[0] = srca + fz_mul255(dstp[0], 255 - srca);
+ dstp ++;
+ u += fa;
+ v += fb;
+ }
+ dst0 += dstw;
+ u0 += fc;
+ v0 += fd;
+ }
+}
+
+static void img_4o4(FZ_PSRC, FZ_PDST, FZ_PCTM)
+{
+ byte argb[4];
+ byte ssa;
+ while (h--)
+ {
+ byte *dstp = dst0;
+ int u = u0;
+ int v = v0;
+ int w = w0;
+ while (w--)
+ {
+ sampleargb(src, srcw, srch, u, v, argb);
+ ssa = 255 - argb[0];
+ dstp[0] = argb[0] + fz_mul255(dstp[0], ssa);
+ dstp[1] = argb[1] + fz_mul255(dstp[1], ssa);
+ dstp[2] = argb[2] + fz_mul255(dstp[2], ssa);
+ dstp[3] = argb[3] + fz_mul255(dstp[3], ssa);
+ dstp += 4;
+ u += fa;
+ v += fb;
+ }
+ dst0 += dstw;
+ u0 += fc;
+ v0 += fd;
+ }
+}
+
+static void img_w3i1o4(byte *rgb, FZ_PSRC, FZ_PDST, FZ_PCTM)
+{
+ byte rgb0 = rgb[0];
+ byte rgb1 = rgb[1];
+ byte rgb2 = rgb[2];
+ byte sa, ssa;
+ while (h--)
+ {
+ byte *dstp = dst0;
+ int u = u0;
+ int v = v0;
+ int w = w0;
+ while (w--)
+ {
+ sa = samplemask(src, srcw, srch, u, v);
+ ssa = 255 - sa;
+ dstp[0] = sa + fz_mul255(dstp[0], ssa);
+ dstp[1] = rgb0 + fz_mul255((short)dstp[1] - rgb0, ssa);
+ dstp[2] = rgb1 + fz_mul255((short)dstp[2] - rgb1, ssa);
+ dstp[3] = rgb2 + fz_mul255((short)dstp[3] - rgb2, ssa);
+ dstp += 4;
+ u += fa;
+ v += fb;
+ }
+ dst0 += dstw;
+ u0 += fc;
+ v0 += fd;
+ }
+}
+
+void (*fz_img_ncn)(FZ_PSRC, int sn, FZ_PDST, FZ_PCTM) = img_ncn;
+void (*fz_img_1c1)(FZ_PSRC, FZ_PDST, FZ_PCTM) = img_1c1;
+void (*fz_img_4c4)(FZ_PSRC, FZ_PDST, FZ_PCTM) = img_4c4;
+void (*fz_img_1o1)(FZ_PSRC, FZ_PDST, FZ_PCTM) = img_1o1;
+void (*fz_img_4o4)(FZ_PSRC, FZ_PDST, FZ_PCTM) = img_4o4;
+void (*fz_img_w3i1o4)(byte*,FZ_PSRC,FZ_PDST,FZ_PCTM) = img_w3i1o4;
+
diff --git a/render/optscale.c b/render/optscale.c
new file mode 100644
index 00000000..ede19f1c
--- /dev/null
+++ b/render/optscale.c
@@ -0,0 +1,191 @@
+#include <fitz.h>
+
+typedef unsigned char byte;
+
+static void srown(byte *src, byte *dst, int w, int denom, int n)
+{
+ int x, left, k;
+ int sum[FZ_MAXCOLORS];
+
+ left = 0;
+ for (k = 0; k < n; k++)
+ sum[k] = 0;
+
+ for (x = 0; x < w; x++)
+ {
+ for (k = 0; k < n; k++)
+ sum[k] += src[x * n + k];
+ if (++left == denom)
+ {
+ left = 0;
+ for (k = 0; k < n; k++)
+ {
+ dst[k] = sum[k] / denom;
+ sum[k] = 0;
+ }
+ dst += n;
+ }
+ }
+
+ /* left overs */
+ if (left)
+ for (k = 0; k < n; k++)
+ dst[k] = sum[k] / left;
+}
+
+static void srow1(byte *src, byte *dst, int w, int denom)
+{
+ srown(src, dst, w, denom, 1);
+}
+
+static void srow2(byte *src, byte *dst, int w, int denom)
+{
+ srown(src, dst, w, denom, 2);
+}
+
+static void srow4(byte *src, byte *dst, int w, int denom)
+{
+ srown(src, dst, w, denom, 4);
+}
+
+static void srow5(byte *src, byte *dst, int w, int denom)
+{
+ srown(src, dst, w, denom, 5);
+}
+
+static void scoln(byte *src, byte *dst, int w, int denom, int n)
+{
+ int x, y, k;
+ byte *s;
+ int sum[FZ_MAXCOLORS];
+
+ for (x = 0; x < w; x++)
+ {
+ s = src + (x * n);
+ for (k = 0; k < n; k++)
+ sum[k] = 0;
+ for (y = 0; y < denom; y++)
+ for (k = 0; k < n; k++)
+ sum[k] += s[y * w * n + k];
+ for (k = 0; k < n; k++)
+ dst[k] = sum[k] / denom;
+ dst += n;
+ }
+}
+
+static void scol1(byte *src, byte *dst, int w, int denom)
+{
+ scoln(src, dst, w, denom, 1);
+}
+
+static void scol2(byte *src, byte *dst, int w, int denom)
+{
+ scoln(src, dst, w, denom, 2);
+}
+
+static void scol4(byte *src, byte *dst, int w, int denom)
+{
+ scoln(src, dst, w, denom, 4);
+}
+
+static void scol5(byte *src, byte *dst, int w, int denom)
+{
+ scoln(src, dst, w, denom, 5);
+}
+
+void (*fz_srown)(byte *src, byte *dst, int w, int denom, int n) = srown;
+void (*fz_srow1)(byte *src, byte *dst, int w, int denom) = srow1;
+void (*fz_srow2)(byte *src, byte *dst, int w, int denom) = srow2;
+void (*fz_srow4)(byte *src, byte *dst, int w, int denom) = srow4;
+void (*fz_srow5)(byte *src, byte *dst, int w, int denom) = srow5;
+
+void (*fz_scoln)(byte *src, byte *dst, int w, int denom, int n) = scoln;
+void (*fz_scol1)(byte *src, byte *dst, int w, int denom) = scol1;
+void (*fz_scol2)(byte *src, byte *dst, int w, int denom) = scol2;
+void (*fz_scol4)(byte *src, byte *dst, int w, int denom) = scol4;
+void (*fz_scol5)(byte *src, byte *dst, int w, int denom) = scol5;
+
+fz_error *
+fz_scalepixmap(fz_pixmap **dstp, fz_pixmap *src, int xdenom, int ydenom)
+{
+ fz_error *error;
+ fz_pixmap *dst;
+ unsigned char *buf;
+ int y, iy, oy;
+ int ow, oh, n;
+
+ void (*srowx)(byte *src, byte *dst, int w, int denom) = nil;
+ void (*scolx)(byte *src, byte *dst, int w, int denom) = nil;
+
+ ow = (src->w + xdenom - 1) / xdenom;
+ oh = (src->h + ydenom - 1) / ydenom;
+ n = src->n;
+
+ buf = fz_malloc(ow * n * ydenom);
+ if (!buf)
+ return fz_outofmem;
+
+ error = fz_newpixmap(&dst, 0, 0, ow, oh, src->n);
+ if (error)
+ {
+ fz_free(buf);
+ return error;
+ }
+
+ switch (n)
+ {
+ case 1: srowx = fz_srow1; scolx = fz_scol1; break;
+ case 2: srowx = fz_srow2; scolx = fz_scol2; break;
+ case 4: srowx = fz_srow4; scolx = fz_scol4; break;
+ case 5: srowx = fz_srow5; scolx = fz_scol5; break;
+ }
+
+ if (srowx && scolx)
+ {
+ for (y = 0, oy = 0; y < (src->h / ydenom) * ydenom; y += ydenom, oy++)
+ {
+ for (iy = 0; iy < ydenom; iy++)
+ srowx(src->samples + (y + iy) * src->w * n,
+ buf + iy * ow * n,
+ src->w, xdenom);
+ scolx(buf, dst->samples + oy * dst->w * n, dst->w, ydenom);
+ }
+
+ ydenom = src->h - y;
+ if (ydenom)
+ {
+ for (iy = 0; iy < ydenom; iy++)
+ srowx(src->samples + (y + iy) * src->w * n,
+ buf + iy * ow * n,
+ src->w, xdenom);
+ scolx(buf, dst->samples + oy * dst->w * n, dst->w, ydenom);
+ }
+ }
+
+ else
+ {
+ for (y = 0, oy = 0; y < (src->h / ydenom) * ydenom; y += ydenom, oy++)
+ {
+ for (iy = 0; iy < ydenom; iy++)
+ fz_srown(src->samples + (y + iy) * src->w * n,
+ buf + iy * ow * n,
+ src->w, xdenom, n);
+ fz_scoln(buf, dst->samples + oy * dst->w * n, dst->w, ydenom, n);
+ }
+
+ ydenom = src->h - y;
+ if (ydenom)
+ {
+ for (iy = 0; iy < ydenom; iy++)
+ fz_srown(src->samples + (y + iy) * src->w * n,
+ buf + iy * ow * n,
+ src->w, xdenom, n);
+ fz_scoln(buf, dst->samples + oy * dst->w * n, dst->w, ydenom, n);
+ }
+ }
+
+ fz_free(buf);
+ *dstp = dst;
+ return nil;
+}
+
diff --git a/render/optunpack.c b/render/optunpack.c
new file mode 100644
index 00000000..1c77a787
--- /dev/null
+++ b/render/optunpack.c
@@ -0,0 +1,183 @@
+#include <fitz.h>
+
+typedef unsigned char byte;
+
+/*
+ * Apply decode parameters
+ */
+
+static void decodetile(fz_pixmap *pix, int skip, float *decode)
+{
+ int min[FZ_MAXCOLORS];
+ int max[FZ_MAXCOLORS];
+ int sub[FZ_MAXCOLORS];
+ int useless = 1;
+ byte *p = pix->samples;
+ int n = pix->n;
+ int wh = pix->w * pix->h;
+ int i;
+
+ min[0] = 0;
+ max[0] = 255;
+ sub[0] = 255;
+
+ for (i = skip; i < n; i++)
+ {
+ min[i] = decode[(i - skip) * 2] * 255;
+ max[i] = decode[(i - skip) * 2 + 1] * 255;
+ sub[i] = max[i] - min[i];
+ if (min[i] != 0 || max[i] != 255)
+ useless = 0;
+ }
+
+ if (useless)
+ return;
+
+ while (wh--)
+ {
+ for (i = 0; i < n; i++)
+ p[i] = min[i] + fz_mul255(sub[i], p[i]);
+ p += n;
+ }
+}
+
+/*
+ * Unpack image samples and optionally pad pixels with opaque alpha
+ */
+
+#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])
+
+static byte t1pad0[256][8];
+static byte t1pad1[256][16];
+
+static void init1()
+{
+ 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] = 255;
+ t1pad1[i][k * 2 + 1] = x;
+ }
+ }
+
+ inited = 1;
+}
+
+static void loadtile1(byte *src, int sw, byte *dst, int dw, int w, int h, int pad)
+{
+ 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;
+ }
+ }
+
+ else if (pad == 1)
+ {
+ 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;
+ }
+ }
+
+ else
+ {
+ while (h--)
+ {
+ dp = dst;
+ for (x = 0; x < w; x++)
+ {
+ if ((x % pad) == 0)
+ *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 \
+ while (h--) \
+ { \
+ byte *dp = dst; \
+ for (x = 0; x < w; x++) \
+ { \
+ if ((x % pad) == 0) \
+ *dp++ = 255; \
+ *dp++ = getf(src, x); \
+ } \
+ src += sw; \
+ dst += dw; \
+ } \
+}
+
+static void loadtile2(byte *src, int sw, byte *dst, int dw, int w, int h, int pad)
+ TILE(ttwo)
+static void loadtile4(byte *src, int sw, byte *dst, int dw, int w, int h, int pad)
+ TILE(tnib)
+static void loadtile8(byte *src, int sw, byte *dst, int dw, int w, int h, int pad)
+ TILE(toct)
+
+void (*fz_decodetile)(fz_pixmap *pix, int skip, float *decode) = decodetile;
+void (*fz_loadtile1)(byte*, int sw, byte*, int dw, int w, int h, int pad) = loadtile1;
+void (*fz_loadtile2)(byte*, int sw, byte*, int dw, int w, int h, int pad) = loadtile2;
+void (*fz_loadtile4)(byte*, int sw, byte*, int dw, int w, int h, int pad) = loadtile4;
+void (*fz_loadtile8)(byte*, int sw, byte*, int dw, int w, int h, int pad) = loadtile8;
+
diff --git a/render/fill.c b/render/pathfill.c
index d25f78b1..d25f78b1 100644
--- a/render/fill.c
+++ b/render/pathfill.c
diff --git a/render/edgelist.c b/render/pathscan.c
index 9eaaf7a7..7dd6397d 100644
--- a/render/edgelist.c
+++ b/render/pathscan.c
@@ -247,8 +247,8 @@ sortael(fz_edge **a, int n)
}
}
-fz_error *
-fz_insertael(fz_ael *ael, fz_gel *gel, int y, int *e)
+static fz_error *
+insertael(fz_ael *ael, fz_gel *gel, int y, int *e)
{
/* insert edges that start here */
while (*e < gel->len && gel->edges[*e].y == y) {
@@ -269,8 +269,8 @@ fz_insertael(fz_ael *ael, fz_gel *gel, int y, int *e)
return nil;
}
-void
-fz_advanceael(fz_ael *ael)
+static void
+advanceael(fz_ael *ael)
{
fz_edge *edge;
int i = 0;
@@ -298,3 +298,157 @@ fz_advanceael(fz_ael *ael)
}
}
+/*
+ * Scan convert
+ */
+
+static inline void
+addspan(unsigned char *list, int x0, int x1, int xofs, int hs)
+{
+ int x0pix, x0sub;
+ int x1pix, x1sub;
+
+ if (x0 == x1)
+ return;
+
+ /* x between 0 and width of bbox */
+ x0 -= xofs;
+ x1 -= xofs;
+
+ x0pix = x0 / hs;
+ x0sub = x0 % hs;
+ x1pix = x1 / hs;
+ x1sub = x1 % hs;
+
+ if (x0pix == x1pix)
+ {
+ list[x0pix] += x1sub - x0sub;
+ list[x0pix+1] += x0sub - x1sub;
+ }
+
+ else
+ {
+ list[x0pix] += hs - x0sub;
+ list[x0pix+1] += x0sub;
+ list[x1pix] += x1sub - hs;
+ list[x1pix+1] += -x1sub;
+ }
+}
+
+static inline void
+nonzerowinding(fz_ael *ael, unsigned char *list, int xofs, int hs)
+{
+ int winding = 0;
+ int x = 0;
+ int i;
+ for (i = 0; i < ael->len; i++)
+ {
+ if (!winding && (winding + ael->edges[i]->ydir))
+ x = ael->edges[i]->x;
+ if (winding && !(winding + ael->edges[i]->ydir))
+ addspan(list, x, ael->edges[i]->x, xofs, hs);
+ winding += ael->edges[i]->ydir;
+ }
+}
+
+static inline void
+evenodd(fz_ael *ael, unsigned char *list, int xofs, int hs)
+{
+ int even = 0;
+ int x = 0;
+ int i;
+ for (i = 0; i < ael->len; i++)
+ {
+ if (!even)
+ x = ael->edges[i]->x;
+ else
+ addspan(list, x, ael->edges[i]->x, xofs, hs);
+ even = !even;
+ }
+}
+
+static void toalpha(unsigned char *list, int n)
+{
+ int d = 0;
+ while (n--)
+ {
+ d += *list;
+ *list++ = d;
+ }
+}
+
+fz_error *
+fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, int y0, int y1,
+ void (*blitfunc)(int,int,int,unsigned char*,void*), void *blitdata)
+{
+ fz_error *error;
+ unsigned char *deltas;
+ int y, e;
+ int yd, yc;
+
+ int xmin = fz_idiv(gel->xmin, gel->hs);
+ int xmax = fz_idiv(gel->xmax, gel->hs) + 1;
+
+ int xofs = xmin * gel->hs;
+ int hs = gel->hs;
+ int vs = gel->vs;
+
+ if (gel->len == 0)
+ return nil;
+
+ deltas = fz_malloc(xmax - xmin + 1);
+ if (!deltas)
+ return fz_outofmem;
+
+ memset(deltas, 0, xmax - xmin + 1);
+
+ e = 0;
+ y = gel->edges[0].y;
+ yc = fz_idiv(y, vs);
+ yd = yc;
+
+ while (ael->len > 0 || e < gel->len)
+ {
+ yc = fz_idiv(y, vs);
+ if (yc != yd) {
+ if (yd >= y0 && yd < y1)
+ {
+ toalpha(deltas, xmax - xmin);
+ blitfunc(yd, xmin, xmax - xmin, deltas, blitdata);
+ memset(deltas, 0, xmax - xmin + 1);
+ }
+ }
+ yd = yc;
+
+ error = insertael(ael, gel, y, &e);
+ if (error) {
+ fz_free(deltas);
+ return error;
+ }
+
+ if (yd >= y0 && yd < y1)
+ {
+ if (eofill)
+ evenodd(ael, deltas, xofs, hs);
+ else
+ nonzerowinding(ael, deltas, xofs, hs);
+ }
+
+ advanceael(ael);
+
+ if (ael->len > 0)
+ y ++;
+ else if (e < gel->len)
+ y = gel->edges[e].y;
+ }
+
+ if (yd >= y0 && yd < y1)
+ {
+ toalpha(deltas, xmax - xmin);
+ blitfunc(yd, xmin, xmax - xmin, deltas, blitdata);
+ }
+
+ fz_free(deltas);
+ return nil;
+}
+
diff --git a/render/stroke.c b/render/pathstroke.c
index 2527e6ad..2527e6ad 100644
--- a/render/stroke.c
+++ b/render/pathstroke.c
diff --git a/render/rastport.c b/render/rastport.c
deleted file mode 100644
index 3eb89e43..00000000
--- a/render/rastport.c
+++ /dev/null
@@ -1,570 +0,0 @@
-#include <fitz.h>
-
-typedef unsigned char byte;
-
-/*
- * General Porter-Duff compositing -- blit image regions
- *
- * duff_NoN
- * duff_NiM
- * duff_NiMoN
- */
-
-/* dst = src over dst */
-static void
-duff_NoN(byte *sp0, int sw, int sn, byte *dp0, int dw, int w0, int h)
-{
- int k;
- while (h--)
- {
- byte *sp = sp0;
- byte *dp = dp0;
- int w = w0;
- while (w--)
- {
- byte sa = sp[0];
- byte ssa = 255 - sa;
- for (k = 0; k < sn; k++)
- {
- dp[k] = sp[k] + fz_mul255(dp[k], ssa);
- }
- sp += sn;
- dp += sn;
- }
- sp0 += sw;
- dp0 += dw;
- }
-}
-
-/* dst = src in msk */
-static void
-duff_NiMcN(byte *sp0, int sw, int sn, byte *mp0, int mw, int mn, byte *dp0, int dw, int w0, int h)
-{
- int k;
- while (h--)
- {
- byte *sp = sp0;
- byte *mp = mp0;
- byte *dp = dp0;
- int w = w0;
- while (w--)
- {
- byte ma = mp[0];
- for (k = 0; k < sn; k++)
- dp[k] = fz_mul255(sp[k], ma);
- sp += sn;
- mp += mn;
- dp += sn;
- }
- sp0 += sw;
- mp0 += mw;
- dp0 += dw;
- }
-}
-
-/* dst = src in msk over dst */
-static void
-duff_NiMoN(byte *sp0, int sw, int sn, byte *mp0, int mw, int mn, byte *dp0, int dw, int w0, int h)
-{
- int k;
- while (h--)
- {
- byte *sp = sp0;
- byte *mp = mp0;
- byte *dp = dp0;
- int w = w0;
- while (w--)
- {
- /* TODO: validate this */
- byte ma = mp[0];
- byte sa = fz_mul255(sp[0], ma);
- byte ssa = 255 - sa;
- for (k = 0; k < sn; k++)
- {
- dp[k] = fz_mul255(sp[k], ma) + fz_mul255(dp[k], ssa);
- }
- sp += sn;
- mp += mn;
- dp += sn;
- }
- sp0 += sw;
- mp0 += mw;
- dp0 += dw;
- }
-}
-
-static void duff_1o1(byte *sp0, int sw, byte *dp0, int dw, int w0, int h)
-{
- /* duff_NoN(sp0, sw, 1, dp0, dw, w0, h); */
- while (h--)
- {
- byte *sp = sp0;
- byte *dp = dp0;
- int w = w0;
- while (w--)
- {
- dp[0] = sp[0] + fz_mul255(dp[0], 255 - sp[0]);
- sp ++;
- dp ++;
- }
- sp0 += sw;
- dp0 += dw;
- }
-}
-
-static void duff_4o4(byte *sp0, int sw, byte *dp0, int dw, int w0, int h)
-{
- /* duff_NoN(sp0, sw, 4, dp0, dw, w0, h); */
- while (h--)
- {
- byte *sp = sp0;
- byte *dp = dp0;
- int w = w0;
- while (w--)
- {
- byte ssa = 255 - sp[0];
- dp[0] = sp[0] + fz_mul255(dp[0], ssa);
- dp[1] = sp[1] + fz_mul255(dp[1], ssa);
- dp[2] = sp[2] + fz_mul255(dp[2], ssa);
- dp[3] = sp[3] + fz_mul255(dp[3], ssa);
- sp += 4;
- dp += 4;
- }
- sp0 += sw;
- dp0 += dw;
- }
-}
-
-static void duff_1i1c1(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw, int w0, int h)
-{
- /* duff_NiMcN(sp0, sw, 1, mp0, mw, 1, dp0, dw, w0, h); */
- while (h--)
- {
- byte *sp = sp0;
- byte *mp = mp0;
- byte *dp = dp0;
- int w = w0;
- while (w--)
- {
- dp[0] = fz_mul255(sp[0], mp[0]);
- sp ++;
- mp ++;
- dp ++;
- }
- sp0 += sw;
- mp0 += mw;
- dp0 += dw;
- }
-}
-
-static void duff_4i1c4(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw, int w0, int h)
-{
- /* duff_NiMcN(sp0, sw, 4, mp0, mw, 1, dp0, dw, w0, h); */
- while (h--)
- {
- byte *sp = sp0;
- byte *mp = mp0;
- byte *dp = dp0;
- int w = w0;
- while (w--)
- {
- byte ma = mp[0];
- dp[0] = fz_mul255(sp[0], ma);
- dp[1] = fz_mul255(sp[1], ma);
- dp[2] = fz_mul255(sp[2], ma);
- dp[3] = fz_mul255(sp[3], ma);
- sp += 4;
- mp += 1;
- dp += 4;
- }
- sp0 += sw;
- mp0 += mw;
- dp0 += dw;
- }
-}
-
-static void duff_1i1o1(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw, int w0, int h)
-{
- /* duff_NiMoN(sp0, sw, 1, mp0, mw, 1, dp0, dw, w0, h); */
- while (h--)
- {
- byte *sp = sp0;
- byte *mp = mp0;
- byte *dp = dp0;
- int w = w0;
- while (w--)
- {
- byte ma = mp[0];
- byte sa = fz_mul255(sp[0], ma);
- byte ssa = 255 - sa;
- dp[0] = fz_mul255(sp[0], ma) + fz_mul255(dp[0], ssa);
- sp ++;
- mp ++;
- dp ++;
- }
- sp0 += sw;
- mp0 += mw;
- dp0 += dw;
- }
-}
-
-static void duff_4i1o4(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw, int w0, int h)
-{
- /* duff_NiMoN(sp0, sw, 4, mp0, mw, 1, dp0, dw, w0, h); */
- while (h--)
- {
- byte *sp = sp0;
- byte *mp = mp0;
- byte *dp = dp0;
- int w = w0;
- while (w--)
- {
- byte ma = mp[0];
- byte sa = fz_mul255(sp[0], ma);
- byte ssa = 255 - sa;
- dp[0] = fz_mul255(sp[0], ma) + fz_mul255(dp[0], ssa);
- dp[1] = fz_mul255(sp[1], ma) + fz_mul255(dp[1], ssa);
- dp[2] = fz_mul255(sp[2], ma) + fz_mul255(dp[2], ssa);
- dp[3] = fz_mul255(sp[3], ma) + fz_mul255(dp[3], ssa);
- sp += 4;
- mp += 1;
- dp += 4;
- }
- sp0 += sw;
- mp0 += mw;
- dp0 += dw;
- }
-}
-
-/*
- * Mask -- blit one scanline of mask
- *
- * msk_1c1
- * msk_1o1
- * msk_1i1c1
- * msk_1i1o1
- * msk_w3i1o4
- * msk_w3i1i1o4
- */
-
-static void msk_1c1(byte *src, byte *dst, int w)
-{
- memcpy(dst, src, w);
-}
-
-static void msk_1o1(byte *src, byte *dst, int w)
-{
- while (w--)
- {
- dst[0] = src[0] + fz_mul255(dst[0], 255 - src[0]);
- src++;
- dst++;
- }
-}
-
-static void msk_w3i1o4(byte *rgb, byte *src, byte *dst, int n)
-{
- byte rgb0 = rgb[0];
- byte rgb1 = rgb[1];
- byte rgb2 = rgb[2];
- byte sa, ssa;
- while (n--)
- {
- sa = src[0];
- ssa = 255 - sa;
- dst[0] = sa + fz_mul255(dst[0], ssa);
- dst[1] = rgb0 + fz_mul255((short)dst[1] - rgb0, ssa);
- dst[2] = rgb1 + fz_mul255((short)dst[2] - rgb1, ssa);
- dst[3] = rgb2 + fz_mul255((short)dst[3] - rgb2, ssa);
- src ++;
- dst += 4;
- }
-}
-
-/*
- * Image -- draw transformed image
- *
- */
-
-#define lerp(a,b,t) (a + (((b - a) * t) >> 16))
-
-static inline byte getcomp(byte *s, int w, int h, int u, int v, int n, int k)
-{
- if (u < 0 || u >= w) return 0;
- if (v < 0 || v >= h) return 0;
- return s[(w * v + u) * n + k];
-}
-
-static inline int samplecomp(byte *s, int w, int h, int u, int v, int n, int k)
-{
- int ui = u >> 16;
- int vi = v >> 16;
- int ud = u & 0xFFFF;
- int vd = v & 0xFFFF;
- int a = getcomp(s, w, h, ui, vi, n, k);
- int b = getcomp(s, w, h, ui+1, vi, n, k);
- int c = getcomp(s, w, h, ui, vi+1, n, k);
- int d = getcomp(s, w, h, ui+1, vi+1, n, k);
- int ab = lerp(a, b, ud);
- int cd = lerp(c, d, ud);
- return lerp(ab, cd, vd);
-}
-
-static inline byte getmask(byte *s, int w, int h, int u, int v)
-{
- if (u < 0 || u >= w) return 0;
- if (v < 0 || v >= h) return 0;
- return s[w * v + u];
-}
-
-static inline int samplemask(byte *s, int w, int h, int u, int v)
-{
- int ui = u >> 16;
- int vi = v >> 16;
- int ud = u & 0xFFFF;
- int vd = v & 0xFFFF;
- int a = getmask(s, w, h, ui, vi);
- int b = getmask(s, w, h, ui+1, vi);
- int c = getmask(s, w, h, ui, vi+1);
- int d = getmask(s, w, h, ui+1, vi+1);
- int ab = lerp(a, b, ud);
- int cd = lerp(c, d, ud);
- return lerp(ab, cd, vd);
-}
-
-static inline void lerpargb(byte *dst, byte *a, byte *b, int t)
-{
- dst[0] = lerp(a[0], b[0], t);
- dst[1] = lerp(a[1], b[1], t);
- dst[2] = lerp(a[2], b[2], t);
- dst[3] = lerp(a[3], b[3], t);
-}
-
-static inline byte *getargb(byte *s, int w, int h, int u, int v)
-{
- static byte zero[4] = { 0, 0, 0, 0 };
- if (u < 0 || u >= w) return zero;
- if (v < 0 || v >= h) return zero;
- return s + ((w * v + u) << 2);
-}
-
-static inline void sampleargb(byte *s, int w, int h, int u, int v, byte *abcd)
-{
- byte ab[4];
- byte cd[4];
- int ui = u >> 16;
- int vi = v >> 16;
- int ud = u & 0xFFFF;
- int vd = v & 0xFFFF;
- byte *a = getargb(s, w, h, ui, vi);
- byte *b = getargb(s, w, h, ui+1, vi);
- byte *c = getargb(s, w, h, ui, vi+1);
- byte *d = getargb(s, w, h, ui+1, vi+1);
- lerpargb(ab, a, b, ud);
- lerpargb(cd, c, d, ud);
- lerpargb(abcd, ab, cd, vd);
-}
-
-/*
- * img_NcN
- * img_1c1
- * img_4c4
- * img_1o1
- * img_4o4
- * img_1i1c1
- * img_1i1o1
- * img_4i1c4
- * img_4i1o4
- * img_w3i1o4
- * img_w3i1i1o4
- */
-
-static void img_NcN(FZ_PSRC, int srcn, FZ_PDST, FZ_PCTM)
-{
- int k;
- while (h--)
- {
- byte *dstp = dst0;
- int u = u0;
- int v = v0;
- int w = w0;
- while (w--)
- {
- for (k = 0; k < srcn; k++)
- {
- dstp[k] = samplecomp(src, srcw, srch, u, v, srcn, k);
- dstp += srcn;
- u += fa;
- v += fb;
- }
- }
- dst0 += dstw;
- u0 += fc;
- v0 += fd;
- }
-}
-
-static void img_1c1(FZ_PSRC, FZ_PDST, FZ_PCTM)
-{
- while (h--)
- {
- byte *dstp = dst0;
- int u = u0;
- int v = v0;
- int w = w0;
- while (w--)
- {
- dstp[0] = samplemask(src, srcw, srch, u, v);
- dstp ++;
- u += fa;
- v += fb;
- }
- dst0 += dstw;
- u0 += fc;
- v0 += fd;
- }
-}
-
-static void img_4c4(FZ_PSRC, FZ_PDST, FZ_PCTM)
-{
- while (h--)
- {
- byte *dstp = dst0;
- int u = u0;
- int v = v0;
- int w = w0;
- while (w--)
- {
- sampleargb(src, srcw, srch, u, v, dstp);
- dstp += 4;
- u += fa;
- v += fb;
- }
- dst0 += dstw;
- u0 += fc;
- v0 += fd;
- }
-}
-
-static void img_1o1(FZ_PSRC, FZ_PDST, FZ_PCTM)
-{
- byte srca;
- while (h--)
- {
- byte *dstp = dst0;
- int u = u0;
- int v = v0;
- int w = w0;
- while (w--)
- {
- srca = samplemask(src, srcw, srch, u, v);
- dstp[0] = srca + fz_mul255(dstp[0], 255 - srca);
- dstp ++;
- u += fa;
- v += fb;
- }
- dst0 += dstw;
- u0 += fc;
- v0 += fd;
- }
-}
-
-static void img_4o4(FZ_PSRC, FZ_PDST, FZ_PCTM)
-{
- byte argb[4];
- byte ssa;
- while (h--)
- {
- byte *dstp = dst0;
- int u = u0;
- int v = v0;
- int w = w0;
- while (w--)
- {
- sampleargb(src, srcw, srch, u, v, argb);
- ssa = 255 - argb[0];
- dstp[0] = argb[0] + fz_mul255(dstp[0], ssa);
- dstp[1] = argb[1] + fz_mul255(dstp[1], ssa);
- dstp[2] = argb[2] + fz_mul255(dstp[2], ssa);
- dstp[3] = argb[3] + fz_mul255(dstp[3], ssa);
- dstp += 4;
- u += fa;
- v += fb;
- }
- dst0 += dstw;
- u0 += fc;
- v0 += fd;
- }
-}
-
-static void img_w3i1o4(byte *rgb, FZ_PSRC, FZ_PDST, FZ_PCTM)
-{
- byte rgb0 = rgb[0];
- byte rgb1 = rgb[1];
- byte rgb2 = rgb[2];
- byte sa, ssa;
- while (h--)
- {
- byte *dstp = dst0;
- int u = u0;
- int v = v0;
- int w = w0;
- while (w--)
- {
- sa = samplemask(src, srcw, srch, u, v);
- ssa = 255 - sa;
- dstp[0] = sa + fz_mul255(dstp[0], ssa);
- dstp[1] = rgb0 + fz_mul255((short)dstp[1] - rgb0, ssa);
- dstp[2] = rgb1 + fz_mul255((short)dstp[2] - rgb1, ssa);
- dstp[3] = rgb2 + fz_mul255((short)dstp[3] - rgb2, ssa);
- dstp += 4;
- u += fa;
- v += fb;
- }
- dst0 += dstw;
- u0 += fc;
- v0 += fd;
- }
-}
-
-/*
- * Fill in the big fat vtable
- */
-
-static fz_rastfuncs deftab =
-{
- duff_NoN,
- duff_NiMcN,
- duff_NiMoN,
- duff_1o1,
- duff_4o4,
- duff_1i1c1,
- duff_4i1c4,
- duff_1i1o1,
- duff_4i1o4,
-
- msk_1c1,
- msk_1o1,
- msk_w3i1o4,
-
- nil,
- nil,
- nil,
-
- img_NcN,
- img_1c1,
- img_4c4,
- img_1o1,
- img_4o4,
- img_w3i1o4
-};
-
-void
-fz_loadrastfuncs(fz_rastfuncs *tab)
-{
- *tab = deftab;
-#ifdef HAVE_CPUDEP
- fz_accelrastfuncs(tab);
-#endif
-}
-
diff --git a/render/rastppc.c b/render/rastppc.c
deleted file mode 100644
index b693b2d7..00000000
--- a/render/rastppc.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * PowerPC specific render optims live here
- */
-
-#include <fitz.h>
-
-#ifdef HAVE_ALTIVEC
-
-#endif /* HAVE_ALTIVEC */
-
-#if defined (ARCH_PPC)
-void
-fz_accelrastfuncs(fz_rastfuncs *tab)
-{
-# ifdef HAVE_ALTIVEC
- if (fz_cpuflags & HAVE_ALTIVEC)
- {
- /* ... */
- }
-# endif
-}
-#endif
-
diff --git a/render/render.c b/render/render.c
index 92ab519f..424d8c1a 100644
--- a/render/render.c
+++ b/render/render.c
@@ -39,8 +39,6 @@ fz_newrenderer(fz_renderer **gcp, fz_colorspace *pcm, int maskonly, int gcmem)
if (error)
goto cleanup;
- fz_loadrastfuncs(&gc->rast);
-
gc->dest = nil;
gc->over = nil;
gc->rgb[0] = 0;
@@ -150,7 +148,6 @@ enum { HS = 17, VS = 15, SF = 1 };
struct spandata
{
- fz_rastfuncs *rast;
int x, n;
fz_pixmap *dst;
unsigned char *rgb;
@@ -160,7 +157,6 @@ struct spandata
static void spanfunc(int y, int x, int n, unsigned char *path, void *userdata)
{
struct spandata *user = userdata;
- fz_rastfuncs *rast = user->rast;
fz_pixmap *dst = user->dst;
unsigned char *dstp;
@@ -173,13 +169,13 @@ static void spanfunc(int y, int x, int n, unsigned char *path, void *userdata)
{
case FNONE:
assert(dst->n == 1);
- rast->msk_1c1(path, dstp, user->n); break;
+ fz_path_1c1(path, dstp, user->n); break;
case FOVER:
assert(dst->n == 1);
- rast->msk_1o1(path, dstp, user->n); break;
+ fz_path_1o1(path, dstp, user->n); break;
case FOVER | FRGB:
assert(dst->n == 4);
- rast->msk_w3i1o4(user->rgb, path, dstp, user->n); break;
+ fz_path_w3i1o4(user->rgb, path, dstp, user->n); break;
default:
assert(!"impossible flag in path span function");
}
@@ -222,7 +218,6 @@ renderpath(fz_renderer *gc, fz_pathnode *path, fz_matrix ctm)
DEBUG("path %s;\n", path->paint == FZ_STROKE ? "stroke" : "fill");
- user.rast = &gc->rast;
user.x = clip.min.x - gbox.min.x;
user.n = clip.max.x - clip.min.x;
user.flag = gc->flag;
@@ -290,32 +285,17 @@ static void drawglyph(fz_renderer *gc, fz_pixmap *dst, fz_glyph *src, int xorig,
{
case FNONE:
assert(dst->n == 1);
- while (h--)
- {
- gc->rast.msk_1c1(sp, dp, w);
- sp += src->w;
- dp += dst->w;
- }
+ fz_text_1c1(sp, src->w, dp, dst->w, w, h);
break;
case FOVER:
assert(dst->n == 1);
- while (h--)
- {
- gc->rast.msk_1o1(sp, dp, w);
- sp += src->w;
- dp += dst->w;
- }
+ fz_text_1o1(sp, src->w, dp, dst->w, w, h);
break;
case FOVER | FRGB:
assert(dst->n == 4);
- while (h--)
- {
- gc->rast.msk_w3i1o4(gc->rgb, sp, dp, w);
- sp += src->w;
- dp += dst->w * 4;
- }
+ fz_text_w3i1o4(gc->rgb, sp, src->w, dp, dst->w * 4, w, h);
break;
default:
@@ -499,9 +479,9 @@ DEBUG(" fnone %d x %d\n", w, h);
goto cleanup;
if (image->cs)
- gc->rast.img_4c4(PSRC, PDST(gc->dest), PCTM);
+ fz_img_4c4(PSRC, PDST(gc->dest), PCTM);
else
- gc->rast.img_1c1(PSRC, PDST(gc->dest), PCTM);
+ fz_img_1c1(PSRC, PDST(gc->dest), PCTM);
}
break;
@@ -509,15 +489,15 @@ DEBUG(" fnone %d x %d\n", w, h);
{
DEBUG(" fover %d x %d\n", w, h);
if (image->cs)
- gc->rast.img_4o4(PSRC, PDST(gc->over), PCTM);
+ fz_img_4o4(PSRC, PDST(gc->over), PCTM);
else
- gc->rast.img_1o1(PSRC, PDST(gc->over), PCTM);
+ fz_img_1o1(PSRC, PDST(gc->over), PCTM);
}
break;
case FOVER | FRGB:
DEBUG(" fover+rgb %d x %d\n", w, h);
- gc->rast.img_w3i1o4(gc->rgb, PSRC, PDST(gc->over), PCTM);
+ fz_img_w3i1o4(gc->rgb, PSRC, PDST(gc->over), PCTM);
break;
default:
@@ -590,11 +570,11 @@ blendover(fz_renderer *gc, fz_pixmap *src, fz_pixmap *dst)
dp = dst->samples + ((y - dst->y) * dst->w + (x - dst->x)) * dst->n;
if (src->n == 1 && dst->n == 1)
- gc->rast.duff_1o1(sp, src->w, dp, dst->w, w, h);
+ fz_duff_1o1(sp, src->w, dp, dst->w, w, h);
else if (src->n == 4 && dst->n == 4)
- gc->rast.duff_4o4(sp, src->w * 4, dp, dst->w * 4, w, h);
+ fz_duff_4o4(sp, src->w * 4, dp, dst->w * 4, w, h);
else if (src->n == dst->n)
- gc->rast.duff_NoN(sp, src->w * src->n, src->n, dp, dst->w * dst->n, w, h);
+ fz_duff_non(sp, src->w * src->n, src->n, dp, dst->w * dst->n, w, h);
else
assert(!"blendover src and dst mismatch");
}
@@ -635,22 +615,22 @@ blendmask(fz_renderer *gc, fz_pixmap *src, fz_pixmap *msk, fz_pixmap *dst, int o
if (over)
{
if (src->n == 1 && msk->n == 1 && dst->n == 1)
- gc->rast.duff_1i1o1(sp, src->w, mp, msk->w, dp, dst->w, w, h);
+ fz_duff_1i1o1(sp, src->w, mp, msk->w, dp, dst->w, w, h);
else if (src->n == 4 && msk->n == 1 && dst->n == 4)
- gc->rast.duff_4i1o4(sp, src->w * 4, mp, msk->w, dp, dst->w * 4, w, h);
+ fz_duff_4i1o4(sp, src->w * 4, mp, msk->w, dp, dst->w * 4, w, h);
else if (src->n == dst->n)
- gc->rast.duff_NiMoN(sp, src->w * src->n, src->n, mp, msk->w * msk->n, msk->n, dp, dst->w * dst->n, w, h);
+ fz_duff_nimon(sp, src->w * src->n, src->n, mp, msk->w * msk->n, msk->n, dp, dst->w * dst->n, w, h);
else
assert(!"blendmaskover src and msk and dst mismatch");
}
else
{
if (src->n == 1 && msk->n == 1 && dst->n == 1)
- gc->rast.duff_1i1c1(sp, src->w, mp, msk->w, dp, dst->w, w, h);
+ fz_duff_1i1c1(sp, src->w, mp, msk->w, dp, dst->w, w, h);
else if (src->n == 4 && msk->n == 1 && dst->n == 4)
- gc->rast.duff_4i1c4(sp, src->w * 4, mp, msk->w, dp, dst->w * 4, w, h);
+ fz_duff_4i1c4(sp, src->w * 4, mp, msk->w, dp, dst->w * 4, w, h);
else if (src->n == dst->n)
- gc->rast.duff_NiMcN(sp, src->w * src->n, src->n, mp, msk->w * msk->n, msk->n, dp, dst->w * dst->n, w, h);
+ fz_duff_nimcn(sp, src->w * src->n, src->n, mp, msk->w * msk->n, msk->n, dp, dst->w * dst->n, w, h);
else
assert(!"blendmask src and msk and dst mismatch");
}
diff --git a/render/scale.c b/render/scale.c
deleted file mode 100644
index 01ebec2d..00000000
--- a/render/scale.c
+++ /dev/null
@@ -1,225 +0,0 @@
-#include <fitz.h>
-
-/* TODO: these should go in fz_rastfuncs */
-
-typedef void (*rowfunc)(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom);
-typedef void (*colfunc)(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom);
-
-static void
-scalerow(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom)
-{
- int x, left, k;
- int sum[FZ_MAXCOLORS];
-
- left = 0;
- for (k = 0; k < ncomp; k++)
- sum[k] = 0;
-
- for (x = 0; x < w; x++)
- {
- for (k = 0; k < ncomp; k++)
- sum[k] += src[x * ncomp + k];
- if (++left == denom)
- {
- left = 0;
- for (k = 0; k < ncomp; k++)
- {
- dst[k] = sum[k] / denom;
- sum[k] = 0;
- }
- dst += ncomp;
- }
- }
-
- /* left overs */
- if (left)
- for (k = 0; k < ncomp; k++)
- dst[k] = sum[k] / left;
-}
-
-static void
-scalerow1(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom)
-{
- int x, left;
- int sum;
-
- left = 0;
- sum = 0;
-
- for (x = 0; x < w; x++)
- {
- sum += *src++;
- if (++left == denom)
- {
- left = 0;
- *dst++ = sum / denom;
- sum = 0;
- }
- }
-
- /* left overs */
- if (left)
- {
- *dst++ = sum / left;
- }
-}
-
-static void
-scalerow2(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom)
-{
- int x, left;
- int sum0, sum1;
-
- left = 0;
- sum0 = 0;
- sum1 = 0;
-
- for (x = 0; x < w; x++)
- {
- sum0 += *src++;
- sum1 += *src++;
- if (++left == denom)
- {
- left = 0;
- *dst++ = sum0 / denom;
- *dst++ = sum1 / denom;
- sum0 = 0;
- sum1 = 0;
- }
- }
-
- /* left overs */
- if (left)
- {
- *dst++ = sum0 / left;
- *dst++ = sum1 / left;
- }
-}
-
-
-static void
-scalecols(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom)
-{
- int x, y, k;
- unsigned char *s;
- int sum[FZ_MAXCOLORS];
-
- for (x = 0; x < w; x++)
- {
- s = src + (x * ncomp);
- for (k = 0; k < ncomp; k++)
- sum[k] = 0;
- for (y = 0; y < denom; y++)
- for (k = 0; k < ncomp; k++)
- sum[k] += s[y * w * ncomp + k];
- for (k = 0; k < ncomp; k++)
- dst[k] = sum[k] / denom;
- dst += ncomp;
- }
-}
-
-static void
-scalecols1(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom)
-{
- int x, y;
- unsigned char *s;
- int sum;
-
- for (x = 0; x < w; x++)
- {
- s = src + x;
- sum = 0;
- for (y = 0; y < denom; y++)
- sum += s[y * w];
- *dst++ = sum / denom;
- }
-}
-
-static void
-scalecols2(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom)
-{
- int x, y;
- unsigned char *s;
- int sum0, sum1;
-
- for (x = 0; x < w; x++)
- {
- s = src + (x * 2);
- sum0 = 0;
- sum1 = 0;
- for (y = 0; y < denom; y++)
- {
- sum0 += s[y * w * 2 + 0];
- sum1 += s[y * w * 2 + 1];
- }
- *dst++ = sum0 / denom;
- *dst++ = sum1 / denom;
- }
-}
-
-fz_error *
-fz_scalepixmap(fz_pixmap **dstp, fz_pixmap *src, int xdenom, int ydenom)
-{
- fz_error *error;
- fz_pixmap *dst;
- unsigned char *buf;
- int y, iy, oy;
- int ow, oh, n;
- rowfunc rowfunc;
- colfunc colfunc;
-
- ow = (src->w + xdenom - 1) / xdenom;
- oh = (src->h + ydenom - 1) / ydenom;
- n = src->n;
-
- buf = fz_malloc(ow * n * ydenom);
- if (!buf)
- return fz_outofmem;
-
- error = fz_newpixmap(&dst, 0, 0, ow, oh, src->n);
- if (error)
- {
- fz_free(buf);
- return error;
- }
-
- switch (n)
- {
- case 1:
- rowfunc = scalerow1;
- colfunc = scalecols1;
- break;
- case 2:
- rowfunc = scalerow2;
- colfunc = scalecols2;
- break;
- default:
- rowfunc = scalerow;
- colfunc = scalecols;
- break;
- }
-
- for (y = 0, oy = 0; y < (src->h / ydenom) * ydenom; y += ydenom, oy++)
- {
- for (iy = 0; iy < ydenom; iy++)
- rowfunc(src->samples + (y + iy) * src->w * n,
- buf + iy * ow * n,
- src->w, n, xdenom);
- colfunc(buf, dst->samples + oy * dst->w * n, dst->w, n, ydenom);
- }
-
- ydenom = src->h - y;
- if (ydenom)
- {
- for (iy = 0; iy < ydenom; iy++)
- rowfunc(src->samples + (y + iy) * src->w * n,
- buf + iy * ow * n,
- src->w, n, xdenom);
- colfunc(buf, dst->samples + oy * dst->w * n, dst->w, n, ydenom);
- }
-
- fz_free(buf);
- *dstp = dst;
- return nil;
-}
-
diff --git a/render/scanconv.c b/render/scanconv.c
deleted file mode 100644
index 662a4cdb..00000000
--- a/render/scanconv.c
+++ /dev/null
@@ -1,152 +0,0 @@
-#include <fitz.h>
-
-static inline void
-addspan(unsigned char *list, int x0, int x1, int xofs, int hs)
-{
- int x0pix, x0sub;
- int x1pix, x1sub;
-
- if (x0 == x1)
- return;
-
- /* x between 0 and width of bbox */
- x0 -= xofs;
- x1 -= xofs;
-
- x0pix = x0 / hs;
- x0sub = x0 % hs;
- x1pix = x1 / hs;
- x1sub = x1 % hs;
-
- if (x0pix == x1pix)
- {
- list[x0pix] += x1sub - x0sub;
- list[x0pix+1] += x0sub - x1sub;
- }
-
- else
- {
- list[x0pix] += hs - x0sub;
- list[x0pix+1] += x0sub;
- list[x1pix] += x1sub - hs;
- list[x1pix+1] += -x1sub;
- }
-}
-
-static inline void
-nonzerowinding(fz_ael *ael, unsigned char *list, int xofs, int hs)
-{
- int winding = 0;
- int x = 0;
- int i;
- for (i = 0; i < ael->len; i++)
- {
- if (!winding && (winding + ael->edges[i]->ydir))
- x = ael->edges[i]->x;
- if (winding && !(winding + ael->edges[i]->ydir))
- addspan(list, x, ael->edges[i]->x, xofs, hs);
- winding += ael->edges[i]->ydir;
- }
-}
-
-static inline void
-evenodd(fz_ael *ael, unsigned char *list, int xofs, int hs)
-{
- int even = 0;
- int x = 0;
- int i;
- for (i = 0; i < ael->len; i++)
- {
- if (!even)
- x = ael->edges[i]->x;
- else
- addspan(list, x, ael->edges[i]->x, xofs, hs);
- even = !even;
- }
-}
-
-static void toalpha(unsigned char *list, int n)
-{
- int d = 0;
- while (n--)
- {
- d += *list;
- *list++ = d;
- }
-}
-
-fz_error *
-fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, int y0, int y1,
- void (*blitfunc)(int,int,int,unsigned char*,void*), void *blitdata)
-{
- fz_error *error;
- unsigned char *deltas;
- int y, e;
- int yd, yc;
-
- int xmin = fz_idiv(gel->xmin, gel->hs);
- int xmax = fz_idiv(gel->xmax, gel->hs) + 1;
-
- int xofs = xmin * gel->hs;
- int hs = gel->hs;
- int vs = gel->vs;
-
- if (gel->len == 0)
- return nil;
-
- deltas = fz_malloc(xmax - xmin + 1);
- if (!deltas)
- return fz_outofmem;
-
- memset(deltas, 0, xmax - xmin + 1);
-
- e = 0;
- y = gel->edges[0].y;
- yc = fz_idiv(y, vs);
- yd = yc;
-
- while (ael->len > 0 || e < gel->len)
- {
- yc = fz_idiv(y, vs);
- if (yc != yd) {
- if (yd >= y0 && yd < y1)
- {
- toalpha(deltas, xmax - xmin);
- blitfunc(yd, xmin, xmax - xmin, deltas, blitdata);
- memset(deltas, 0, xmax - xmin + 1);
- }
- }
- yd = yc;
-
- error = fz_insertael(ael, gel, y, &e);
- if (error) {
- fz_free(deltas);
- return error;
- }
-
- if (yd >= y0 && yd < y1)
- {
- if (eofill)
- evenodd(ael, deltas, xofs, hs);
- else
- nonzerowinding(ael, deltas, xofs, hs);
- }
-
- fz_advanceael(ael);
-
- if (ael->len > 0)
- y ++;
- else if (e < gel->len)
- y = gel->edges[e].y;
- }
-
- if (yd >= y0 && yd < y1)
- {
- toalpha(deltas, xmax - xmin);
- blitfunc(yd, xmin, xmax - xmin, deltas, blitdata);
- }
-
- fz_free(deltas);
- return nil;
-}
-
diff --git a/test/pdfrip.c b/test/pdfrip.c
index f5f762da..6e3f6bef 100644
--- a/test/pdfrip.c
+++ b/test/pdfrip.c
@@ -87,6 +87,9 @@ int main(int argc, char **argv)
char *password = "";
+ fz_cpudetect();
+ fz_accelerate();
+
while ((c = getopt(argc, argv, "dz:p:")) != -1)
{
switch (c)
diff --git a/test/x11pdf.c b/test/x11pdf.c
index 46e95632..88aebe47 100644
--- a/test/x11pdf.c
+++ b/test/x11pdf.c
@@ -242,6 +242,8 @@ static void dumptext()
fz_error *error;
pdf_textline *line;
+ printf("----");
+
error = pdf_loadtextfromtree(&line, page->tree);
if (error)
fz_abort(error);
@@ -363,6 +365,7 @@ int main(int argc, char **argv)
usage();
fz_cpudetect();
+ fz_accelerate();
filename = argv[optind++];
diff --git a/test/ximage.c b/test/ximage.c
index 3b4a9b8b..1e56fa2e 100644
--- a/test/ximage.c
+++ b/test/ximage.c
@@ -20,9 +20,9 @@ typedef void (*ximage_convert_func_t)
int h
);
-#define POOLSIZE 6
+#define POOLSIZE 4
#define WIDTH 256
-#define HEIGHT 64
+#define HEIGHT 256
enum {
ARGB8888,
diff --git a/tree/optimize.c b/tree/optimize.c
index b65a37ca..cbb9ad31 100644
--- a/tree/optimize.c
+++ b/tree/optimize.c
@@ -181,6 +181,14 @@ retry:
shape = current->first;
color = shape->next;
+ if (color == nil)
+ {
+ fz_removenode(current);
+ prev = nil;
+ current = node->first;
+ goto retry;
+ }
+
if (fz_ispathnode(shape))
{
if (getrect((fz_pathnode*)shape, &bbox))