tags:

views:

371

answers:

7

Hi, I wrote this function for filling closed loop, pixvali is declared globally to store the color value of the pixel where the first click will be done (inside the closed loop).

But the problem is that this recursion doesn't terminate when its first fill(..,..)get over, and it says stack is overflowed...

void fill(int x,int y)
{
    GLfloat pixval[3];
    glReadPixels(x,y,1,1,GL_RGB,GL_FLOAT,pixval);
    if(pixval[0]==pixvali[0] && pixval[1]==pixvali[1] && pixval[2]== pixvali[2])
    {
     glBegin(GL_POINTS);
      glVertex2i(x,y);
     glEnd();
     glFlush();
     fill(x-1,y);
     fill(x+1,y);
     fill(x,y-1);
     fill(x,y+1);
    } 
}
A: 

instead you may use the following if it does not hurt the code;

...
    fill(x-1,y);
    fill(x,y-1);
    fill(x,y+1);
    fill(x+1,y); // change order
...
sarimura
Why would this help?
Paul Hankin
I was not exactly sure about.. Since the problem is solved, forget my opinion.
sarimura
+3  A: 

The stack overflows because you are using recursion, and the depth of the recursion is linear in the number of pixels in the shape you're filling.

It may also be that you are trying to fill the shape in the same color as it already is. That is, the current gl color is the same as pixvali. In that case, you'll get infinite recursion.

Paul Hankin
+2  A: 

It's kind of hard to tell from the question, but my guess would be that, you begin going in a loop of pixels.

For example, think that you have only 4 pixels that you need to color (0,0), (0,1), (1,0), (1,1).

You begin coloring (0,0). Then your recursion will enter (1,0) since(-1,0) doesn't need coloring. then (0,0) again since, it's the pixel that is (x-1, y) again and so on.

You need to add some way to mark pixels that have been colored already. But that's just a guess because you can't really see what's going on outside that functions.

SurDin
The comparison between pixval and pixvali is supposedly that marker. I just hope he draws with the pixvali color as he is reading the current xy color in pixval...
extraneon
Where does he compare then to the filled color? (i.e. you want to fill color x with color y, you need to check that color x is filled and nothing else, other wise you can just flood the whole screen)Personally I'd look for a color some distance from x, but that's not the point really.
SurDin
see my problem is coming like:It draws a line from the clicked point till the boundry going in -x direction.. As my first recurtion is for -x; after the line gets drawn, it shows stack overflow..think on this properly and then post any comment..
Abhay
I think that you should read the answers that you were given and think on them.
SurDin
@Abhay: Try a smaller area to fill. My guess is that the stack is really too small for the area you try to fill.
Aaron Digulla
A: 

implement your own stack, don't use recursion for flood fill unless you are filling shapes with relatively small surface area in terms of pixels.

a typical implementation is:

Stack stack; 
stack.push(firstPoint);

while(!stack.isEmpty()){
   Point currentPoint= stack.pop();
   //do what ever you want to do here, namely paint.
   //boundary check ur surrounding points and push them in the stack if they are inbounds
}
MahdeTo
+1  A: 

Not sure of the implementation details, but if the 12 byte local array is allocated on the stack (3 floats a 4 bytes each), then you have 4 bytes each for the x and y parameters, and probably four bytes for the return address. That gives at least 24 every time you recurse. That means you only need a bit more than 40'000 calls to blow through 1MB of stack space, if there's nothing else on it, which won't be true.

To put that in perspective, 43'690 pixels is only about 10% of an 800x600 display.

JimG
Oops, didn't notice the array was GLFloat, my brain just substituted three bytes for RGB. Obviously that would make the stack requirements even worse per call.
JimG
Fixed the numbers :)
Aaron Digulla
+1  A: 

You need to check what pixels are you editing.

e.g. If you have an image from 0,0 to 10,10 and you edit 11,10 you will get outside of memory.

So you need to check if x,y is between the boundaries of the image.

x>=left&&x<=right&&y>=top&&y<=bottom
csiz
A: 

At first glance, the algorithm looks good. I'm a bit worried about the "==" because they don't work well with float values. I suggest to use

abs(val1 - val2) < limit

instead (where limit is < 1 and > 0. Try 0.0001, for example).

To track down the bug, I suggest to add a printf() at the beginning of the function. When you see what the function tries to fill, that will help. Maybe it is stuck somewhere and calls itself again and again with the same coordinates?

Also, the stack may simple be too small for the area you try to fill. Try with a small area first, say a small rectangle only 4 by 3 pixels. Don't try to click it with the mouse but start with a known good point inside (just call fill() in your code).

Also printing the values for the color could help.

Aaron Digulla