From 90c44c34a9fa7f07c45f7849c32e0058f66772fb Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 23 Mar 2023 20:42:38 +0000 Subject: [PATCH] Make `core:image` packages work on `js` platform (wasm32) by not requiring `core:os` --- core/image/{which.odin => general.odin} | 62 +++++++++++++++++-------- core/image/general_js.odin | 10 ++++ core/image/general_loader.odin | 61 ------------------------ core/image/general_os.odin | 38 +++++++++++++++ core/image/netpbm/netpbm.odin | 36 -------------- core/image/netpbm/netpbm_js.odin | 10 ++++ core/image/netpbm/netpbm_os.odin | 41 ++++++++++++++++ core/image/png/png.odin | 16 ------- core/image/png/png_js.odin | 4 ++ core/image/png/png_os.odin | 19 ++++++++ core/image/qoi/qoi.odin | 30 ------------ core/image/qoi/qoi_js.odin | 6 +++ core/image/qoi/qoi_os.odin | 37 +++++++++++++++ core/image/tga/tga.odin | 29 ------------ core/image/tga/tga_js.odin | 5 ++ core/image/tga/tga_os.odin | 34 ++++++++++++++ 16 files changed, 247 insertions(+), 191 deletions(-) rename core/image/{which.odin => general.odin} (75%) create mode 100644 core/image/general_js.odin delete mode 100644 core/image/general_loader.odin create mode 100644 core/image/general_os.odin create mode 100644 core/image/netpbm/netpbm_js.odin create mode 100644 core/image/netpbm/netpbm_os.odin create mode 100644 core/image/png/png_js.odin create mode 100644 core/image/png/png_os.odin create mode 100644 core/image/qoi/qoi_js.odin create mode 100644 core/image/qoi/qoi_os.odin create mode 100644 core/image/tga/tga_js.odin create mode 100644 core/image/tga/tga_os.odin diff --git a/core/image/which.odin b/core/image/general.odin similarity index 75% rename from core/image/which.odin rename to core/image/general.odin index ab608174f..17a8f35ea 100644 --- a/core/image/which.odin +++ b/core/image/general.odin @@ -1,6 +1,48 @@ package image -import "core:os" +import "core:mem" +import "core:bytes" + +Loader_Proc :: #type proc(data: []byte, options: Options, allocator: mem.Allocator) -> (img: ^Image, err: Error) +Destroy_Proc :: #type proc(img: ^Image) + +@(private) +_internal_loaders: [Which_File_Type]Loader_Proc +_internal_destroyers: [Which_File_Type]Destroy_Proc + +register :: proc(kind: Which_File_Type, loader: Loader_Proc, destroyer: Destroy_Proc) { + assert(loader != nil) + assert(destroyer != nil) + assert(_internal_loaders[kind] == nil) + _internal_loaders[kind] = loader + + assert(_internal_destroyers[kind] == nil) + _internal_destroyers[kind] = destroyer +} + +load_from_bytes :: proc(data: []byte, 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) +} + + +destroy :: proc(img: ^Image, allocator := context.allocator) { + if img == nil { + return + } + context.allocator = allocator + destroyer := _internal_destroyers[img.which] + if destroyer != nil { + destroyer(img) + } else { + assert(img.metadata == nil) + bytes.buffer_destroy(&img.pixels) + free(img) + } +} Which_File_Type :: enum { Unknown, @@ -28,11 +70,6 @@ Which_File_Type :: enum { XBM, // X BitMap } -which :: proc{ - which_bytes, - which_file, -} - which_bytes :: proc(data: []byte) -> Which_File_Type { test_tga :: proc(s: string) -> bool { get8 :: #force_inline proc(s: ^string) -> u8 { @@ -164,16 +201,3 @@ which_bytes :: proc(data: []byte) -> Which_File_Type { } return .Unknown } - - -which_file :: proc(path: string) -> Which_File_Type { - f, err := os.open(path) - if err != 0 { - return .Unknown - } - header: [128]byte - os.read(f, header[:]) - file_type := which_bytes(header[:]) - os.close(f) - return file_type -} \ No newline at end of file diff --git a/core/image/general_js.odin b/core/image/general_js.odin new file mode 100644 index 000000000..841d9c200 --- /dev/null +++ b/core/image/general_js.odin @@ -0,0 +1,10 @@ +//+build js +package image + +load :: proc{ + load_from_bytes, +} + +which :: proc{ + which_bytes, +} diff --git a/core/image/general_loader.odin b/core/image/general_loader.odin deleted file mode 100644 index 36629c39e..000000000 --- a/core/image/general_loader.odin +++ /dev/null @@ -1,61 +0,0 @@ -package image - -import "core:mem" -import "core:os" -import "core:bytes" - -Loader_Proc :: #type proc(data: []byte, options: Options, allocator: mem.Allocator) -> (img: ^Image, err: Error) -Destroy_Proc :: #type proc(img: ^Image) - -@(private) -_internal_loaders: [Which_File_Type]Loader_Proc -_internal_destroyers: [Which_File_Type]Destroy_Proc - -register :: proc(kind: Which_File_Type, loader: Loader_Proc, destroyer: Destroy_Proc) { - assert(loader != nil) - assert(destroyer != nil) - assert(_internal_loaders[kind] == nil) - _internal_loaders[kind] = loader - - assert(_internal_destroyers[kind] == nil) - _internal_destroyers[kind] = destroyer -} - -load :: proc{ - load_from_bytes, - load_from_file, -} - -load_from_bytes :: proc(data: []byte, 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_bytes(data, options, allocator) - } else { - return nil, .Unable_To_Read_File - } -} - -destroy :: proc(img: ^Image, allocator := context.allocator) { - if img == nil { - return - } - context.allocator = allocator - destroyer := _internal_destroyers[img.which] - if destroyer != nil { - destroyer(img) - } else { - assert(img.metadata == nil) - bytes.buffer_destroy(&img.pixels) - free(img) - } -} \ No newline at end of file diff --git a/core/image/general_os.odin b/core/image/general_os.odin new file mode 100644 index 000000000..144a3470f --- /dev/null +++ b/core/image/general_os.odin @@ -0,0 +1,38 @@ +//+build !js +package image + +import "core:os" + +load :: proc{ + load_from_bytes, + load_from_file, +} + + +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_bytes(data, options, allocator) + } else { + return nil, .Unable_To_Read_File + } +} + + +which :: proc{ + which_bytes, + which_file, +} + +which_file :: proc(path: string) -> Which_File_Type { + f, err := os.open(path) + if err != 0 { + return .Unknown + } + header: [128]byte + os.read(f, header[:]) + file_type := which_bytes(header[:]) + os.close(f) + return file_type +} \ No newline at end of file diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin index 70eb3567e..cb07b1e3a 100644 --- a/core/image/netpbm/netpbm.odin +++ b/core/image/netpbm/netpbm.odin @@ -4,7 +4,6 @@ import "core:bytes" import "core:fmt" import "core:image" import "core:mem" -import "core:os" import "core:strconv" import "core:strings" import "core:unicode" @@ -27,23 +26,6 @@ PFM :: Formats{.Pf, .PF} ASCII :: Formats{.P1, .P2, .P3} BINARY :: Formats{.P4, .P5, .P6} + PAM + PFM -load :: proc { - load_from_file, - load_from_bytes, -} - -load_from_file :: proc(filename: string, allocator := context.allocator) -> (img: ^Image, err: Error) { - context.allocator = allocator - - data, ok := os.read_entire_file(filename); defer delete(data) - if !ok { - err = .Unable_To_Read_File - return - } - - return load_from_bytes(data) -} - load_from_bytes :: proc(data: []byte, allocator := context.allocator) -> (img: ^Image, err: Error) { context.allocator = allocator @@ -67,24 +49,6 @@ load_from_bytes :: proc(data: []byte, allocator := context.allocator) -> (img: ^ return img, nil } -save :: proc { - save_to_file, - save_to_buffer, -} - -save_to_file :: proc(filename: string, img: ^Image, custom_info: Info = {}, allocator := context.allocator) -> (err: Error) { - context.allocator = allocator - - data: []byte; defer delete(data) - data = save_to_buffer(img, custom_info) or_return - - if ok := os.write_entire_file(filename, data); !ok { - return .Unable_To_Write_File - } - - return Format_Error.None -} - save_to_buffer :: proc(img: ^Image, custom_info: Info = {}, allocator := context.allocator) -> (buffer: []byte, err: Error) { context.allocator = allocator diff --git a/core/image/netpbm/netpbm_js.odin b/core/image/netpbm/netpbm_js.odin new file mode 100644 index 000000000..7db17a05d --- /dev/null +++ b/core/image/netpbm/netpbm_js.odin @@ -0,0 +1,10 @@ +//+build js +package netpbm + +load :: proc { + load_from_bytes, +} + +save :: proc { + save_to_buffer, +} diff --git a/core/image/netpbm/netpbm_os.odin b/core/image/netpbm/netpbm_os.odin new file mode 100644 index 000000000..609f1ea1f --- /dev/null +++ b/core/image/netpbm/netpbm_os.odin @@ -0,0 +1,41 @@ +//+build !js +package netpbm + +import "core:os" + +load :: proc { + load_from_file, + load_from_bytes, +} + + +load_from_file :: proc(filename: string, allocator := context.allocator) -> (img: ^Image, err: Error) { + context.allocator = allocator + + data, ok := os.read_entire_file(filename); defer delete(data) + if !ok { + err = .Unable_To_Read_File + return + } + + return load_from_bytes(data) +} + + +save :: proc { + save_to_file, + save_to_buffer, +} + +save_to_file :: proc(filename: string, img: ^Image, custom_info: Info = {}, allocator := context.allocator) -> (err: Error) { + context.allocator = allocator + + data: []byte; defer delete(data) + data = save_to_buffer(img, custom_info) or_return + + if ok := os.write_entire_file(filename, data); !ok { + return .Unable_To_Write_File + } + + return Format_Error.None +} \ No newline at end of file diff --git a/core/image/png/png.odin b/core/image/png/png.odin index 02983997c..91adddafc 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -17,7 +17,6 @@ import "core:compress" import "core:compress/zlib" import "core:image" -import "core:os" import "core:hash" import "core:bytes" import "core:io" @@ -336,19 +335,6 @@ load_from_bytes :: proc(data: []byte, options := Options{}, allocator := context return img, err } -load_from_file :: proc(filename: string, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { - context.allocator = allocator - - data, ok := os.read_entire_file(filename) - defer delete(data) - - if ok { - return load_from_bytes(data, options) - } else { - return nil, .Unable_To_Read_File - } -} - load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { context.allocator = allocator options := options @@ -1641,8 +1627,6 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH return nil } -load :: proc{load_from_file, load_from_bytes, load_from_context} - @(init, private) _register :: proc() { diff --git a/core/image/png/png_js.odin b/core/image/png/png_js.odin new file mode 100644 index 000000000..57c27fc64 --- /dev/null +++ b/core/image/png/png_js.odin @@ -0,0 +1,4 @@ +//+build js +package png + +load :: proc{load_from_bytes, load_from_context} diff --git a/core/image/png/png_os.odin b/core/image/png/png_os.odin new file mode 100644 index 000000000..cc65e7b42 --- /dev/null +++ b/core/image/png/png_os.odin @@ -0,0 +1,19 @@ +//+build !js +package png + +import "core:os" + +load :: proc{load_from_file, load_from_bytes, load_from_context} + +load_from_file :: proc(filename: string, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { + context.allocator = allocator + + data, ok := os.read_entire_file(filename) + defer delete(data) + + if ok { + return load_from_bytes(data, options) + } else { + return nil, .Unable_To_Read_File + } +} diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index 29a17d4f4..7a195ea88 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -15,7 +15,6 @@ package qoi import "core:image" import "core:compress" import "core:bytes" -import "core:os" Error :: image.Error Image :: image.Image @@ -166,20 +165,6 @@ save_to_memory :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{} return nil } -save_to_file :: proc(output: string, img: ^Image, options := Options{}, allocator := context.allocator) -> (err: Error) { - context.allocator = allocator - - out := &bytes.Buffer{} - defer bytes.buffer_destroy(out) - - save_to_memory(out, img, options) or_return - write_ok := os.write_entire_file(output, out.buf[:]) - - return nil if write_ok else .Unable_To_Write_File -} - -save :: proc{save_to_memory, save_to_file} - load_from_bytes :: proc(data: []byte, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { ctx := &compress.Context_Memory_Input{ input_data = data, @@ -189,19 +174,6 @@ load_from_bytes :: proc(data: []byte, options := Options{}, allocator := context return img, err } -load_from_file :: proc(filename: string, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { - context.allocator = allocator - - data, ok := os.read_entire_file(filename) - defer delete(data) - - if ok { - return load_from_bytes(data, options) - } else { - return nil, .Unable_To_Read_File - } -} - @(optimization_mode="speed") load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { context.allocator = allocator @@ -359,8 +331,6 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a return } -load :: proc{load_from_file, load_from_bytes, load_from_context} - /* Cleanup of image-specific data. */ diff --git a/core/image/qoi/qoi_js.odin b/core/image/qoi/qoi_js.odin new file mode 100644 index 000000000..08ba10c8b --- /dev/null +++ b/core/image/qoi/qoi_js.odin @@ -0,0 +1,6 @@ +//+build js +package qoi + +save :: proc{save_to_memory} + +load :: proc{load_from_bytes, load_from_context} diff --git a/core/image/qoi/qoi_os.odin b/core/image/qoi/qoi_os.odin new file mode 100644 index 000000000..cfd5733a3 --- /dev/null +++ b/core/image/qoi/qoi_os.odin @@ -0,0 +1,37 @@ +//+build !js +package qoi + +import "core:os" +import "core:bytes" + +save :: proc{save_to_memory, save_to_file} + + +save_to_file :: proc(output: string, img: ^Image, options := Options{}, allocator := context.allocator) -> (err: Error) { + context.allocator = allocator + + out := &bytes.Buffer{} + defer bytes.buffer_destroy(out) + + save_to_memory(out, img, options) or_return + write_ok := os.write_entire_file(output, out.buf[:]) + + return nil if write_ok else .Unable_To_Write_File +} + + +load :: proc{load_from_file, load_from_bytes, load_from_context} + + +load_from_file :: proc(filename: string, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { + context.allocator = allocator + + data, ok := os.read_entire_file(filename) + defer delete(data) + + if ok { + return load_from_bytes(data, options) + } else { + return nil, .Unable_To_Read_File + } +} \ No newline at end of file diff --git a/core/image/tga/tga.odin b/core/image/tga/tga.odin index 39c46c7c7..4adf426c7 100644 --- a/core/image/tga/tga.odin +++ b/core/image/tga/tga.odin @@ -14,7 +14,6 @@ package tga import "core:mem" import "core:image" import "core:bytes" -import "core:os" import "core:compress" import "core:strings" @@ -92,20 +91,6 @@ save_to_memory :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{} return nil } -save_to_file :: proc(output: string, img: ^Image, options := Options{}, allocator := context.allocator) -> (err: Error) { - context.allocator = allocator - - out := &bytes.Buffer{} - defer bytes.buffer_destroy(out) - - save_to_memory(out, img, options) or_return - write_ok := os.write_entire_file(output, out.buf[:]) - - return nil if write_ok else .Unable_To_Write_File -} - -save :: proc{save_to_memory, save_to_file} - load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { context.allocator = allocator options := options @@ -398,20 +383,6 @@ load_from_bytes :: proc(data: []byte, options := Options{}, allocator := context return img, err } -load_from_file :: proc(filename: string, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { - context.allocator = allocator - - data, ok := os.read_entire_file(filename) - defer delete(data) - - if ok { - return load_from_bytes(data, options) - } else { - return nil, .Unable_To_Read_File - } -} - -load :: proc{load_from_file, load_from_bytes, load_from_context} destroy :: proc(img: ^Image) { if img == nil || img.width == 0 || img.height == 0 { diff --git a/core/image/tga/tga_js.odin b/core/image/tga/tga_js.odin new file mode 100644 index 000000000..0ba246041 --- /dev/null +++ b/core/image/tga/tga_js.odin @@ -0,0 +1,5 @@ +//+build js +package tga + +save :: proc{save_to_memory} +load :: proc{load_from_bytes, load_from_context} diff --git a/core/image/tga/tga_os.odin b/core/image/tga/tga_os.odin new file mode 100644 index 000000000..e7e40cfe3 --- /dev/null +++ b/core/image/tga/tga_os.odin @@ -0,0 +1,34 @@ +//+build !js +package tga + +import "core:os" +import "core:bytes" + +save :: proc{save_to_memory, save_to_file} + +save_to_file :: proc(output: string, img: ^Image, options := Options{}, allocator := context.allocator) -> (err: Error) { + context.allocator = allocator + + out := &bytes.Buffer{} + defer bytes.buffer_destroy(out) + + save_to_memory(out, img, options) or_return + write_ok := os.write_entire_file(output, out.buf[:]) + + return nil if write_ok else .Unable_To_Write_File +} + +load :: proc{load_from_file, load_from_bytes, load_from_context} + +load_from_file :: proc(filename: string, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { + context.allocator = allocator + + data, ok := os.read_entire_file(filename) + defer delete(data) + + if ok { + return load_from_bytes(data, options) + } else { + return nil, .Unable_To_Read_File + } +} \ No newline at end of file