I tried to apply box blur to an image (without a matrix but just iterating over 9 neighbooring pixels) but I am always getting a segmentation fault
after I get to 408th pixel of an image (on the 1st row). I don't know what could cause it because debugging with printf()
didn't show any meaningful results
void blur(int height, int width, RGBTRIPLE image[height][width])
{
BYTE totalRed, totalGreen, totalBlue;
totalRed = totalGreen = totalBlue = 0;
for (int i = 1; i < height - 1; i )
{
for (int j = 1; j < width - 1; j )
{
for (int h = -1; h <= 1; h )
{
for (int w = -1; w <= 1; w )
{
totalRed = image[i h][j w].rgbtRed;
totalGreen = image[i h][j w].rgbtGreen;
totalBlue = image[i h][j w].rgbtBlue;
}
}
image[j][i].rgbtRed = round((totalRed / 9));
image[j][i].rgbtGreen = round((totalGreen / 9));
image[j][i].rgbtBlue = round((totalBlue / 9));
}
}
return;
}
EDIT
I fixed the issue, thanks to everyone who answered me.
CodePudding user response:
The problem is you transposed the index values for storing the updated value: image[j][i].rgbtRed = round((totalRed / 9))
should be
image[i][j].rgbtRed = round((totalRed / 9));
image[i][j].rgbtGreen = round((totalGreen / 9));
image[i][j].rgbtBlue = round((totalBlue / 9));
Note however that you overwrite the pixels in row i
that will be used for blurring the next row, which is incorrect. Also note that you should make special cases for the boundary rows and columns. More work is needed on the algorithm.
CodePudding user response:
I would suggest you to post a minimal "working" example that we could compile and reproduce results on something like Compiler Explorer.
As @Fe2O3 commented on the original post, you have i and j flipped in these assignments:
image[j][i].rgbtRed = round((totalRed / 9));
image[j][i].rgbtGreen = round((totalGreen / 9));
image[j][i].rgbtBlue = round((totalBlue / 9));
Which could cause problems whenever the images are not squares.
Additionally, you're using a byte-sized variable to store the sum of 9 bytes worth of bytes, meaning your max value will be 9*255=2295. I'd highly recommend you upgrading the type of totalRed/Green/Blue to at least 16 bits.
Finally, as @[Some Programmer Dude] suggested, there's nothing to round as in C division of integers will not convert the resulting value to float/double. The value will be truncated, so your result will look like
if (x > 0) {
floor(x)
} else if (x < 0) {
ceil(x)
} else {
crash_and_burn()
}