png: Move metadata.

This commit is contained in:
Jeroen van Rijn
2021-10-06 22:43:33 +02:00
parent 263d63aa56
commit c4b4a841d6
5 changed files with 218 additions and 222 deletions
+99 -6
View File
@@ -26,8 +26,11 @@ Image :: struct {
*/
background: Maybe([3]u16),
metadata_ptr: rawptr,
metadata_type: typeid,
metadata: Image_Metadata,
}
Image_Metadata :: union {
^PNG_Info,
}
/*
@@ -152,10 +155,101 @@ PNG_Error :: enum {
Invalid_Chunk_Length,
}
/*
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
}