diff options
Diffstat (limited to 'core/image/common.odin')
| -rw-r--r-- | core/image/common.odin | 105 |
1 files changed, 99 insertions, 6 deletions
diff --git a/core/image/common.odin b/core/image/common.odin index 2826a65ca..919670a61 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -26,8 +26,11 @@ Image :: struct { */ background: Maybe([3]u16), - metadata_ptr: rawptr, - metadata_type: typeid, + metadata: Image_Metadata, +} + +Image_Metadata :: union { + ^PNG_Info, } /* @@ -153,9 +156,100 @@ PNG_Error :: enum { } /* - Functions to help with image buffer calculations + PNG-specific structs */ +PNG_Info :: struct { + header: PNG_IHDR, + chunks: [dynamic]PNG_Chunk, +} + +PNG_Chunk_Header :: struct #packed { + length: u32be, + type: PNG_Chunk_Type, +} + +PNG_Chunk :: struct #packed { + header: PNG_Chunk_Header, + data: []byte, + crc: u32be, +} + +PNG_Chunk_Type :: enum u32be { + // IHDR must come first in a file + IHDR = 'I' << 24 | 'H' << 16 | 'D' << 8 | 'R', + // PLTE must precede the first IDAT chunk + PLTE = 'P' << 24 | 'L' << 16 | 'T' << 8 | 'E', + bKGD = 'b' << 24 | 'K' << 16 | 'G' << 8 | 'D', + tRNS = 't' << 24 | 'R' << 16 | 'N' << 8 | 'S', + IDAT = 'I' << 24 | 'D' << 16 | 'A' << 8 | 'T', + + iTXt = 'i' << 24 | 'T' << 16 | 'X' << 8 | 't', + tEXt = 't' << 24 | 'E' << 16 | 'X' << 8 | 't', + zTXt = 'z' << 24 | 'T' << 16 | 'X' << 8 | 't', + + iCCP = 'i' << 24 | 'C' << 16 | 'C' << 8 | 'P', + pHYs = 'p' << 24 | 'H' << 16 | 'Y' << 8 | 's', + gAMA = 'g' << 24 | 'A' << 16 | 'M' << 8 | 'A', + tIME = 't' << 24 | 'I' << 16 | 'M' << 8 | 'E', + + sPLT = 's' << 24 | 'P' << 16 | 'L' << 8 | 'T', + sRGB = 's' << 24 | 'R' << 16 | 'G' << 8 | 'B', + hIST = 'h' << 24 | 'I' << 16 | 'S' << 8 | 'T', + cHRM = 'c' << 24 | 'H' << 16 | 'R' << 8 | 'M', + sBIT = 's' << 24 | 'B' << 16 | 'I' << 8 | 'T', + + /* + eXIf tags are not part of the core spec, but have been ratified + in v1.5.0 of the PNG Ext register. + + We will provide unprocessed chunks to the caller if `.return_metadata` is set. + Applications are free to implement an Exif decoder. + */ + eXIf = 'e' << 24 | 'X' << 16 | 'I' << 8 | 'f', + + // PNG files must end with IEND + IEND = 'I' << 24 | 'E' << 16 | 'N' << 8 | 'D', + + /* + XCode sometimes produces "PNG" files that don't adhere to the PNG spec. + We recognize them only in order to avoid doing further work on them. + + Some tools like PNG Defry may be able to repair them, but we're not + going to reward Apple for producing proprietary broken files purporting + to be PNGs by supporting them. + + */ + iDOT = 'i' << 24 | 'D' << 16 | 'O' << 8 | 'T', + CbGI = 'C' << 24 | 'b' << 16 | 'H' << 8 | 'I', +} + +PNG_IHDR :: struct #packed { + width: u32be, + height: u32be, + bit_depth: u8, + color_type: PNG_Color_Type, + compression_method: u8, + filter_method: u8, + interlace_method: PNG_Interlace_Method, +} +PNG_IHDR_SIZE :: size_of(PNG_IHDR) +#assert (PNG_IHDR_SIZE == 13) +PNG_Color_Value :: enum u8 { + Paletted = 0, // 1 << 0 = 1 + Color = 1, // 1 << 1 = 2 + Alpha = 2, // 1 << 2 = 4 +} +PNG_Color_Type :: distinct bit_set[PNG_Color_Value; u8] + +PNG_Interlace_Method :: enum u8 { + None = 0, + Adam7 = 1, +} + +/* + Functions to help with image buffer calculations +*/ compute_buffer_size :: proc(width, height, channels, depth: int, extra_row_bytes := int(0)) -> (size: int) { size = ((((channels * width * depth) + 7) >> 3) + extra_row_bytes) * height return @@ -164,7 +258,6 @@ compute_buffer_size :: proc(width, height, channels, depth: int, extra_row_bytes /* For when you have an RGB(A) image, but want a particular channel. */ - Channel :: enum u8 { R = 1, G = 2, @@ -226,8 +319,8 @@ return_single_channel :: proc(img: ^Image, channel: Channel) -> (res: ^Image, ok res.depth = img.depth res.pixels = t res.background = img.background - res.metadata_ptr = img.metadata_ptr - res.metadata_type = img.metadata_type + // res.metadata_ptr = img.metadata_ptr + // res.metadata_type = img.metadata_type return res, true } |