stevesketch
4/25/2016 - 8:40 AM

#Effects

void fastblur(PImage pp,int radius){
pp.loadPixels();
  if (radius<1){
    return;
  }
  int[] pix=pp.pixels;
  int w=pp.width;
  int h=pp.height;
  int wm=w-1;
  int hm=h-1;
  int wh=w*h;
  int div=radius+radius+1;

  int r[]=new int[wh];
  int g[]=new int[wh];
  int b[]=new int[wh];
  int rsum,gsum,bsum,x,y,i,p,yp,yi,yw;
  int vmin[] = new int[max(w,h)];

  int divsum=(div+1)>>1;
  divsum*=divsum;
  int dv[]=new int[256*divsum];
  for (i=0;i<256*divsum;i++){
    dv[i]=(i/divsum);
  }

  yw=yi=0;

  int[][] stack=new int[div][3];
  int stackpointer;
  int stackstart;
  int[] sir;
  int rbs;
  int r1=radius+1;
  int routsum,goutsum,boutsum;
  int rinsum,ginsum,binsum;

  for (y=0;y<h;y++){
    rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;
    for(i=-radius;i<=radius;i++){
      p=pix[yi+min(wm,max(i,0))];
      sir=stack[i+radius];
      sir[0]=(p & 0xff0000)>>16;
      sir[1]=(p & 0x00ff00)>>8;
      sir[2]=(p & 0x0000ff);
      rbs=r1-abs(i);
      rsum+=sir[0]*rbs;
      gsum+=sir[1]*rbs;
      bsum+=sir[2]*rbs;
      if (i>0){
        rinsum+=sir[0];
        ginsum+=sir[1];
        binsum+=sir[2];
      } else {
        routsum+=sir[0];
        goutsum+=sir[1];
        boutsum+=sir[2];
      }
    }
    stackpointer=radius;

    for (x=0;x<w;x++){

      r[yi]=dv[rsum];
      g[yi]=dv[gsum];
      b[yi]=dv[bsum];
      
      rsum-=routsum;
      gsum-=goutsum;
      bsum-=boutsum;

      stackstart=stackpointer-radius+div;
      sir=stack[stackstart%div];
      
      routsum-=sir[0];
      goutsum-=sir[1];
      boutsum-=sir[2];
      
      if(y==0){
        vmin[x]=min(x+radius+1,wm);
      }
      p=pix[yw+vmin[x]];
      
      sir[0]=(p & 0xff0000)>>16;
      sir[1]=(p & 0x00ff00)>>8;
      sir[2]=(p & 0x0000ff);

      rinsum+=sir[0];
      ginsum+=sir[1];
      binsum+=sir[2];

      rsum+=rinsum;
      gsum+=ginsum;
      bsum+=binsum;
      
      stackpointer=(stackpointer+1)%div;
      sir=stack[(stackpointer)%div];
     
      routsum+=sir[0];
      goutsum+=sir[1];
      boutsum+=sir[2];
     
       rinsum-=sir[0];
      ginsum-=sir[1];
      binsum-=sir[2];
     
       yi++;
    }
    yw+=w;
  }
  for (x=0;x<w;x++){
    rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;
    yp=-radius*w;
    for(i=-radius;i<=radius;i++){
      yi=max(0,yp)+x;
     
       sir=stack[i+radius];
      
      sir[0]=r[yi];
      sir[1]=g[yi];
      sir[2]=b[yi];
     
      rbs=r1-abs(i);
      
      rsum+=r[yi]*rbs;
      gsum+=g[yi]*rbs;
      bsum+=b[yi]*rbs;
     
      if (i>0){
        rinsum+=sir[0];
        ginsum+=sir[1];
        binsum+=sir[2];
      } else {
        routsum+=sir[0];
        goutsum+=sir[1];
        boutsum+=sir[2];
      }
      
      if(i<hm){
        yp+=w;
      }
    }
    yi=x;
    stackpointer=radius;
    for (y=0;y<h;y++){
      pix[yi]=0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum];

      rsum-=routsum;
      gsum-=goutsum;
      bsum-=boutsum;

      stackstart=stackpointer-radius+div;
      sir=stack[stackstart%div];
     
      routsum-=sir[0];
      goutsum-=sir[1];
      boutsum-=sir[2];
     
       if(x==0){
        vmin[y]=min(y+r1,hm)*w;
      }
      p=x+vmin[y];
      
      sir[0]=r[p];
      sir[1]=g[p];
      sir[2]=b[p];
      
      rinsum+=sir[0];
      ginsum+=sir[1];
      binsum+=sir[2];

      rsum+=rinsum;
      gsum+=ginsum;
      bsum+=binsum;

      stackpointer=(stackpointer+1)%div;
      sir=stack[stackpointer];
     
      routsum+=sir[0];
      goutsum+=sir[1];
      boutsum+=sir[2];
      
      rinsum-=sir[0];
      ginsum-=sir[1];
      binsum-=sir[2];

      yi+=w;
    }
  }
  
  pp.updatePixels();
}
void fastblur(int radius){
loadPixels();
  if (radius<1){
    return;
  }
  int[] pix=pixels;
  int w=width;
  int h=height;
  int wm=w-1;
  int hm=h-1;
  int wh=w*h;
  int div=radius+radius+1;

  int r[]=new int[wh];
  int g[]=new int[wh];
  int b[]=new int[wh];
  int rsum,gsum,bsum,x,y,i,p,yp,yi,yw;
  int vmin[] = new int[max(w,h)];

  int divsum=(div+1)>>1;
  divsum*=divsum;
  int dv[]=new int[256*divsum];
  for (i=0;i<256*divsum;i++){
    dv[i]=(i/divsum);
  }

  yw=yi=0;

  int[][] stack=new int[div][3];
  int stackpointer;
  int stackstart;
  int[] sir;
  int rbs;
  int r1=radius+1;
  int routsum,goutsum,boutsum;
  int rinsum,ginsum,binsum;

  for (y=0;y<h;y++){
    rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;
    for(i=-radius;i<=radius;i++){
      p=pix[yi+min(wm,max(i,0))];
      sir=stack[i+radius];
      sir[0]=(p & 0xff0000)>>16;
      sir[1]=(p & 0x00ff00)>>8;
      sir[2]=(p & 0x0000ff);
      rbs=r1-abs(i);
      rsum+=sir[0]*rbs;
      gsum+=sir[1]*rbs;
      bsum+=sir[2]*rbs;
      if (i>0){
        rinsum+=sir[0];
        ginsum+=sir[1];
        binsum+=sir[2];
      } else {
        routsum+=sir[0];
        goutsum+=sir[1];
        boutsum+=sir[2];
      }
    }
    stackpointer=radius;

    for (x=0;x<w;x++){

      r[yi]=dv[rsum];
      g[yi]=dv[gsum];
      b[yi]=dv[bsum];
      
      rsum-=routsum;
      gsum-=goutsum;
      bsum-=boutsum;

      stackstart=stackpointer-radius+div;
      sir=stack[stackstart%div];
      
      routsum-=sir[0];
      goutsum-=sir[1];
      boutsum-=sir[2];
      
      if(y==0){
        vmin[x]=min(x+radius+1,wm);
      }
      p=pix[yw+vmin[x]];
      
      sir[0]=(p & 0xff0000)>>16;
      sir[1]=(p & 0x00ff00)>>8;
      sir[2]=(p & 0x0000ff);

      rinsum+=sir[0];
      ginsum+=sir[1];
      binsum+=sir[2];

      rsum+=rinsum;
      gsum+=ginsum;
      bsum+=binsum;
      
      stackpointer=(stackpointer+1)%div;
      sir=stack[(stackpointer)%div];
     
      routsum+=sir[0];
      goutsum+=sir[1];
      boutsum+=sir[2];
     
       rinsum-=sir[0];
      ginsum-=sir[1];
      binsum-=sir[2];
     
       yi++;
    }
    yw+=w;
  }
  for (x=0;x<w;x++){
    rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;
    yp=-radius*w;
    for(i=-radius;i<=radius;i++){
      yi=max(0,yp)+x;
     
       sir=stack[i+radius];
      
      sir[0]=r[yi];
      sir[1]=g[yi];
      sir[2]=b[yi];
     
      rbs=r1-abs(i);
      
      rsum+=r[yi]*rbs;
      gsum+=g[yi]*rbs;
      bsum+=b[yi]*rbs;
     
      if (i>0){
        rinsum+=sir[0];
        ginsum+=sir[1];
        binsum+=sir[2];
      } else {
        routsum+=sir[0];
        goutsum+=sir[1];
        boutsum+=sir[2];
      }
      
      if(i<hm){
        yp+=w;
      }
    }
    yi=x;
    stackpointer=radius;
    for (y=0;y<h;y++){
      pix[yi]=0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum];

      rsum-=routsum;
      gsum-=goutsum;
      bsum-=boutsum;

      stackstart=stackpointer-radius+div;
      sir=stack[stackstart%div];
     
      routsum-=sir[0];
      goutsum-=sir[1];
      boutsum-=sir[2];
     
       if(x==0){
        vmin[y]=min(y+r1,hm)*w;
      }
      p=x+vmin[y];
      
      sir[0]=r[p];
      sir[1]=g[p];
      sir[2]=b[p];
      
      rinsum+=sir[0];
      ginsum+=sir[1];
      binsum+=sir[2];

      rsum+=rinsum;
      gsum+=ginsum;
      bsum+=binsum;

      stackpointer=(stackpointer+1)%div;
      sir=stack[stackpointer];
     
      routsum+=sir[0];
      goutsum+=sir[1];
      boutsum+=sir[2];
      
      rinsum-=sir[0];
      ginsum-=sir[1];
      binsum-=sir[2];

      yi+=w;
    }
  }
  
  updatePixels();
}

