947
947
rt[0]= rt1[0] + ((fac3*rt1[0]*(rt2[0]-256))>>16);
948
948
rt[1]= rt1[1] + ((fac3*rt1[1]*(rt2[1]-256))>>16);
949
949
rt[2]= rt1[2] + ((fac3*rt1[2]*(rt2[2]-256))>>16);
950
950
rt[3]= rt1[3] + ((fac3*rt1[3]*(rt2[3]-256))>>16);
952
952
rt1+= 4; rt2+= 4; rt+= 4;
957
// This function calculates the blur band for the wipe effects
958
float in_band(float width,float dist, float perc,int side,int dir){
960
float t1,t2,alpha,percwidth;
964
percwidth = width * perc;
966
percwidth = width * (1 - perc);
971
t1 = dist / width; //percentange of width that is
972
t2 = 1 / width; //amount of alpha per % point
975
alpha = (t1*t2*100) + (1-perc); // add point's alpha contrib to current position in wipe
977
alpha = (1-perc) - (t1*t2*100);
984
float check_zone(int x, int y, int xo, int yo, Sequence *seq, float facf0) {
986
float posx, posy,hyp,hyp2,angle,hwidth,b1,b2,b3,pointdist;
988
float hyp3,hyp4,b4,b5
990
float temp1,temp2,temp3,temp4; //some placeholder variables
993
float widthf,output=0;
994
WipeVars *wipe = (WipeVars *)seq->effectdata;
1002
angle = pow(fabs(angle)/45,log(xo)/log(2));
1009
posx = xo - facf0 * xo;
1010
posy = yo - facf0 * yo;
1012
switch (wipe->wipetype) {
1013
case DO_SINGLE_WIPE:
1014
width = (int)(wipe->edgeWidth*((xo+yo)/2.0));
1015
hwidth = (float)width/2.0;
1017
if (angle == 0.0)angle = 0.000001;
1018
b1 = posy - (-angle)*posx;
1019
b2 = y - (-angle)*x;
1020
hyp = fabs(angle*x+y+(-posy-angle*posx))/sqrt(angle*angle+1);
1028
output = in_band(width,hyp,facf0,1,1);
1030
output = in_band(width,hyp,facf0,0,1);
1034
output = in_band(width,hyp,facf0,0,1);
1036
output = in_band(width,hyp,facf0,1,1);
1041
case DO_DOUBLE_WIPE:
1042
if(!wipe->forward)facf0 = 1-facf0; // Go the other direction
1044
width = (int)(wipe->edgeWidth*((xo+yo)/2.0)); // calculate the blur width
1045
hwidth = (float)width/2.0;
1046
if (angle == 0)angle = 0.000001;
1047
b1 = posy/2 - (-angle)*posx/2;
1048
b3 = (yo-posy/2) - (-angle)*(xo-posx/2);
1049
b2 = y - (-angle)*x;
1051
hyp = abs(angle*x+y+(-posy/2-angle*posx/2))/sqrt(angle*angle+1);
1052
hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))/sqrt(angle*angle+1);
1054
temp1 = xo*(1-facf0/2)-xo*facf0/2;
1055
temp2 = yo*(1-facf0/2)-yo*facf0/2;
1056
pointdist = sqrt(temp1*temp1 + temp2*temp2);
1058
if(b2 < b1 && b2 < b3 ){
1059
if(hwidth < pointdist)
1060
output = in_band(hwidth,hyp,facf0,0,1);
1062
else if(b2 > b1 && b2 > b3 ){
1063
if(hwidth < pointdist)
1064
output = in_band(hwidth,hyp2,facf0,0,1);
1067
if( hyp < hwidth && hyp2 > hwidth )
1068
output = in_band(hwidth,hyp,facf0,1,1);
1069
else if( hyp > hwidth && hyp2 < hwidth )
1070
output = in_band(hwidth,hyp2,facf0,1,1);
1072
output = in_band(hwidth,hyp2,facf0,1,1) * in_band(hwidth,hyp,facf0,1,1);
1074
if(!wipe->forward)output = 1-output;
1078
temp1: angle of effect center in rads
1079
temp2: angle of line through (halfx,halfy) and (x,y) in rads
1080
temp3: angle of low side of blur
1081
temp4: angle of high side of blur
1084
widthf = wipe->edgeWidth*2*3.14159;
1085
temp1 = 2 * 3.14159 * facf0;
1088
temp1 = 2*3.14159-temp1;
1094
temp2 = asin(abs(y)/sqrt(x*x + y*y));
1095
if(x <= 0 && y >= 0)
1096
temp2 = 3.14159 - temp2;
1097
else if(x<=0 && y <= 0)
1099
else if(x >= 0 && y <= 0)
1100
temp2 = 2*3.14159 - temp2;
1103
temp3 = temp1-(widthf/2)*facf0;
1104
temp4 = temp1+(widthf/2)*(1-facf0);
1107
temp3 = temp1-(widthf/2)*(1-facf0);
1108
temp4 = temp1+(widthf/2)*facf0;
1110
if (temp3 < 0) temp3 = 0;
1111
if (temp4 > 2*3.14159) temp4 = 2*3.14159;
1116
else if (temp2 > temp4)
1119
output = (temp2-temp3)/(temp4-temp3);
1120
if(x == 0 && y == 0){
1123
if(output != output)
1126
output = 1 - output;
1128
/* BOX WIPE IS NOT WORKING YET */
1129
/* case DO_CROSS_WIPE: */
1130
/* BOX WIPE IS NOT WORKING YET */
1131
/* case DO_BOX_WIPE:
1132
if(invert)facf0 = 1-facf0;
1134
width = (int)(wipe->edgeWidth*((xo+yo)/2.0));
1135
hwidth = (float)width/2.0;
1136
if (angle == 0)angle = 0.000001;
1137
b1 = posy/2 - (-angle)*posx/2;
1138
b3 = (yo-posy/2) - (-angle)*(xo-posx/2);
1139
b2 = y - (-angle)*x;
1141
hyp = abs(angle*x+y+(-posy/2-angle*posx/2))/sqrt(angle*angle+1);
1142
hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))/sqrt(angle*angle+1);
1144
temp1 = xo*(1-facf0/2)-xo*facf0/2;
1145
temp2 = yo*(1-facf0/2)-yo*facf0/2;
1146
pointdist = sqrt(temp1*temp1 + temp2*temp2);
1148
if(b2 < b1 && b2 < b3 ){
1149
if(hwidth < pointdist)
1150
output = in_band(hwidth,hyp,facf0,0,1);
1152
else if(b2 > b1 && b2 > b3 ){
1153
if(hwidth < pointdist)
1154
output = in_band(hwidth,hyp2,facf0,0,1);
1157
if( hyp < hwidth && hyp2 > hwidth )
1158
output = in_band(hwidth,hyp,facf0,1,1);
1159
else if( hyp > hwidth && hyp2 < hwidth )
1160
output = in_band(hwidth,hyp2,facf0,1,1);
1162
output = in_band(hwidth,hyp2,facf0,1,1) * in_band(hwidth,hyp,facf0,1,1);
1164
if(invert)facf0 = 1-facf0;
1166
b1 = posy/2 - (-angle)*posx/2;
1167
b3 = (yo-posy/2) - (-angle)*(xo-posx/2);
1168
b2 = y - (-angle)*x;
1170
hyp = abs(angle*x+y+(-posy/2-angle*posx/2))/sqrt(angle*angle+1);
1171
hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))/sqrt(angle*angle+1);
1173
if(b2 < b1 && b2 < b3 ){
1174
if(hwidth < pointdist)
1175
output *= in_band(hwidth,hyp,facf0,0,1);
1177
else if(b2 > b1 && b2 > b3 ){
1178
if(hwidth < pointdist)
1179
output *= in_band(hwidth,hyp2,facf0,0,1);
1182
if( hyp < hwidth && hyp2 > hwidth )
1183
output *= in_band(hwidth,hyp,facf0,1,1);
1184
else if( hyp > hwidth && hyp2 < hwidth )
1185
output *= in_band(hwidth,hyp2,facf0,1,1);
1187
output *= in_band(hwidth,hyp2,facf0,1,1) * in_band(hwidth,hyp,facf0,1,1);
1192
if(xo > yo) yo = xo;
1198
width = (int)(wipe->edgeWidth*((xo+yo)/2.0));
1199
hwidth = (float)width/2.0;
1201
temp1 = (halfx-(halfx)*facf0);
1202
pointdist = sqrt(temp1*temp1 + temp1*temp1);
1204
temp2 = sqrt((halfx-x)*(halfx-x) + (halfy-y)*(halfy-y));
1205
if(temp2 > pointdist)
1206
output = in_band(hwidth,fabs(temp2-pointdist),facf0,0,1);
1208
output = in_band(hwidth,fabs(temp2-pointdist),facf0,1,1);
1215
if (output < 0) output = 0;
1216
else if(output > 1) output = 1;
1220
void init_wipe_effect(Sequence *seq)
1222
if(seq->effectdata)MEM_freeN(seq->effectdata);
1223
seq->effectdata = MEM_callocN(sizeof(struct WipeVars), "wipevars");
1226
void do_wipe_effect(Sequence *seq, float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out)
1229
char *rt1, *rt2, *rt;
1230
rt1 = (char *)rect1;
1231
rt2 = (char *)rect2;
1239
float check = check_zone(x,y,xo,yo,seq,facf0);
1242
rt[0] = (int)(rt1[0]*check)+ (int)(rt2[0]*(1-check));
1243
rt[1] = (int)(rt1[1]*check)+ (int)(rt2[1]*(1-check));
1244
rt[2] = (int)(rt1[2]*check)+ (int)(rt2[2]*(1-check));
1245
rt[3] = (int)(rt1[3]*check)+ (int)(rt2[3]*(1-check));
1277
/* Glow Functions */
1279
void RVBlurBitmap2 ( unsigned char* map, int width,int height,float blur,
1281
/* MUUUCCH better than the previous blur. */
1282
/* We do the blurring in two passes which is a whole lot faster. */
1283
/* I changed the math arount to implement an actual Gaussian */
1286
/* Watch out though, it tends to misbehaven with large blur values on */
1287
/* a small bitmap. Avoid avoid avoid. */
1288
/*=============================== */
1290
unsigned char* temp=NULL,*swap;
1293
int index, ix, halfWidth;
1294
float fval, k, curColor[3], curColor2[3], weight=0;
1296
/* If we're not really blurring, bail out */
1300
/* Allocate memory for the tempmap and the blur filter matrix */
1301
temp= MEM_mallocN( (width*height*4), "blurbitmaptemp");
1305
/* Allocate memory for the filter elements */
1306
halfWidth = ((quality+1)*blur);
1307
filter = (float *)MEM_mallocN(sizeof(float)*halfWidth*2, "blurbitmapfilter");
1313
/* Apparently we're calculating a bell curve */
1314
/* based on the standard deviation (or radius) */
1315
/* This code is based on an example */
1316
/* posted to comp.graphics.algorithms by */
1317
/* Blancmange (bmange@airdmhor.gen.nz) */
1319
k = -1.0/(2.0*3.14159*blur*blur);
1321
for (ix = 0;ix< halfWidth;ix++){
1322
weight = (float)exp(k*(ix*ix));
1323
filter[halfWidth - ix] = weight;
1324
filter[halfWidth + ix] = weight;
1328
/* Normalize the array */
1330
for (ix = 0;ix< halfWidth*2;ix++)
1333
for (ix = 0;ix< halfWidth*2;ix++)
1337
for (y=0;y<height;y++){
1338
/* Do the left & right strips */
1339
for (x=0;x<halfWidth;x++){
1340
index=(x+y*width)*4;
1342
curColor[0]=curColor[1]=curColor[2]=0;
1343
curColor2[0]=curColor2[1]=curColor2[2]=0;
1345
for (i=x-halfWidth;i<x+halfWidth;i++){
1346
if ((i>=0)&&(i<width)){
1347
curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
1348
curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
1349
curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
1351
curColor2[0]+=map[(width-1-i+y*width)*4+GlowR] *
1353
curColor2[1]+=map[(width-1-i+y*width)*4+GlowG] *
1355
curColor2[2]+=map[(width-1-i+y*width)*4+GlowB] *
1360
temp[index+GlowR]=curColor[0];
1361
temp[index+GlowG]=curColor[1];
1362
temp[index+GlowB]=curColor[2];
1364
temp[((width-1-x+y*width)*4)+GlowR]=curColor2[0];
1365
temp[((width-1-x+y*width)*4)+GlowG]=curColor2[1];
1366
temp[((width-1-x+y*width)*4)+GlowB]=curColor2[2];
1369
/* Do the main body */
1370
for (x=halfWidth;x<width-halfWidth;x++){
1371
index=(x+y*width)*4;
1373
curColor[0]=curColor[1]=curColor[2]=0;
1374
for (i=x-halfWidth;i<x+halfWidth;i++){
1375
curColor[0]+=map[(i+y*width)*4+GlowR]*filter[fx];
1376
curColor[1]+=map[(i+y*width)*4+GlowG]*filter[fx];
1377
curColor[2]+=map[(i+y*width)*4+GlowB]*filter[fx];
1380
temp[index+GlowR]=curColor[0];
1381
temp[index+GlowG]=curColor[1];
1382
temp[index+GlowB]=curColor[2];
1387
swap=temp;temp=map;map=swap;
1390
/* Blur the columns */
1391
for (x=0;x<width;x++){
1392
/* Do the top & bottom strips */
1393
for (y=0;y<halfWidth;y++){
1394
index=(x+y*width)*4;
1396
curColor[0]=curColor[1]=curColor[2]=0;
1397
curColor2[0]=curColor2[1]=curColor2[2]=0;
1398
for (i=y-halfWidth;i<y+halfWidth;i++){
1399
if ((i>=0)&&(i<height)){
1401
curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
1402
curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
1403
curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
1406
curColor2[0]+=map[(x+(height-1-i)*width) *
1407
4+GlowR]*filter[fy];
1408
curColor2[1]+=map[(x+(height-1-i)*width) *
1409
4+GlowG]*filter[fy];
1410
curColor2[2]+=map[(x+(height-1-i)*width) *
1411
4+GlowB]*filter[fy];
1415
temp[index+GlowR]=curColor[0];
1416
temp[index+GlowG]=curColor[1];
1417
temp[index+GlowB]=curColor[2];
1418
temp[((x+(height-1-y)*width)*4)+GlowR]=curColor2[0];
1419
temp[((x+(height-1-y)*width)*4)+GlowG]=curColor2[1];
1420
temp[((x+(height-1-y)*width)*4)+GlowB]=curColor2[2];
1422
/* Do the main body */
1423
for (y=halfWidth;y<height-halfWidth;y++){
1424
index=(x+y*width)*4;
1426
curColor[0]=curColor[1]=curColor[2]=0;
1427
for (i=y-halfWidth;i<y+halfWidth;i++){
1428
curColor[0]+=map[(x+i*width)*4+GlowR]*filter[fy];
1429
curColor[1]+=map[(x+i*width)*4+GlowG]*filter[fy];
1430
curColor[2]+=map[(x+i*width)*4+GlowB]*filter[fy];
1433
temp[index+GlowR]=curColor[0];
1434
temp[index+GlowG]=curColor[1];
1435
temp[index+GlowB]=curColor[2];
1441
swap=temp;temp=map;map=swap;
1449
/* Adds two bitmaps and puts the results into a third map. */
1450
/* C must have been previously allocated but it may be A or B. */
1451
/* We clamp values to 255 to prevent weirdness */
1452
/*=============================== */
1453
void RVAddBitmaps (unsigned char* a, unsigned char* b, unsigned char* c, int width, int height)
1457
for (y=0;y<height;y++){
1458
for (x=0;x<width;x++){
1459
index=(x+y*width)*4;
1460
c[index+GlowR]=MIN2(255,a[index+GlowR]+b[index+GlowR]);
1461
c[index+GlowG]=MIN2(255,a[index+GlowG]+b[index+GlowG]);
1462
c[index+GlowB]=MIN2(255,a[index+GlowB]+b[index+GlowB]);
1463
c[index+GlowA]=MIN2(255,a[index+GlowA]+b[index+GlowA]);
1468
/* For each pixel whose total luminance exceeds the threshold, */
1469
/* Multiply it's value by BOOST and add it to the output map */
1470
void RVIsolateHighlights (unsigned char* in, unsigned char* out, int width, int height, int threshold, float boost, float clamp)
1476
for(y=0;y< height;y++) {
1477
for (x=0;x< width;x++) {
1478
index= (x+y*width)*4;
1480
/* Isolate the intensity */
1481
intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold);
1483
out[index+GlowR]=MIN2(255*clamp, (in[index+GlowR]*boost*intensity)/255);
1484
out[index+GlowG]=MIN2(255*clamp, (in[index+GlowG]*boost*intensity)/255);
1485
out[index+GlowB]=MIN2(255*clamp, (in[index+GlowB]*boost*intensity)/255);
1496
void init_glow_effect(Sequence *seq)
1500
if(seq->effectdata)MEM_freeN(seq->effectdata);
1501
seq->effectdata = MEM_callocN(sizeof(struct GlowVars), "glowvars");
1503
glow = (GlowVars *)seq->effectdata;
1513
//void do_glow_effect(Cast *cast, float facf0, float facf1, int xo, int yo, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *outbuf, ImBuf *use)
1514
void do_glow_effect(Sequence *seq, float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out)
1516
unsigned char *outbuf=(unsigned char *)out;
1517
unsigned char *inbuf=(unsigned char *)rect1;
1518
GlowVars *glow = (GlowVars *)seq->effectdata;
1520
RVIsolateHighlights (inbuf, outbuf , x, y, glow->fMini*765, glow->fBoost, glow->fClamp);
1521
RVBlurBitmap2 (outbuf, x, y, glow->dDist,glow->dQuality);
1523
RVAddBitmaps (inbuf , outbuf, outbuf, x, y);
957
1526
void make_black_ibuf(ImBuf *ibuf)
959
1528
unsigned int *rect;
962
1531
if(ibuf==0 || ibuf->rect==0) return;
964
1533
tot= ibuf->x*ibuf->y;
965
1534
rect= ibuf->rect;
966
1535
while(tot--) *(rect++)= 0;
970
1539
void multibuf(ImBuf *ibuf, float fmul)
973
1542
int a, mul, icol;
975
1544
mul= (int)(256.0*fmul);
977
1546
a= ibuf->x*ibuf->y;
978
1547
rt= (char *)ibuf->rect;
981
1550
icol= (mul*rt[0])>>8;
982
1551
if(icol>254) rt[0]= 255; else rt[0]= icol;
983
1552
icol= (mul*rt[1])>>8;
1306
1883
if(seq->type==SEQ_IMAGE) {
1307
1884
if(se->ok && se->ibuf==0) {
1309
1886
/* if playanim or render: no waitcursor */
1310
1887
if((G.f & G_PLAYANIM)==0) waitcursor(1);
1312
strcpy(name, seq->strip->dir);
1313
strcat(name, se->name);
1889
strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
1890
strncat(name, se->name, FILE_MAXFILE);
1314
1891
BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
1315
1892
se->ibuf= IMB_loadiffname(name, IB_rect);
1317
1894
if((G.f & G_PLAYANIM)==0) waitcursor(0);
1319
1896
if(se->ibuf==0) se->ok= 0;
1321
if(se->ibuf->depth==32 && se->ibuf->zbuf==0) converttopremul(se->ibuf);
1898
if(seq->flag & SEQ_MAKE_PREMUL) {
1899
if(se->ibuf->depth==32 && se->ibuf->zbuf==0) converttopremul(se->ibuf);
1322
1901
seq->strip->orx= se->ibuf->x;
1323
1902
seq->strip->ory= se->ibuf->y;
1903
if(seq->flag & SEQ_FILTERY) IMB_filtery(se->ibuf);
1904
if(seq->mul==0.0) seq->mul= 1.0;
1905
if(seq->mul != 1.0) multibuf(se->ibuf, seq->mul);
1327
1909
else if(seq->type==SEQ_MOVIE) {
1328
1910
if(se->ok && se->ibuf==0) {
1330
1912
/* if playanim r render: no waitcursor */
1331
1913
if((G.f & G_PLAYANIM)==0) waitcursor(1);
1333
1915
if(seq->anim==0) {
1334
strcpy(name, seq->strip->dir);
1335
strcat(name, seq->strip->stripdata->name);
1916
strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
1917
strncat(name, seq->strip->stripdata->name, FILE_MAXFILE-1);
1336
1918
BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
1338
1920
seq->anim = openanim(name, IB_rect);
1340
1922
if(seq->anim) {
1341
1923
se->ibuf = IMB_anim_absolute(seq->anim, se->nr);
1344
1926
if(se->ibuf==0) se->ok= 0;
1346
if(se->ibuf->depth==32) converttopremul(se->ibuf);
1928
if(seq->flag & SEQ_MAKE_PREMUL) {
1929
if(se->ibuf->depth==32) converttopremul(se->ibuf);
1347
1931
seq->strip->orx= se->ibuf->x;
1348
1932
seq->strip->ory= se->ibuf->y;
1349
1933
if(seq->flag & SEQ_FILTERY) IMB_filtery(se->ibuf);
1350
1934
if(seq->mul==0.0) seq->mul= 1.0;
1351
1935
if(seq->mul != 1.0) multibuf(se->ibuf, seq->mul);
1353
if((G.f & G_PLAYANIM)==0) waitcursor(0);
1937
if((G.f & G_PLAYANIM)==0) waitcursor(0);
1356
else if(seq->type==SEQ_SCENE && se->ibuf==0) {
1940
else if(seq->type==SEQ_SCENE && se->ibuf==0 && seq->scene) { // scene can be NULL after deletions
1942
int redisplay= (!G.background && !(R.flag & R_RENDERING));
1359
1944
oldsce= G.scene;
1360
1945
set_scene_bg(seq->scene);
1362
1947
/* prevent eternal loop */
1363
1948
doseq= G.scene->r.scemode & R_DOSEQ;
1364
1949
G.scene->r.scemode &= ~R_DOSEQ;
1366
1951
/* store stuffies */
1367
1952
oldcfra= CFRA; CFRA= seq->sfra + se->nr;
1370
rectot= R.rectot; R.rectot= 0;
1955
rectot= R.rectot; R.rectot= NULL;
1371
1956
oldx= R.rectx; oldy= R.recty;
1372
1957
/* needed because current 3D window cannot define the layers, like in a background render */
1376
1961
RE_initrender(NULL);
1377
if (!G.background) {
1963
mainwindow_make_active();
1378
1964
if(R.r.mode & R_FIELDS) update_for_newframe_muted();
1381
1967
free_filesel_spec(G.scene->r.pic);