From dc94d6a4aa630c46b2e28701a15a2bd9b366fd02 Mon Sep 17 00:00:00 2001 From: June McEnroe Date: Sun, 23 Jan 2022 16:03:22 -0500 Subject: Account for ICOs lying about bpp, drop BITMAPCOREHEADER --- tools/ico2png.c | 45 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 25 deletions(-) (limited to 'tools/ico2png.c') diff --git a/tools/ico2png.c b/tools/ico2png.c index 71644b6..6e79ed7 100644 --- a/tools/ico2png.c +++ b/tools/ico2png.c @@ -128,7 +128,7 @@ int main(int argc, char *argv[]) { icon.colors = SDL_ReadU8(ico); SDL_ReadU8(ico); // reserved icon.planes = SDL_ReadLE16(ico); - icon.bpp = SDL_ReadLE16(ico); + icon.bpp = SDL_ReadLE16(ico); // some ICOs lie about this... icon.length = SDL_ReadLE32(ico); icon.offset = SDL_ReadLE32(ico); Uint32 score = icon.width * icon.height * icon.colors; @@ -158,37 +158,32 @@ int main(int argc, char *argv[]) { pngWrite(png, zero, 3); pngUint32(png, ~pngCRC); - // Copy the palette, reserving index 0 for transparency. We assume at most - // 255 colors will be used by the icon. + // Read the real bpp and palette count from the DIB header SDL_RWseek(ico, bestIcon.offset, RW_SEEK_SET); Uint32 dibHeaderLength = SDL_ReadLE32(ico); - Uint32 paletteCount = 1 << bestIcon.bpp; - Uint8 *palette = calloc(1 + paletteCount, 3); - if (!palette) errx(1, "calloc failed"); - if (dibHeaderLength == 0x0C) { - SDL_RWseek(ico, bestIcon.offset + dibHeaderLength, RW_SEEK_SET); - for (Uint32 i = 0; i < paletteCount; ++i) { - palette[3 * (i + 1) + 2] = SDL_ReadU8(ico); - palette[3 * (i + 1) + 1] = SDL_ReadU8(ico); - palette[3 * (i + 1) + 0] = SDL_ReadU8(ico); - } - } else if (dibHeaderLength == 0x28) { - SDL_RWseek(ico, 0x1C, RW_SEEK_CUR); - paletteCount = SDL_ReadLE32(ico); - if (!paletteCount) paletteCount = 1 << bestIcon.bpp; - SDL_RWseek(ico, bestIcon.offset + dibHeaderLength, RW_SEEK_SET); - for (Uint32 i = 0; i < paletteCount; ++i) { - palette[3 * (i + 1) + 2] = SDL_ReadU8(ico); - palette[3 * (i + 1) + 1] = SDL_ReadU8(ico); - palette[3 * (i + 1) + 0] = SDL_ReadU8(ico); - SDL_ReadU8(ico); - } - } else { + if (dibHeaderLength != 0x28) { errx( 1, "%s: unrecognized DIB header length %u", icoPath, dibHeaderLength ); } + SDL_RWseek(ico, 0x0A, RW_SEEK_CUR); + bestIcon.bpp = SDL_ReadLE16(ico); // the truth + SDL_RWseek(ico, 0x10, RW_SEEK_CUR); + Uint32 paletteCount = SDL_ReadLE32(ico); + if (!paletteCount) paletteCount = 1 << bestIcon.bpp; + + // Copy the palette, reserving index 0 for transparency. We assume at most + // 255 colors will be used by the icon. + Uint8 *palette = calloc(1 + paletteCount, 3); + if (!palette) errx(1, "calloc failed"); + SDL_RWseek(ico, bestIcon.offset + dibHeaderLength, RW_SEEK_SET); + for (Uint32 i = 0; i < paletteCount; ++i) { + palette[3 * (i + 1) + 2] = SDL_ReadU8(ico); + palette[3 * (i + 1) + 1] = SDL_ReadU8(ico); + palette[3 * (i + 1) + 0] = SDL_ReadU8(ico); + SDL_ReadU8(ico); + } pngChunk(png, "PLTE", 3 * (1 + paletteCount)); pngWrite(png, palette, 3 * (1 + paletteCount)); pngUint32(png, ~pngCRC); -- cgit 1.4.1