int[][] chan_data;
int[] tmp = new int[9];

// 
//  dilateErode(PImage, value, channel, itterations) 
//  PImage = image to effect
//  value = dilate - median - erode = 0 - 4 - 8
//  channel = HUE, SATURATION, BRIGHTNESS, RED, BLUE, YELLOW
// `itterations = number of times to solve

void dilateErode(PImage buffer, int position, int channel, int itts) {
  chan_data = new int[buffer.width][buffer.height];

  for (int i = 0; i < itts; i++) {
    buffer.loadPixels();
    for (int x=0; x<buffer.width; x++) {
      for (int y=0; y<buffer.height; y++) {
        color c = buffer.get(x, y) & 0x00ffffff;
          
        chan_data[x][y] = ((((int)getChannel(c, channel)) & 0xff) << 24) | c;
      
      }
    }
  

    for (int x=1; x<buffer.width-1; x++) {
      for (int y=1; y<buffer.height-1; y++) {
        tmp[0] = chan_data[x-1][y-1];
        tmp[1] = chan_data[x][y-1];
        tmp[2] = chan_data[x+1][y-1];

        tmp[3] = chan_data[x-1][y];
        tmp[4] = chan_data[x][y];
        tmp[5] = chan_data[x+1][y];

        tmp[6] = chan_data[x-1][y+1];
        tmp[7] = chan_data[x][y+1];
        tmp[8] = chan_data[x+1][y+1];

        int[] s = sort(tmp);
        int index = y*buffer.width + x;
        // buffer.fill( (s[position] & 0x00ffffff) | 0xff000000 );
        //buffer.rect(x, y, 1, 1);
        color cc = s[position];
        color cwa = (cc & 0x00ffffff) | 0xff000000;
        buffer.pixels[index] =  cwa;
      }
    }




    buffer.updatePixels();

    //image(buffer, 0, 0, width, height);
  }
}

