Add additional error checking to helpers.

This commit is contained in:
Jeroen van Rijn
2021-10-06 20:10:37 +02:00
parent 2e9eec156c
commit 21c6d691d8
6 changed files with 176 additions and 143 deletions
+38 -34
View File
@@ -34,15 +34,17 @@ destroy :: proc(img: ^Image) {
}
bytes.buffer_destroy(&img.pixels)
assert(img.metadata_ptr != nil && img.metadata_type == Info)
v := (^Info)(img.metadata_ptr)
for chunk in &v.chunks {
delete(chunk.data)
}
delete(v.chunks)
// Clean up Info.
free(img.metadata_ptr)
/*
We don't need to do anything for the individual chunks.
They're allocated on the temp allocator, as is info.chunks
See read_chunk.
*/
free(img)
}
@@ -50,46 +52,50 @@ destroy :: proc(img: ^Image) {
Chunk helpers
*/
gamma :: proc(c: Chunk) -> f32 {
assert(c.header.type == .gAMA)
res := (^gAMA)(raw_data(c.data))^
when true {
// Returns the wrong result on old backend
// Fixed for -llvm-api
return f32(res.gamma_100k) / 100_000.0
} else {
return f32(u32(res.gamma_100k)) / 100_000.0
gamma :: proc(c: Chunk) -> (res: f32, ok: bool) {
if c.header.type != .gAMA || len(c.data) != size_of(gAMA) {
return {}, false
}
gama := (^gAMA)(raw_data(c.data))^
return f32(gama.gamma_100k) / 100_000.0, true
}
INCHES_PER_METER :: 1000.0 / 25.4
phys :: proc(c: Chunk) -> pHYs {
assert(c.header.type == .pHYs)
res := (^pHYs)(raw_data(c.data))^
return res
phys :: proc(c: Chunk) -> (res: pHYs, ok: bool) {
if c.header.type != .pHYs || len(c.data) != size_of(pHYs) {
return {}, false
}
return (^pHYs)(raw_data(c.data))^, true
}
phys_to_dpi :: proc(p: pHYs) -> (x_dpi, y_dpi: f32) {
return f32(p.ppu_x) / INCHES_PER_METER, f32(p.ppu_y) / INCHES_PER_METER
}
time :: proc(c: Chunk) -> tIME {
assert(c.header.type == .tIME)
res := (^tIME)(raw_data(c.data))^
return res
time :: proc(c: Chunk) -> (res: tIME, ok: bool) {
if c.header.type != .tIME || len(c.data) != size_of(tIME) {
return {}, false
}
return (^tIME)(raw_data(c.data))^, true
}
core_time :: proc(c: Chunk) -> (t: coretime.Time, ok: bool) {
png_time := time(c)
using png_time
return coretime.datetime_to_time(
int(year), int(month), int(day),
int(hour), int(minute), int(second),
)
if png_time, png_ok := time(c); png_ok {
using png_time
return coretime.datetime_to_time(
int(year), int(month), int(day),
int(hour), int(minute), int(second),
)
} else {
return {}, false
}
}
text :: proc(c: Chunk) -> (res: Text, ok: bool) {
assert(len(c.data) == int(c.header.length))
#partial switch c.header.type {
case .tEXt:
ok = true
@@ -228,9 +234,7 @@ iccp_destroy :: proc(i: iCCP) {
}
srgb :: proc(c: Chunk) -> (res: sRGB, ok: bool) {
ok = true
if c.header.type != .sRGB || len(c.data) != 1 {
if c.header.type != .sRGB || len(c.data) != size_of(sRGB_Rendering_Intent) {
return {}, false
}
@@ -238,7 +242,7 @@ srgb :: proc(c: Chunk) -> (res: sRGB, ok: bool) {
if res.intent > max(sRGB_Rendering_Intent) {
ok = false; return
}
return
return res, true
}
plte :: proc(c: Chunk) -> (res: PLTE, ok: bool) {