/** * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. * * The Original Code is: all of this file. * * Contributor(s): none yet. * * ***** END GPL LICENSE BLOCK ***** */ #include #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", NUM|INT, "debug", 0.0, 0.0, 2.0, "0:off 1: show primary blur buffer 2: show 2nd blur buffer", }; /* 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; int show; } 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) { } 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; /* This doesn't seem to work... paprmh */ 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; } } /* this doesn't seem to work...paprmh*/ if(cast->gamma != 1.0) gamwarp(tbuf, 1.0 / cast->gamma); if(ibuf->rect)memcpy(ibuf->rect, tbuf->rect, 4*ibuf->x*ibuf->y); if(ibuf->rect_float) memcpy(ibuf->rect_float, tbuf->rect_float, 4*ibuf->x*ibuf->y*sizeof(float)); freeImBuf(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, infac; int n, b1, b2; char *irect, *prect, *mrect; float *irectf, *prectf, *mrectf; /* which 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= (fac-pfac)/(ifac-pfac); n= mbuf->x*mbuf->y; if(cast->show) fac=cast->show-1; if(mbuf->rect_float){ if(fac>=1) { memcpy(mbuf->rect_float, ibuf->rect_float, 4*n*sizeof(float)); } else if(fac<=0) { memcpy(mbuf->rect_float, pbuf->rect_float, 4*n*sizeof(float)); } else { /* interpolate */ infac= 1-fac; irectf= (float *)ibuf->rect_float; prectf= (float *)pbuf->rect_float; mrectf= (float *)mbuf->rect_float; while(n--) { mrectf[0]= irectf[0]*fac+ prectf[0]*infac; mrectf[1]= irectf[1]*fac+ prectf[1]*infac; mrectf[2]= irectf[2]*fac+ prectf[2]*infac; mrectf[3]= irectf[3]*fac+ prectf[3]*infac; mrectf+= 4; irectf+= 4; prectf+= 4; } } } else if(mbuf->rect){ b1= (int)fac*255.0; if(b1>255) b1= 255; b2= 255-b1; if(b1==255) { memcpy(mbuf->rect, ibuf->rect, 4*n); } else if(b1==0) { memcpy(mbuf->rect, pbuf->rect, 4*n); } else { /* interpolate */ 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; } if(out->rect) memcpy(out->rect, ibuf1->rect, 4*out->x*out->y); if(out->rect_float) memcpy(out->rect_float, ibuf1->rect_float, 4*out->x*out->y*sizeof(float)); /****************I can't get this field code to work... works ok without...paprmh****************/ /* it blurs interlaced, only tested with even fields */ /* de_interlace(out);*/ /* otherwise scaling goes wrong */ /* out->flags &= ~IB_fields;*/ doblur(out, bfacf0, cast); /*fieldA*/ /* if(out->rect)out->rect += out->x * out->y; if(out->rect_float)out->rect_float += out->x * out->y; doblur(out, bfacf1, cast);*/ /*fieldB*/ /* if(out->rect)out->rect -= out->x * out->y; if(out->rect_float)out->rect_float -= out->x * out->y; out->flags |= IB_fields; interlace(out);*/ }