📄 draw.c
字号:
b = &p->bcache[y]; if((p->bfilled & (1<<y)) == 0){ p->bfilled |= 1<<y; *b = p->replcall(p, p->bufbase+y*p->bufdelta, y); } return *b;}/* * Alpha reading function that simply relabels the grey pointer. */static Buffergreymaskread(Param *p, uchar *buf, int y){ Buffer b; b = p->greymaskcall(p, buf, y); b.alpha = b.grey; return b;}#define DBG if(0)static Bufferreadnbit(Param *p, uchar *buf, int y){ Buffer b; Memimage *img; uchar *repl, *r, *w, *ow, bits; int i, n, sh, depth, x, dx, npack, nbits; b.rgba = (ulong*)buf; b.grey = w = buf; b.red = b.blu = b.grn = w; b.alpha = &ones; b.delta = 1; dx = p->dx; img = p->img; depth = img->depth; repl = &replbit[depth][0]; npack = 8/depth; sh = 8-depth; /* copy from p->r.min.x until end of repl rectangle */ x = p->r.min.x; n = dx; if(n > p->img->r.max.x - x) n = p->img->r.max.x - x; r = p->bytermin + y*p->bwidth;DBG print("readnbit dx %d %p=%p+%d*%d, *r=%d fetch %d ", dx, r, p->bytermin, y, p->bwidth, *r, n); bits = *r++; nbits = 8; if(i=x&(npack-1)){DBG print("throwaway %d...", i); bits <<= depth*i; nbits -= depth*i; } for(i=0; i<n; i++){ if(nbits == 0){DBG print("(%.2ux)...", *r); bits = *r++; nbits = 8; } *w++ = repl[bits>>sh];DBG print("bit %x...", repl[bits>>sh]); bits <<= depth; nbits -= depth; } dx -= n; if(dx == 0) return b; assert(x+i == p->img->r.max.x); /* copy from beginning of repl rectangle until where we were before. */ x = p->img->r.min.x; n = dx; if(n > p->r.min.x - x) n = p->r.min.x - x; r = p->bytey0s + y*p->bwidth;DBG print("x=%d r=%p...", x, r); bits = *r++; nbits = 8; if(i=x&(npack-1)){ bits <<= depth*i; nbits -= depth*i; }DBG print("nbits=%d...", nbits); for(i=0; i<n; i++){ if(nbits == 0){ bits = *r++; nbits = 8; } *w++ = repl[bits>>sh];DBG print("bit %x...", repl[bits>>sh]); bits <<= depth; nbits -= depth;DBG print("bits %x nbits %d...", bits, nbits); } dx -= n; if(dx == 0) return b; assert(dx > 0); /* now we have exactly one full scan line: just replicate the buffer itself until we are done */ ow = buf; while(dx--) *w++ = *ow++; return b;}#undef DBG#define DBG if(0)static voidwritenbit(Param *p, uchar *w, Buffer src){ uchar *r; ulong bits; int i, sh, depth, npack, nbits, x, ex; assert(src.grey != nil && src.delta == 1); x = p->r.min.x; ex = x+p->dx; depth = p->img->depth; npack = 8/depth; i=x&(npack-1); bits = i ? (*w >> (8-depth*i)) : 0; nbits = depth*i; sh = 8-depth; r = src.grey; for(; x<ex; x++){ bits <<= depth;DBG print(" %x", *r); bits |= (*r++ >> sh); nbits += depth; if(nbits == 8){ *w++ = bits; nbits = 0; } } if(nbits){ sh = 8-nbits; bits <<= sh; bits |= *w & ((1<<sh)-1); *w = bits; }DBG print("\n"); return;}#undef DBGstatic Bufferreadcmap(Param *p, uchar *buf, int y){ Buffer b; int a, convgrey, copyalpha, dx, i, m; uchar *q, *cmap, *begin, *end, *r, *w; begin = p->bytey0s + y*p->bwidth; r = p->bytermin + y*p->bwidth; end = p->bytey0e + y*p->bwidth; cmap = p->img->cmap->cmap2rgb; convgrey = p->convgrey; copyalpha = (p->img->flags&Falpha) ? 1 : 0; w = buf; dx = p->dx; if(copyalpha){ b.alpha = buf++; a = p->img->shift[CAlpha]/8; m = p->img->shift[CMap]/8; for(i=0; i<dx; i++){ *w++ = r[a]; q = cmap+r[m]*3; r += 2; if(r == end) r = begin; if(convgrey){ *w++ = RGB2K(q[0], q[1], q[2]); }else{ *w++ = q[2]; /* blue */ *w++ = q[1]; /* green */ *w++ = q[0]; /* red */ } } }else{ b.alpha = &ones; for(i=0; i<dx; i++){ q = cmap+*r++*3; if(r == end) r = begin; if(convgrey){ *w++ = RGB2K(q[0], q[1], q[2]); }else{ *w++ = q[2]; /* blue */ *w++ = q[1]; /* green */ *w++ = q[0]; /* red */ } } } b.rgba = (ulong*)(buf-copyalpha); if(convgrey){ b.grey = buf; b.red = b.blu = b.grn = buf; b.delta = 1+copyalpha; }else{ b.blu = buf; b.grn = buf+1; b.red = buf+2; b.grey = nil; b.delta = 3+copyalpha; } return b;}static voidwritecmap(Param *p, uchar *w, Buffer src){ uchar *cmap, *red, *grn, *blu; int i, dx, delta; cmap = p->img->cmap->rgb2cmap; delta = src.delta; red= src.red; grn = src.grn; blu = src.blu; dx = p->dx; for(i=0; i<dx; i++, red+=delta, grn+=delta, blu+=delta) *w++ = cmap[(*red>>4)*256+(*grn>>4)*16+(*blu>>4)];}#define DBG if(0)static Bufferreadbyte(Param *p, uchar *buf, int y){ Buffer b; Memimage *img; int dx, isgrey, convgrey, alphaonly, copyalpha, i, nb; uchar *begin, *end, *r, *w, *rrepl, *grepl, *brepl, *arepl, *krepl; uchar ured, ugrn, ublu; ulong u; img = p->img; begin = p->bytey0s + y*p->bwidth; r = p->bytermin + y*p->bwidth; end = p->bytey0e + y*p->bwidth; w = buf; dx = p->dx; nb = img->depth/8; convgrey = p->convgrey; /* convert rgb to grey */ isgrey = img->flags&Fgrey; alphaonly = p->alphaonly; copyalpha = (img->flags&Falpha) ? 1 : 0;DBG print("copyalpha %d alphaonly %d convgrey %d isgrey %d\n", copyalpha, alphaonly, convgrey, isgrey); /* if we can, avoid processing everything */ if(!(img->flags&Frepl) && !convgrey && (img->flags&Fbytes)){ memset(&b, 0, sizeof b); if(p->needbuf){ memmove(buf, r, dx*nb); r = buf; } b.rgba = (ulong*)r; if(copyalpha) b.alpha = r+img->shift[CAlpha]/8; else b.alpha = &ones; if(isgrey){ b.grey = r+img->shift[CGrey]/8; b.red = b.grn = b.blu = b.grey; }else{ b.red = r+img->shift[CRed]/8; b.grn = r+img->shift[CGreen]/8; b.blu = r+img->shift[CBlue]/8; } b.delta = nb; return b; }DBG print("2\n"); rrepl = replbit[img->nbits[CRed]]; grepl = replbit[img->nbits[CGreen]]; brepl = replbit[img->nbits[CBlue]]; arepl = replbit[img->nbits[CAlpha]]; krepl = replbit[img->nbits[CGrey]]; for(i=0; i<dx; i++){ u = r[0] | (r[1]<<8) | (r[2]<<16) | (r[3]<<24); if(copyalpha) { *w++ = arepl[(u>>img->shift[CAlpha]) & img->mask[CAlpha]];DBG print("a %x\n", w[-1]); } if(isgrey) *w++ = krepl[(u >> img->shift[CGrey]) & img->mask[CGrey]]; else if(!alphaonly){ ured = rrepl[(u >> img->shift[CRed]) & img->mask[CRed]]; ugrn = grepl[(u >> img->shift[CGreen]) & img->mask[CGreen]]; ublu = brepl[(u >> img->shift[CBlue]) & img->mask[CBlue]]; if(convgrey){DBG print("g %x %x %x\n", ured, ugrn, ublu); *w++ = RGB2K(ured, ugrn, ublu);DBG print("%x\n", w[-1]); }else{ *w++ = brepl[(u >> img->shift[CBlue]) & img->mask[CBlue]]; *w++ = grepl[(u >> img->shift[CGreen]) & img->mask[CGreen]]; *w++ = rrepl[(u >> img->shift[CRed]) & img->mask[CRed]]; } } r += nb; if(r == end) r = begin; } b.alpha = copyalpha ? buf : &ones; b.rgba = (ulong*)buf; if(alphaonly){ b.red = b.grn = b.blu = b.grey = nil; if(!copyalpha) b.rgba = nil; b.delta = 1; }else if(isgrey || convgrey){ b.grey = buf+copyalpha; b.red = b.grn = b.blu = buf+copyalpha; b.delta = copyalpha+1;DBG print("alpha %x grey %x\n", b.alpha ? *b.alpha : 0xFF, *b.grey); }else{ b.blu = buf+copyalpha; b.grn = buf+copyalpha+1; b.grey = nil; b.red = buf+copyalpha+2; b.delta = copyalpha+3; } return b;}#undef DBG#define DBG if(0)static voidwritebyte(Param *p, uchar *w, Buffer src){ Memimage *img; int i, isalpha, isgrey, nb, delta, dx, adelta; uchar ff, *red, *grn, *blu, *grey, *alpha; ulong u, mask; img = p->img; red = src.red; grn = src.grn; blu = src.blu; alpha = src.alpha; delta = src.delta; grey = src.grey; dx = p->dx; nb = img->depth/8; mask = (nb==4) ? 0 : ~((1<<img->depth)-1); isalpha = img->flags&Falpha; isgrey = img->flags&Fgrey; adelta = src.delta; if(isalpha && (alpha == nil || alpha == &ones)){ ff = 0xFF; alpha = &ff; adelta = 0; } for(i=0; i<dx; i++){ u = w[0] | (w[1]<<8) | (w[2]<<16) | (w[3]<<24);DBG print("u %.8lux...", u); u &= mask;DBG print("&mask %.8lux...", u); if(isgrey){ u |= ((*grey >> (8-img->nbits[CGrey])) & img->mask[CGrey]) << img->shift[CGrey];DBG print("|grey %.8lux...", u); grey += delta; }else{ u |= ((*red >> (8-img->nbits[CRed])) & img->mask[CRed]) << img->shift[CRed]; u |= ((*grn >> (8-img->nbits[CGreen])) & img->mask[CGreen]) << img->shift[CGreen]; u |= ((*blu >> (8-img->nbits[CBlue])) & img->mask[CBlue]) << img->shift[CBlue]; red += delta; grn += delta; blu += delta;DBG print("|rgb %.8lux...", u); } if(isalpha){ u |= ((*alpha >> (8-img->nbits[CAlpha])) & img->mask[CAlpha]) << img->shift[CAlpha]; alpha += adelta;DBG print("|alpha %.8lux...", u); } w[0] = u; w[1] = u>>8; w[2] = u>>16; w[3] = u>>24; w += nb; }}#undef DBGstatic Readfn*readfn(Memimage *img){ if(img->depth < 8) return readnbit; if(img->nbits[CMap] == 8) return readcmap; return readbyte;}static Readfn*readalphafn(Memimage *m){ USED(m); return readbyte;}static Writefn*writefn(Memimage *img){ if(img->depth < 8) return writenbit; if(img->chan == CMAP8) return writecmap; return writebyte;}static voidnullwrite(Param *p, uchar *s, Buffer b){ USED(p); USED(s); USED(b);}static Bufferreadptr(Param *p, uchar *s, int y){ Buffer b; uchar *q; USED(s); q = p->bytermin + y*p->bwidth; b.red = q; /* ptr to data */ b.grn = b.blu = b.grey = b.alpha = nil; b.rgba = (ulong*)q; b.delta = p->img->depth/8; return b;}static Bufferboolmemmove(Buffer bdst, Buffer bsrc, Buffer b1, int dx, int i, int o){ USED(i); USED(o); USED(b1); USED(bsrc); memmove(bdst.red, bsrc.red, dx*bdst.delta); return bdst;}static Bufferboolcopy8(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o){ uchar *m, *r, *w, *ew; USED(i); USED(o); m = bmask.grey; w = bdst.red; r = bsrc.red; ew = w+dx; for(; w < ew; w++,r++) if(*m++) *w = *r; return bdst; /* not used */}static Bufferboolcopy16(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o){ uchar *m; ushort *r, *w, *ew; USED(i); USED(o); m = bmask.grey; w = (ushort*)bdst.red; r = (ushort*)bsrc.red; ew = w+dx; for(; w < ew; w++,r++) if(*m++) *w = *r; return bdst; /* not used */}static Bufferboolcopy24(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o){ uchar *m; uchar *r, *w, *ew; USED(i); USED(o); m = bmask.grey; w = bdst.red; r = bsrc.red; ew = w+dx*3; while(w < ew){ if(*m++){ *w++ = *r++; *w++ = *r++; *w++ = *r++; }else{ w += 3; r += 3; } } return bdst; /* not used */}static Bufferboolcopy32(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int i, int o){ uchar *m; ulong *r, *w, *ew; USED(i); USED(o); m = bmask.grey; w = (ulong*)bdst.red; r = (ulong*)bsrc.red; ew = w+dx; for(; w < ew; w++,r++) if(*m++) *w = *r; return bdst; /* not used */}static Buffergenconv(Param *p, uchar *buf, int y){ Buffer b; int nb; uchar *r, *w, *ew; /* read from source into RGB format in convbuf */ b = p->convreadcall(p, p->convbuf, y); /* write RGB format into dst format in buf */ p->convwritecall(p->convdpar, buf, b); if(p->convdx){ nb = p->convdpar->img->depth/8; r = buf; w = buf+nb*p->dx; ew = buf+nb*p->convdx; while(w<ew) *w++ = *r++; } b.red = buf; b.blu = b.grn = b.grey = b.alpha = nil; b.rgba = (ulong*)buf; b.delta = 0; return b;}static Readfn*convfn(Memimage *dst, Param *dpar, Memimage *src, Param *spar, int *ndrawbuf){ if(dst->chan == src->chan && !(src->flags&Frepl)){//if(drawdebug) iprint("readptr..."); return readptr; } if(dst->chan==CMAP8 && (src->chan==GREY1||src->chan==GREY2||src->chan==GREY4)){ /* cheat because we know the replicated value is exactly the color map entry. *///if(drawdebug) iprint("Readnbit..."); return readnbit; } spar->convreadcall = readfn(src); spar->convwritecall = writefn(dst); spar->convdpar = dpar; /* allocate a conversion buffer */ spar->convbufoff = *ndrawbuf; *ndrawbuf += spar->dx*4; if(spar->dx > Dx(spar->img->r)){ spar->convdx = spar->dx; spar->dx = Dx(spar->img->r); }//if(drawdebug) iprint("genconv..."); return genconv;}static ulongpixelbits(Memimage *i, Point pt){ uchar *p; ulong val; int off, bpp, npack; val = 0; p = byteaddr(i, pt); switch(bpp=i->depth){ case 1: case 2: case 4: npack = 8/bpp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -