Fix `SDL_GetClipboardData()` for bitmap on Windows (SDL3).
Description
Calling SDL_GetClipboardData on Windows may generate an incorrect bitmap file header for uncompressed bitmaps. This issue arises because SDL3 sometimes populates the BITMAPFILEHEADER with incorrect bfOffBits values, leading to corrupted bitmaps.
This PR addresses the problem by recalculating the pixel offset more accurately in the WIN_GetPixelDataOffset function, considering the presence of a palette array in the case of indexed bitmaps. Additionally, it corrects the usage of biSizeImage, taking into account that this value can sometimes be zero for uncompressed RGB bitmaps.
Quick Test
To test this, compile and run the code on Windows. Take a screenshot and press the V key, then check the generated clipboard.bmp file.
#include <SDL3/SDL.h>
#include <stdbool.h>
static void SDLTest_PasteScreenShot(void)
{
const char *image_formats[] = {
"image/png",
"image/tiff",
"image/bmp",
};
size_t i;
for (i = 0; i < SDL_arraysize(image_formats); ++i) {
size_t size;
void *data = SDL_GetClipboardData(image_formats[i], &size);
if (data) {
char filename[16];
SDL_IOStream *file;
SDL_snprintf(filename, sizeof(filename), "clipboard.%s", image_formats[i] + 6);
file = SDL_IOFromFile(filename, "w");
if (file) {
SDL_Log("Writing clipboard image to %s", filename);
SDL_WriteIO(file, data, size);
SDL_CloseIO(file);
}
SDL_free(data);
return;
}
}
SDL_Log("No supported screenshot data in the clipboard");
}
int main(int argc, char *argv[]) {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("", 300, 200, 0);
SDL_SetWindowTitle(window, "Window BMP Clipboard Test");
bool quit = false;
while (!quit) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_EVENT_KEY_DOWN && event.key.key == SDLK_V) {
SDL_Log("Calling SDLTest_PasteScreenShot\n");
SDLTest_PasteScreenShot();
}
else if (event.type == SDL_EVENT_QUIT) {
quit = true;
}
}
SDL_Delay(20);
}
SDL_Quit();
}
Is this relevant for SDL_LoadBMP() as well?
Is this relevant for SDL_LoadBMP() as well?
Probably, I'd have to check.
But if it calls SDL_GetClipboardData on windows, then it's relevant for sure.
Is this relevant for SDL_LoadBMP() as well?
Probably, I'd have to check.
Can you take a look? I'd like to get that fix in with this PR, so we don't miss it later.
Actually, I'm going to go ahead and merge this, and then work on the SDL BMP fixes separately.
Thanks!