//

final static int[] blends = {ADD, SUBTRACT, DARKEST, LIGHTEST, DIFFERENCE, EXCLUSION, MULTIPLY, SCREEN, OVERLAY, HARD_LIGHT, SOFT_LIGHT, DODGE, BURN};

// ALL Channels, Nxxx stand for negative (255-value)
// channels to work with
final static int RED = 0;
final static int GREEN = 1;
final static int BLUE = 2;
final static int HUE = 3;
final static int SATURATION = 4;
final static int BRIGHTNESS = 5;
final static int ALPH = 6;

final static int NRED = 7;
final static int NGREEN = 8;
final static int NBLUE = 9;
final static int NHUE = 10;
final static int NSATURATION = 11;
final static int NBRIGHTNESS = 12;


float getChannel(color c, int channel) {
  int ch = channel>6?channel-7:channel; // if channel is above 6 minus 7 and change at bottom
  float cc;

  switch(ch) {
  case RED: 
    cc = red(c); 
    break;
  case GREEN: 
    cc = green(c); 
    break;
  case BLUE: 
    cc = blue(c); 
    break;
  case HUE: 
    cc = hue(c); 
    break;
  case SATURATION: 
    cc = saturation(c); 
    break;
   case ALPH: 
    cc = alpha(c); 
    break;
  default: 
    cc= brightness(c); 
    break;
  }

  return channel>6?255-cc:cc;
}


