From 01e8e682c0a6021c117553c53f181487be1c841c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 May 2022 14:38:26 +0100 Subject: [PATCH] Generalized `core:image` loader ```odin import "core:image" import "core:image/png" ... img, err := image.load_from_file("path.png") ``` --- core/image/common.odin | 1 + core/image/general_loader.odin | 39 ++++++++++++++++++++++++++++++++++ core/image/netpbm/netpbm.odin | 12 +++++++++++ core/image/png/png.odin | 6 ++++++ core/image/qoi/qoi.odin | 5 +++++ 5 files changed, 63 insertions(+) create mode 100644 core/image/general_loader.odin diff --git a/core/image/common.odin b/core/image/common.odin index 4085a0a05..75a649e52 100644 --- a/core/image/common.odin +++ b/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, diff --git a/core/image/general_loader.odin b/core/image/general_loader.odin new file mode 100644 index 000000000..73f50f055 --- /dev/null +++ b/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 + } +} diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin index 9574faa26..bcc78c402 100644 --- a/core/image/netpbm/netpbm.odin +++ b/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) } \ No newline at end of file diff --git a/core/image/png/png.odin b/core/image/png/png.odin index d526dfb27..3dcd0df38 100644 --- a/core/image/png/png.odin +++ b/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) +} \ No newline at end of file diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index 83b212be8..346356094 100644 --- a/core/image/qoi/qoi.odin +++ b/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) } \ No newline at end of file