mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-03 21:08:18 +00:00
Implement image loding test
This commit is contained in:
parent
8a0eb0e266
commit
12b33da083
9 changed files with 665 additions and 30 deletions
375
Cargo.lock
generated
375
Cargo.lock
generated
|
@ -2,6 +2,18 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "adler32"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
|
@ -73,6 +85,12 @@ dependencies = [
|
|||
"wasm-bindgen-test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit_field"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
|
@ -95,12 +113,24 @@ version = "1.9.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "console_error_panic_hook"
|
||||
version = "0.1.7"
|
||||
|
@ -111,6 +141,69 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"memoffset",
|
||||
"once_cell",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deflate"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "2.2.0"
|
||||
|
@ -139,6 +232,12 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be"
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.8.4"
|
||||
|
@ -152,12 +251,86 @@ dependencies = [
|
|||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "exr"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14cc0e06fb5f67e5d6beadf3a382fec9baca1aa751c6d5368fdeee7e5932c215"
|
||||
dependencies = [
|
||||
"bit_field",
|
||||
"deflate",
|
||||
"flume",
|
||||
"half",
|
||||
"inflate",
|
||||
"lebe",
|
||||
"smallvec",
|
||||
"threadpool",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flume"
|
||||
version = "0.10.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"nanorand",
|
||||
"pin-project",
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gif"
|
||||
version = "0.11.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06"
|
||||
dependencies = [
|
||||
"color_quant",
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glam"
|
||||
version = "0.17.3"
|
||||
|
@ -197,6 +370,7 @@ dependencies = [
|
|||
"dyn-any",
|
||||
"graph-proc-macros",
|
||||
"graphene-core",
|
||||
"image",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -265,6 +439,12 @@ dependencies = [
|
|||
"wasm-bindgen-test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
|
@ -280,12 +460,49 @@ version = "2.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.24.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e30ca2ecf7666107ff827a8e481de6a132a9b687ed3bb20bb1c144a36c00964"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"color_quant",
|
||||
"exr",
|
||||
"gif",
|
||||
"jpeg-decoder",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
"png",
|
||||
"scoped_threadpool",
|
||||
"tiff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inflate"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
|
||||
|
||||
[[package]]
|
||||
name = "jpeg-decoder"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9478aa10f73e7528198d75109c8be5cd7d15fb530238040148d5f9a22d4c5b3b"
|
||||
dependencies = [
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.57"
|
||||
|
@ -310,6 +527,12 @@ version = "1.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lebe"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7efd1d698db0759e6ef11a7cd44407407399a910c774dd804c64c032da7826ff"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.124"
|
||||
|
@ -347,6 +570,54 @@ version = "2.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nanorand"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
|
@ -357,12 +628,54 @@ dependencies = [
|
|||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78203e83c48cffbe01e4a2d35d566ca4de445d79a85372fc64e378bfc812a260"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.17.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc38c0ad57efb786dd57b9864e5b18bae478c00c824dc55a38bbc9da95dde3ba"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crc32fast",
|
||||
"deflate",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.16"
|
||||
|
@ -438,6 +751,30 @@ version = "0.6.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"crossbeam-deque",
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.5"
|
||||
|
@ -494,6 +831,12 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
||||
|
||||
[[package]]
|
||||
name = "scoped_threadpool"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
|
@ -648,6 +991,26 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "threadpool"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
|
||||
dependencies = [
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiff"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7259662e32d1e219321eb309d5f9d898b779769d81b76e762c07c8e5d38fcb65"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"jpeg-decoder",
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ttf-parser"
|
||||
version = "0.15.0"
|
||||
|
@ -690,6 +1053,12 @@ version = "0.9.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.80"
|
||||
|
@ -792,6 +1161,12 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use core::marker::PhantomData;
|
||||
use core::ops::Add;
|
||||
|
||||
use crate::Node;
|
||||
|
||||
pub struct AddNode;
|
||||
impl<'n, L: Add<R>, R> Node<'n, (L, R)> for AddNode {
|
||||
impl<'n, L: Add<R, Output = O> + 'n, R, O: 'n> Node<'n, (L, R)> for AddNode {
|
||||
type Output = <L as Add<R>>::Output;
|
||||
fn eval(&'n self, input: (L, R)) -> Self::Output {
|
||||
input.0 + input.1
|
||||
|
@ -52,9 +53,27 @@ impl<'n, T, U: 'n> Node<'n, &'n (T, U)> for SndNode {
|
|||
}
|
||||
}
|
||||
|
||||
/// Destructures a Tuple of two values and returns them in reverse order
|
||||
pub struct SwapNode;
|
||||
impl<'n, T: 'n, U: 'n> Node<'n, (T, U)> for SwapNode {
|
||||
type Output = (U, T);
|
||||
fn eval(&'n self, input: (T, U)) -> Self::Output {
|
||||
let (a, b) = input;
|
||||
(b, a)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, T, U: 'n> Node<'n, &'n (T, U)> for SwapNode {
|
||||
type Output = (&'n U, &'n T);
|
||||
fn eval(&'n self, input: &'n (T, U)) -> Self::Output {
|
||||
let (a, b) = input;
|
||||
(b, a)
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a tuple with two instances of the input argument
|
||||
pub struct DupNode;
|
||||
impl<'n, T: Clone> Node<'n, T> for DupNode {
|
||||
impl<'n, T: Clone + 'n> Node<'n, T> for DupNode {
|
||||
type Output = (T, T);
|
||||
fn eval(&'n self, input: T) -> Self::Output {
|
||||
(input.clone(), input) //TODO: use Copy/Clone implementation
|
||||
|
@ -63,13 +82,46 @@ impl<'n, T: Clone> Node<'n, T> for DupNode {
|
|||
|
||||
/// Return the Input Argument
|
||||
pub struct IdNode;
|
||||
impl<'n, T> Node<'n, T> for IdNode {
|
||||
impl<'n, T: 'n> Node<'n, T> for IdNode {
|
||||
type Output = T;
|
||||
fn eval(&'n self, input: T) -> Self::Output {
|
||||
input
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MapResultNode<'n, MN: Node<'n, I>, I, E>(pub MN, pub PhantomData<&'n (I, E)>);
|
||||
|
||||
impl<'n, MN: Node<'n, I>, I, E> Node<'n, Result<I, E>> for MapResultNode<'n, MN, I, E> {
|
||||
type Output = Result<MN::Output, E>;
|
||||
fn eval(&'n self, input: Result<I, E>) -> Self::Output {
|
||||
input.map(|x| self.0.eval(x))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, MN: Node<'n, I>, I, E> MapResultNode<'n, MN, I, E> {
|
||||
pub const fn new(mn: MN) -> Self {
|
||||
Self(mn, PhantomData)
|
||||
}
|
||||
}
|
||||
pub struct FlatMapResultNode<'n, MN: Node<'n, I>, I, E>(pub MN, pub PhantomData<&'n (I, E)>);
|
||||
|
||||
impl<'n, MN: Node<'n, I, Output = Result<O, E>>, I, O: 'n, E: 'n> Node<'n, Result<I, E>> for FlatMapResultNode<'n, MN, I, E> {
|
||||
type Output = Result<O, E>;
|
||||
fn eval(&'n self, input: Result<I, E>) -> Self::Output {
|
||||
match input.map(|x| self.0.eval(x)) {
|
||||
Ok(Ok(x)) => Ok(x),
|
||||
Ok(Err(e)) => Err(e),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, MN: Node<'n, I>, I, E> FlatMapResultNode<'n, MN, I, E> {
|
||||
pub const fn new(mn: MN) -> Self {
|
||||
Self(mn, PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
|
|
@ -134,6 +134,18 @@ impl Color {
|
|||
(self.red, self.green, self.blue, self.alpha)
|
||||
}
|
||||
|
||||
/// Return the all components as a u8 slice, first component is red, followed by green, followed by blue, followed by alpha.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use graphene_core::raster::color::Color;
|
||||
/// let color = Color::from_rgbaf32(0.114, 0.103, 0.98, 0.97).unwrap();
|
||||
/// //TODO: Add test
|
||||
/// ```
|
||||
pub fn to_rgba8(&self) -> [u8; 4] {
|
||||
[(self.red * 255.) as u8, (self.green * 255.) as u8, (self.blue * 255.) as u8, (self.alpha * 255.) as u8]
|
||||
}
|
||||
|
||||
// TODO: Readd formatting
|
||||
|
||||
/// Creates a color from a 8-character RGBA hex string (without a # prefix).
|
||||
|
|
|
@ -58,3 +58,17 @@ where
|
|||
(input, arg)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ConsPassInputNode<Root>(pub Root);
|
||||
|
||||
impl<'n, Root, L, R> Node<'n, (L, R)> for ConsPassInputNode<Root>
|
||||
where
|
||||
Root: Node<'n, R>,
|
||||
{
|
||||
type Output = (L, <Root as Node<'n, R>>::Output);
|
||||
|
||||
fn eval(&'n self, input: (L, R)) -> Self::Output {
|
||||
let arg = self.0.eval(input.1);
|
||||
(input.0, arg)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,3 +24,4 @@ once_cell = {version= "1.10", optional = true}
|
|||
syn = {version = "1.0", default-features = false, features = ["parsing", "printing"]}
|
||||
proc-macro2 = {version = "1.0", default-features = false, features = ["proc-macro"]}
|
||||
quote = {version = "1.0", default-features = false }
|
||||
image = "*"
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
pub mod value;
|
||||
#![feature(type_alias_impl_trait)]
|
||||
//pub mod value;
|
||||
pub use graphene_core::{generic, ops /*, structural*/};
|
||||
|
||||
//#[cfg(feature = "memoization")]
|
||||
//pub mod memo;
|
||||
#[cfg(feature = "memoization")]
|
||||
pub mod memo;
|
||||
|
||||
//pub mod raster;
|
||||
pub mod raster;
|
||||
|
||||
pub use graphene_core::*;
|
||||
|
||||
use dyn_any::DynAny;
|
||||
/*use dyn_any::DynAny;
|
||||
pub type DynNode<'n, T> = &'n (dyn Node<'n, Output = T> + 'n);
|
||||
pub type DynAnyNode<'n> = &'n (dyn Node<'n, Output = &'n dyn DynAny<'n>> + 'n);
|
||||
|
||||
pub trait DynamicInput<'n> {
|
||||
fn set_kwarg_by_name(&mut self, name: &str, value: DynAnyNode<'n>);
|
||||
fn set_arg_by_index(&mut self, index: usize, value: DynAnyNode<'n>);
|
||||
}
|
||||
|
||||
*/
|
||||
use quote::quote;
|
||||
use syn::{Expr, ExprPath, Type};
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
a * b
|
||||
}*/
|
||||
|
||||
/*
|
||||
mod mul {
|
||||
use dyn_any::downcast_ref;
|
||||
use graphene_std::{DynAnyNode, DynNode, DynamicInput, Node};
|
||||
|
@ -69,7 +70,7 @@ mod mul {
|
|||
}
|
||||
}
|
||||
// type SNode<'n> = dyn Node<'n, Output = &'n dyn DynAny<'n>>;
|
||||
|
||||
*/
|
||||
// struct NodeStore<'n>(borrow_stack::FixedSizeStack<'n, Box<SNode<'n>>>);
|
||||
|
||||
// impl<'n> NodeStore<'n> {
|
||||
|
|
|
@ -3,26 +3,26 @@ use once_cell::sync::OnceCell;
|
|||
use std::marker::PhantomData;
|
||||
|
||||
/// Caches the output of a given Node and acts as a proxy
|
||||
pub struct CacheNode<'n, CachedNode: Node<'n>> {
|
||||
pub struct CacheNode<'n, CachedNode: Node<'n, I>, I> {
|
||||
node: CachedNode,
|
||||
cache: OnceCell<CachedNode::Output>,
|
||||
_phantom: PhantomData<&'n ()>,
|
||||
}
|
||||
impl<'n, CashedNode: Node<'n>> Node<'n> for CacheNode<'n, CashedNode>
|
||||
impl<'n, CashedNode: Node<'n, I>, I> Node<'n, I> for CacheNode<'n, CashedNode, I>
|
||||
where
|
||||
CashedNode::Output: 'n,
|
||||
{
|
||||
type Output = &'n CashedNode::Output;
|
||||
fn eval(&'n self) -> Self::Output {
|
||||
self.cache.get_or_init(|| self.node.eval())
|
||||
fn eval(&'n self, input: I) -> Self::Output {
|
||||
self.cache.get_or_init(|| self.node.eval(input))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, CachedNode: Node<'n>> CacheNode<'n, CachedNode> {
|
||||
impl<'n, CachedNode: Node<'n, I>, I> CacheNode<'n, CachedNode, I> {
|
||||
pub fn clear(&'n mut self) {
|
||||
self.cache = OnceCell::new();
|
||||
}
|
||||
pub fn new(node: CachedNode) -> CacheNode<'n, CachedNode> {
|
||||
pub fn new(node: CachedNode) -> CacheNode<'n, CachedNode, I> {
|
||||
CacheNode {
|
||||
node,
|
||||
cache: OnceCell::new(),
|
||||
|
@ -30,7 +30,7 @@ impl<'n, CachedNode: Node<'n>> CacheNode<'n, CachedNode> {
|
|||
}
|
||||
}
|
||||
}
|
||||
impl<'n, CachedNode: Node<'n>> Cache for CacheNode<'n, CachedNode> {
|
||||
impl<'n, CachedNode: Node<'n, I>, I> Cache for CacheNode<'n, CachedNode, I> {
|
||||
fn clear(&mut self) {
|
||||
self.cache = OnceCell::new();
|
||||
}
|
||||
|
|
|
@ -1,18 +1,197 @@
|
|||
use core::marker::PhantomData;
|
||||
use graphene_core::{value::RefNode, value::ValueNode, Node};
|
||||
use graphene_core::ops::FlatMapResultNode;
|
||||
use graphene_core::raster::color::Color;
|
||||
use graphene_core::structural::{ComposeNode, ConsNode};
|
||||
use graphene_core::{generic::FnNode, ops::MapResultNode, structural::After, value::ValueNode, Node};
|
||||
use image::Pixel;
|
||||
use std::path::Path;
|
||||
|
||||
pub struct MapNode<'n, IN: Node<'n, Output = I>, I: Iterator<Item = &'n S>, MAP: Fn(&dyn RefNode<Output = S>) -> MN, MN: Node<'n, Output = O> + 'n, S, O: 'n>(pub IN, pub MAP, PhantomData<&'n (I, S)>);
|
||||
pub struct MapNode<'n, MN: Node<'n, S>, I: IntoIterator<Item = S>, S>(pub MN, PhantomData<&'n (S, I)>);
|
||||
|
||||
impl<'n, IN: Node<'n, Output = I>, I: Iterator<Item = &'n S>, MAP: Fn(&dyn RefNode<Output = S>) -> MN, MN: Node<'n, Output = O>, S, O: 'static + Clone> Node<'n> for MapNode<'n, IN, I, MAP, MN, S, O> {
|
||||
type Output = Vec<O>;
|
||||
fn eval(&'n self) -> Self::Output {
|
||||
self.0
|
||||
.eval()
|
||||
.map(|x| {
|
||||
let map_node = self.1(x as &dyn RefNode<Output = S>);
|
||||
let result = map_node.eval();
|
||||
result.clone()
|
||||
})
|
||||
.collect()
|
||||
impl<'n, I: IntoIterator<Item = S>, MN: Node<'n, S>, S> Node<'n, I> for MapNode<'n, MN, I, S> {
|
||||
type Output = Vec<MN::Output>;
|
||||
fn eval(&'n self, input: I) -> Self::Output {
|
||||
input.into_iter().map(|x| self.0.eval(x)).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, I: IntoIterator<Item = S>, MN: Node<'n, S>, S> MapNode<'n, MN, I, S> {
|
||||
pub const fn new(mn: MN) -> Self {
|
||||
MapNode(mn, PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MapImageNode<'n, MN: Node<'n, Color, Output = Color>>(pub MN, PhantomData<&'n ()>);
|
||||
|
||||
impl<'n, MN: Node<'n, Color, Output = Color>> Node<'n, Image> for MapImageNode<'n, MN> {
|
||||
type Output = Image;
|
||||
fn eval(&'n self, input: Image) -> Self::Output {
|
||||
Image {
|
||||
width: input.width,
|
||||
height: input.height,
|
||||
data: input.data.iter().map(|x| self.0.eval(*x)).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, MN: Node<'n, Color, Output = Color>> MapImageNode<'n, MN> {
|
||||
pub const fn new(mn: MN) -> Self {
|
||||
MapImageNode(mn, PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
IO(std::io::Error),
|
||||
Image(image::ImageError),
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for Error {
|
||||
fn from(e: std::io::Error) -> Self {
|
||||
Error::IO(e)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FileSystem {
|
||||
fn open<P: AsRef<Path>>(&self, path: P) -> Result<Box<dyn std::io::Read>, Error>;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct StdFs;
|
||||
impl FileSystem for StdFs {
|
||||
fn open<P: AsRef<Path>>(&self, path: P) -> Result<Reader, Error> {
|
||||
Ok(Box::new(std::fs::File::open(path)?))
|
||||
}
|
||||
}
|
||||
type Reader = Box<dyn std::io::Read>;
|
||||
|
||||
pub struct FileNode<P: AsRef<Path>, FS: FileSystem>(PhantomData<(P, FS)>);
|
||||
impl<'n, P: AsRef<Path>, FS: FileSystem> Node<'n, (P, FS)> for FileNode<P, FS> {
|
||||
type Output = Result<Reader, Error>;
|
||||
|
||||
fn eval(&'n self, input: (P, FS)) -> Self::Output {
|
||||
let (path, fs) = input;
|
||||
fs.open(path)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BufferNode;
|
||||
impl<'n, Reader: std::io::Read> Node<'n, Reader> for BufferNode {
|
||||
type Output = Result<Vec<u8>, Error>;
|
||||
|
||||
fn eval(&'n self, mut reader: Reader) -> Self::Output {
|
||||
let mut buffer = Vec::new();
|
||||
reader.read_to_end(&mut buffer)?;
|
||||
Ok(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Image {
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
pub data: Vec<Color>,
|
||||
}
|
||||
|
||||
impl IntoIterator for Image {
|
||||
type Item = Color;
|
||||
type IntoIter = std::vec::IntoIter<Color>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.data.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for &'a Image {
|
||||
type Item = &'a Color;
|
||||
type IntoIter = std::slice::Iter<'a, Color>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.data.iter()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn file_node<'n, P: AsRef<Path> + 'n>() -> impl Node<'n, P, Output = Result<Vec<u8>, Error>> {
|
||||
let fs = ValueNode(StdFs).clone();
|
||||
let fs = ConsNode(fs);
|
||||
let file: ComposeNode<P, _, FileNode<P, _>> = FileNode(PhantomData).after(fs);
|
||||
let buffer = FlatMapResultNode::new(BufferNode).after(file);
|
||||
buffer
|
||||
}
|
||||
type Ret<'n> = impl Node<'n, (), Output = u32>;
|
||||
|
||||
pub fn test_node<'n>() -> Ret<'n> {
|
||||
ValueNode(432).clone()
|
||||
}
|
||||
|
||||
pub fn image_node<'n, P: AsRef<Path> + 'n>() -> impl Node<'n, P, Output = Result<Image, Error>> {
|
||||
let file = file_node();
|
||||
let image_loader = FnNode::new(|data: Vec<u8>| image::load_from_memory(&data).map_err(Error::Image).map(|image| image.into_rgba32f()));
|
||||
let image: ComposeNode<'_, P, _, _> = FlatMapResultNode::new(image_loader).after(file);
|
||||
let convert_image = FnNode::new(|image: image::ImageBuffer<_, _>| {
|
||||
let data = image
|
||||
.enumerate_pixels()
|
||||
.map(|(_, _, pixel): (_, _, &image::Rgba<f32>)| {
|
||||
let c = pixel.channels();
|
||||
Color::from_rgbaf32(c[0], c[1], c[2], c[3]).unwrap()
|
||||
})
|
||||
.collect();
|
||||
Image {
|
||||
width: image.width(),
|
||||
height: image.height(),
|
||||
data,
|
||||
}
|
||||
});
|
||||
let image = MapResultNode::new(convert_image).after(image);
|
||||
image
|
||||
}
|
||||
|
||||
pub fn export_image_node<'n>() -> impl Node<'n, (Image, &'n str), Output = Result<(), Error>> {
|
||||
FnNode::new(|input: (Image, &str)| {
|
||||
let (image, path) = input;
|
||||
let mut new_image = image::ImageBuffer::new(image.width, image.height);
|
||||
for ((x, y, pixel), color) in new_image.enumerate_pixels_mut().zip((&image).into_iter()) {
|
||||
let color: Color = *color;
|
||||
assert!(x < image.width);
|
||||
assert!(y < image.height);
|
||||
*pixel = image::Rgba([color.r(), color.g(), color.b(), color.a()])
|
||||
}
|
||||
new_image.save(path).map_err(Error::Image)
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use graphene_core::raster::color::Color;
|
||||
use graphene_core::raster::GrayscaleNode;
|
||||
|
||||
#[test]
|
||||
fn map_node() {
|
||||
let array = [Color::from_rgbaf32(1.0, 0.0, 0.0, 1.0).unwrap()];
|
||||
let map = MapNode(GrayscaleNode, PhantomData);
|
||||
let values = map.eval(array.into_iter());
|
||||
assert_eq!(values[0], Color::from_rgbaf32(0.33333334, 0.33333334, 0.33333334, 1.0).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_image() {
|
||||
/*let image = image_node();
|
||||
let gray = MapImageNode::new(GrayscaleNode);
|
||||
|
||||
let gray_scale_picture = MapResultNode::new(gray).after(image);
|
||||
let gray_scale_picture = gray_scale_picture.eval("image");
|
||||
*/
|
||||
let test_node = test_node();
|
||||
{
|
||||
let foo = test_node.eval(());
|
||||
std::mem::drop(foo);
|
||||
}
|
||||
let export = export_image_node();
|
||||
|
||||
/*let export = FnNode::new(|input: (&str, &str)| {
|
||||
let (input, output) = input;*/
|
||||
//let picture = gray_scale_picture.eval("/home/dennis/screenshot.png").unwrap().clone();
|
||||
//export.eval((picture, "screenshot.png"));
|
||||
/*});
|
||||
export.eval(("screenshot.png", "/home/dennis/screenshot.png"));*/
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue