aboutsummaryrefslogtreecommitdiff
path: root/core/image/common.odin
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2021-10-06 22:43:33 +0200
committerJeroen van Rijn <Kelimion@users.noreply.github.com>2021-10-06 22:43:33 +0200
commitc4b4a841d68f4bde69f4e1472b7d8fa24f96a376 (patch)
tree5fb212b07e4941e164d2ea66b201158bee798ddc /core/image/common.odin
parent263d63aa5678276532776c129829b6a77f56bcad (diff)
png: Move metadata.
Diffstat (limited to 'core/image/common.odin')
-rw-r--r--core/image/common.odin105
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
}