This commit is contained in:
Generated
+459
-15
@@ -17,6 +17,21 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_colours"
|
||||
version = "1.2.2"
|
||||
@@ -138,12 +153,32 @@ version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.4"
|
||||
@@ -208,6 +243,58 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
||||
|
||||
[[package]]
|
||||
name = "core-graphics"
|
||||
version = "0.23.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"core-graphics-types",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-graphics-types"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-text"
|
||||
version = "20.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9d2790b5c08465d49f8dc05c8bcae9fea467855947db39b0f8145c091aaced5"
|
||||
dependencies = [
|
||||
"core-foundation",
|
||||
"core-graphics",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
@@ -291,6 +378,58 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "cstr"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68523903c8ae5aacfa32a0d9ae60cadeb764e1da14ee0d26b1f3089f13a54636"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-next"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"dirs-sys-next",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys-next"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dlib"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
|
||||
dependencies = [
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dwrote"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"winapi",
|
||||
"wio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.0"
|
||||
@@ -367,6 +506,12 @@ dependencies = [
|
||||
"miniz_oxide 0.5.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "float-ord"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ce81f49ae8a0482e4c55ea62ebbd7e5a686af544c00b9d090bba3ff9be97b3d"
|
||||
|
||||
[[package]]
|
||||
name = "flume"
|
||||
version = "0.10.14"
|
||||
@@ -380,6 +525,69 @@ dependencies = [
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "font-kit"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2845a73bbd781e691ab7c2a028c579727cd254942e8ced57ff73e0eafd60de87"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"byteorder",
|
||||
"core-foundation",
|
||||
"core-graphics",
|
||||
"core-text",
|
||||
"dirs-next",
|
||||
"dwrote",
|
||||
"float-ord",
|
||||
"freetype-sys",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"pathfinder_geometry",
|
||||
"pathfinder_simd",
|
||||
"walkdir",
|
||||
"winapi",
|
||||
"yeslogic-fontconfig-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965"
|
||||
dependencies = [
|
||||
"foreign-types-macros",
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-macros"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
|
||||
|
||||
[[package]]
|
||||
name = "freetype-sys"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e7edc5b9669349acfda99533e9e0bcf26a51862ab43b08ee7745c55d28eb134"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.25"
|
||||
@@ -415,6 +623,16 @@ dependencies = [
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gif"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045"
|
||||
dependencies = [
|
||||
"color_quant",
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.1.0"
|
||||
@@ -445,6 +663,29 @@ version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.24.4"
|
||||
@@ -455,7 +696,7 @@ dependencies = [
|
||||
"byteorder",
|
||||
"color_quant",
|
||||
"exr",
|
||||
"gif",
|
||||
"gif 0.11.4",
|
||||
"jpeg-decoder",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
@@ -474,6 +715,7 @@ dependencies = [
|
||||
"env_logger",
|
||||
"image",
|
||||
"log",
|
||||
"plotters",
|
||||
"rmp-serde",
|
||||
"serde",
|
||||
"viuer",
|
||||
@@ -496,9 +738,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.60"
|
||||
version = "0.3.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
|
||||
checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
@@ -521,6 +763,26 @@ version = "0.2.154"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.13"
|
||||
@@ -715,6 +977,25 @@ version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
|
||||
|
||||
[[package]]
|
||||
name = "pathfinder_geometry"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b7e7b4ea703700ce73ebf128e1450eb69c3a8329199ffbfb9b2a0418e5ad3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"pathfinder_simd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathfinder_simd"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebf45976c56919841273f2a0fc684c28437e2f304e264557d9c72be5d5a718be"
|
||||
dependencies = [
|
||||
"rustc_version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.0.12"
|
||||
@@ -735,6 +1016,58 @@ dependencies = [
|
||||
"syn 1.0.103",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
||||
|
||||
[[package]]
|
||||
name = "plotters"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"font-kit",
|
||||
"image",
|
||||
"lazy_static",
|
||||
"num-traits",
|
||||
"pathfinder_geometry",
|
||||
"plotters-backend",
|
||||
"plotters-bitmap",
|
||||
"plotters-svg",
|
||||
"ttf-parser",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plotters-backend"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7"
|
||||
|
||||
[[package]]
|
||||
name = "plotters-bitmap"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7e7f6fb8302456d7c264a94dada86f76d76e1a03e2294ee86ca7da92983b0a6"
|
||||
dependencies = [
|
||||
"gif 0.12.0",
|
||||
"image",
|
||||
"plotters-backend",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plotters-svg"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705"
|
||||
dependencies = [
|
||||
"plotters-backend",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.17.7"
|
||||
@@ -798,6 +1131,17 @@ dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"libredox",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.4"
|
||||
@@ -858,6 +1202,15 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.34"
|
||||
@@ -871,6 +1224,15 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped_threadpool"
|
||||
version = "0.1.9"
|
||||
@@ -883,6 +1245,12 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.147"
|
||||
@@ -983,6 +1351,26 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "threadpool"
|
||||
version = "1.8.1"
|
||||
@@ -1003,6 +1391,12 @@ dependencies = [
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ttf-parser"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.5"
|
||||
@@ -1031,6 +1425,16 @@ dependencies = [
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
@@ -1039,9 +1443,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.83"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
|
||||
checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
@@ -1049,24 +1453,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.83"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
|
||||
checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.103",
|
||||
"syn 2.0.64",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.83"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
|
||||
checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@@ -1074,22 +1478,32 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.83"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
|
||||
checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.103",
|
||||
"syn 2.0.64",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.83"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
|
||||
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
@@ -1128,6 +1542,15 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
@@ -1266,3 +1689,24 @@ name = "windows_x86_64_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||
|
||||
[[package]]
|
||||
name = "wio"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yeslogic-fontconfig-sys"
|
||||
version = "5.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffb6b23999a8b1a997bf47c7bb4d19ad4029c3327bb3386ebe0a5ff584b33c7a"
|
||||
dependencies = [
|
||||
"cstr",
|
||||
"dlib",
|
||||
"once_cell",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
@@ -15,3 +15,4 @@ env_logger = "0.11.3"
|
||||
bktree = "1.0.1"
|
||||
viuer = "0.7.1"
|
||||
clap = { version = "4.5.4", features = ["derive"] }
|
||||
plotters = "0.3.6"
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ struct Cfg {
|
||||
/// Try to output the images to terminal with viuer
|
||||
#[arg(short, long, default_value_t=false)]
|
||||
show_images: bool,
|
||||
distance: isize,
|
||||
distance: usize,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
@@ -108,7 +108,7 @@ impl Descriptor for DCT {
|
||||
}
|
||||
fn describe(&self, img: &image::DynamicImage) -> u64 {
|
||||
let resized = self.resize(img);
|
||||
let mut dct_values = self.dct(&resized);
|
||||
let dct_values = self.dct(&resized);
|
||||
debug!("DCT-coefficients:\n {}", print_matrix(dct_values));
|
||||
|
||||
// Quantization:
|
||||
|
||||
@@ -76,6 +76,6 @@ impl Descriptor for Median {
|
||||
pub fn get_all_descriptors() -> Vec<Box<dyn Descriptor>> {
|
||||
let mut descriptors: Vec<Box<dyn Descriptor>> = Vec::with_capacity(2);
|
||||
descriptors.push(Box::new(DCT::new()));
|
||||
//descriptors.push(Box::new(Median));
|
||||
descriptors.push(Box::new(Median));
|
||||
descriptors
|
||||
}
|
||||
+70
-18
@@ -1,10 +1,11 @@
|
||||
use image_similarity::store::DescriptorStore;
|
||||
use image_similarity::descriptors::get_all_descriptors;
|
||||
use image_similarity::mutators::get_all_mutators;
|
||||
use log::{error, info};
|
||||
use log::{error};
|
||||
use std::path::PathBuf;
|
||||
use std::{fs, thread};
|
||||
use std::{fs};
|
||||
use clap::Parser;
|
||||
use plotters::prelude::*;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(version, about, long_about = None)]
|
||||
@@ -21,7 +22,8 @@ fn main() {
|
||||
let mut stores: Vec<DescriptorStore> = Vec::new();
|
||||
|
||||
for descriptor in get_all_descriptors() {
|
||||
let store = DescriptorStore::new(descriptor);
|
||||
let filename = format!("{}.store", descriptor.info());
|
||||
let store = DescriptorStore::new(descriptor).with_file(filename);
|
||||
stores.push(store);
|
||||
}
|
||||
|
||||
@@ -35,34 +37,84 @@ fn main() {
|
||||
continue
|
||||
}
|
||||
};
|
||||
let img = match image::open(file.path()) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!("Failed to process {}: {}", name, e);
|
||||
continue
|
||||
}
|
||||
};
|
||||
|
||||
//Store the phashes of the base image
|
||||
for store in &mut stores {
|
||||
store.store(&img, name.clone());
|
||||
let mut get = true;
|
||||
for store in &stores {
|
||||
if store.has_value(&name) {
|
||||
get = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for mutator in &mutators {
|
||||
let mutated = mutator.mutate(&img);
|
||||
let mutated_name = "mut".to_string() + &mutator.tag() + &name.clone();
|
||||
// We assume that if a base image exists in the store, the mutated images also exist
|
||||
if get {
|
||||
let img = match image::open(file.path()) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!("Failed to process {}: {}", name, e);
|
||||
continue
|
||||
}
|
||||
};
|
||||
|
||||
//Store the phashes of the base image
|
||||
for store in &mut stores {
|
||||
store.store(&mutated, mutated_name.clone());
|
||||
store.store(&img, name.clone());
|
||||
}
|
||||
|
||||
for mutator in &mutators {
|
||||
let mutated = mutator.mutate(&img);
|
||||
let mutated_name = "mut".to_string() + &mutator.tag() + &name.clone();
|
||||
for store in &mut stores {
|
||||
store.store(&mutated, mutated_name.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for store in &stores {
|
||||
store.save().expect("Error saving store");
|
||||
println!("{}", store);
|
||||
}
|
||||
|
||||
// Create PR-curve graphs from stores
|
||||
for store in &stores {
|
||||
println!("Store for {}: ", store.descriptor.info());
|
||||
store.print_stats();
|
||||
//store.print_stats();
|
||||
let stats = store.get_stats(16);
|
||||
let filename = format!("{}-pr.png", store.descriptor.info());
|
||||
let root = BitMapBackend::new(&filename, (1024, 768)).into_drawing_area();
|
||||
root.fill(&WHITE).unwrap();
|
||||
let mut chart = ChartBuilder::on(&root)
|
||||
// Set the caption of the chart
|
||||
.caption("PR curves", ("sans-serif", 40).into_font())
|
||||
.margin(25)
|
||||
.set_all_label_area_size(50)
|
||||
// Finally attach a coordinate on the drawing area and make a chart context
|
||||
.build_cartesian_2d(0f64..1f64, 0f64..1f64).unwrap();
|
||||
chart.configure_mesh()
|
||||
.x_labels(10)
|
||||
.y_labels(10)
|
||||
.disable_mesh()
|
||||
.x_desc("Recall")
|
||||
.y_desc("Precision")
|
||||
.x_label_formatter(&|x| format!("{:.3}", x))
|
||||
.y_label_formatter(&|x| format!("{:.3}", x))
|
||||
.draw().unwrap();
|
||||
let colors = [&RED, &BLUE, &CYAN, &MAGENTA, &BLACK, &GREEN, &YELLOW];
|
||||
let n = colors.len();
|
||||
let mut i = 0;
|
||||
for mutator_stats in stats {
|
||||
// And we can draw something in the drawing area
|
||||
let pr_curve = mutator_stats.pr_curve();
|
||||
let color = colors[i % n];
|
||||
chart.draw_series(LineSeries::new(
|
||||
pr_curve,
|
||||
color,
|
||||
)).unwrap()
|
||||
.label(mutator_stats.name)
|
||||
.legend(move |(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], color));
|
||||
i += 1;
|
||||
}
|
||||
chart.configure_series_labels().border_style(BLACK).draw().unwrap();
|
||||
//println!("{}", store);
|
||||
}
|
||||
}
|
||||
|
||||
+64
-29
@@ -18,12 +18,55 @@ pub enum SaveError {
|
||||
}
|
||||
|
||||
/// Struct for calculating Recall-Precision per mutation
|
||||
struct PRStats {
|
||||
pub struct PRStats {
|
||||
true_positives: [u64; 64],
|
||||
false_positives: [u64; 64],
|
||||
false_negatives: [u64; 64],
|
||||
tag: String,
|
||||
name: String
|
||||
pub tag: String,
|
||||
pub name: String
|
||||
}
|
||||
|
||||
impl PRStats {
|
||||
pub fn precision(&self, threshold: usize) -> f64 {
|
||||
let t = match threshold {
|
||||
0..=64 => threshold,
|
||||
_ => std::cmp::max(0, std::cmp::min(64, threshold))
|
||||
};
|
||||
let tpos = self.true_positives[t] as f64;
|
||||
let fpos = self.false_positives[t] as f64;
|
||||
let p = tpos / (tpos + fpos);
|
||||
p
|
||||
}
|
||||
pub fn recall(&self, threshold: usize) -> f64 {
|
||||
let t = match threshold {
|
||||
0..=64 => threshold,
|
||||
_ => std::cmp::max(0, std::cmp::min(64, threshold))
|
||||
};
|
||||
let tpos = self.true_positives[t] as f64;
|
||||
let fneg = self.false_negatives[t] as f64;
|
||||
let r = tpos / (tpos + fneg);
|
||||
r
|
||||
}
|
||||
pub fn pr(&self, threshold: usize) -> (f64, f64) {
|
||||
let t = match threshold {
|
||||
0..=64 => threshold,
|
||||
_ => std::cmp::max(0, std::cmp::min(64, threshold))
|
||||
};
|
||||
let tpos = self.true_positives[t] as f64;
|
||||
let fpos = self.false_positives[t] as f64;
|
||||
let fneg = self.false_negatives[t] as f64;
|
||||
let p = tpos / (tpos + fpos);
|
||||
let r = tpos / (tpos + fneg);
|
||||
(r, p)
|
||||
}
|
||||
pub fn pr_curve(&self) -> Vec<(f64, f64)> {
|
||||
let mut curve = Vec::new();
|
||||
for i in 0..64 {
|
||||
curve.push(self.pr(i));
|
||||
}
|
||||
curve
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Uses a hashmap to map descriptors to buckets of files.
|
||||
@@ -71,7 +114,9 @@ impl DescriptorStore {
|
||||
let mut seen: HashSet<String> = HashSet::new();
|
||||
for bucket in self.map.values() {
|
||||
for element in bucket {
|
||||
seen.insert(element.clone());
|
||||
if !element.starts_with("mut.") {
|
||||
seen.insert(element.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
self.seen = Some(seen);
|
||||
@@ -199,15 +244,15 @@ impl DescriptorStore {
|
||||
}
|
||||
|
||||
/// Nearest neighbours
|
||||
pub fn nn(&self, from: u64, max_distance: isize) -> Vec<(&u64, isize)> {
|
||||
let mut neighbours = self.bktree.find(from, max_distance);
|
||||
pub fn nn(&self, from: u64, max_distance: usize) -> Vec<(&u64, isize)> {
|
||||
let mut neighbours = self.bktree.find(from, max_distance.try_into().unwrap());
|
||||
neighbours.sort_by(|a, b| a.1.cmp(&b.1));
|
||||
neighbours
|
||||
}
|
||||
|
||||
|
||||
/// Returns a flat vector with all the filenames that are within a given distance
|
||||
pub fn nn_flat_results(&self, from: u64, max_distance: isize) -> Vec<String> {
|
||||
pub fn nn_flat_results(&self, from: u64, max_distance: usize) -> Vec<String> {
|
||||
let nn = self.nn(from, max_distance);
|
||||
let mut results: Vec<String> = Vec::new();
|
||||
for (key, _) in nn {
|
||||
@@ -218,7 +263,7 @@ impl DescriptorStore {
|
||||
results
|
||||
}
|
||||
|
||||
pub fn print_nn(&self, from: u64, max_distance: isize, show_images: bool) {
|
||||
pub fn print_nn(&self, from: u64, max_distance: usize, show_images: bool) {
|
||||
//println!("{from:064b}");
|
||||
let neighbours = self.nn(from, max_distance);
|
||||
let (term_width, _) = viuer::terminal_size();
|
||||
@@ -280,7 +325,8 @@ impl DescriptorStore {
|
||||
print!("DescriptorStore:\n{}Total: {}", output, self.map.len())
|
||||
}
|
||||
|
||||
pub fn print_stats(&self) {
|
||||
pub fn get_stats(&self, mut max_threshold: usize) -> Vec<PRStats> {
|
||||
max_threshold = std::cmp::min(64, max_threshold);
|
||||
let mut mutator_stats = Vec::new();
|
||||
for mutator in get_all_mutators() {
|
||||
mutator_stats.push(
|
||||
@@ -298,7 +344,7 @@ impl DescriptorStore {
|
||||
for image in set.iter() {
|
||||
let phash = self.get(image).unwrap();
|
||||
debug!("Checking {}, with phash: {}", image, phash);
|
||||
for threshold in 0..64 {
|
||||
for threshold in 0..max_threshold {
|
||||
debug!("Threshold: {}", threshold);
|
||||
//Assume miss, therefore a false negative
|
||||
//Undo the miss when there is a true positive
|
||||
@@ -328,8 +374,13 @@ impl DescriptorStore {
|
||||
}
|
||||
}
|
||||
}
|
||||
mutator_stats
|
||||
}
|
||||
|
||||
pub fn print_stats(&self) {
|
||||
let mut mutator_stats = self.get_stats(64);
|
||||
for mutator in &mut mutator_stats {
|
||||
println!("{}:", mutator.name);
|
||||
for threshold in 0..64 {
|
||||
let tpos = mutator.true_positives[threshold] as f64;
|
||||
let fpos = mutator.false_positives[threshold] as f64;
|
||||
@@ -337,27 +388,11 @@ impl DescriptorStore {
|
||||
let p = tpos / (tpos + fpos);
|
||||
let r = tpos / (tpos + fneg);
|
||||
let f1 = 2.0*tpos / (2.0*tpos + fpos + fneg);
|
||||
println!("{} / {}:", mutator.name, threshold);
|
||||
println!("Precision: {}, Recall: {}, F1 score: {}", p, r, f1);
|
||||
println!("Tp: {}, Fp: {}, Fn: {}", tpos, fpos, fneg);
|
||||
debug!("Precision: {}, Recall: {}, F1 score: {}", p, r, f1);
|
||||
debug!("Tp: {}, Fp: {}, Fn: {}", tpos, fpos, fneg);
|
||||
println!("{}, {}" , p, r)
|
||||
}
|
||||
// println!("\t{} true positives: {}", mutator.name, mutator.true_positives);
|
||||
// println!("\t{} false positives: {}", mutator.name, mutator.false_positives);
|
||||
// println!(
|
||||
// "\t{} Precision: {:.3}", mutator.name,
|
||||
// mutator.true_positives as f64 /
|
||||
// (mutator.true_positives + mutator.false_positives) as f64
|
||||
// );
|
||||
// println!(
|
||||
// "\t{} Recall: {:.3}", mutator.name,
|
||||
// mutator.true_positives as f64 /
|
||||
// //(mutator.true_positives + mutator.false_negatives) as f64
|
||||
// set.len() as f64
|
||||
// );
|
||||
}
|
||||
//println!("Images processed: {}", set.len())
|
||||
// println!("{} true positives", true_positives);
|
||||
// println!("{} false positives", false_positives);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user