Replace core:image's sidecar with explicit metadata_ptr and metadata_type.

To unpack, use:
```odin

v: ^png.Info;

if img.metadata_ptr != nil && img.metadata_type == png.Info {
	v = (^png.Info)(img.metadata_ptr);
	...
}
```
This commit is contained in:
Jeroen van Rijn
2021-06-21 16:32:42 +02:00
parent 18471f358e
commit e036a321a0
3 changed files with 23 additions and 23 deletions
+17 -14
View File
@@ -4,18 +4,20 @@ import "core:bytes"
import "core:mem" import "core:mem"
Image :: struct { Image :: struct {
width: int, width: int,
height: int, height: int,
channels: int, channels: int,
depth: int, depth: int,
pixels: bytes.Buffer, pixels: bytes.Buffer,
/* /*
Some image loaders/writers can return/take an optional background color. Some image loaders/writers can return/take an optional background color.
For convenience, we return them as u16 so we don't need to switch on the type For convenience, we return them as u16 so we don't need to switch on the type
in our viewer, and can just test against nil. in our viewer, and can just test against nil.
*/ */
background: Maybe([3]u16), background: Maybe([3]u16),
sidecar: any,
metadata_ptr: rawptr,
metadata_type: typeid,
} }
/* /*
@@ -190,13 +192,14 @@ return_single_channel :: proc(img: ^Image, channel: Channel) -> (res: ^Image, ok
} }
res = new(Image); res = new(Image);
res.width = img.width; res.width = img.width;
res.height = img.height; res.height = img.height;
res.channels = 1; res.channels = 1;
res.depth = img.depth; res.depth = img.depth;
res.pixels = t; res.pixels = t;
res.background = img.background; res.background = img.background;
res.sidecar = img.sidecar; res.metadata_ptr = img.metadata_ptr;
res.metadata_type = img.metadata_type;
return res, true; return res, true;
} }
+3 -3
View File
@@ -14,7 +14,7 @@ import "core:os"
main :: proc() { main :: proc() {
file: string; file: string;
options := image.Options{}; options := image.Options{.return_metadata};
err: compress.Error; err: compress.Error;
img: ^image.Image; img: ^image.Image;
@@ -27,11 +27,11 @@ main :: proc() {
fmt.printf("Trying to read PNG file %v returned %v\n", file, err); fmt.printf("Trying to read PNG file %v returned %v\n", file, err);
} else { } else {
v: ^png.Info; v: ^png.Info;
ok: bool;
fmt.printf("Image: %vx%vx%v, %v-bit.\n", img.width, img.height, img.channels, img.depth); fmt.printf("Image: %vx%vx%v, %v-bit.\n", img.width, img.height, img.channels, img.depth);
if v, ok = img.sidecar.(^png.Info); ok { if img.metadata_ptr != nil && img.metadata_type == png.Info {
v = (^png.Info)(img.metadata_ptr);
// Handle ancillary chunks as you wish. // Handle ancillary chunks as you wish.
// We provide helper functions for a few types. // We provide helper functions for a few types.
for c in v.chunks { for c in v.chunks {
+3 -6
View File
@@ -392,10 +392,7 @@ load_from_stream :: proc(stream: io.Stream, options := Options{}, allocator := c
img = new(Image); img = new(Image);
} }
info: ^Info; info := new(Info, context.allocator);
if img.sidecar == nil {
info = new(Info);
}
ctx := &compress.Context{ ctx := &compress.Context{
input = stream, input = stream,
@@ -417,7 +414,6 @@ load_from_stream :: proc(stream: io.Stream, options := Options{}, allocator := c
header: IHDR; header: IHDR;
img.sidecar = info;
info.chunks.allocator = context.temp_allocator; info.chunks.allocator = context.temp_allocator;
// State to ensure correct chunk ordering. // State to ensure correct chunk ordering.
@@ -659,7 +655,8 @@ load_from_stream :: proc(stream: io.Stream, options := Options{}, allocator := c
} }
if .return_header in options || .return_metadata in options { if .return_header in options || .return_metadata in options {
img.sidecar = info; img.metadata_ptr = info;
img.metadata_type = typeid_of(Info);
} }
if .do_not_decompress_image in options { if .do_not_decompress_image in options {
img.channels = final_image_channels; img.channels = final_image_channels;