We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › ArrayIndexOutOfBoundsException
Page Index Toggle Pages: 1
ArrayIndexOutOfBoundsException (Read 1555 times)
ArrayIndexOutOfBoundsException
May 30th, 2010, 8:32pm
 
Hey all,

I am new to processing and programming in general, and I am trying to put together two programs that I found. I am trying to put a fastblur and a zoom/pan program together so that zooming is linked to blurring but panning is not. You need to have the processing utils library for it to work. Also, you need to insert an image you have on your computer (you should put it in the data folder of the sketch). I tried to put each section in order so that drawing would occur correctly, but I now have an array index out of bounds exception. The code for the program is below, and the error message is below that. Thanks!

import org.gicentre.processing.utils.zoom.*;
PImage a;
PImage b;

ZoomPan zoomer;

void setup(){
 size(800,800);
 smooth();
 zoomer = new ZoomPan(this);
 a=loadImage("Jellyfish.jpg");
 size(a.width, a.height);
 b=new PImage(a.width, a.height);
 fill(255);
 noStroke();
 frameRate(25);
}

void draw(){
 background(0);
 System.arraycopy(a.pixels,0,b.pixels,0,a.pixels.length);
 fastblur(b,mouseY/4);
 zoomer.transform();
 image(b,0,0);
}

void fastblur(PImage img,int radius){
 
 if (radius<1){
   return;
 }
 int[] pix=img.pixels;
 int w=img.width;
 int h=img.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 rl=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=rl-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=rl-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+rl,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];
     
     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;
   }
 }
 
   img.updatePixels();
}




This is the error message:

processing.app.debug.RunnerException: ArrayIndexOutOfBoundsException: -31
     at processing.app.Sketch.placeException(Unknown Source)
     at processing.app.debug.Runner.findException(Unknown Source)
     at processing.app.debug.Runner.reportException(Unknown Source)
     at processing.app.debug.Runner.exception(Unknown Source)
     at processing.app.debug.EventThread.exceptionEvent(Unknown Source)
     at processing.app.debug.EventThread.handleEvent(Unknown Source)
     at processing.app.debug.EventThread.run(Unknown Source)
Exception in thread "Animation Thread" java.lang.ArrayIndexOutOfBoundsException: -31
     at Middles.fastblur(Middles.java:192)
     at Middles.draw(Middles.java:43)
     at processing.core.PApplet.handleDraw(Unknown Source)
     at processing.core.PApplet.run(Unknown Source)
     at java.lang.Thread.run(Thread.java:619)


It occurs at the line:  pix[yi]=0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum];


Any help is greatly appreciated; my project is due in a couple of days.
Re: ArrayIndexOutOfBoundsException
Reply #1 - May 31st, 2010, 12:14am
 
Looks like one of rsum, gsum or bsum became negative (-31). It can happen in a line like rsum-=routsum;. Hard to provide a fix without a deep understanding of the algorithm, at worse check that the indexes are within dv's range.
Re: ArrayIndexOutOfBoundsException
Reply #2 - May 31st, 2010, 4:46am
 
you also need to be aware that % can return a negative value if the first argument is -ve, it's not necessarily a value between 0 and (div - 1) like you'd expect

ps use comments!
Re: ArrayIndexOutOfBoundsException
Reply #3 - May 31st, 2010, 8:20am
 
In additon to what PhiLho and koogy said above, you have to be careful when you're using bit-shift operations (<< and >>) with int's, because the highest bit of an int is actually used to hold the sign (positive/negative) of the number.  Here's an example to show what happens when you bit-shift too far:
Code:
void setup() {
size(100, 100);
}

void draw() {
if (frameCount<32) {
int x = (1 << frameCount);
print("Binary: " + binary(x));
print(" Hex: " + hex(x));
print(" Decimal: " + x + "\n");
}
}


One useful tool to hunt down a problem like this (regardless of whether it's bit-shifting or whatever) is what's called assertion testing.  Write a little method called assert() that looks something like this:
Code:

void assert(boolean condition) {
if (condition==false) println("Assertion failed!");
}

Then you can use the assert() method to test things that you know should be true at points in your code.  For example, right before the line that's giving you trouble, insert the line:
Code:
assert(rsum>=0); 


Run the program and see if you get an assert failure before it crashes.  If not, change the assert to test bsum and repeat.  When you figure out which one is the culprit, you can move the assert to other places in the code to test conditions there, etc.

There are more advanced forms of assert(), some of them built into Java, that give line numbers and such, but I don't know to use those.  This simple do-it-yourself version should be useful for a small program like this, though.

Good luck, and feel free to ask if you have more questions.
Re: ArrayIndexOutOfBoundsException
Reply #4 - May 31st, 2010, 9:55am
 
Good idea to bring on assertions, Smitty.

Out of curiosity, I just tried native Java asserts in Processing 0184, and they work! Apparently they are enabled by default.
Code:
assert f1x >= f2x : "Wrong order, we have " + f1x + " lower than " + f2x; 

makes an exception when the condition isn't meet:
Quote:
Exception in thread "Animation Thread" java.lang.AssertionError: Wrong order, we have 267.71243 lower than 532.2876
     at IsPointOnEllipse.IsPointInEllipse(IsPointOnEllipse.java:51)

(the test makes no sense, I just took a random sketch for the test and tested a random couple of variables!)
Page Index Toggle Pages: 1