diff options
-rw-r--r-- | cards.c | 45 | ||||
-rw-r--r-- | cards.h | 1 | ||||
-rw-r--r-- | dump.c | 10 |
3 files changed, 55 insertions, 1 deletions
diff --git a/cards.c b/cards.c index 174b081..29aa7a4 100644 --- a/cards.c +++ b/cards.c @@ -358,6 +358,51 @@ fail: return NULL; } +int invertPalette(SDL_Surface *surface) { + const SDL_Palette *palette = surface->format->palette; + SDL_Palette *invert = SDL_AllocPalette(palette->ncolors); + if (!invert) return -1; + for (int i = 0; i < invert->ncolors; ++i) { + invert->colors[i].r = ~palette->colors[i].r; + invert->colors[i].g = ~palette->colors[i].g; + invert->colors[i].b = ~palette->colors[i].b; + invert->colors[i].a = palette->colors[i].a; + } + if (SDL_SetSurfacePalette(surface, invert) < 0) return -1; + SDL_FreePalette(invert); + return 0; +} + +int invertPixels(SDL_Surface *surface) { + if (SDL_LockSurface(surface) < 0) return -1; + Uint8 *pixels = surface->pixels; + for (int y = 0; y < surface->h; ++y) { + Uint32 *row = (Uint32 *)&pixels[y * surface->pitch]; + for (int x = 0; x < surface->w; ++x) { + Uint32 color = ~row[x] & ~surface->format->Amask; + Uint32 alpha = row[x] & surface->format->Amask; + row[x] = color | alpha; + } + } + SDL_UnlockSurface(surface); + return 0; +} + +int Cards_Invert(struct Cards *cards) { + for (int i = 0; i < Cards_Count; ++i) { + if (!cards->surfaces[i]) continue; + if (cards->surfaces[i]->format->palette) { + if (invertPalette(cards->surfaces[i]) < 0) return -1; + } else if (cards->surfaces[i]->format->BytesPerPixel == 4) { + if (invertPixels(cards->surfaces[i]) < 0) return -1; + } else { + SDL_SetError("unexpected surface format"); + return -1; + } + } + return 0; +} + void Cards_Free(struct Cards *cards) { for (int i = 0; i < Cards_Count; ++i) { if (!cards->surfaces[i]) continue; diff --git a/cards.h b/cards.h index 0ed1b8f..8cd99c4 100644 --- a/cards.h +++ b/cards.h @@ -62,6 +62,7 @@ enum Cards_Flags { }; struct Cards *Cards_Load(SDL_RWops *rw, enum Cards_Flags flags); +int Cards_Invert(struct Cards *cards); void Cards_Free(struct Cards *cards); #endif diff --git a/dump.c b/dump.c index 5ad4456..474af92 100644 --- a/dump.c +++ b/dump.c @@ -15,6 +15,7 @@ */ #include <err.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <sysexits.h> @@ -26,12 +27,14 @@ int main(int argc, char *argv[]) { enum Cards_Flags flags = 0; + bool invert = false; int opt; - while (0 < (opt = getopt(argc, argv, "abk"))) { + while (0 < (opt = getopt(argc, argv, "abik"))) { switch (opt) { break; case 'a': flags |= Cards_AlphaCorners; break; case 'b': flags |= Cards_BlackBorders; + break; case 'i': invert = true; break; case 'k': flags |= Cards_ColorKey; break; default: return EX_USAGE; } @@ -49,6 +52,11 @@ int main(int argc, char *argv[]) { if (!cards) errx(EX_DATAERR, "Cards_Load: %s", SDL_GetError()); SDL_RWclose(rw); + if (invert) { + int error = Cards_Invert(cards); + if (error) errx(EX_DATAERR, "Cards_Invert: %s", SDL_GetError()); + } + for (int i = 0; i < Cards_Count; ++i) { if (!cards->surfaces[i]) continue; char name[sizeof("00.bmp")]; |