loadPixels();
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
      color cc = img.get(x,y);
      float c_a = 0.0;
      float c_b = 0.0;
      float c_c = 0.0;
      for (int i = x - 1; i <= x+1; i++) {
        for (int j = y - 1; j <= y+1; j++) {
          c_a += a[(i+width)%width][(j+height)%height][p];
          c_b += b[(i+width)%width][(j+height)%height][p];
          c_c += c[(i+width)%width][(j+height)%height][p];
        }
      }
      c_a /= 9.0;
      c_b /= 9.0;
      c_c /= 9.0;
      // adjust these values to alter behaviour
      a[x][y][q] = constrain(c_a + c_a * (c_b - c_c), 0, 1);
      b[x][y][q] = constrain(c_b + c_b * (c_c - c_a), 0, 1);
      c[x][y][q] = constrain(c_c + c_c * (c_a - c_b), 0, 1);
      int index = y*width + x;
      pixels[index] = color(0.5,0.0,a[x][y][q]);
      //set(x,y,color(0.5,0.7,a[x][y][q]));
    }
  }
  updatePixels();
  if (p == 0) {
    p = 1; q = 0;
  }
  else {
    p = 0; q = 1;
  }
boolean alternate = false;
int threshold = 153,
lineLength = 8;//8;//6;


void alterPixels(){
  int[] directions = {
 (width*-1)-1,
 (width*-1)+1,
 width+1,
 width-1
};
loadPixels();
  for (int k=width+1; k<pixels.length-width-1; k++) {
    int pModifier = directions[int(random(directions.length))];
    if (brightness(pixels[k]) == threshold) {
      //
    } else if (brightness(pixels[k]) < threshold) {
      pixels[k] = pixels[k+pModifier];
    } else {
      //
    }
    //
    if (brightness(pixels[k]) < 125) {
      for (int i=0; i<directions.length; i++) {
        pixels[k+pModifier] = color(
                    red(pixels[k-pModifier])-10,
                    green(pixels[k])-10,
                    blue(pixels[k+pModifier])
                  );
      }
    }
  }
updatePixels();
threshold = setThreshold(threshold,75,125);
}

