Sujet : Re: filling area by color atack safety
De : bc (at) *nospam* freeuk.com (bart)
Groupes : comp.lang.cDate : 16. Mar 2024, 20:13:32
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <ut4r0q$31rir$1@dont-email.me>
References : 1
User-Agent : Mozilla Thunderbird
On 16/03/2024 04:11, fir wrote:
i was writing simple editor (something like paint but more custom for my eventual needs) for big pixel (low resolution) drawing
it showed in a minute i need a click for changing given drawed area of
of one color into another color (becouse if no someone would need to do it by hand pixel by pixel and the need to change color of given element is very common)
there is very simple method of doing it - i men i click in given color pixel then replace it by my color and call the same function on adjacent 4 pixels (only need check if it is in screen at all and if the color to change is that initial color
int RecolorizePixelAndAdjacentOnes(int x, int y, unsigned old_color, unsigned new_color)
{
if(old_color == new_color) return 0;
if(XYIsInScreen( x, y))
if(GetPixelUnsafe(x,y)==old_color)
{
SetPixelSafe(x,y,new_color);
RecolorizePixelAndAdjacentOnes(x+1, y, old_color, new_color);
RecolorizePixelAndAdjacentOnes(x-1, y, old_color, new_color);
RecolorizePixelAndAdjacentOnes(x, y-1, old_color, new_color);
RecolorizePixelAndAdjacentOnes(x, y+1, old_color, new_color);
return 1;
}
return 0;
}
it work but im not quite sure how to estimate the safety of this -
On my machine, it's OK up to a 400x400 image (starting with all one colour and filling from the centre with another colour).
At 500x500, I get stack overflow. The 400x400 the maximum recursion depth is 80,000 calls.
I don't an alternative ATM, I'm just reporting what I saw with my test program shown below, since some here don't believe that recursion can be problematical.
--------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned char byte;
enum {dimx=400};
enum {dimy=dimx};
byte image[dimx][dimy];
int maxdepth;
byte getpixel(int x, int y) {
return image[x][y];
}
void setpixel(int x, int y, byte newcol) {
image[x][y]=newcol;
}
int onscreen(int x, int y) {
return x>=0 && x<dimx && y>=0 && y<dimy;
}
void fill(int x, int y, unsigned old_color, unsigned new_color)
{
if(old_color == new_color) return;
static int depth=0;
++depth;
if (depth>maxdepth) maxdepth=depth;
if(onscreen( x, y)) {
//printf("FILL %d %d %d depth:%d\n",x,y, onscreen(x,y), depth);
if(getpixel(x,y)==old_color)
{
setpixel(x,y,new_color);
fill(x+1, y, old_color, new_color);
fill(x-1, y, old_color, new_color);
fill(x, y-1, old_color, new_color);
fill(x, y+1, old_color, new_color);
--depth;
return;
}
}
--depth;
return;
}
static void writepgm(byte* file) {
int x, y;
void* f;
f = fopen(file,"w");
fprintf(f,"%s\n","P2");
fprintf(f,"%d %d\n",dimx,dimy);
fprintf(f,"255\n");
for (y=0; y<dimy; ++y) {
for (x=0; x<dimx; ++x) {
fprintf(f,"%u%s",image[y][x]," ");
}
fprintf(f,"\n");
}
fclose(f);
}
int main(void) {
fill(dimx/2, dimy/2, 0, 80);
printf("maxdepth=%d\n",maxdepth);
puts("");
puts("Writing test.ppm:");
writepgm("test.ppm");
}