This commit is contained in:
Generated
+22
-290
@@ -32,15 +32,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_colours"
|
||||
version = "1.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a1558bd2075d341b9ca698ec8eb6fcc55a746b1fc4255585aad5b141d918a80"
|
||||
dependencies = [
|
||||
"rgb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.14"
|
||||
@@ -77,7 +68,7 @@ version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -87,7 +78,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -96,12 +87,6 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.22.1"
|
||||
@@ -176,7 +161,7 @@ dependencies = [
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
"windows-targets 0.52.5",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -232,15 +217,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
|
||||
|
||||
[[package]]
|
||||
name = "console"
|
||||
version = "0.15.8"
|
||||
name = "console_error_panic_hook"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb"
|
||||
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
|
||||
dependencies = [
|
||||
"encode_unicode",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
"cfg-if",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -347,31 +330,6 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"crossterm_winapi",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm_winapi"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.2"
|
||||
@@ -436,12 +394,6 @@ version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
||||
|
||||
[[package]]
|
||||
name = "encode_unicode"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.0"
|
||||
@@ -465,16 +417,6 @@ dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "exr"
|
||||
version = "1.5.2"
|
||||
@@ -490,12 +432,6 @@ dependencies = [
|
||||
"threadpool",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.24"
|
||||
@@ -709,16 +645,17 @@ dependencies = [
|
||||
name = "image_similarity"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"base64",
|
||||
"bktree",
|
||||
"clap",
|
||||
"console_error_panic_hook",
|
||||
"env_logger",
|
||||
"image",
|
||||
"log",
|
||||
"plotters",
|
||||
"rmp-serde",
|
||||
"serde",
|
||||
"viuer",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -770,7 +707,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.5",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -783,12 +720,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.9"
|
||||
@@ -838,18 +769,6 @@ dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nanorand"
|
||||
version = "0.7.0"
|
||||
@@ -948,29 +867,6 @@ version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.9"
|
||||
@@ -1122,15 +1018,6 @@ dependencies = [
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.5"
|
||||
@@ -1171,15 +1058,6 @@ version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
|
||||
|
||||
[[package]]
|
||||
name = "rgb"
|
||||
version = "0.8.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rmp"
|
||||
version = "0.8.11"
|
||||
@@ -1211,19 +1089,6 @@ dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
@@ -1257,36 +1122,6 @@ version = "1.0.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-mio"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.10.0"
|
||||
@@ -1330,27 +1165,6 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"rustix",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.61"
|
||||
@@ -1409,22 +1223,6 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "viuer"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec2ede5c8814363f92f862892dfe71a266f6816b649ca435aed1ff5e2cf3454e"
|
||||
dependencies = [
|
||||
"ansi_colours",
|
||||
"base64 0.21.7",
|
||||
"console",
|
||||
"crossterm",
|
||||
"image",
|
||||
"lazy_static",
|
||||
"tempfile",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
@@ -1533,7 +1331,7 @@ version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1548,16 +1346,7 @@ 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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1566,22 +1355,7 @@ version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1590,46 +1364,28 @@ version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.5",
|
||||
"windows_aarch64_msvc 0.52.5",
|
||||
"windows_i686_gnu 0.52.5",
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.5",
|
||||
"windows_x86_64_gnu 0.52.5",
|
||||
"windows_x86_64_gnullvm 0.52.5",
|
||||
"windows_x86_64_msvc 0.52.5",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.5"
|
||||
@@ -1642,48 +1398,24 @@ version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.5"
|
||||
|
||||
+5
-1
@@ -13,6 +13,10 @@ base64 = "0.22.1"
|
||||
log = "0.4.21"
|
||||
env_logger = "0.11.3"
|
||||
bktree = "1.0.1"
|
||||
viuer = "0.7.1"
|
||||
clap = { version = "4.5.4", features = ["derive"] }
|
||||
plotters = "0.3.6"
|
||||
wasm-bindgen = "0.2.92"
|
||||
console_error_panic_hook = "0.1.7"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
@@ -23,5 +23,5 @@ fn main() {
|
||||
debug!("Phash integer:\n{phash}");
|
||||
debug!("Phash binary:\n{phash:064b}");
|
||||
let output = URL_SAFE_NO_PAD.encode(phash.to_be_bytes());
|
||||
println!("{output}")
|
||||
println!("{output}");
|
||||
}
|
||||
|
||||
+2
-8
@@ -24,17 +24,11 @@ fn main() {
|
||||
|
||||
let img = image::open(cfg.path)
|
||||
.expect("Unable to open file");
|
||||
// let conf = viuer::Config {
|
||||
// width: Some(16),
|
||||
// height: Some(8),
|
||||
// ..Default::default()
|
||||
// };
|
||||
// viuer::print(&img, &conf).expect("Image printing failed.");
|
||||
|
||||
let phash: u64 = desc.describe(&img);
|
||||
let store =
|
||||
let _store =
|
||||
DescriptorStore::new(Box::new(desc))
|
||||
.with_file("dct50.messagepack");
|
||||
info!("Phash integer:\n{phash}");
|
||||
info!("Phash binary:\n{phash:064b}");
|
||||
store.print_nn(phash, cfg.distance, cfg.show_images);
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
use image_similarity::descriptors::{Descriptor, DCT};
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let desc = DCT::new();
|
||||
|
||||
//Initialize hashmap, empty or from cached file:
|
||||
let count = fs::read_dir("img").unwrap().count();
|
||||
let map_file = fs::read("map.messagepack");
|
||||
let mut map: HashMap<String, u64> = match map_file {
|
||||
Ok(f) => rmp_serde::from_slice(&f).unwrap(),
|
||||
Err(_e) => HashMap::with_capacity(count),
|
||||
};
|
||||
|
||||
//Calculate phashes for all images
|
||||
for node in fs::read_dir("img").unwrap() {
|
||||
let file = node.expect("Error walking directory");
|
||||
let name = file.file_name().into_string().expect("Issue with filename");
|
||||
if !map.contains_key(&name) {
|
||||
let img = image::open(file.path()).expect("Unable to open file");
|
||||
let phash = desc.describe(&img);
|
||||
map.insert(name, phash);
|
||||
}
|
||||
}
|
||||
|
||||
for (key, val) in map.iter() {
|
||||
println!("{key: >15}: {val}\t {val:b}");
|
||||
}
|
||||
|
||||
//Serialize hashmap with MessagePack:
|
||||
let _serialized: Vec<u8> = rmp_serde::to_vec(&map).unwrap();
|
||||
//fs::write("map.messagepack",&serialized).unwrap();
|
||||
}
|
||||
+3
-11
@@ -16,23 +16,15 @@ fn main() {
|
||||
|
||||
let cfg = Cfg::parse();
|
||||
|
||||
let img = image::open(&cfg.path)
|
||||
let img = image::open(cfg.path)
|
||||
.expect("Unable to open file");
|
||||
|
||||
let mutators = get_all_mutators();
|
||||
|
||||
let conf = viuer::Config {
|
||||
width: Some(16),
|
||||
height: Some(8),
|
||||
..Default::default()
|
||||
};
|
||||
for mutator in mutators {
|
||||
let mutated = mutator.mutate(&img);
|
||||
let filename = "mut".to_string() + &mutator.tag() + &"png".to_string();
|
||||
println!("Saving to {}", filename);
|
||||
let filename = "mut".to_string() + &mutator.tag() + "png";
|
||||
println!("Saving to {filename}");
|
||||
mutated.save(filename).expect("Saving image failed");
|
||||
if cfg.show_images {
|
||||
viuer::print(&mutated, &conf).expect("Image printing failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
+24
-16
@@ -29,10 +29,11 @@ impl DCT {
|
||||
50..=100 => 200.0 - 2.0*quality as f32,
|
||||
_ => 100.0 // Invalid input: set to base quality
|
||||
};
|
||||
for i in 0..64 {
|
||||
quantization_matrix[i] = ((scalar * self.quantization_matrix[i] as f32 + 50.0) / 100.0).floor() as u8;
|
||||
if quantization_matrix[i] == 0 {
|
||||
quantization_matrix[i] = 1;
|
||||
//for i in 0..64 {
|
||||
for (_, cell) in quantization_matrix.iter_mut().enumerate() {
|
||||
*cell = ((scalar * *cell as f32 + 50.0) / 100.0).floor() as u8;
|
||||
if *cell == 0 {
|
||||
*cell = 1;
|
||||
}
|
||||
}
|
||||
self.quantization_matrix = quantization_matrix;
|
||||
@@ -40,17 +41,17 @@ impl DCT {
|
||||
}
|
||||
|
||||
///
|
||||
fn dct(&self, img: &image::DynamicImage) -> [f64; 64] {
|
||||
pub fn dct(&self, img: &image::DynamicImage) -> [f64; 64] {
|
||||
let mut dct_values: [f64; 64] = [0.0; 64];
|
||||
for u in 0..8 {
|
||||
for v in 0..8 {
|
||||
let k = (v*8)+u;
|
||||
let mut alpha = 0.25;
|
||||
if u == 0 {
|
||||
alpha = alpha / SQRT_2
|
||||
alpha /= SQRT_2
|
||||
}
|
||||
if v == 0 {
|
||||
alpha = alpha / SQRT_2
|
||||
alpha /= SQRT_2
|
||||
}
|
||||
let v: f64 = v as f64;
|
||||
let u: f64 = u as f64;
|
||||
@@ -72,7 +73,8 @@ impl DCT {
|
||||
|
||||
fn idct(&self, dct_values: [f64; 64]) -> [u8; 64] {
|
||||
let mut reconstructed: [u8; 64] = [0; 64];
|
||||
for k in 0..64 {
|
||||
//for k in 0..64 {
|
||||
for (k, item) in reconstructed.iter_mut().enumerate() {
|
||||
let x = (k%8) as f64;
|
||||
let y = (k/8) as f64;
|
||||
let mut sum = 0.0;
|
||||
@@ -80,10 +82,10 @@ impl DCT {
|
||||
for v in 0..8 {
|
||||
let mut alpha = 1.0;
|
||||
if u == 0 {
|
||||
alpha = alpha / SQRT_2
|
||||
alpha /= SQRT_2
|
||||
}
|
||||
if v == 0 {
|
||||
alpha = alpha / SQRT_2
|
||||
alpha /= SQRT_2
|
||||
}
|
||||
let uv = (v*8)+u;
|
||||
let v = v as f64;
|
||||
@@ -96,12 +98,18 @@ impl DCT {
|
||||
}
|
||||
}
|
||||
sum = 127.0 + (0.25 * sum).round();
|
||||
reconstructed[k] = std::cmp::min(255_u8, sum as u8);
|
||||
*item = std::cmp::min(255_u8, sum as u8);
|
||||
}
|
||||
reconstructed
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for DCT {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Descriptor for DCT {
|
||||
fn info(&self) -> String {
|
||||
"dct".to_string()
|
||||
@@ -124,7 +132,7 @@ impl Descriptor for DCT {
|
||||
if log_enabled!(Level::Debug) {
|
||||
resized.save("resize.png").expect("Error saving file");
|
||||
// De-quantization:
|
||||
let mut dequant = dct_values.clone();
|
||||
let mut dequant = dct_values;
|
||||
for i in 0..64 {
|
||||
dequant[i] = dct_values[i] * self.quantization_matrix[i] as f64;
|
||||
}
|
||||
@@ -189,8 +197,8 @@ impl Descriptor for DCT {
|
||||
}
|
||||
|
||||
// Shift masks
|
||||
sign_mask = sign_mask << 1;
|
||||
pearson_mask = pearson_mask << 1;
|
||||
sign_mask <<= 1;
|
||||
pearson_mask <<= 1;
|
||||
debug!("Sign mask: {:028b}", sign_mask);
|
||||
debug!("Pearson mask: {:028b}", pearson_mask);
|
||||
}
|
||||
@@ -199,11 +207,11 @@ impl Descriptor for DCT {
|
||||
|
||||
let mut mask = sign_mask;
|
||||
debug!("Mask: {:064b}", mask);
|
||||
mask = mask << 28;
|
||||
mask <<= 28;
|
||||
debug!("Mask: {:064b}", mask);
|
||||
mask += pearson_mask;
|
||||
debug!("Mask: {:064b}", mask);
|
||||
mask = mask << 8;
|
||||
mask <<= 8;
|
||||
debug!("Mask: {:064b}", mask);
|
||||
// TODO: Do something with these last 8 bits.
|
||||
mask
|
||||
|
||||
@@ -55,10 +55,8 @@ impl Descriptor for Median {
|
||||
fn describe(&self, img: &image::DynamicImage) -> u64 {
|
||||
let img = self.resize(img);
|
||||
let mut values: [u8; 64] = [0; 64];
|
||||
let mut i: usize = 0;
|
||||
for (_, _, pix) in img.pixels() {
|
||||
for (i, (_, _, pix)) in img.pixels().enumerate() {
|
||||
values[i] = pix[0];
|
||||
i = i+1;
|
||||
}
|
||||
let median = median64(&values);
|
||||
let mut mask: u64 = 0;
|
||||
@@ -67,15 +65,16 @@ impl Descriptor for Median {
|
||||
if pix[0] > median {
|
||||
mask += 1;
|
||||
}
|
||||
mask = mask << 1;
|
||||
mask <<= 1;
|
||||
}
|
||||
mask
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
let descriptors: Vec<Box<dyn Descriptor>> =
|
||||
vec![Box::new(DCT::new()), Box::new(Median)];
|
||||
// descriptors.push(Box::new(DCT::new()));
|
||||
// descriptors.push(Box::new(Median));
|
||||
descriptors
|
||||
}
|
||||
@@ -5,3 +5,4 @@
|
||||
pub mod descriptors;
|
||||
pub mod store;
|
||||
pub mod mutators;
|
||||
pub mod wasm;
|
||||
+6
-14
@@ -28,7 +28,6 @@ fn main() {
|
||||
}
|
||||
|
||||
for node in fs::read_dir(cfg.path).unwrap() {
|
||||
//println!("{:?}", node);
|
||||
let file = node.expect("Error walking directory");
|
||||
let name = match file.file_name().into_string() {
|
||||
Ok(v) => v,
|
||||
@@ -54,7 +53,7 @@ fn main() {
|
||||
error!("Failed to process {}: {}", name, e);
|
||||
continue
|
||||
}
|
||||
};
|
||||
}.thumbnail_exact(8, 8);
|
||||
|
||||
//Store the phashes of the base image
|
||||
for store in &mut stores {
|
||||
@@ -72,7 +71,7 @@ fn main() {
|
||||
}
|
||||
for store in &stores {
|
||||
store.save().expect("Error saving store");
|
||||
println!("{}", store);
|
||||
println!("{store}");
|
||||
}
|
||||
|
||||
// Create PR-curve graphs from stores
|
||||
@@ -96,18 +95,17 @@ fn main() {
|
||||
.disable_mesh()
|
||||
.x_desc("Recall")
|
||||
.y_desc("Precision")
|
||||
.x_label_formatter(&|x| format!("{:.3}", x))
|
||||
.y_label_formatter(&|x| format!("{:.3}", x))
|
||||
.x_label_formatter(&|x| format!("{x:.3}"))
|
||||
.y_label_formatter(&|x| format!("{x:.3}"))
|
||||
.draw().unwrap();
|
||||
let colors = [&RED, &BLUE, &CYAN, &MAGENTA, &BLACK, &GREEN, &YELLOW];
|
||||
let n = colors.len();
|
||||
let mut i = 0;
|
||||
for mutator_stats in stats {
|
||||
for (i, mutator_stats) in stats.into_iter().enumerate() {
|
||||
// And we can draw something in the drawing area
|
||||
let pr_curve = mutator_stats.pr_curve(max_threshold);
|
||||
println!("{}:", mutator_stats.name);
|
||||
for (x, y) in pr_curve.clone() {
|
||||
println!("{}, {}", x, y);
|
||||
println!("{x}, {y}");
|
||||
}
|
||||
let color = colors[i % n];
|
||||
chart.draw_series(LineSeries::new(
|
||||
@@ -116,17 +114,11 @@ fn main() {
|
||||
).point_size(2)).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();
|
||||
chart.configure_series_labels()
|
||||
.position(SeriesLabelPosition::MiddleLeft)
|
||||
//.legend_area_size(5)
|
||||
.border_style(BLACK)
|
||||
//.background_style(BLUE.mix(0.1))
|
||||
//.label_font(("Calibri", 20))
|
||||
.draw()
|
||||
.unwrap();
|
||||
//println!("{}", store);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-5
@@ -72,10 +72,12 @@ impl Mutator for Blur {
|
||||
}
|
||||
|
||||
pub fn get_all_mutators() -> Vec<Box<dyn Mutator>> {
|
||||
let mut mutators: Vec<Box<dyn Mutator>> = Vec::with_capacity(4);
|
||||
mutators.push(Box::new(Flip));
|
||||
mutators.push(Box::new(Hue));
|
||||
mutators.push(Box::new(Sharp));
|
||||
mutators.push(Box::new(Blur));
|
||||
let mutators: Vec<Box<dyn Mutator>> = //Vec::with_capacity(4);
|
||||
vec![
|
||||
Box::new(Flip),
|
||||
Box::new(Hue),
|
||||
Box::new(Sharp),
|
||||
Box::new(Blur),
|
||||
];
|
||||
mutators
|
||||
}
|
||||
+30
-71
@@ -34,8 +34,7 @@ impl PRStats {
|
||||
};
|
||||
let tpos = self.true_positives[t] as f64;
|
||||
let fpos = self.false_positives[t] as f64;
|
||||
let p = tpos / (tpos + fpos);
|
||||
p
|
||||
tpos / (tpos + fpos)
|
||||
}
|
||||
pub fn recall(&self, threshold: usize) -> f64 {
|
||||
let t = match threshold {
|
||||
@@ -44,8 +43,7 @@ impl PRStats {
|
||||
};
|
||||
let tpos = self.true_positives[t] as f64;
|
||||
let fneg = self.false_negatives[t] as f64;
|
||||
let r = tpos / (tpos + fneg);
|
||||
r
|
||||
tpos / (tpos + fneg)
|
||||
}
|
||||
pub fn pr(&self, threshold: usize) -> (f64, f64) {
|
||||
let t = match threshold {
|
||||
@@ -87,7 +85,7 @@ pub struct DescriptorStore {
|
||||
}
|
||||
|
||||
impl DescriptorStore {
|
||||
/// Makes a new empty DescriptorStore with default settings
|
||||
/// Makes a new empty `DescriptorStore` with default settings
|
||||
pub fn new(descriptor: Box<dyn Descriptor>) -> Self {
|
||||
let map: HashMap<u64, Vec<String>> = HashMap::new();
|
||||
//let seen: HashSet<String> = HashSet::new();
|
||||
@@ -105,23 +103,22 @@ impl DescriptorStore {
|
||||
pub fn with_file<P: AsRef<Path>>(mut self, path: P) -> Self {
|
||||
self.save_location = std::path::PathBuf::from(path.as_ref());
|
||||
let map_file = fs::read(&self.save_location);
|
||||
match map_file {
|
||||
Ok(f) => {
|
||||
self.map = rmp_serde::from_slice(&f).unwrap();
|
||||
for i in self.map.keys() {
|
||||
self.bktree.insert(*i);
|
||||
}
|
||||
let mut seen: HashSet<String> = HashSet::new();
|
||||
for bucket in self.map.values() {
|
||||
for element in bucket {
|
||||
if !element.starts_with("mut.") {
|
||||
seen.insert(element.clone());
|
||||
}
|
||||
if let Ok(f) = map_file {
|
||||
self.map = rmp_serde::from_slice(&f).unwrap();
|
||||
for i in self.map.keys() {
|
||||
self.bktree.insert(*i);
|
||||
}
|
||||
let mut seen: HashSet<String> = HashSet::new();
|
||||
for bucket in self.map.values() {
|
||||
for element in bucket {
|
||||
if !element.starts_with("mut.") {
|
||||
seen.insert(element.clone());
|
||||
}
|
||||
}
|
||||
self.seen = Some(seen);
|
||||
},
|
||||
Err(_) => info!("{} not found, starting from empty store.", self.save_location.display()),
|
||||
}
|
||||
self.seen = Some(seen);
|
||||
} else {
|
||||
info!("{} not found, starting from empty store.", self.save_location.display());
|
||||
};
|
||||
self
|
||||
}
|
||||
@@ -147,8 +144,8 @@ impl DescriptorStore {
|
||||
Ok(value) => value,
|
||||
Err(_e) => return Err(SaveError::Serialization),
|
||||
};
|
||||
match fs::write(&self.save_location, &serialized) {
|
||||
Ok(_) => Ok(()),
|
||||
match fs::write(&self.save_location, serialized) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(_e) => Err(SaveError::File),
|
||||
}
|
||||
}
|
||||
@@ -167,7 +164,7 @@ impl DescriptorStore {
|
||||
},
|
||||
None => {
|
||||
for bucket in self.map.values() {
|
||||
if bucket.contains(&value) {
|
||||
if bucket.contains(value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -178,7 +175,7 @@ impl DescriptorStore {
|
||||
|
||||
pub fn get(&self, value: &String) -> Option<u64> {
|
||||
for (key, bucket) in self.map.iter() {
|
||||
if bucket.contains(&value) {
|
||||
if bucket.contains(value) {
|
||||
return Some(*key);
|
||||
}
|
||||
}
|
||||
@@ -187,7 +184,7 @@ impl DescriptorStore {
|
||||
|
||||
/// Inserts a single value into the store
|
||||
pub fn insert(&mut self, key: &u64, value: String) {
|
||||
let bucket = match self.map.get(&key) {
|
||||
let bucket = match self.map.get(key) {
|
||||
Some(b) => {
|
||||
let mut n = b.clone();
|
||||
if !n.contains(&value) {
|
||||
@@ -213,7 +210,9 @@ impl DescriptorStore {
|
||||
continue
|
||||
}
|
||||
};
|
||||
if !self.has_value(&name) { // !self.contains(name.to_string()) {
|
||||
if !self.has_value(&name) {
|
||||
debug!("{} already known, skipping.", name);
|
||||
} else {
|
||||
info!("Processing {}", name);
|
||||
let img = match image::open(file.path()) {
|
||||
Ok(v) => v,
|
||||
@@ -227,8 +226,6 @@ impl DescriptorStore {
|
||||
println!("{} duplicate of {:?}", name, self.map.get(&phash));
|
||||
}
|
||||
self.insert(&phash, name);
|
||||
} else {
|
||||
debug!("{} already known, skipping.", name);
|
||||
}
|
||||
self.save().expect("error");
|
||||
}
|
||||
@@ -238,15 +235,15 @@ impl DescriptorStore {
|
||||
|
||||
pub fn store(&mut self, img: &DynamicImage, name: String) {
|
||||
if !self.has_value(&name) {
|
||||
let phash = self.descriptor.describe(&img);
|
||||
let phash = self.descriptor.describe(img);
|
||||
self.insert(&phash, name);
|
||||
}
|
||||
}
|
||||
|
||||
/// Nearest neighbours
|
||||
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));
|
||||
let neighbours = self.bktree.find(from, max_distance.try_into().unwrap());
|
||||
//neighbours.sort_by(|a, b| a.1.cmp(&b.1));
|
||||
neighbours
|
||||
}
|
||||
|
||||
@@ -263,44 +260,6 @@ impl DescriptorStore {
|
||||
results
|
||||
}
|
||||
|
||||
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();
|
||||
let mut x = 0;
|
||||
let mut y = 8;
|
||||
for (element, distance) in neighbours {
|
||||
let elements = self.map.get(element);
|
||||
match elements {
|
||||
Some(paths) => {
|
||||
for path in paths {
|
||||
println!("{element:064b}: {:?} (distance: {distance})", path);
|
||||
if show_images {
|
||||
if x+16 >= term_width {
|
||||
x = 0;
|
||||
y += 8;
|
||||
}
|
||||
let conf = viuer::Config {
|
||||
width: Some(16),
|
||||
height: Some(8),
|
||||
x,
|
||||
y,
|
||||
use_kitty: false,
|
||||
..Default::default()
|
||||
};
|
||||
x += 16;
|
||||
let path = "data/".to_string() + path;
|
||||
let img = image::open(&path).unwrap();
|
||||
let img = img.grayscale().thumbnail_exact(8, 8);
|
||||
viuer::print(&img, &conf).expect("Image printing failed.");
|
||||
}
|
||||
}
|
||||
},
|
||||
None => ()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_most_dups(&self) {
|
||||
let mut most = 0;
|
||||
for bucket in self.map.values() {
|
||||
@@ -319,7 +278,7 @@ impl DescriptorStore {
|
||||
let value_entry = format!("{value}\n");
|
||||
output.push_str(&value_entry);
|
||||
}
|
||||
output.push_str("\n");
|
||||
output.push('\n');
|
||||
}
|
||||
}
|
||||
print!("DescriptorStore:\n{}Total: {}", output, self.map.len())
|
||||
@@ -415,7 +374,7 @@ impl fmt::Display for DescriptorStore {
|
||||
let value_entry = format!("\t{value}\n");
|
||||
output.push_str(&value_entry);
|
||||
}
|
||||
output.push_str("\n");
|
||||
output.push('\n');
|
||||
}
|
||||
write!(f, "DescriptorStore:\n{}Total: {}", output, self.map.len())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user