home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- * canblend -
- * Blend rows and columns into the canvas.
- *
- * Paul Haeberli - 1991
- *
- * exports
- *
- void beginstroke()
- void endstroke()
- void setnegalpha(v)
- void setclonemode(c)
- void setcurcolor(c)
- unsigned long getcurcolor()
- void avg_clear();
- long avg_get();
- void clonesource(c,dx,dy)
- void readpix_init()
- void setblend(b)
- int getblend()
- *
- */
- #include "stdio.h"
- #include "canvas.h"
- #include "lum.h"
-
- void (*constblendrow)();
- void (*blendrow)();
- void (*blendcol)();
-
- static void writepix_constblendrow();
- static void writepix_blendrow();
- static void writepix_blendcol();
-
- /* lum macros */
-
- #define NOTHING (-1)
- #define DATLEN (200*200)
- #define PA(a) ((a))
- #define MA(a) (256-(a))
- #define MYLUM(r,g,b) ((RINTLUM*(r)+GINTLUM*(g)+BINTLUM*(b)+127)>>8)
-
- #define LLUM(c) ((RINTLUM*(c)[OFFSET_R]+ \
- GINTLUM*(c)[OFFSET_G]+ \
- BINTLUM*(c)[OFFSET_B]+127)>>8)
- /* lerp macros */
-
- #define NLERP(v1,v2,a) ((v1)+(((((v2)-(v1))*(a))+bloff)>>8))
- #define CLERP(v1,v2,ma) (((v1)*(ma)+(v2))>>8)
-
- /* blend macros */
-
- #define CLIPROW(d,x,y,n,mat) { \
- if(clip) { \
- if(y<0 || y>=d->ysize) return; \
- if(x>=d->xsize) return; \
- if((x+n)<=0) return; \
- if((x+n)>d->xsize) n = d->xsize-x; \
- if(x<0) { n += x; mat -= x; x = 0; } \
- } \
- }
-
- #define CLIPCOL(d,x,y,n,mat) { \
- if(clip) { \
- if(x<0 || x>=d->xsize) return; \
- if(y>=d->ysize) return; \
- if((y+n)<=0) return; \
- if((y+n)>d->ysize) n = d->ysize-y; \
- if(y<0) { n += y; mat -= y; y = 0; } \
- } \
- }
-
- #define NBLEND(d,r,g,b,a) { \
- (d)[OFFSET_R] = NLERP((d)[OFFSET_R],r,a); \
- (d)[OFFSET_G] = NLERP((d)[OFFSET_G],g,a); \
- (d)[OFFSET_B] = NLERP((d)[OFFSET_B],b,a); \
- }
-
- #define CBLEND(d,r,g,b,ma) { \
- (d)[OFFSET_R] = CLERP((d)[OFFSET_R],r,ma); \
- (d)[OFFSET_G] = CLERP((d)[OFFSET_G],g,ma); \
- (d)[OFFSET_B] = CLERP((d)[OFFSET_B],b,ma); \
- }
-
- #define XBLEND(d,cr,cg,cb,a) { \
- v = NLERP((d)[OFFSET_R],cr,a); \
- if(v&0xff00) { \
- if(v<0) v = 0; else v = 255; \
- } \
- (d)[OFFSET_R] = v; \
- v = NLERP((d)[OFFSET_G],cg,a); \
- if(v&0xff00) { \
- if(v<0) v = 0; else v = 255; \
- } \
- (d)[OFFSET_G] = v; \
- v = NLERP((d)[OFFSET_B],cb,a); \
- if(v&0xff00) { \
- if(v<0) v = 0; else v = 255; \
- } \
- (d)[OFFSET_B] = v; \
- }
-
- /* chromalerp macros */
-
- #define NCHROMABLEND() { \
- ld = LLUM(dptr); \
- curc = (unsigned char *)(chromatab+ld); \
- r = dptr[OFFSET_R] = NLERP(dptr[OFFSET_R],curc[OFFSET_R],a); \
- b = dptr[OFFSET_B] = NLERP(dptr[OFFSET_B],curc[OFFSET_B],a); \
- g = ((ld<<8)-(r*RINTLUM)-(b*BINTLUM)+(GINTLUM/2))/GINTLUM; \
- if(g&0xff00) { \
- if(g<0) g = 0; else g = 255; \
- } \
- dptr[OFFSET_G] = g; \
- }
-
- #define XCHROMABLEND() { \
- ld = LLUM(dptr); \
- curc = (unsigned char *)(chromatab+ld); \
- r = NLERP(dptr[OFFSET_R],curc[OFFSET_R],a); \
- if(r&0xff00) { \
- if(r<0) r = 0; else r = 255; \
- } \
- dptr[OFFSET_R] = r; \
- b = NLERP(dptr[OFFSET_B],curc[OFFSET_B],a); \
- if(b&0xff00) { \
- if(b<0) b = 0; else b = 255; \
- } \
- dptr[OFFSET_B] = b; \
- g = ((ld<<8)-(r*RINTLUM)-(b*BINTLUM)+(GINTLUM/2))/GINTLUM; \
- if(g&0xff00) { \
- if(g<0) g = 0; else g = 255; \
- } \
- dptr[OFFSET_G] = g; \
- }
-
- /* on darker macros */
-
- #define NONDARKERBLEND() { \
- if(LLUM(dptr)<cl) \
- NBLEND(dptr,cr,cg,cb,a); \
- }
-
- #define XONDARKERBLEND() { \
- if(LLUM(dptr)<cl) \
- NBLEND(dptr,cr,cg,cb,a); \
- }
-
- /* on lighter macros */
-
- #define NONLIGHTERBLEND() { \
- if(LLUM(dptr)>=cl) \
- NBLEND(dptr,cr,cg,cb,a); \
- }
-
- #define XONLIGHTERBLEND() { \
- if(LLUM(dptr)>=cl) \
- NBLEND(dptr,cr,cg,cb,a); \
- }
-
- static int negalpha;
- static int clonemode;
- static unsigned long *chromatab;
- static unsigned long *chromatable;
- static curb;
- static canvas *clonesrc;
- static int clonedx, clonedy;
- static float fclonedx, fclonedy;
- static float eclonedx, eclonedy;
- static unsigned long ar, ag, ab, adiv;
- static unsigned short curlum;
- static unsigned long curchroma;
- static long *pixdata;
- static long *pixptr;
- static int stoff;
- static int bloffset;
- static unsigned long curcolor;
-
- static mybitrev(val)
- unsigned int val;
- {
- val = ((val>>4 )&0x0f)|((val<<4 )&0xf0);
- val = ((val>>2 )&0x33)|((val<<2 )&0xcc);
- val = ((val>>1 )&0x55)|((val<<1 )&0xaa);
- return val&0xff;
- }
-
- void beginstroke()
- {
- float dx, dy;
-
- bloffset = mybitrev(stoff++);
- dx = fclonedx+eclonedx;
- dy = fclonedy+eclonedy;
- clonedx = round(dx);
- clonedy = round(dy);
- eclonedx = dx-clonedx;
- eclonedy = dy-clonedy;
- }
-
- void endstroke()
- {
- }
-
- void setnegalpha(v)
- int v;
- {
- negalpha = v;
- }
-
- void setclonemode(c)
- {
- clonemode = c;
- }
-
- /*
- * color handling
- *
- */
- void setcurcolor(c)
- unsigned long c;
- {
- unsigned char *curc, *chro;
- int b, hb;
-
- if(c != curcolor) {
- curcolor = c;
- curc = (unsigned char *)&curcolor;
- curlum = MYLUM(curc[OFFSET_R],curc[OFFSET_G],curc[OFFSET_B]);
- chro = (unsigned char *)&curchroma;
- b = curc[OFFSET_R];
- if(curc[OFFSET_G]>b)
- b = curc[OFFSET_G];
- if(curc[OFFSET_B]>b)
- b = curc[OFFSET_B];
- if(b == 0)
- b = 1;
- hb = b>>1;
- chro[OFFSET_R] = (255*curc[OFFSET_R]+hb)/b;
- chro[OFFSET_G] = (255*curc[OFFSET_G]+hb)/b;
- chro[OFFSET_B] = (255*curc[OFFSET_B]+hb)/b;
- chromatab = 0;
- }
- }
-
- unsigned long getcurcolor()
- {
- return curcolor;
- }
-
- static makechromatab()
- {
- int i, h, clum;
- int r, g, b, a, bloff;
- unsigned char *cptr;
- unsigned char *curc;
-
- if(!chromatable)
- chromatable = (unsigned long *)mymalloc(256*sizeof(long));
- cptr = (unsigned char *)chromatable;
- curc = (unsigned char *)&curcolor;
- r = curc[OFFSET_R];
- g = curc[OFFSET_G];
- b = curc[OFFSET_B];
- clum = curlum;
- h = clum/2;
- bloff = 127;
- for(i=0; i<256; i++) {
- if(i<clum) {
- cptr[OFFSET_R] = (i*r+h)/clum;
- cptr[OFFSET_G] = (i*g+h)/clum;
- cptr[OFFSET_B] = (i*b+h)/clum;
- } else {
- a = PA((256*(i-clum)/(255.0-clum))+0.49);
- cptr[OFFSET_R] = NLERP(r,255,a);
- cptr[OFFSET_G] = NLERP(g,255,a);
- cptr[OFFSET_B] = NLERP(b,255,a);
- }
- cptr+=4;
- }
- chromatab = chromatable;
- }
-
- /*
- * averaging functions follow
- *
- */
- void avg_clear()
- {
- ar = 0;
- ag = 0;
- ab = 0;
- adiv = 0;
- }
-
- long avg_get()
- {
- if(adiv == 0)
- return 0x808080;
- ar = (255*ar)/adiv;
- ag = (255*ag)/adiv;
- ab = (255*ab)/adiv;
- return ((ab<<16)+(ag<<8)+(ar<<0));
- }
-
- #define SETDPTR() dptr = (unsigned char*)&dest->data[x+y*dest->xsize]
- #define SETDMAX() dmax = dptr+n*sizeof(long);
- #define SETCOLDMAX() dmax = dptr+n*xsize;
- #define SETBLOFF() bloff = bloffset;
- #define SETCURC() curc = (unsigned char *)&curcolor; \
- cr = curc[OFFSET_R]; \
- cg = curc[OFFSET_G]; \
- cb = curc[OFFSET_B];
-
- static void avg_constblendrow(dest,a,x,y,n,clip)
- canvas *dest;
- short a;
- int x, y, n, clip;
- {
- unsigned char *dptr, *dmax, *mat;
- unsigned long lar, lag, lab, ladiv;
- int bloff;
-
- CLIPROW(dest,x,y,n,mat);
- lar = lag = lab = 0;
- ladiv = 255*n;
- SETBLOFF();
- SETDPTR();
- SETDMAX();
- while(dptr != dmax) {
- lar += dptr[OFFSET_R];
- lag += dptr[OFFSET_G];
- lab += dptr[OFFSET_B];
- dptr += 4;
- }
- ar += (a*lar+bloff)>>8;
- ag += (a*lag+bloff)>>8;
- ab += (a*lab+bloff)>>8;
- adiv += (a*ladiv+bloff)>>8;
- }
-
- static void avg_blendrow(dest,mat,x,y,n,clip)
- canvas *dest;
- unsigned char *mat;
- int x, y, n, clip;
- {
- unsigned char *dptr, *dmax;
- int bloff, a;
- unsigned long lar, lag, lab, ladiv;
-
- CLIPROW(dest,x,y,n,mat);
- lar = lag = lab = ladiv = 0;
- SETBLOFF();
- SETDPTR();
- SETDMAX();
- while(dptr != dmax) {
- a = PA(*mat++);
- if(a) {
- lar += (a*dptr[OFFSET_R]+bloff)>>8;
- lag += (a*dptr[OFFSET_G]+bloff)>>8;
- lab += (a*dptr[OFFSET_B]+bloff)>>8;
- ladiv += a;
- }
- dptr += sizeof(long);
- }
- ar += lar;
- ag += lag;
- ab += lab;
- adiv += ladiv;
- }
-
- static void avg_blendcol(dest,mat,x,y,n,clip)
- canvas *dest;
- unsigned char *mat;
- int x, y, n, clip;
- {
- unsigned char *dptr, *dmax;
- int bloff, a, xsize;
- unsigned long lar, lag, lab, ladiv;
-
- CLIPCOL(dest,x,y,n,mat);
- lar = lag = lab = ladiv = 0;
- xsize = dest->xsize*sizeof(long);
- SETBLOFF();
- SETDPTR();
- SETCOLDMAX();
- while(dptr != dmax) {
- a = PA(*mat++);
- if(a) {
- lar += (a*dptr[OFFSET_R]+bloff)>>8;
- lag += (a*dptr[OFFSET_G]+bloff)>>8;
- lab += (a*dptr[OFFSET_B]+bloff)>>8;
- ladiv += a;
- }
- dptr += xsize;
- }
- ar += lar;
- ag += lag;
- ab += lab;
- adiv += ladiv;
- }
-
- /*
- * rgb blending functions follow
- *
- *
- */
- static void rgb_constblendrow(dest,a,x,y,n,clip)
- canvas *dest;
- short a;
- int x, y, n, clip;
- {
- unsigned char *curc, *dptr, *dmax, *mat;
- int v, cr, cg, cb, ma, bloff;
-
- CLIPROW(dest,x,y,n,mat);
- if(clonemode) {
- writepix_constblendrow(dest,a,x,y,n);
- return;
- }
- SETBLOFF();
- SETCURC();
- SETDPTR();
- SETDMAX();
- if(negalpha) {
- a = PA(-a);
- while(dptr != dmax) {
- XBLEND(dptr,cr,cg,cb,a);
- dptr += sizeof(long);
- }
- } else {
- a = PA(a);
- ma = MA(a);
- cr = (a * curc[OFFSET_R])+bloff;
- cg = (a * curc[OFFSET_G])+bloff;
- cb = (a * curc[OFFSET_B])+bloff;
- while(dptr != dmax) {
- CBLEND(dptr,cr,cg,cb,ma);
- dptr += sizeof(long);
- }
- }
- }
-
- static void rgb_blendrow(dest,mat,x,y,n,clip)
- canvas *dest;
- unsigned char *mat;
- int x, y, n, clip;
- {
- unsigned char *curc, *dptr, *dmax;
- int a, v, cr, cg, cb, bloff;
-
- CLIPROW(dest,x,y,n,mat);
- if(clonemode) {
- writepix_blendrow(dest,mat,x,y,n);
- return;
- }
- SETBLOFF();
- SETCURC();
- SETDPTR();
- SETDMAX();
- if(negalpha) {
- while(dptr != dmax) {
- a = PA(-(*mat++));
- if(a)
- XBLEND(dptr,cr,cg,cb,a);
- dptr += sizeof(long);
- }
- } else {
- while(dptr != dmax) {
- a = PA(*mat++);
- if(a)
- NBLEND(dptr,cr,cg,cb,a);
- dptr += sizeof(long);
- }
- }
- }
-
- static void rgb_blendcol(dest,mat,x,y,n,clip)
- canvas *dest;
- unsigned char *mat;
- int x, y, n, clip;
- {
- unsigned char *curc, *dptr, *dmax;
- int a, v, cr, cg, cb, xsize, bloff;
-
- CLIPCOL(dest,x,y,n,mat);
- if(clonemode) {
- writepix_blendcol(dest,mat,x,y,n);
- return;
- }
- xsize = dest->xsize*sizeof(long);
- SETBLOFF();
- SETCURC();
- SETDPTR();
- SETCOLDMAX();
- if(negalpha) {
- while(dptr != dmax) {
- a = PA(-((int)(*mat++)));
- if(a)
- XBLEND(dptr,cr,cg,cb,a);
- dptr += xsize;
- }
- } else {
- while(dptr != dmax) {
- a = PA(*mat++);
- if(a)
- NBLEND(dptr,cr,cg,cb,a);
- dptr += xsize;
- }
- }
- }
-
- /*
- * chroma blending functions follow
- *
- *
- */
- static void chroma_constblendrow(dest,a,x,y,n,clip)
- canvas *dest;
- short a;
- int x, y, n, clip;
- {
- unsigned char *curc, *dptr, *dmax, *mat;
- int ld, r, g, b, bloff;
-
- CLIPROW(dest,x,y,n,mat);
- if(clonemode) {
- writepix_constblendrow(dest,a,x,y,n);
- return;
- }
- if(!chromatab)
- makechromatab();
- SETBLOFF();
- SETDPTR();
- SETDMAX();
- if(negalpha) {
- a = PA(-a);
- while(dptr != dmax) {
- XCHROMABLEND();
- dptr += sizeof(long);
- }
- } else {
- while(dptr != dmax) {
- NCHROMABLEND();
- dptr += sizeof(long);
- }
- }
- }
-
- static void chroma_blendrow(dest,mat,x,y,n,clip)
- canvas *dest;
- unsigned char *mat;
- int x, y, n, clip;
- {
- unsigned char *curc, *dptr, *dmax;
- int a, ld, r, g, b, bloff;
-
- CLIPROW(dest,x,y,n,mat);
- if(clonemode) {
- writepix_blendrow(dest,mat,x,y,n);
- return;
- }
- if(!chromatab)
- makechromatab();
- SETBLOFF();
- SETDPTR();
- SETDMAX();
- if(negalpha) {
- while(dptr != dmax) {
- a = PA(-((int)*mat++));
- if(a)
- XCHROMABLEND();
- dptr += sizeof(long);
- }
- } else {
- while(dptr != dmax) {
- a = PA(*mat++);
- if(a)
- NCHROMABLEND();
- dptr += sizeof(long);
- }
- }
- }
-
- static void chroma_blendcol(dest,mat,x,y,n,clip)
- canvas *dest;
- unsigned char *mat;
- int x, y, n, clip;
- {
- unsigned char *curc, *dptr, *dmax;
- int a, ld, r, g, b, xsize, bloff;
-
- CLIPCOL(dest,x,y,n,mat);
- if(clonemode) {
- writepix_blendcol(dest,mat,x,y,n);
- return;
- }
- if(!chromatab)
- makechromatab();
- xsize = dest->xsize*sizeof(long);
- SETBLOFF();
- SETDPTR();
- SETCOLDMAX();
- if(negalpha) {
- while(dptr != dmax) {
- a = PA(-((int)*mat++));
- if(a)
- XCHROMABLEND();
- dptr += xsize;
- }
- } else {
- while(dptr != dmax) {
- a = PA(*mat++);
- if(a)
- NCHROMABLEND();
- dptr += xsize;
- }
- }
- }
-
- /*
- * darker blend follows
- *
- */
- static void darker_constblendrow(dest,a,x,y,n,clip)
- canvas *dest;
- short a;
- int x, y, n, clip;
- {
- unsigned char *curc, *dptr, *dmax, *mat;
- int cl, cr, cg, cb, bloff;
-
- CLIPROW(dest,x,y,n,mat);
- if(clonemode) {
- writepix_constblendrow(dest,a,x,y,n);
- return;
- }
- cl = curlum;
- a = PA(a);
- SETBLOFF();
- SETCURC();
- SETDPTR();
- SETDMAX();
- while(dptr != dmax) {
- NONDARKERBLEND();
- dptr += sizeof(long);
- }
- }
-
- static void darker_blendrow(dest,mat,x,y,n,clip)
- canvas *dest;
- unsigned char *mat;
- int x, y, n, clip;
- {
- unsigned char *curc, *dptr, *dmax;
- int a, ma, cl, cr, cg, cb, bloff;
-
- CLIPROW(dest,x,y,n,mat);
- if(clonemode) {
- writepix_blendrow(dest,mat,x,y,n);
- return;
- }
- cl = curlum;
- SETBLOFF();
- SETCURC();
- SETDPTR();
- SETDMAX();
- while(dptr != dmax) {
- a = PA(*mat++);
- if(a)
- NONDARKERBLEND();
- dptr += sizeof(long);
- }
- }
-
- static void darker_blendcol(dest,mat,x,y,n,clip)
- canvas *dest;
- unsigned char *mat;
- int x, y, n, clip;
- {
- unsigned char *curc, *dptr, *dmax;
- int a, cl, cr, cg, cb, xsize, bloff;
-
- CLIPCOL(dest,x,y,n,mat);
- if(clonemode) {
- writepix_blendcol(dest,mat,x,y,n);
- return;
- }
- xsize = dest->xsize*sizeof(long);
- cl = curlum;
- SETBLOFF();
- SETCURC();
- SETDPTR();
- SETCOLDMAX();
- while(dptr != dmax) {
- a = PA(*mat++);
- if(a)
- NONDARKERBLEND();
- dptr += xsize;
- }
- }
-
- /*
- * lighter blend follows
- *
- */
- static void lighter_constblendrow(dest,a,x,y,n,clip)
- canvas *dest;
- short a;
- int x, y, n, clip;
- {
- unsigned char *curc, *dptr, *dmax, *mat;
- int cl, cr, cg, cb, bloff;
-
- CLIPROW(dest,x,y,n,mat);
- if(clonemode) {
- writepix_constblendrow(dest,a,x,y,n);
- return;
- }
- cl = curlum;
- a = PA(a);
- SETBLOFF();
- SETCURC();
- SETDPTR();
- SETDMAX();
- while(dptr != dmax) {
- NONLIGHTERBLEND();
- dptr += sizeof(long);
- }
- }
-
- static void lighter_blendrow(dest,mat,x,y,n,clip)
- canvas *dest;
- unsigned char *mat;
- int x, y, n ,clip;
- {
- unsigned char *curc, *dptr, *dmax;
- int a, cl, cr, cg, cb, bloff;
-
- CLIPROW(dest,x,y,n,mat);
- if(clonemode) {
- writepix_blendrow(dest,mat,x,y,n);
- return;
- }
- cl = curlum;
- SETBLOFF();
- SETCURC();
- SETDPTR();
- SETDMAX();
- while(dptr != dmax) {
- a = PA(*mat++);
- if(a)
- NONLIGHTERBLEND();
- dptr += sizeof(long);
- }
- }
-
- static void lighter_blendcol(dest,mat,x,y,n,clip)
- canvas *dest;
- unsigned char *mat;
- int x, y, n, clip;
- {
- unsigned char *curc, *dptr, *dmax;
- int a, ma, cl, cr, cg, cb, xsize, bloff;
-
- CLIPCOL(dest,x,y,n,mat);
- if(clonemode) {
- writepix_blendcol(dest,mat,x,y,n);
- return;
- }
- cl = curlum;
- xsize = dest->xsize*sizeof(long);
- SETBLOFF();
- SETCURC();
- SETDPTR();
- SETCOLDMAX();
- while(dptr != dmax) {
- a = PA(*mat++);
- if(a)
- NONLIGHTERBLEND();
- dptr += xsize;
- }
- }
-
- /*
- * writepix blend follows
- *
- */
- static unsigned char *getwritepixrow()
- {
- int n;
- unsigned char *lptr;
-
- n = *pixptr++;
- if(n == NOTHING)
- return 0;
- else {
- lptr = (unsigned char *)pixptr;
- pixptr += n;
- return lptr;
- }
- }
-
- static void writepix_constblendrow(dest,a,x,y,n)
- canvas *dest;
- short a;
- int x, y, n;
- {
- unsigned char *dptr, *dmax, *sptr;
- int v, bloff;
-
- sptr = getwritepixrow();
- if(!sptr)
- return;
- SETBLOFF();
- SETDPTR();
- SETDMAX();
- if(negalpha) {
- a = PA(-a);
- while(dptr != dmax) {
- XBLEND(dptr,sptr[OFFSET_R],sptr[OFFSET_G],sptr[OFFSET_B],a);
- sptr += sizeof(long);
- dptr += sizeof(long);
- }
- } else {
- a = PA(a);
- while(dptr != dmax) {
- NBLEND(dptr,sptr[OFFSET_R],sptr[OFFSET_G],sptr[OFFSET_B],a);
- sptr += sizeof(long);
- dptr += sizeof(long);
- }
- }
- }
-
- static void writepix_blendrow(dest,mat,x,y,n)
- canvas *dest;
- unsigned char *mat;
- int x, y, n;
- {
- unsigned char *dptr, *dmax, *sptr;
- int a, v, bloff;
-
- sptr = getwritepixrow();
- if(!sptr)
- return;
- SETBLOFF();
- SETDPTR();
- SETDMAX();
- if(negalpha) {
- while(dptr != dmax) {
- a = PA(-((int)(*mat++)));
- if(a)
- XBLEND(dptr,sptr[OFFSET_R],sptr[OFFSET_G],sptr[OFFSET_B],a);
- sptr += sizeof(long);
- dptr += sizeof(long);
- }
- } else {
- while(dptr != dmax) {
- a = PA(*mat++);
- if(a)
- NBLEND(dptr,sptr[OFFSET_R],sptr[OFFSET_G],sptr[OFFSET_B],a);
- sptr += sizeof(long);
- dptr += sizeof(long);
- }
- }
- }
-
- static void writepix_blendcol(dest,mat,x,y,n)
- canvas *dest;
- unsigned char *mat;
- int x, y, n;
- {
- unsigned char *dptr, *dmax, *sptr;
- int a, v, xsize, bloff;
-
- sptr = getwritepixrow();
- if(!sptr)
- return;
- xsize = dest->xsize*sizeof(long);
- SETBLOFF();
- SETDPTR();
- SETCOLDMAX();
- if(negalpha) {
- while(dptr != dmax) {
- a = PA(-((int)(*mat++)));
- if(a)
- XBLEND(dptr,sptr[OFFSET_R],sptr[OFFSET_G],sptr[OFFSET_B],a);
- sptr += sizeof(long);
- dptr += xsize;
- }
- } else {
- while(dptr != dmax) {
- a = PA(*mat++);
- if(a)
- NBLEND(dptr,sptr[OFFSET_R],sptr[OFFSET_G],sptr[OFFSET_B],a);
- sptr += sizeof(long);
- dptr += xsize;
- }
- }
- }
-
- /*
- * readpix stuff follows
- *
- *
- */
- void clonesource(c,dx,dy)
- canvas *c;
- float dx, dy;
- {
- clonesrc = c;
- fclonedx = dx;
- fclonedy = dy;
- }
-
- void readpix_init()
- {
- if(!pixdata)
- pixdata = (long *)mymalloc(DATLEN*sizeof(long));
- pixptr = pixdata;
- }
-
- static int addnothing()
- {
- *pixptr++ = NOTHING;
- }
-
- static saverow(x,y,n)
- int x, y, n;
- {
- x += clonedx;
- y += clonedy;
- if(!clonesrc || x<0 || x+n>=clonesrc->xsize) {
- addnothing();
- return;
- }
- if(y<0 || y>=clonesrc->ysize) {
- addnothing();
- return;
- }
- *pixptr++ = n;
- bcopy(clonesrc->data+(y*clonesrc->xsize+x),pixptr,n*sizeof(long));
- pixptr += n;
- }
-
- static savecol(x,y,n)
- int x, y, n;
- {
- unsigned long *lptr;
- int xsize;
-
- x += clonedx;
- y += clonedy;
- if(!clonesrc || x<0 || x>=clonesrc->xsize) {
- addnothing();
- return;
- }
- if(y<0 || y+n>=clonesrc->ysize) {
- addnothing();
- return;
- }
- *pixptr++ = n;
- lptr = clonesrc->data+(y*clonesrc->xsize+x);
- xsize = clonesrc->xsize;
- while(n--) {
- *pixptr++ = *lptr;
- lptr += xsize;
- }
- }
-
- static void readpix_constblendrow(dest,a,x,y,n,clip)
- canvas *dest;
- short a;
- int x, y, n, clip;
- {
- unsigned char *mat;
-
- CLIPROW(dest,x,y,n,mat);
- saverow(x,y,n);
- }
-
- static void readpix_blendrow(dest,mat,x,y,n,clip)
- canvas *dest;
- unsigned char *mat;
- int x, y, n, clip;
- {
- CLIPROW(dest,x,y,n,mat);
- saverow(x,y,n);
- }
-
- static void readpix_blendcol(dest,mat,x,y,n,clip)
- canvas *dest;
- unsigned char *mat;
- int x, y, n, clip;
- {
- CLIPCOL(dest,x,y,n,mat);
- savecol(x,y,n);
- }
-
- /*
- * general setblend function
- *
- *
- */
- void setblend(b)
- int b;
- {
- curb = b;
- switch(b) {
- case BLEND_AVGCOLOR:
- constblendrow = avg_constblendrow;
- blendrow = avg_blendrow;
- blendcol = avg_blendcol;
- break;
- case BLEND_RGB:
- constblendrow = rgb_constblendrow;
- blendrow = rgb_blendrow;
- blendcol = rgb_blendcol;
- break;
- case BLEND_CHROMA:
- constblendrow = chroma_constblendrow;
- blendrow = chroma_blendrow;
- blendcol = chroma_blendcol;
- break;
- case BLEND_DARKER:
- constblendrow = darker_constblendrow;
- blendrow = darker_blendrow;
- blendcol = darker_blendcol;
- break;
- case BLEND_LIGHTER:
- constblendrow = lighter_constblendrow;
- blendrow = lighter_blendrow;
- blendcol = lighter_blendcol;
- break;
- case BLEND_READPIX:
- constblendrow = readpix_constblendrow;
- blendrow = readpix_blendrow;
- blendcol = readpix_blendcol;
- break;
- }
- }
-
- int getblend()
- {
- return curb;
- }
-