Browse Source

Generalized `core:image` loader

```odin
import "core:image"
import "core:image/png"

...

img, err := image.load_from_file("path.png")
```
gingerBill 3 years ago
parent
commit
01e8e682c0

+ 1 - 0
core/image/common.odin

@@ -172,6 +172,7 @@ General_Image_Error :: enum {
 	Unable_To_Write_File,
 
 	// Invalid
+	Unsupported_Format,
 	Invalid_Signature,
 	Invalid_Input_Image,
 	Image_Dimensions_Too_Large,

+ 39 - 0
core/image/general_loader.odin

@@ -0,0 +1,39 @@
+package image
+
+import "core:mem"
+import "core:os"
+
+Loader_Proc :: #type proc(data: []byte, options: Options, allocator: mem.Allocator) -> (img: ^Image, err: Error)
+
+@(private)
+_internal_loaders: [Which_File_Type]Loader_Proc
+
+register_loader :: proc(kind: Which_File_Type, loader: Loader_Proc) {
+	assert(_internal_loaders[kind] == nil)
+	_internal_loaders[kind] = loader
+}
+
+load :: proc{
+	load_from_slice,
+	load_from_file,
+}
+
+load_from_slice :: proc(data: []u8, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
+	loader := _internal_loaders[which(data)]
+	if loader == nil {
+		return nil, .Unsupported_Format
+	}
+	return loader(data, options, allocator)
+}
+
+
+load_from_file :: proc(filename: string, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
+	data, ok := os.read_entire_file(filename, allocator)
+	defer delete(data, allocator)
+	if ok {
+		return load_from_slice(data, options, allocator)
+	} else {
+		img = new(Image, allocator)
+		return img, .Unable_To_Read_File
+	}
+}

+ 12 - 0
core/image/netpbm/netpbm.odin

@@ -748,4 +748,16 @@ autoselect_pbm_format_from_image :: proc(img: ^Image, prefer_binary := true, for
 
 	// We couldn't find a suitable format
 	return {}, false
+}
+
+@(init, private)
+_register :: proc() {
+	loader :: proc(data: []byte, options: Options, allocator: mem.Allocator) -> (img: ^Image, err: Error) {
+		return load_from_buffer(data, allocator)
+	}
+	register_loader(.PBM, loader)
+	register_loader(.PGM, loader)
+	register_loader(.PPM, loader)
+	register_loader(.PAM, loader)
+	register_loader(.PFM, loader)
 }

+ 6 - 0
core/image/png/png.odin

@@ -1640,3 +1640,9 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH
 }
 
 load :: proc{load_from_file, load_from_slice, load_from_context}
+
+
+@(init, private)
+_register :: proc() {
+	image.register_loader(.PNG, load_from_slice)
+}

+ 5 - 0
core/image/qoi/qoi.odin

@@ -403,4 +403,9 @@ qoi_hash :: #force_inline proc(pixel: RGBA_Pixel) -> (index: u8) {
 	i4 := u16(pixel.a) * 11
 
 	return u8((i1 + i2 + i3 + i4) & 63)
+}
+
+@(init, private)
+_register :: proc() {
+	image.register_loader(.QOI, load_from_slice)
 }