/* This file is part of "scramble", a filter plugin for Adobe Photoshop Copyright (C) 2006-9 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 */ #include "world.h" #include #include "scramble.h" OSErr process(FilterRecordPtr pb, struct params *p){ long t, ticks = TICKCOUNT(); int j, ncols = pb->outRect.right - pb->outRect.left, nrows = pb->outRect.bottom - pb->outRect.top, htiles, vtiles; unsigned long ntiles, dst, src; if(!p || p->tilew <= 0 || p->tilew > ncols || p->tileh <= 0 || p->tileh > nrows){ //dbg("bad tile size"); return filterBadParameters; }else{ char *buf = malloc(p->tilew*pb->planes), *out = pb->outData; htiles = ncols/p->tilew; vtiles = nrows/p->tileh; ntiles = htiles*vtiles; srand(ticks); // loop through each tile of the image, top to bottom, left to right for(dst = 0; dst < ntiles; ++dst){ int strip = p->tilew*pb->planes; // pick a random tile to swap with // FIXME: this produces visibly poor results if using Windows' // 15-bit RNG and relatively large tile counts. src = dst + (unsigned long)rand() % (ntiles-dst); if(src != dst){ int srccol = p->tilew*(src % htiles), srcrow = p->tileh*(src / htiles), dstcol = p->tilew*(dst % htiles), dstrow = p->tileh*(dst / htiles); // swap tile for(j = p->tileh; j--;){ // move source tile to our current tile memcpy(buf, out + pb->outRowBytes*(dstrow+j) + dstcol*pb->planes, strip); memcpy(out + pb->outRowBytes*(dstrow+j) + dstcol*pb->planes, out + pb->outRowBytes*(srcrow+j) + srccol*pb->planes, strip); // copy the original current tile where the source came from memcpy(out + pb->outRowBytes*(srcrow+j) + srccol*pb->planes, buf, strip); } } 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(dst, ntiles); } } free(buf); } return noErr; }