From 12ed2f24020b95e0699f48864962da819414fd44 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Fri, 22 Oct 2021 18:51:20 +0200 Subject: [PATCH] Add support for palette icon formats To support more icon formats. --- app/src/icon.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/app/src/icon.c b/app/src/icon.c index 119c5eeb..607c7162 100644 --- a/app/src/icon.c +++ b/app/src/icon.c @@ -173,6 +173,7 @@ to_sdl_pixel_format(enum AVPixelFormat fmt) { case AV_PIX_FMT_BGR555BE: return SDL_PIXELFORMAT_BGR555; case AV_PIX_FMT_RGB444BE: return SDL_PIXELFORMAT_RGB444; case AV_PIX_FMT_BGR444BE: return SDL_PIXELFORMAT_BGR444; + case AV_PIX_FMT_PAL8: return SDL_PIXELFORMAT_INDEX8; default: return SDL_PIXELFORMAT_UNKNOWN; } } @@ -190,10 +191,9 @@ load_from_path(const char *path) { goto error; } - bool is_packed_rgb = desc->flags & AV_PIX_FMT_FLAG_RGB - && !(desc->flags & AV_PIX_FMT_FLAG_PLANAR); - if (!is_packed_rgb) { - LOGE("Could not load non-RGB icon"); + bool is_packed = !(desc->flags & AV_PIX_FMT_FLAG_PLANAR); + if (!is_packed) { + LOGE("Could not load non-packed icon"); goto error; } @@ -217,6 +217,41 @@ load_from_path(const char *path) { goto error; } + if (frame->format == AV_PIX_FMT_PAL8) { + // Initialize the SDL palette + uint8_t *data = frame->data[1]; + SDL_Color colors[256]; + for (int i = 0; i < 256; ++i) { + SDL_Color *color = &colors[i]; + + // The palette is transported in AVFrame.data[1], is 1024 bytes + // long (256 4-byte entries) and is formatted the same as in + // AV_PIX_FMT_RGB32 described above (i.e., it is also + // endian-specific). + // +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + color->a = data[i * 4]; + color->r = data[i * 4 + 1]; + color->g = data[i * 4 + 2]; + color->b = data[i * 4 + 3]; +#else + color->a = data[i * 4 + 3]; + color->r = data[i * 4 + 2]; + color->g = data[i * 4 + 1]; + color->b = data[i * 4]; +#endif + } + + SDL_Palette *palette = surface->format->palette; + assert(palette); + int ret = SDL_SetPaletteColors(palette, colors, 0, 256); + if (ret) { + LOGE("Could not set palette colors"); + SDL_FreeSurface(surface); + goto error; + } + } + surface->userdata = frame; // frame owns the data return surface;