/** * $Id:$ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * The contents of this file may be used under the terms of either the GNU * General Public License Version 2 or later (the "GPL", see * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or * later (the "BL", see http://www.blender.org/BL/ ) which has to be * bought from the Blender Foundation to become active, in which case the * above mentioned GPL option does not apply. * * The Original Code is Copyright (C) 1997 by Ton Roosendaal, Frank van Beek and Joeri Kassenaar. * All rights reserved. * * The Original Code is: all of this file. * * Contributor(s): none yet. * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ /* inbetween.c aug 93 */ #include #include #include #include #include #include #include /* codes is werkbuffer: * 1: pixel binnen in vorm 128: edge 129: edge zonder vector */ int sizex, sizey, transx, transy; void convertworktoibuf(ibuf, work) struct ImBuf *ibuf; uchar *work; { ulong x, y, *lp; uchar *cp; lp= ibuf->rect; cp= work; for(y=0; yy; y++) { for(x=0; xx; x++, lp++, cp++) { if(*cp==1) *lp= 0x808080; else if(*cp==128) *lp= 0xFFFFFF; else *lp= 0; } } } void drawvectorbuf(vbuf, work1, work2) float *vbuf; uchar *work1, *work2; { float vec[2], *fp; long win; int x, y; uchar *cp; prefsize(2*sizex, 2*sizey); win= winopen(vbuf); RGBmode(); gconfig(); cpack(0); clear(); ortho2(-0.5, (float)sizex-0.5, -0.5, (float)sizey-0.5); cp= work1; fp= vbuf; for(y=0; y=1.0) fac= 0.0; swapbuffers(); } winclose(win); } void initworkrect(work, ibuf) uchar *work; struct ImBuf *ibuf; { /* maak rect 1 kleur met edge en verwijder losstaande pixels */ ulong x, y, transp, *lp, num; uchar *cp, *cp0, *cp1; lp= ibuf->rect; cp= work; transp= *lp; for(y=0; yy; y++) { for(x=0; xx; x++, lp++, cp++) { if(*lp==transp) *cp= 0; else *cp= 1; } } /* losstaand verwijderen */ cp0= work; cp= cp0+ibuf->x; cp1= cp+ibuf->x; for(y=0; yy-2; y++) { for(x=0; xx-2; x++, cp0++, cp++, cp1++) { num= cp0[0]+cp0[1]+cp0[2]+cp[0]+cp[1]+cp[2]+cp1[0]+cp1[1]+cp1[2]; if(num==1 && cp[1]) cp[1]= 0; if(num==8 && cp[1]==0) cp[1]= 1; } cp0+=2; cp+=2; cp1+=2; } /* edge en losstaand verwijderen */ cp0= work; cp= cp0+ibuf->x; cp1= cp+ibuf->x; for(y=0; yy-2; y++) { for(x=0; xx-2; x++, cp0++, cp++, cp1++) { if(cp[1]) { num= cp0[1]+cp[0]+cp[1]+cp[2]+cp1[1]; num= (num>>7) + (num & 127); if(num<5) cp[1]= 128; } } cp0+=2; cp+=2; cp1+=2; } } void translatework(work) char *work; { int x, y, ofs; char *temp, *cp1, *cp2; ofs= sizex*transy+transx; temp= callocN(sizex*sizey, "translatework"); cp1= work; cp2= temp; for(y=0; y=0 && x+transx=0 && y+transymaxx1) maxx1= x; if(y>maxy1) maxy1= y; gemx1+= x; gemy1+= y; count++; } } } gemx1/= count; gemy1/= count; count= 0; cp= work2; for(y=0; ymaxx2) maxx2= x; if(y>maxy2) maxy2= y; gemx2+= x; gemy2+= y; count++; } } } gemx2/= count; gemy2/= count; transx= gemx2-gemx1; transy= gemy2-gemy1; } int walkdist(work1, work2, sx, sy, dx, dy) uchar *work1, *work2; int sx, sy, dx, dy; { /* - vertek vanuit work1[sy][sx]==EDGE * - alleen lopen als work1!=EDGE && (work1 XOR work2) * - stoppen als work2[y][x]==EDGE of dist>max * - bij diagonaal lopen ook pixels ernaast kijken: anders glipt ie er tussendoor! */ int distplus= 0, distmin= 0, wofs, val, sxo, syo, diag, max, getsecond; int firstnotedge, solminout=0, solplusout=0; uchar *wo1, *wo2; sxo= sx; syo= sy; if(dx!=0 && dy!=0) { max= 50; diag= 1; } else { max= 70; diag= 0; } /* eerst ene kant op */ wo1= work1+ sizex*sy+sx; wo2= work2+ sizex*sy+sx; wofs= sizex*dy+dx; val= 0; getsecond= 0; /* als eerste pixel van wandeling 'leeg' is, pas de tweede edge pakken */ firstnotedge= 0; while(distplus=sizex) break; else if(sx<0) break; if(sy>=sizey) break; else if(sy<0) break; if(firstnotedge==0) { if(*wo1 & 128); else { firstnotedge= 1; if(*wo1==0 && *wo2==0) { getsecond= 1; solplusout= 1; /* solution outside */ } } } if(*wo2 & 128) { if(getsecond==1) getsecond= 0; else { val= 1; break; } } else if(diag) { /* ernaast kijken */ if( (wo2[dx] & 128) || (wo2[dy*sizex] & 128) ) { if(getsecond==1) getsecond= 0; else { val= 1; break; } } } if(firstnotedge==1) { if(*wo1 && *wo2) break; /* verkeerde richting */ } sx+= dx; sy+= dy; wo1+= wofs; wo2+= wofs; distplus++; } if(val && distplus==0) return 0; if(val==0) distplus= 100; /* andere kant op */ sx= sxo; sy= syo; wo1= work1+ sizex*sy+sx; wo2= work2+ sizex*sy+sx; dx= -dx; dy= -dy; wofs= sizex*dy+dx; val= 0; getsecond= 0; firstnotedge= 0; while(distmin=sizex) break; else if(sx<0) break; if(sy>=sizey) break; else if(sy<0) break; if(firstnotedge==0) { if(*wo1 & 128); else { firstnotedge= 1; if(*wo1==0 && *wo2==0) { getsecond= 1; solminout= 1; /* solution outside */ } } } if(*wo2 & 128) { if(getsecond==1) getsecond= 0; else { val= 1; break; } } else if(diag) { /* ernaast kijken */ if( (wo2[dx] & 128) || (wo2[dy*sizex] & 128) ) { if(getsecond==1) getsecond= 0; else { val= 1; break; } } } if(firstnotedge==1) { if(*wo1 && *wo2) break; /* verkeerde richting */ } sx+= dx; sy+= dy; wo1+= wofs; wo2+= wofs; distmin++; } if(val==0) distmin= 100; if(solminout && solplusout) return 100; if(solminout && distplus!=100) return distplus; if(solplusout && distmin!=100) return (-distmin); if( distmin=0 && ny>=0 && nx0) { fp[0]= valx; fp[1]= valy; *count |= 2; count++; fp+= 2; nr--; } } void interpolscanfrombuf(fp, nr, count) float *fp; int nr; char *count; { float sx, sy, ex, ey, d, fac; sx= fp[-2]; sy= fp[-1]; ex= fp[2*nr]; ey= fp[2*nr+1]; fac=d= 1.0/(float)(nr+1); /* op fp-2 staat startwaarde, op fp+nr staat eindwaarde */ while(nr>0) { fp[0]= sx+ fac*(ex-sx); fp[1]= sy+ fac*(ey-sy); *count |= 2; count++; fac+= d; fp+=2; nr--; } } void middelvectors(frombuf, countbuf, sum) float *frombuf; char *countbuf; int sum; { float *fp1, *fp2, *fp3, div, fx, fy; int x, y; char *cp1, *cp2, *cp3; fp1= frombuf; fp2= fp1+2*sizex; fp3= fp2+2*sizex; cp1= countbuf; cp2= cp1+sizex; cp3= cp2+sizex; for(y=1; y=0 && ny>=0 && nx0) accumfrombuf(dx, dy, cp2-1, fp2-2, 4); if(nx>1) accumfrombuf(dx, dy, cp2-2, fp2-4, 2); if(nx0) { cp2-= sizex; fp2-= 2*sizex; accumfrombuf(dx, dy, cp2, fp2, 4); if(nx>0) accumfrombuf(dx, dy, cp2-1, fp2-2, 2); if(nx1) accumfrombuf(dx, dy, cp2-2*sizex, fp2-4*sizex, 2); if(ny0) accumfrombuf(dx, dy, cp2-1, fp2-2, 2); if(nx0) accumfrombuf(dx, dy, cp2-1, fp2-2, 2); if(x0) { cp2-= sizex; fp2-= 2*sizex; accumfrombuf(dx, dy, cp2, fp2, 2); if(nx>0) accumfrombuf(dx, dy, cp2-1, fp2-2, 1); if(nx0) accumfrombuf(dx, dy, cp2-1, fp2-2, 1); if(nxrect; fp= frombuf; for(y=0; y=sizex) nx= sizex-1; if(ny<0) ny=0; else if(ny>=sizey) ny= sizey-1; ri= ibuf->rect+ ny*sizex+nx; *ro= *ri; } } } void blendbufs(orect, arect, fac) ulong *orect, *arect; float fac; { int f1, f2, x, y; char *cp1, *cp2; /* orect= a*orect+ (1-a)*arect */ f1= 255.5*fac; f2= 255-f1; for(y=0; y>8; cp1[2]= (f1*cp1[2]+f2*cp2[2])>>8; cp1[3]= (f1*cp1[3]+f2*cp2[3])>>8; } } } } void invertvectorbuf(buf, vectorbuf) float *buf, *vectorbuf; { float *fp1, *fp2; int x, y; fp1= vectorbuf; for(y=0; y= 3) { ibuf1 = loadiffname(argv[1], LI_rect); ibuf2 = loadiffname(argv[2],LI_rect); if(argc>3) ofs= atoi(argv[3]); } else { printf("usage: inbetween image1 image2\n"); exit(0); } if(ibuf1->x!=ibuf2->x || ibuf1->y!=ibuf2->y) { printf("Error: different image size\n"); exit(0); } ibuf1->ftype= TGA; freecmapImBuf(ibuf1); ibuf1->depth= 24; ibuf2->ftype= TGA; freecmapImBuf(ibuf2); ibuf2->depth= 24; obuf= dupImBuf(ibuf1); sizex= ibuf1->x; sizey= ibuf1->y; work1= mallocN(ibuf1->x*ibuf1->y, "work1"); work2= mallocN(ibuf1->x*ibuf1->y, "work2"); vectorbuf= mallocN(8*ibuf1->x*ibuf1->y, "vector"); frombuf= mallocN(8*ibuf1->x*ibuf1->y, "from"); initworkrect(work1, ibuf1); /* edgedetectie */ initworkrect(work2, ibuf2); find_main_translate(work1, work2); /* van plaatje 1 naar plaatje 2 *************** */ translatework(work1); /* goto inspring; */ makevectorbuf(vectorbuf, work1, work2, 0); /* drawvectorbuf(vectorbuf, work1, work2); */ /* exit(0); */ makefrombuf(vectorbuf, work1, frombuf); for(a=1; arect, abuf->rect, ((float)a)/(float)tweens); freeImBuf(abuf); saveiff(obuf, name, SI_rect); printf("saved %s\n", name); } if(a+ofs<10) sprintf(name, "/pics/test/inbetw/000%d", a+ofs); else if(a+ofs<100) sprintf(name, "/pics/test/inbetw/00%d", a+ofs); else sprintf(name, "/pics/test/inbetw/0%d", a+ofs); saveiff(ibuf2, name, SI_rect); freeN(work1); freeN(work2); freeN(vectorbuf); freeN(frombuf); }