Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix SDL_GetClipboardData() for bitmap on Windows (SDL3). #11409

Merged
merged 1 commit into from
Dec 24, 2024

Conversation

evertonse
Copy link
Contributor

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();
}

@slouken
Copy link
Collaborator

slouken commented Nov 4, 2024

Is this relevant for SDL_LoadBMP() as well?

@slouken slouken added this to the 3.2.0 milestone Nov 4, 2024
@evertonse
Copy link
Contributor Author

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.

@slouken
Copy link
Collaborator

slouken commented Dec 24, 2024

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.

@slouken
Copy link
Collaborator

slouken commented Dec 24, 2024

Actually, I'm going to go ahead and merge this, and then work on the SDL BMP fixes separately.

Thanks!

@slouken slouken merged commit 8a0f649 into libsdl-org:main Dec 24, 2024
38 of 39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants