From a75041e8dd820b89e746c737f58d0163e100a3e6 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Thu, 10 Feb 2022 13:44:59 +0100 Subject: [PATCH] Fixed bug #2140: basic support to convert 16 colors palette PIXELFORMAT_INDEX4, to allow conversion to SDL_Texture --- src/video/SDL_blit_0.c | 83 ++++++++++++++++++++++++++++++++++++++++ src/video/SDL_fillrect.c | 22 ++++++++--- 2 files changed, 100 insertions(+), 5 deletions(-) diff --git a/src/video/SDL_blit_0.c b/src/video/SDL_blit_0.c index e2eecba7d..54882f8b1 100644 --- a/src/video/SDL_blit_0.c +++ b/src/video/SDL_blit_0.c @@ -452,11 +452,94 @@ static const SDL_BlitFunc colorkey_blit[] = { (SDL_BlitFunc) NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key }; + +static void +Blit4bto4(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + Uint32 *dst = (Uint32 *) info->dst; + int srcskip = info->src_skip; + int dstskip = info->dst_skip; + Uint32 *map = (Uint32 *) info->table; + int c; + + /* Set up some basic variables */ + srcskip += width - (width + 1) / 2; + + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if ((c & 0x1) == 0) { + byte = *src++; + } + bit = (byte & 0xF0) >> 4; + if (1) { + *dst = map[bit]; + } + byte <<= 4; + dst++; + } + src += srcskip; + dst = (Uint32 *) ((Uint8 *) dst + dstskip); + } +} + +static void +Blit4bto4Key(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + Uint32 *dst = (Uint32 *) info->dst; + int srcskip = info->src_skip; + int dstskip = info->dst_skip; + Uint32 ckey = info->colorkey; + Uint32 *map = (Uint32 *) info->table; + int c; + + /* Set up some basic variables */ + srcskip += width - (width + 1) / 2; + + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if ((c & 0x1) == 0) { + byte = *src++; + } + bit = (byte & 0xF0) >> 4; + if (bit != ckey) { + *dst = map[bit]; + } + byte <<= 4; + dst++; + } + src += srcskip; + dst = (Uint32 *) ((Uint8 *) dst + dstskip); + } +} + SDL_BlitFunc SDL_CalculateBlit0(SDL_Surface * surface) { int which; + /* 4bits to 32bits */ + if (surface->format->BitsPerPixel == 4) { + if (surface->map->dst->format->BytesPerPixel == 4) { + switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) { + case 0: + return Blit4bto4; + + case SDL_COPY_COLORKEY: + return Blit4bto4Key; + } + } + /* We don't fully support 4-bit packed pixel modes */ + return NULL; + } + if (surface->format->BitsPerPixel != 1) { /* We don't support sub 8-bit packed pixel modes */ return (SDL_BlitFunc) NULL; diff --git a/src/video/SDL_fillrect.c b/src/video/SDL_fillrect.c index 0b40bb25c..13872d271 100644 --- a/src/video/SDL_fillrect.c +++ b/src/video/SDL_fillrect.c @@ -309,11 +309,6 @@ SDL_FillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, return SDL_InvalidParamError("SDL_FillRects(): dst"); } - /* This function doesn't work on surfaces < 8 bpp */ - if (dst->format->BitsPerPixel < 8) { - return SDL_SetError("SDL_FillRects(): Unsupported surface format"); - } - /* Nothing to do */ if (dst->w == 0 || dst->h == 0) { return 0; @@ -328,6 +323,23 @@ SDL_FillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, return SDL_InvalidParamError("SDL_FillRects(): rects"); } + /* This function doesn't usually work on surfaces < 8 bpp + * Except: support for 4bits, when filling full size. + */ + if (dst->format->BitsPerPixel < 8) { + if (count == 1) { + const SDL_Rect *r = &rects[0]; + if (r->x == 0 && r->y == 0 && r->w == dst->w && r->w == dst->h) { + if (dst->format->BitsPerPixel == 4) { + Uint8 b = (((Uint8) color << 4) | (Uint8) color); + SDL_memset(dst->pixels, b, dst->h * dst->pitch); + return 1; + } + } + } + return SDL_SetError("SDL_FillRects(): Unsupported surface format"); + } + #if SDL_ARM_NEON_BLITTERS if (SDL_HasNEON() && dst->format->BytesPerPixel != 3 && fill_function == NULL) { switch (dst->format->BytesPerPixel) {