diff --git a/patterns/bmp.hexpat b/patterns/bmp.hexpat index f7345a9..4fb201d 100644 --- a/patterns/bmp.hexpat +++ b/patterns/bmp.hexpat @@ -10,13 +10,38 @@ struct BitmapFileHeader { u32 bfOffBits; }; -struct BitmapInfoHeader { +enum Compression : u32 { + BI_RGB, + BI_RLE8, + BI_RLE4, + BI_BITFIELDS, + BI_JPEG, + BI_PNG, + BI_ALPHABITFIELDS, + BI_CMYK, + BI_CMYKRLE8, + BI_CMYKRLE4, +}; + +struct CIEXYZ { + u32 ciexyzX; + u32 ciexyzY; + u32 ciexyzZ; +}; + +struct CIEXYZTRIPLE { + CIEXYZ ciexyzRed; + CIEXYZ ciexyzGreen; + CIEXYZ ciexyzBlue; +}; + +struct BitmapInfoHeaderV1 { u32 biSize; s32 biWidth; s32 biHeight; u16 biPlanes; u16 biBitCount; - u32 biCompression; + Compression biCompression; u32 biSizeImage; s32 biXPelsPerMeter; s32 biYPelsPerMeter; @@ -24,6 +49,31 @@ struct BitmapInfoHeader { u32 biClrImportant; }; +struct BitmapInfoHeaderV2 : BitmapInfoHeaderV1 { + u32 biRedMask; + u32 biGreenMask; + u32 biBlueMask; +}; + +struct BitmapInfoHeaderV3 : BitmapInfoHeaderV2 { + u32 biAlphaMask; +}; + +struct BitmapInfoHeaderV4 : BitmapInfoHeaderV3 { + u32 biCSType; + CIEXYZTRIPLE biEndpoints; + u32 biGammaRed; + u32 biGammaGreen; + u32 biGammaBlue; +}; + +struct BitmapInfoHeaderV5 : BitmapInfoHeaderV4 { + u32 biIntent; + u32 biProfileData; + u32 biProfileSize; + u32 biReserved; +}; + struct Colors { u8 blue; u8 green; @@ -32,11 +82,21 @@ struct Colors { }; struct Bitmap { - u8 data[std::mem::size()] [[no_unique_address, hidden]]; + u8 data[std::mem::size()] [[no_unique_address, hidden]]; BitmapFileHeader bmfh; - BitmapInfoHeader bmih; + // Deduce the header version from its size + u32 bmInfoHeaderSize [[hidden, no_unique_address]]; + match (bmInfoHeaderSize) { + (40): BitmapInfoHeaderV1 bmih; + (52): BitmapInfoHeaderV2 bmih; + (56): BitmapInfoHeaderV3 bmih; + (108): BitmapInfoHeaderV4 bmih; + (124): BitmapInfoHeaderV5 bmih; + (_): BitmapInfoHeaderV1 bmih; + } + padding[bmih.biSize - sizeof(bmih)]; - if ((bmih.biBitCount != 24) && (bmih.biBitCount != 32)) + if (bmih.biBitCount <= 8) { if (bmih.biClrUsed > 0 ) Colors rgbq[bmih.biClrUsed];