diff options
author | Tor Andersson <tor@ghostscript.com> | 2004-11-29 16:15:08 +0100 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2004-11-29 16:15:08 +0100 |
commit | 9a36550815c3d874ce62650bf06ee85a3f705f1c (patch) | |
tree | cc45ee69f0eca20520b388c44909703142c9196a | |
parent | fa0b09e3a0c696069033195a394b09d30a8c0573 (diff) | |
download | mupdf-9a36550815c3d874ce62650bf06ee85a3f705f1c.tar.xz |
shift things about a bit
-rw-r--r-- | Jamfile | 25 | ||||
-rw-r--r-- | TODO | 5 | ||||
-rw-r--r-- | base/cpudep.c | 6 | ||||
-rw-r--r-- | filter/dctd.c | 4 | ||||
-rw-r--r-- | include/fitz.h | 2 | ||||
-rw-r--r-- | include/fitz/cpudep.h | 4 | ||||
-rw-r--r-- | include/fitz/pathscan.h (renamed from include/fitz/scanconv.h) | 2 | ||||
-rw-r--r-- | include/fitz/render.h | 81 | ||||
-rw-r--r-- | mupdf/colorspace1.c | 5 | ||||
-rw-r--r-- | mupdf/image.c (renamed from mupdf/image1.c) | 76 | ||||
-rw-r--r-- | mupdf/image2.c | 255 | ||||
-rw-r--r-- | mupdf/resources.c | 2 | ||||
-rw-r--r-- | render/archppc.c | 65 | ||||
-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.c | 324 | ||||
-rw-r--r-- | render/optimage.c | 238 | ||||
-rw-r--r-- | render/optscale.c | 191 | ||||
-rw-r--r-- | render/optunpack.c | 183 | ||||
-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.c | 570 | ||||
-rw-r--r-- | render/rastppc.c | 23 | ||||
-rw-r--r-- | render/render.c | 60 | ||||
-rw-r--r-- | render/scale.c | 225 | ||||
-rw-r--r-- | render/scanconv.c | 152 | ||||
-rw-r--r-- | test/pdfrip.c | 3 | ||||
-rw-r--r-- | test/x11pdf.c | 3 | ||||
-rw-r--r-- | test/ximage.c | 4 | ||||
-rw-r--r-- | tree/optimize.c | 8 |
31 files changed, 1360 insertions, 1329 deletions
@@ -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 @@ -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)) |