Browse Source

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);
	...
}
```
Jeroen van Rijn 4 years ago
parent
commit
e036a321a0
3 changed files with 23 additions and 23 deletions
  1. 17 14
      core/image/common.odin
  2. 3 3
      core/image/png/example.odin
  3. 3 6
      core/image/png/png.odin

+ 17 - 14
core/image/common.odin

@@ -4,18 +4,20 @@ import "core:bytes"
 import "core:mem"
 import "core:mem"
 
 
 Image :: struct {
 Image :: struct {
-	width:      int,
-	height:     int,
-	channels:   int,
-	depth:      int,
-	pixels:     bytes.Buffer,
+	width:         int,
+	height:        int,
+	channels:      int,
+	depth:         int,
+	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),
-	sidecar:    any,
+	background:    Maybe([3]u16),
+
+	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.height     = img.height;
-	res.channels   = 1;
-	res.depth      = img.depth;
-	res.pixels     = t;
-	res.background = img.background;
-	res.sidecar    = img.sidecar;
+	res.width         = img.width;
+	res.height        = img.height;
+	res.channels      = 1;
+	res.depth         = img.depth;
+	res.pixels        = t;
+	res.background    = img.background;
+	res.metadata_ptr  = img.metadata_ptr;
+	res.metadata_type = img.metadata_type;
 
 
 	return res, true;
 	return res, true;
 }
 }

+ 3 - 3
core/image/png/example.odin

@@ -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
core/image/png/png.odin

@@ -392,10 +392,7 @@ load_from_stream :: proc(stream: io.Stream, options := Options{}, allocator := c
 		img = new(Image);
 		img = new(Image);
 	}
 	}
 
 
-	info: ^Info;
-	if img.sidecar == nil {
-		info = new(Info);
-	}
+	info := new(Info, context.allocator);
 
 
 	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;