Search code examples
ccs50blurfloating-point-exceptions

CS50 Blur (Floating point exception core dumped)


Im doing the filter-less problem in CS50, i did pretty much all the other filter correctly but im a little struggling with the blur.

I don't really get how malloc works (i just ctrl+c ctrl+v how they allocated space for 'image' to do 'copy') and how to do the average of the surrounding pixels, i tried something with the average function i thought it would work but it tells me 'floating point exception (core dumped)' and i think the problem is in the for loop but idk how to fix it honestly.

Usually i like to found solutions to my problems by myself but here i really don't understand im on this one for almost 2 weeks and i don't wanna see videos.

void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE (*copy)[width] = calloc(height, width * sizeof(RGBTRIPLE));
for (int i = 0; i < height; i++)
{
    for (int j = 0; j < width; j++)
    {
        copy[i][j] = image[i][j];
    }
}

for (int i = 0; i < height; i++)
{
    for (int j = 0; j < width; j++)
    {
        image[i][j] = average(i, j, height, width, copy);
    }
}
free(copy);
return;
}

RGBTRIPLE average (int pxlheight, int pxlwidth, int height, int width, RGBTRIPLE 
copy[height][width])
{
RGBTRIPLE caca;
int x = 0;
int y = 0;

for (int i = pxlheight - 1; i <= pxlheight + 1 && i >= 0 && i <= height - 1; i++)
{
    y++;
    for (int j = pxlwidth - 1; j <= pxlwidth + 1 && j >= 0 && j <= width - 1; j++)
    {
        x++;
        caca.rgbtRed += copy[i][j].rgbtRed;
        caca.rgbtGreen += copy[i][j].rgbtGreen;
        caca.rgbtBlue += copy[i][j].rgbtBlue;
    }
}

caca.rgbtRed = round(caca.rgbtRed / (x * y));
caca.rgbtGreen = round(caca.rgbtGreen / (x * y));
caca.rgbtBlue = round(caca.rgbtBlue / (x * y));

return caca;

}


Solution

  • Thanks to everyone for your useful tips and remarks

    There was a lot of problems you guys pointed to and i tried fixing everything

    First, i and j started at < 0 so it was impossible to go through the for loop, keeping x and y at 0 and causing a floating point exception by dividing by 0. So i just defined i and j better and made a condition to them like this :

    for (int i = (pxlheight - 1 < 0) ? 0 : pxlheight - 1; i <= pxlheight + 1 && i <= height - 1; i++)

    for (int j = (pxlwidth - 1 < 0) ? 0 : pxlwidth - 1; j <= pxlwidth + 1 && j <= width - 1; j++)

    Next, when i tried running my program it was working but the output image was almost completely black and i was pretty sure it wasn't the result i shoul've got.

    The problem was that i was adding up values to BYTE types that cannot exceed 255. So i just created 3 float values, defined them to 0.0, and added all the values to them to then divide them by rows * columns and giving the results to the RGBTRIPLE fields after rounding the result and turning it to int

    float proutR = 0.0; float proutG = 0.0; float proutB = 0.0;

    proutR += copy[i][j].rgbtRed; proutG += copy[i][j].rgbtGreen; proutB += copy[i][j].rgbtBlue;

    caca.rgbtRed = (int) round(proutR / (x * y)); caca.rgbtGreen = (int) round(proutG / (x * y)); caca.rgbtBlue = (int) round(proutB / (x * y));

    Thanks again to everyone each of your comments helped me to figure out the problem and solve it without giving me the solution directly

    So at the end it gives this and it works nicely :

    RGBTRIPLE average (int pxlheight, int pxlwidth, int height, int width, 
    RGBTRIPLE copy[height][width])
    {
    RGBTRIPLE caca;
    int x = 0;
    int y;
    float proutR = 0.0;
    float proutG = 0.0;
    float proutB = 0.0;
    
    for (int i = (pxlheight - 1 < 0) ? 0 : pxlheight - 1; i <= pxlheight + 1 && i <= height - 1; i++)
    {
        x++;
        y = 0;
        for (int j = (pxlwidth - 1 < 0) ? 0 : pxlwidth - 1; j <= pxlwidth + 1 && j <= width - 1; j++)
        {
            y++;
            proutR += copy[i][j].rgbtRed;
            proutG += copy[i][j].rgbtGreen;
            proutB += copy[i][j].rgbtBlue;
        }
    }
    
    caca.rgbtRed = (int) round(proutR / (x * y));
    caca.rgbtGreen = (int) round(proutG / (x * y));
    caca.rgbtBlue = (int) round(proutB / (x * y));
    
    return caca;
    

    }