Re: BUG IN SDL - Blitting to a packed indexed surface
Sam Lantinga <[email protected]> Sat, 31 Dec 2016 18:12:58 -0800
| Newsgroups | gmane.comp.lib.sdl |
|---|---|
| Message-ID | <CACC3sbFQtFtTFKZBm-u5Pi_oM+W_HESo_hSvDMo2-c_qoAoYqQ@mail.gmail.com> |
SDL doesn't currently have any bitmap blitters. This should have returned an error, and that's fixed. https://hg.libsdl.org/SDL/rev/754cac536474 Thanks! On Fri, Dec 23, 2016 at 6:02 PM, geoffp <[email protected]> wrote: > I'm pretty sure the following is a bug in SDL. > > When SDL_BlitSurface has a target with a two-colour (i.e. 1-bit depth) > packed (8 pixels per byte) format, it will in some situations try to write > 1 byte per pixel. Since the target doesn't have enough memory space to > accommodate this, pixel data may get written to regions in RAM where it has > no business being, potentially causing a crash. > > A minimal program to demonstrate the effect is as follows. I ran this with > SDL-2.0.5 on a 32-bit Windows platform. > > > > > Code: > > > // Make test surfaces in two formats, 32-bit ARGB and 1-bit two-colour: > SDL_Surface *s32 = SDL_CreateRGBSurface(0, 30, 10, 32, 0xff0000, > 0x00ff00, 0x0000ff, 0xff000000); > SDL_Surface *s01 = SDL_ConvertSurfaceFormat(s32, > SDL_PIXELFORMAT_INDEX1LSB, 0); > > // Set a palette for the indexed surface. > // (It already has a default palette (white, black), but for some reason > this bug > // appears only if the palette is first changed to (black, white). I've > no idea why.) > SDL_Color c[2] = { {0,0,0,0xff}, {0xff,0xff,0xff,0xff} }; > SDL_SetPaletteColors(s01->format->palette, c, 0, 2); > > // Confirm that these formats are as expected: > printf("s32 pitch = %d bytes per row\n", s32->pitch); // 120 (4 bytes > per pixel) > printf("s01 pitch = %d bytes per row\n", s01->pitch); // 4 (8 pixels > per byte) > > // Place a white rectangle on the (default-initialized) transparent > background of s32: > SDL_Rect rect = { 1, 1, 5, 3 }; > SDL_FillRect(s32, &rect, 0xffffffff); > > // Blit the s32 image to s01: > int result = SDL_BlitSurface(s32, NULL, s01, NULL); > printf("SDL_BlitSurface result = %d\n", result); > > // Show the s01 pixel data: > printf("s01: %d x %d surface:\n", s01->w, s01->h); > for(int r = 0; r != s01->h; r++) > { > for(int b = 0; b != s01->pitch; b++) > printf("%x ", *((Uint8*)(s01->pixels) + r * s01->pitch + b) ); > printf("\n"); > } > > > > The output I get is: > > > > > Code: > > > s32 pitch = 120 bytes per row > s01 pitch = 4 bytes per row > SDL_BlitSurface result = 0 > s01: 30 x 10 surface: > 0 0 0 0 > 0 1 1 1 > 1 1 1 1 > 1 1 1 1 > 1 1 0 0 > 0 0 0 0 > 0 0 0 0 > 0 0 0 0 > 0 0 0 0 > 0 0 0 0 > > > > > It seems that SDL_BlitSurface has forgotten that its target surface has a > packed format, and is trying to write 1 byte per pixel. > > Note that if properly packed pixel data is put on this kind of surface, it > blits just fine in the other direction, when it is the source instead of > the destination. > > _______________________________________________ > SDL mailing list > [email protected] > http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org > > _______________________________________________ SDL mailing list [email protected] http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org