/* This file is part of "life", a Filter plugin for Adobe Photoshop Copyright (C) 2003-6 Toby Thain, toby@telegraphics.com.au 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Photoshop filter implementing Conway's Life cellular automaton. */ #include "world.h" #include "PIFilter.h" OSErr process(FilterRecordPtr pb); OSErr process(FilterRecordPtr pb){ unsigned char *inrow,*outrow,*inp,*outp; int i,j,n,ncols = pb->inRect.right - pb->inRect.left, nrows = pb->inRect.bottom - pb->inRect.top, pl=pb->planes; long rb=pb->inRowBytes,t,ticks = TICKCOUNT(); for(inrow=pb->inData,outrow=pb->outData,j=0 ; joutRowBytes,++j){ /* handle coordinate wraparound at top and bottom of image */ long yprev = j ? -rb : (nrows-1)*rb, ynext = j==nrows-1 ? -(nrows-1)*rb : rb; for(inp=inrow,outp=outrow,i=0 ; i>7) + (inp[yprev]>>7) + (inp[xnext+yprev]>>7) + (inp[xprev]>>7) + (inp[xnext]>>7) + (inp[xprev+ynext]>>7) + (inp[ynext]>>7) + (inp[xnext+ynext]>>7); if(pl==3){ outp[2] = outp[1]; // copy Green to Blue (T-2) outp[1] = outp[0]; // copy Red to Green (T-1) } /* next cell state: if 2 neighbours, cell is unchanged if 3 neighbours, it's a birth otherwise, it dies. */ outp[0] = n==2 ? -(inp[0]>>7) : -(n==3); // compute generation T } if((t = TICKCOUNT()) > ticks){ ticks = t + TICKS_SEC/4; /* check every 1/4 sec */ /* allow user to cancel */ if (pb->abortProc()) return userCanceledErr; else /* report progress */ pb->progressProc(j + pb->inRect.top - pb->filterRect.top, pb->filterRect.bottom - pb->filterRect.top); } } return noErr; }