aboutsummaryrefslogtreecommitdiff
path: root/core/image/common.odin
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2024-06-06 16:32:18 +0200
committerJeroen van Rijn <Kelimion@users.noreply.github.com>2024-06-06 16:32:18 +0200
commit678fdae966e0e4b959a917f11d276b60fb78772f (patch)
tree75162c9da40285c635ed7f99af1901273c26a7c5 /core/image/common.odin
parent3a9b86628a484aa03b594599653c1cab4b916c8e (diff)
Rebased.
Diffstat (limited to 'core/image/common.odin')
-rw-r--r--core/image/common.odin126
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 {