/* * Copyright (c) 1999, Not a Number / NeoGeo b.v. * */ #include "plugin.h" /* ******************** GLOBAL VARIABLES ***************** */ char name[24]= "Blur"; /* structure for buttons, * butcode name default min max 0 */ VarStruct varstr[]= { LABEL, "Input: 1 strip", 0.0, 0.0, 0.0, "", NUMSLI|FLO, "Blur", 0.5, 0.0, 10.0, "Maximum filtersize", NUMSLI|FLO, "Gamma", 1.0, 0.4, 2.0, "Gamma correction", TOG|INT, "Animated", 0.0, 0.0, 1.0, "For (Ipo) animated blur", }; /* The cast struct is for input in the main doit function Varstr and Cast must have the same variables in the same order */ typedef struct Cast { int dummy; /* because of the 'label' button */ float blur; float gamma; float use_ipo; } Cast; /* cfra: the current frame */ float cfra; void plugin_seq_doit(Cast *, float, float, int, int, ImBuf *, ImBuf *, ImBuf *, ImBuf *); /* ******************** Fixed functions ***************** */ int plugin_seq_getversion(void) { return B_PLUGIN_VERSION; } void plugin_but_changed(int but) { } void plugin_init() { } void plugin_getinfo(PluginInfo *info) { info->name= name; info->nvars= sizeof(varstr)/sizeof(VarStruct); info->cfra= &cfra; info->varstr= varstr; info->init= plugin_init; info->seq_doit= (SeqDoit) plugin_seq_doit; info->callback= plugin_but_changed; } void blurbuf(struct ImBuf *ibuf, int nr, Cast *cast) { /* nr = number of blurs */ /* the ibuf->rect is replaced */ struct ImBuf *tbuf, *ttbuf; int i, x4; tbuf= dupImBuf(ibuf); x4= ibuf->x/4; if(cast->gamma != 1.0) gamwarp(tbuf, cast->gamma); /* reduce */ for(i=0; ix<4 || tbuf->y<4) break; } /* enlarge */ for(i=0; ix > x4) { scaleImBuf(tbuf, ibuf->x, ibuf->y); break; } } if(cast->gamma != 1.0) gamwarp(tbuf, 1.0 / cast->gamma); freeN(ibuf->rect); ibuf->rect= tbuf->rect; freeN(tbuf); } void doblur(struct ImBuf *mbuf, float fac, Cast *cast) { /* make two filtered images, like a mipmap structure * fac is filtersize in pixels */ struct ImBuf *ibuf, *pbuf; float ifac, pfac; int n, b1, b2; char *irect, *prect, *mrect; /* wich buffers ? */ if(fac>7.0) fac= 7.0; if(fac<=1.0) return; pfac= 2.0; pbuf= dupImBuf(mbuf); n= 1; while(pfac < fac) { blurbuf(pbuf, n, cast); blurbuf(pbuf, n, cast); n++; pfac+= 1.0; } ifac= pfac; pfac-= 1.0; ibuf= dupImBuf(pbuf); blurbuf(ibuf, n, cast); blurbuf(ibuf, n, cast); fac= 255.0*(fac-pfac)/(ifac-pfac); b1= fac; if(b1>255) b1= 255; b2= 255-b1; if(b1==255) { memcpy(mbuf->rect, ibuf->rect, 4*ibuf->x*ibuf->y); } else if(b1==0) { memcpy(mbuf->rect, pbuf->rect, 4*pbuf->x*pbuf->y); } else { /* interpolate */ n= ibuf->x*ibuf->y; irect= (char *)ibuf->rect; prect= (char *)pbuf->rect; mrect= (char *)mbuf->rect; while(n--) { mrect[0]= (irect[0]*b1+ prect[0]*b2)>>8; mrect[1]= (irect[1]*b1+ prect[1]*b2)>>8; mrect[2]= (irect[2]*b1+ prect[2]*b2)>>8; mrect[3]= (irect[3]*b1+ prect[3]*b2)>>8; mrect+= 4; irect+= 4; prect+= 4; } } freeImBuf(ibuf); freeImBuf(pbuf); } void plugin_seq_doit(Cast *cast, float facf0, float facf1, int x, int y, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *out, ImBuf *use) { float bfacf0, bfacf1; if(cast->use_ipo==0) { bfacf0= bfacf1= cast->blur+1.0; } else { bfacf0 = (facf0 * 6.0) + 1.0; bfacf1 = (facf1 * 6.0) + 1.0; } memcpy(out->rect, ibuf1->rect, 4*out->x*out->y); /* it blurs interlaced, only tested with even fields */ de_interlace(out); /* otherwise scaling goes wrong */ out->flags &= ~IB_fields; doblur(out, bfacf0, cast); /*fieldA*/ out->rect += out->x * out->y; doblur(out, bfacf1, cast); /*fieldB*/ out->rect -= out->x * out->y; out->flags |= IB_fields; interlace(out); }