int setThreshold(int threshold, int minThreshold, int maxThreshold) {
 if (threshold <= maxThreshold && threshold >= minThreshold && alternate) {
   threshold++;
 } else if (threshold <= maxThreshold && threshold >= minThreshold) {
   threshold--;
 } else if (alternate) {
   threshold = maxThreshold;
   alternate = !alternate;
 } else {
   threshold = minThreshold;
   alternate = !alternate;
 }
 return threshold;
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import javax.swing.JOptionPane;
import javax.swing.JTextField;


/**
 * Francis Lyons
 * 10/13/14
 *
 *   program built to delete i frames and repeat certain sections of b-frames
 *
 *   takes as an argument the filename w/o filetype of the video to be used (works with videos in AVI format, converted using FFMPEG)
 *   
 *   reccomended to use avidemux or something similar to find total number of frames in video / specific frame locations
 *  reads through the bytes of an avi and finds and deletes the key frames within a section of frames that you specify. 
 * you can also choose how many times to repeat each b-frame within that section 
 * (to increase the 'growing' or 'blooming' effect) and how many times to repeat the entire section of frames.
 */

public class NewMash 
{
	public static final int[] F_BYTES = new int[4];
	public static final int[] I_BYTES = new int[4];
	
	/*
	 * the nextFrame method should return the long position of the 
	 * beginning of the next frame, regardless of if it is a keyframe
	 * or not.  method will return -1 if it hits the end of the file
	 * before finding another frame
	 * takes as a parameter the current read position in the file
	 */
	public static long nextFrame(RandomAccessFile file, long start) throws IOException
	{
		long startPos = -1;
		long currentPos = start;  // get current read position
		file.seek(start);
		
		while(file.getFilePointer() < file.length())
		{
			file.seek(currentPos);  // currentPos is incremented by 1 each time, reads in if went to far
			if(file.read() == F_BYTES[0] && file.read() == F_BYTES[1] && file.read() == F_BYTES[2] && file.read() == F_BYTES[3])
			{
				// we have found the beginning of a frame
				// grab the found frame start position and get out of the while loop
				
				startPos = currentPos;
				break;
			}
	    	currentPos++;
		}
		file.seek(start);
		return startPos;
	}
	
	
	/*
	 * method to check if current frame is a keyframe
	 * to be used properly this method should be used in conjunction
	 * with nextFrame (this method should take as a parameter the long position
	 * of the beginning of a frame in the file, then it will return boolean
	 * of whether or not the frame is an i frame)
	 * 
	 * right now the number of bytes to search for the iframe flag
	 * is hardcoded at 15 to be safe
	 */
	public static boolean isIFrame(RandomAccessFile file, long pos) throws IOException
	{
	    boolean iFrame = false;
	    
	    for(int i = 0; i < 15; i++)
	    {
			file.seek(pos + i);  // start reading at the given position, then moves 1 forward each time
			
			if(file.read() == I_BYTES[0] && file.read() == I_BYTES[1] && file.read() == I_BYTES[2] && file.read() == I_BYTES[3])
			{
				// we have found the flag that indicates that this is an iframe
				// exit the for loop
				
				iFrame = true; 
				break;
			}
	    }
	    file.seek(pos);
	    return iFrame;
	}
	

	public static void main(String[] args) throws IOException 
	{
		
		String filename = args[0];  // only argument should be the filename of the video
		
		// get user input for various parameters
		JTextField endBeginTxtFld = new JTextField(); // end of beginning unchanged area
		JTextField startTxtFld = new JTextField(); // start of changed area
		JTextField endTxtFld = new JTextField();  // end of changed area
		JTextField repeatTxtFld = new JTextField(); // number of times to repeat each frame
		JTextField totalRepTxtFld = new JTextField();  //  number of times to repeat whole change area
		
		Object[] message = {"end of beginning: ", endBeginTxtFld, 
						"start frame: ", startTxtFld, 
						"end frame: ", endTxtFld,
						"number of times to repeat each frame: ", repeatTxtFld,
						"number of times to repeat total frame area: ", totalRepTxtFld};
		
		JOptionPane.showConfirmDialog(null, message, "Enter Specified Values", JOptionPane.OK_OPTION);

		// get strings for each of the inputs
		String endBegStr = endBeginTxtFld.getText();
		String startStr = startTxtFld.getText();
		String endStr = endTxtFld.getText();
		String repeatStr = repeatTxtFld.getText();
		String totalRepStr = totalRepTxtFld.getText();
			
		// get usable integer values from above strings
		int endBegin = Integer.parseInt(endBegStr);
		int start = Integer.parseInt(startStr);
		int end = Integer.parseInt(endStr);
		int repeat = Integer.parseInt(repeatStr);
		int totalRep = Integer.parseInt(totalRepStr);
		
		
		F_BYTES[0] = 48; // decimal equivalent of 30 in hex
		F_BYTES[1] = 48; // decimal equivalent of 30 in hex
		F_BYTES[2] = 100; // decimal equivalent of 64 in hex
		F_BYTES[3] = 99; // decimal equivalent of 63 in hex
		
		I_BYTES[0] = 0; // decimal equivalent of 00 in hex
		I_BYTES[1] = 1; // decimal equivalent of 01 in hex
		I_BYTES[2] = 176; // decimal equivalent of B0 in hex
		I_BYTES[3] = 1; // decimal equivalent of 01 in hex
		
		
		RandomAccessFile file = new RandomAccessFile(filename + ".avi", "rw");
		
		// skip some initial frames otherwise video just changes from green
		int frames = 0;
		long current = nextFrame(file, 0);
		System.out.println("finding beginning");
		while(frames < endBegin)
		{
			current = nextFrame(file, current + 1);
			frames++;  // found another frame, increment count
			//System.out.println(frames + " / " + copyBegin);
		}
		
	    
	    FileOutputStream newFile = new FileOutputStream(filename + "_0.avi" ,true);
	    
		file.seek(0);
	    System.out.println("copying beginning");
	    // copy beginning of file until moved past startOffSet number of frames
		while(file.getFilePointer() < current)
		{
		   newFile.write(file.readByte());
		}
		
		System.out.println("skipping from beginning to repeat area");
		
		// go through these frames but dont read them over
		while(frames < start)
		{
			current = nextFrame(file, current + 1);
			frames++;  // found another frame, increment count
			//System.out.println(frames + " / " + start);
		}

	    
    	long currFrame = nextFrame(file, file.getFilePointer());
    	long nextFrame;
    	
    	long startFrame = currFrame;
    	
	    // need to loop through file and copy over bytes unless we are in an iframe
    	System.out.println("copying repeat area");
    	for(int j = 0; j < totalRep; j++)
    	{
    		file.seek(startFrame);
    		currFrame = startFrame;
    		nextFrame = nextFrame(file, currFrame + 1);
        	int frameCount = start;
    		
		    while(file.getFilePointer() < file.length() && frameCount < end)
		    {	
		    	if(nextFrame == -1)
		    	{
		    		// there is no next frame, just copy the rest
		    	    while(file.getFilePointer() < file.length())
		    	    {
		    	    	newFile.write(file.readByte());
		    	    }
		    	}
		    	
		    	// if next frame is iFrame and we want to delete them, skip past it
		    	else if(isIFrame(file, currFrame))
		    	{
		    		//System.out.println("skipped iFrame");
		    		// skip to next frame
		    		file.seek(nextFrame);
		    	}
		    	
		    	// if not iFrame then we want to copy it
		    	else
		    	{
				    for(int i = 0; i < repeat; i++)
				    {
				   		while(file.getFilePointer() < nextFrame)
				   		{
				   			newFile.write(file.readByte());
				   		}
				   		file.seek(currFrame);
				   	}
		    	}
		    	
		    	// nextFrame is now the current frame
		    	currFrame = nextFrame;
		    	nextFrame = nextFrame(file, file.getFilePointer() + 1);
		    	frameCount++;
		    	//System.out.println(frameCount + " / " + end);
		    	newFile.flush();
		    	//System.out.println(file.getFilePointer() + " / " + file.length());
		    }
		    System.out.println("repeat: " + j);
    	}
    	
    	System.out.println("copying end");
	    while(file.getFilePointer() < file.length())
	    {
		    //copy rest of the file after 'end'
	    	nextFrame = nextFrame(file, file.getFilePointer() + 1);
	    	
	    	if(nextFrame == -1)
	    	{
	    		// there is no next frame, just copy the rest
	    	    while(file.getFilePointer() < file.length())
	    	    {
	    	    	newFile.write(file.readByte());
	    	    }
	    	}
	    	
	    	// if next frame is iFrame and we want to delete them, skip past it
	    	else if(isIFrame(file, currFrame))
	    	{
	    		//System.out.println("skipped iFrame");
	    		// skip to next frame
	    		file.seek(nextFrame);
	    	}
	    	
	    	// if not iFrame or we want to keep iFrames then copy it
	    	else
	    	{
			    while(file.getFilePointer() < nextFrame)
			    {
			    	newFile.write(file.readByte());
			    }
			    file.seek(currFrame);
	    	}
	    	currFrame = nextFrame;
	    	nextFrame = nextFrame(file, file.getFilePointer() + 1);
	    	newFile.flush();
	    }
	    
	    System.out.println("done");
	    newFile.close();
	}	

}
boolean alternate = false;
boolean lighter = false;
int threshold = 127;
int div = 255;
float minLength = width/50+randomNormal();
int[] directions = {
(width/div*-1)-1,
(width/div*-1)+1,
width/div+1,
width/div-1
};

void alterPixels() {
  loadPixels();
  for (int k=width+1; k<pixels.length-width-1; k++) {
    int pModifier = directions[int(random(directions.length))];
    if (brightness(pixels[k]) == threshold) {
      pixels[k] = pixels[k] << int(randomNormal());
      pixels[k] = pixels[k] >> int(map(randomNormal(), 0, 1, -1, 1));
    } else if (brightness(pixels[k]) > threshold) {
      pixels[k] = pixels[k+pModifier];
    } else {
      //
    }
  }
  updatePixels();
  threshold = setThreshold(threshold, 00, 135);
}

float randomNormal() {
  float x = 1.0, y = 1.0, s = 10.0;
  while (s >= 1.0) {
    x = random(-1.0f, 1.0f);
    y = random(-1.0f, 1.0f);
    s = x*x + y*y;
  }
  return x * sqrt(-s * log(s)/s);
}

int setThreshold(int threshold, int minThreshold, int maxThreshold) {
  if (threshold <= maxThreshold && threshold >= minThreshold && alternate) {
    threshold++;
  } else if (threshold <= maxThreshold && threshold >= minThreshold) {
    threshold--;
  } else if (alternate) {
    threshold = maxThreshold;
    alternate = !alternate;
  } else {
    threshold = minThreshold;
    alternate = !alternate;
  }
  return threshold;
}