diff options
| author | Jeroen van Rijn <Kelimion@users.noreply.github.com> | 2024-06-06 16:32:18 +0200 |
|---|---|---|
| committer | Jeroen van Rijn <Kelimion@users.noreply.github.com> | 2024-06-06 16:32:18 +0200 |
| commit | 678fdae966e0e4b959a917f11d276b60fb78772f (patch) | |
| tree | 75162c9da40285c635ed7f99af1901273c26a7c5 /core/image/common.odin | |
| parent | 3a9b86628a484aa03b594599653c1cab4b916c8e (diff) | |
Rebased.
Diffstat (limited to 'core/image/common.odin')
| -rw-r--r-- | core/image/common.odin | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/core/image/common.odin b/core/image/common.odin index b576a9521..fe75371b3 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -12,6 +12,7 @@ package image import "core:bytes" import "core:mem" +import "core:io" import "core:compress" import "base:runtime" @@ -62,6 +63,7 @@ Image_Metadata :: union #shared_nil { ^PNG_Info, ^QOI_Info, ^TGA_Info, + ^BMP_Info, } @@ -159,11 +161,13 @@ Error :: union #shared_nil { Netpbm_Error, PNG_Error, QOI_Error, + BMP_Error, compress.Error, compress.General_Error, compress.Deflate_Error, compress.ZLIB_Error, + io.Error, runtime.Allocator_Error, } @@ -197,6 +201,128 @@ General_Image_Error :: enum { } /* + BMP-specific +*/ +BMP_Error :: enum { + None = 0, + Invalid_File_Size, + Unsupported_BMP_Version, + Unsupported_OS2_File, + Unsupported_Compression, + Unsupported_BPP, + Invalid_Stride, + Invalid_Color_Count, + Implausible_File_Size, + Bitfield_Version_Unhandled, // We don't (yet) handle bit fields for this BMP version. + Bitfield_Sum_Exceeds_BPP, // Total mask bit count > bpp + Bitfield_Overlapped, // Channel masks overlap +} + +// img.metadata is wrapped in a struct in case we need to add to it later +// without putting it in BMP_Header +BMP_Info :: struct { + info: BMP_Header, +} + +BMP_Magic :: enum u16le { + Bitmap = 0x4d42, // 'BM' + OS2_Bitmap_Array = 0x4142, // 'BA' + OS2_Icon = 0x4349, // 'IC', + OS2_Color_Icon = 0x4943, // 'CI' + OS2_Pointer = 0x5450, // 'PT' + OS2_Color_Pointer = 0x5043, // 'CP' +} + +// See: http://justsolve.archiveteam.org/wiki/BMP#Well-known_versions +BMP_Version :: enum u32le { + OS2_v1 = 12, // BITMAPCOREHEADER (Windows V2 / OS/2 version 1.0) + OS2_v2 = 64, // BITMAPCOREHEADER2 (OS/2 version 2.x) + V3 = 40, // BITMAPINFOHEADER + V4 = 108, // BITMAPV4HEADER + V5 = 124, // BITMAPV5HEADER + + ABBR_16 = 16, // Abbreviated + ABBR_24 = 24, // .. + ABBR_48 = 48, // .. + ABBR_52 = 52, // .. + ABBR_56 = 56, // .. +} + +BMP_Header :: struct #packed { + // File header + magic: BMP_Magic, + size: u32le, + _res1: u16le, // Reserved; must be zero + _res2: u16le, // Reserved; must be zero + pixel_offset: u32le, // Offset in bytes, from the beginning of BMP_Header to the pixel data + // V3 + info_size: BMP_Version, + width: i32le, + height: i32le, + planes: u16le, + bpp: u16le, + compression: BMP_Compression, + image_size: u32le, + pels_per_meter: [2]u32le, + colors_used: u32le, + colors_important: u32le, // OS2_v2 is equal up to here + // V4 + masks: [4]u32le `fmt:"32b"`, + colorspace: BMP_Logical_Color_Space, + endpoints: BMP_CIEXYZTRIPLE, + gamma: [3]BMP_GAMMA16_16, + // V5 + intent: BMP_Gamut_Mapping_Intent, + profile_data: u32le, + profile_size: u32le, + reserved: u32le, +} +#assert(size_of(BMP_Header) == 138) + +OS2_Header :: struct #packed { + // BITMAPCOREHEADER minus info_size field + width: i16le, + height: i16le, + planes: u16le, + bpp: u16le, +} +#assert(size_of(OS2_Header) == 8) + +BMP_Compression :: enum u32le { + RGB = 0x0000, + RLE8 = 0x0001, + RLE4 = 0x0002, + Bit_Fields = 0x0003, // If Windows + Huffman1D = 0x0003, // If OS2v2 + JPEG = 0x0004, // If Windows + RLE24 = 0x0004, // If OS2v2 + PNG = 0x0005, + Alpha_Bit_Fields = 0x0006, + CMYK = 0x000B, + CMYK_RLE8 = 0x000C, + CMYK_RLE4 = 0x000D, +} + +BMP_Logical_Color_Space :: enum u32le { + CALIBRATED_RGB = 0x00000000, + sRGB = 0x73524742, // 'sRGB' + WINDOWS_COLOR_SPACE = 0x57696E20, // 'Win ' +} + +BMP_FXPT2DOT30 :: u32le +BMP_CIEXYZ :: [3]BMP_FXPT2DOT30 +BMP_CIEXYZTRIPLE :: [3]BMP_CIEXYZ +BMP_GAMMA16_16 :: [2]u16le + +BMP_Gamut_Mapping_Intent :: enum u32le { + INVALID = 0x00000000, // If not V5, this field will just be zero-initialized and not valid. + ABS_COLORIMETRIC = 0x00000008, + BUSINESS = 0x00000001, + GRAPHICS = 0x00000002, + IMAGES = 0x00000004, +} + +/* Netpbm-specific definitions */ Netpbm_Format :: enum { |