ソースを参照

Merge pull request #1027 from Kelimion/png

Replace `core:image`'s `sidecar` with explicit pointer and type
Jeroen van Rijn 4 年 前
コミット
797c41950a
3 ファイル変更23 行追加23 行削除
  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"
 
 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.
 		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.
 	*/
-	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.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;
 }

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

@@ -14,7 +14,7 @@ import "core:os"
 main :: proc() {
 	file: string;
 
-	options := image.Options{};
+	options := image.Options{.return_metadata};
 	err:       compress.Error;
 	img:      ^image.Image;
 
@@ -27,11 +27,11 @@ main :: proc() {
 		fmt.printf("Trying to read PNG file %v returned %v\n", file, err);
 	} else {
 		v: ^png.Info;
-		ok: bool;
 
 		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.
 			// We provide helper functions for a few types.
 			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);
 	}
 
-	info: ^Info;
-	if img.sidecar == nil {
-		info = new(Info);
-	}
+	info := new(Info, context.allocator);
 
 	ctx := &compress.Context{
 		input = stream,
@@ -417,7 +414,6 @@ load_from_stream :: proc(stream: io.Stream, options := Options{}, allocator := c
 
 	header:	IHDR;
 
-	img.sidecar = info;
 	info.chunks.allocator = context.temp_allocator;
 
 	// 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 {
-		img.sidecar = info;
+		img.metadata_ptr  = info;
+		img.metadata_type = typeid_of(Info);
 	}
 	if .do_not_decompress_image in options {
 		img.channels = final_image_channels;