0

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.

  • You should be working from a *copy* of the image, otherwise you will blur from pixels that have already been blurred. – Weather Vane Aug 03 '22 at 11:06
  • 2
    `totalRed = totalGreen = totalBlue = 0;` should be inside the second loop. You've also ignored the trickier edge pixels. – Weather Vane Aug 03 '22 at 11:09
  • If you catch the crash in a [*debugger*](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems), when and where in your code does it happen? What are the values of all involved variables when the crash happens? Will any of the indexes be out of bounds? And when you call `blur`, what is `image` exactly? How is it defined and initialized in the calling function? – Some programmer dude Aug 03 '22 at 11:09
  • 5
    Do you mean `[ j ][ i ]` or `[ i ][ j ]` when you are assigning the rounded values? – Fe2O3 Aug 03 '22 at 11:09
  • `BYTE totalRed, totalGreen, totalBlue;` should be `double totalRed, totalGreen, totalBlue;` – Weather Vane Aug 03 '22 at 11:11
  • 1
    On a different note, all your divisions (like e.g. `totalRed / 9`) are *integer* divisions, and will yield a truncated integer result. I.e. anything between `0` and `8` will result in `0`, anything between `9` and `17` will result in `1`, etc. There's nothing to `round`. – Some programmer dude Aug 03 '22 at 11:15
  • You are completely skipping all the edge pixels. – Gerhardh Aug 03 '22 at 11:22

2 Answers2

1

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.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
1

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()
}
Rafael Dantas
  • 78
  • 1
  • 7