Search code examples
c++pixelsdl-1.2

SDL pixels of surface become 0 3/4 of the way through


I have a function that reads pixels of a surface and writes the indices of the pixels that are brightest to another array. Using gdb, I have noticed that all the values in the pixel array become 0 exactly 3/4 of the way in, and after exactly 1020 pixels from that point, the program segfaults. This is the code:

void scanBrightPixels(int** write_to, int* pcount, SDL_Surface* image) {
   SDL_PixelFormat* f = image->format;
   SDL_LockSurface(image);
   Uint32* pixels = (Uint32*) image->pixels;
   SDL_UnlockSurface(image);
   int lpcount = 0;
    for (int i = 0; i < image->w * image->h / 4 * 3; i++) {
        Uint8 r, g, b;
        Uint8 brightness;
        SDL_GetRGB(pixels[i], f, &r, &g, &b); // this is where the segfault happens
        brightness = (Uint8) ((r * 0.33) + (g * 0.5) + (b * 0.16));
        if (brightness >= 251) {
            (*write_to)[lpcount] = i;
            lpcount++;
        }
    }
    *pcount = lpcount;
}

The function is also called from std::async, if that makes a difference. Any ideas?


Solution

  • You should not call SDL_UnlockSurface until after you are done using the pixels pointer. Pixels may be invalid after calling unlock. This is especially the case if the surface is stored on the gpu. Otherwise it could accidentally work even after calling unlock.

    Also it is not guaranteed that the next row of pixels begins immediately where the previous one ends in memory as your code seems to assume. The SDL_Surface member pitch is the number of bytes in memory between the start of 2 adjacent rows.

    Last, I am not sure what is the intention of "/4*3" in calculating the loop end index.

    I hope this helps.