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