Fixed bug #2140: basic support to convert 16 colors palette PIXELFORMAT_INDEX4, to allow conversion to SDL_Texture
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
diff --git a/src/video/SDL_blit_0.c b/src/video/SDL_blit_0.c
index e2eecba..54882f8 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 0b40bb2..13872d2 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) {