diff --git a/Cargo.lock b/Cargo.lock index 4dc3b5b..938349d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,10 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "ab_glyph_rasterizer" -version = "0.1.2" -source = "registry+/~https://github.com/rust-lang/crates.io-index" - [[package]] name = "adler32" version = "1.0.4" @@ -175,14 +170,6 @@ name = "constant_time_eq" version = "0.1.5" source = "registry+/~https://github.com/rust-lang/crates.io-index" -[[package]] -name = "conv" -version = "0.3.3" -source = "registry+/~https://github.com/rust-lang/crates.io-index" -dependencies = [ - "custom_derive 0.1.7 (registry+/~https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "core-foundation" version = "0.7.0" @@ -248,11 +235,6 @@ dependencies = [ "lazy_static 1.4.0 (registry+/~https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "custom_derive" -version = "0.1.7" -source = "registry+/~https://github.com/rust-lang/crates.io-index" - [[package]] name = "dbase" version = "0.0.4" @@ -729,22 +711,6 @@ dependencies = [ "tiff 0.5.0 (registry+/~https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "imageproc" -version = "0.21.0" -source = "registry+/~https://github.com/rust-lang/crates.io-index" -dependencies = [ - "conv 0.3.3 (registry+/~https://github.com/rust-lang/crates.io-index)", - "image 0.23.8 (registry+/~https://github.com/rust-lang/crates.io-index)", - "itertools 0.9.0 (registry+/~https://github.com/rust-lang/crates.io-index)", - "num 0.3.0 (registry+/~https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+/~https://github.com/rust-lang/crates.io-index)", - "rand_distr 0.2.2 (registry+/~https://github.com/rust-lang/crates.io-index)", - "rayon 1.3.1 (registry+/~https://github.com/rust-lang/crates.io-index)", - "rulinalg 0.4.2 (registry+/~https://github.com/rust-lang/crates.io-index)", - "rusttype 0.9.2 (registry+/~https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "indexmap" version = "1.3.2" @@ -761,14 +727,6 @@ dependencies = [ "libc 0.2.69 (registry+/~https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "itertools" -version = "0.9.0" -source = "registry+/~https://github.com/rust-lang/crates.io-index" -dependencies = [ - "either 1.5.3 (registry+/~https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "itoa" version = "0.4.5" @@ -800,6 +758,11 @@ dependencies = [ "winapi-build 0.1.1 (registry+/~https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "lab" +version = "0.8.1" +source = "registry+/~https://github.com/rust-lang/crates.io-index" + [[package]] name = "lazy_static" version = "1.4.0" @@ -836,14 +799,6 @@ name = "matches" version = "0.1.8" source = "registry+/~https://github.com/rust-lang/crates.io-index" -[[package]] -name = "matrixmultiply" -version = "0.1.15" -source = "registry+/~https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rawpointer 0.1.0 (registry+/~https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "maybe-uninit" version = "2.0.0" @@ -957,7 +912,7 @@ dependencies = [ "gtk 0.8.1 (registry+/~https://github.com/rust-lang/crates.io-index)", "hound 3.4.0 (registry+/~https://github.com/rust-lang/crates.io-index)", "image 0.23.8 (registry+/~https://github.com/rust-lang/crates.io-index)", - "imageproc 0.21.0 (registry+/~https://github.com/rust-lang/crates.io-index)", + "lab 0.8.1 (registry+/~https://github.com/rust-lang/crates.io-index)", "line_drawing 0.8.0 (registry+/~https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+/~https://github.com/rust-lang/crates.io-index)", "openssl 0.10.29 (registry+/~https://github.com/rust-lang/crates.io-index)", @@ -972,39 +927,6 @@ dependencies = [ "winapi 0.3.8 (registry+/~https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "num" -version = "0.1.42" -source = "registry+/~https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-integer 0.1.43 (registry+/~https://github.com/rust-lang/crates.io-index)", - "num-iter 0.1.41 (registry+/~https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.12 (registry+/~https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num" -version = "0.3.0" -source = "registry+/~https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-bigint 0.3.0 (registry+/~https://github.com/rust-lang/crates.io-index)", - "num-complex 0.3.0 (registry+/~https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.43 (registry+/~https://github.com/rust-lang/crates.io-index)", - "num-iter 0.1.41 (registry+/~https://github.com/rust-lang/crates.io-index)", - "num-rational 0.3.0 (registry+/~https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.12 (registry+/~https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-bigint" -version = "0.3.0" -source = "registry+/~https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 1.0.0 (registry+/~https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.43 (registry+/~https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.12 (registry+/~https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "num-complex" version = "0.2.4" @@ -1014,14 +936,6 @@ dependencies = [ "num-traits 0.2.12 (registry+/~https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "num-complex" -version = "0.3.0" -source = "registry+/~https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-traits 0.2.12 (registry+/~https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "num-integer" version = "0.1.43" @@ -1047,7 +961,6 @@ version = "0.3.0" source = "registry+/~https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 1.0.0 (registry+/~https://github.com/rust-lang/crates.io-index)", - "num-bigint 0.3.0 (registry+/~https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.43 (registry+/~https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.12 (registry+/~https://github.com/rust-lang/crates.io-index)", ] @@ -1121,14 +1034,6 @@ dependencies = [ "vcpkg 0.2.8 (registry+/~https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "owned_ttf_parser" -version = "0.6.0" -source = "registry+/~https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ttf-parser 0.6.2 (registry+/~https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "pango" version = "0.8.0" @@ -1263,14 +1168,6 @@ dependencies = [ "getrandom 0.1.14 (registry+/~https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rand_distr" -version = "0.2.2" -source = "registry+/~https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand 0.7.3 (registry+/~https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rand_hc" version = "0.2.0" @@ -1279,11 +1176,6 @@ dependencies = [ "rand_core 0.5.1 (registry+/~https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rawpointer" -version = "0.1.0" -source = "registry+/~https://github.com/rust-lang/crates.io-index" - [[package]] name = "rayon" version = "1.3.1" @@ -1364,15 +1256,6 @@ dependencies = [ "winreg 0.6.2 (registry+/~https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rulinalg" -version = "0.4.2" -source = "registry+/~https://github.com/rust-lang/crates.io-index" -dependencies = [ - "matrixmultiply 0.1.15 (registry+/~https://github.com/rust-lang/crates.io-index)", - "num 0.1.42 (registry+/~https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rust-argon2" version = "0.7.0" @@ -1396,15 +1279,6 @@ dependencies = [ "transpose 0.1.0 (registry+/~https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rusttype" -version = "0.9.2" -source = "registry+/~https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ab_glyph_rasterizer 0.1.2 (registry+/~https://github.com/rust-lang/crates.io-index)", - "owned_ttf_parser 0.6.0 (registry+/~https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "ryu" version = "1.0.4" @@ -1637,11 +1511,6 @@ name = "try-lock" version = "0.2.2" source = "registry+/~https://github.com/rust-lang/crates.io-index" -[[package]] -name = "ttf-parser" -version = "0.6.2" -source = "registry+/~https://github.com/rust-lang/crates.io-index" - [[package]] name = "unicase" version = "2.6.0" @@ -1823,7 +1692,6 @@ dependencies = [ ] [metadata] -"checksum ab_glyph_rasterizer 0.1.2 (registry+/~https://github.com/rust-lang/crates.io-index)" = "2b7e4e8cf778db814365e46839949ca74df4efb10e87ba4913e6ec5967ef0285" "checksum adler32 1.0.4 (registry+/~https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" "checksum approx 0.3.2 (registry+/~https://github.com/rust-lang/crates.io-index)" = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" "checksum argparse 0.2.2 (registry+/~https://github.com/rust-lang/crates.io-index)" = "3f8ebf5827e4ac4fd5946560e6a99776ea73b596d80898f357007317a7141e47" @@ -1848,7 +1716,6 @@ dependencies = [ "checksum color_quant 1.0.1 (registry+/~https://github.com/rust-lang/crates.io-index)" = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd" "checksum colored 1.9.3 (registry+/~https://github.com/rust-lang/crates.io-index)" = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" "checksum constant_time_eq 0.1.5 (registry+/~https://github.com/rust-lang/crates.io-index)" = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" -"checksum conv 0.3.3 (registry+/~https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" "checksum core-foundation 0.7.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" "checksum core-foundation-sys 0.7.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" "checksum crc32fast 1.2.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" @@ -1856,7 +1723,6 @@ dependencies = [ "checksum crossbeam-epoch 0.8.2 (registry+/~https://github.com/rust-lang/crates.io-index)" = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" "checksum crossbeam-queue 0.2.1 (registry+/~https://github.com/rust-lang/crates.io-index)" = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" "checksum crossbeam-utils 0.7.2 (registry+/~https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -"checksum custom_derive 0.1.7 (registry+/~https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" "checksum dbase 0.0.4 (registry+/~https://github.com/rust-lang/crates.io-index)" = "f11532d799d221b4b11d7e0df6dcace80a64b9b274687a638f76e4668872bc1a" "checksum deflate 0.8.4 (registry+/~https://github.com/rust-lang/crates.io-index)" = "e7e5d2a2273fed52a7f947ee55b092c4057025d7a3e04e5ecdbd25d6c3fb1bd7" "checksum directories 2.0.2 (registry+/~https://github.com/rust-lang/crates.io-index)" = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" @@ -1902,21 +1768,19 @@ dependencies = [ "checksum hyper-tls 0.4.1 (registry+/~https://github.com/rust-lang/crates.io-index)" = "3adcd308402b9553630734e9c36b77a7e48b3821251ca2493e8cd596763aafaa" "checksum idna 0.2.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" "checksum image 0.23.8 (registry+/~https://github.com/rust-lang/crates.io-index)" = "543904170510c1b5fb65140485d84de4a57fddb2ed685481e9020ce3d2c9f64c" -"checksum imageproc 0.21.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "7b0fbd0ced24e3bc65052406fa6466203fe9c8d1990a3327567433e47109ed1a" "checksum indexmap 1.3.2 (registry+/~https://github.com/rust-lang/crates.io-index)" = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292" "checksum iovec 0.1.4 (registry+/~https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -"checksum itertools 0.9.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" "checksum itoa 0.4.5 (registry+/~https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" "checksum jpeg-decoder 0.1.19 (registry+/~https://github.com/rust-lang/crates.io-index)" = "5b47b4c4e017b01abdc5bcc126d2d1002e5a75bbe3ce73f9f4f311a916363704" "checksum js-sys 0.3.39 (registry+/~https://github.com/rust-lang/crates.io-index)" = "fa5a448de267e7358beaf4a5d849518fe9a0c13fce7afd44b06e68550e5562a7" "checksum kernel32-sys 0.2.2 (registry+/~https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum lab 0.8.1 (registry+/~https://github.com/rust-lang/crates.io-index)" = "25f435d0dc44d7fcfbd5b10a4f34b9cebff86e4d85a5efbbc1b58cc8e35e56fb" "checksum lazy_static 1.4.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.69 (registry+/~https://github.com/rust-lang/crates.io-index)" = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" "checksum line_drawing 0.8.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "f81902e542483002b103c6424d23e765c2e5a65f732923299053a601bce50ab2" "checksum log 0.4.8 (registry+/~https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "checksum lzw 0.10.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" "checksum matches 0.1.8 (registry+/~https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -"checksum matrixmultiply 0.1.15 (registry+/~https://github.com/rust-lang/crates.io-index)" = "dcad67dcec2d58ff56f6292582377e6921afdf3bfbd533e26fb8900ae575e002" "checksum maybe-uninit 2.0.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" "checksum memchr 2.3.3 (registry+/~https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" "checksum memoffset 0.5.4 (registry+/~https://github.com/rust-lang/crates.io-index)" = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" @@ -1927,11 +1791,7 @@ dependencies = [ "checksum miow 0.2.1 (registry+/~https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum native-tls 0.2.4 (registry+/~https://github.com/rust-lang/crates.io-index)" = "2b0d88c06fe90d5ee94048ba40409ef1d9315d86f6f38c2efdaad4fb50c58b2d" "checksum net2 0.2.34 (registry+/~https://github.com/rust-lang/crates.io-index)" = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" -"checksum num 0.1.42 (registry+/~https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" -"checksum num 0.3.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "ab3e176191bc4faad357e3122c4747aa098ac880e88b168f106386128736cf4a" -"checksum num-bigint 0.3.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "b7f3fc75e3697059fb1bc465e3d8cca6cf92f56854f201158b3f9c77d5a3cfa0" "checksum num-complex 0.2.4 (registry+/~https://github.com/rust-lang/crates.io-index)" = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" -"checksum num-complex 0.3.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "b05ad05bd8977050b171b3f6b48175fea6e0565b7981059b486075e1026a9fb5" "checksum num-integer 0.1.43 (registry+/~https://github.com/rust-lang/crates.io-index)" = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" "checksum num-iter 0.1.41 (registry+/~https://github.com/rust-lang/crates.io-index)" = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f" "checksum num-rational 0.3.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "a5b4d7360f362cfb50dde8143501e6940b22f644be75a4cc90b2d81968908138" @@ -1943,7 +1803,6 @@ dependencies = [ "checksum openssl-probe 0.1.2 (registry+/~https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" "checksum openssl-src 111.9.0+1.1.1g (registry+/~https://github.com/rust-lang/crates.io-index)" = "a2dbe10ddd1eb335aba3780eb2eaa13e1b7b441d2562fd962398740927f39ec4" "checksum openssl-sys 0.9.56 (registry+/~https://github.com/rust-lang/crates.io-index)" = "f02309a7f127000ed50594f0b50ecc69e7c654e16d41b4e8156d1b3df8e0b52e" -"checksum owned_ttf_parser 0.6.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "9f923fb806c46266c02ab4a5b239735c144bdeda724a50ed058e5226f594cde3" "checksum pango 0.8.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "1e9c6b728f1be8edb5f9f981420b651d5ea30bdb9de89f1f1262d0084a020577" "checksum pango-sys 0.9.1 (registry+/~https://github.com/rust-lang/crates.io-index)" = "86b93d84907b3cf0819bff8f13598ba72843bee579d5ebc2502e4b0367b4be7d" "checksum percent-encoding 2.1.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" @@ -1961,19 +1820,15 @@ dependencies = [ "checksum rand 0.7.3 (registry+/~https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" "checksum rand_chacha 0.2.2 (registry+/~https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" "checksum rand_core 0.5.1 (registry+/~https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -"checksum rand_distr 0.2.2 (registry+/~https://github.com/rust-lang/crates.io-index)" = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2" "checksum rand_hc 0.2.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -"checksum rawpointer 0.1.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "ebac11a9d2e11f2af219b8b8d833b76b1ea0e054aa0e8d8e9e4cbde353bdf019" "checksum rayon 1.3.1 (registry+/~https://github.com/rust-lang/crates.io-index)" = "62f02856753d04e03e26929f820d0a0a337ebe71f849801eea335d464b349080" "checksum rayon-core 1.7.1 (registry+/~https://github.com/rust-lang/crates.io-index)" = "e92e15d89083484e11353891f1af602cc661426deb9564c298b270c726973280" "checksum redox_syscall 0.1.56 (registry+/~https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum redox_users 0.3.4 (registry+/~https://github.com/rust-lang/crates.io-index)" = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" "checksum remove_dir_all 0.5.2 (registry+/~https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" "checksum reqwest 0.10.4 (registry+/~https://github.com/rust-lang/crates.io-index)" = "02b81e49ddec5109a9dcfc5f2a317ff53377c915e9ae9d4f2fb50914b85614e2" -"checksum rulinalg 0.4.2 (registry+/~https://github.com/rust-lang/crates.io-index)" = "04ada202c9685e1d72a7420c578e92b358dbf807d3dfabb676a3dab9cc3bb12f" "checksum rust-argon2 0.7.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" "checksum rustfft 3.0.1 (registry+/~https://github.com/rust-lang/crates.io-index)" = "77008ed59a8923c8b4ac2e5eaa6d28fbe893d3b9515098a4a5fc7767d6430fe5" -"checksum rusttype 0.9.2 (registry+/~https://github.com/rust-lang/crates.io-index)" = "dc7c727aded0be18c5b80c1640eae0ac8e396abf6fa8477d96cb37d18ee5ec59" "checksum ryu 1.0.4 (registry+/~https://github.com/rust-lang/crates.io-index)" = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1" "checksum satellite 0.1.0 (git+/~https://github.com/richinfante/satellite-rs?rev=1f95726)" = "" "checksum schannel 0.1.19 (registry+/~https://github.com/rust-lang/crates.io-index)" = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" @@ -2001,7 +1856,6 @@ dependencies = [ "checksum tower-service 0.3.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" "checksum transpose 0.1.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "643e21580bb0627c7bb09e5cedbb42c8705b19d012de593ed6b0309270b3cd1e" "checksum try-lock 0.2.2 (registry+/~https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" -"checksum ttf-parser 0.6.2 (registry+/~https://github.com/rust-lang/crates.io-index)" = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc" "checksum unicase 2.6.0 (registry+/~https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" "checksum unicode-bidi 0.3.4 (registry+/~https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.12 (registry+/~https://github.com/rust-lang/crates.io-index)" = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" diff --git a/Cargo.toml b/Cargo.toml index 0e370d6..c7f908c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,10 +27,10 @@ directories = "2.0.2" filetime = "0.2.10" gcd = "2.0.1" hound = "3.4.0" +lab = "0.8.1" line_drawing = "0.8.0" log = "0.4.8" image = { version = "0.23.4", features = ["png"] } -imageproc = "0.21.0" reqwest = { version = "0.10.4", features = ["blocking"] } rustfft = "3.0.1" satellite = { git = "/~https://github.com/richinfante/satellite-rs", rev = "1f95726" } diff --git a/src/gui/work.rs b/src/gui/work.rs index d2b15c9..a21cbf0 100644 --- a/src/gui/work.rs +++ b/src/gui/work.rs @@ -459,7 +459,6 @@ pub fn process() { ); callback(noaa_apt::process( &mut context, - &settings, &signal, contrast_adjustment, rotate, diff --git a/src/imageext.rs b/src/imageext.rs new file mode 100644 index 0000000..f01006c --- /dev/null +++ b/src/imageext.rs @@ -0,0 +1,139 @@ +/// Some extra utilities for working with images, that use or complement +/// available functions from `image` crate + +use image::{RgbaImage, SubImage, Pixel, GenericImage, GenericImageView}; +use lab::Lab; +use std::convert::TryInto; + +/// A set of per-channel histograms from an image with 8 bits per channel. +pub struct ChannelHistogram { + /// Per-channel histograms. + pub channels: Vec<[u32; 256]>, +} + +/// A set of per-channel cumulative histograms from an image with 8 bits per channel. +pub struct CumulativeChannelHistogram { + /// Per-channel cumulative histograms. + pub channels: Vec<[u32; 256]>, +} + +/// Equalize the histogram of the grayscale (but still Rgba image with +/// R = G = B, A = 255), by equalizing the histogram of one of channels (R), +/// and using that for all the other (G, B). Alpha channel is not modified. +pub fn equalize_histogram_grayscale(sub_image: &mut SubImage<&mut RgbaImage>) { + // since it's a grayscale image (R = G = B, A = 255), use R channel histogram: + let hist = cumulative_histogram_rgba(sub_image).channels[0]; + let total = hist[255] as f32; + + for y in 0..sub_image.height() { + for x in 0..sub_image.width() { + let p = sub_image.get_pixel_mut(x, y); + + // Each histogram has length 256 and RgbaImage has 8 bits per pixel + let fraction = hist[p.channels()[0] as usize] as f32 / total; + + // apply f to channels r, g, b and apply g to alpha channel + p.apply_with_alpha( + // for R, G, B, use equalized values: + |_| (255. * fraction) as u8, + // for A, leave unmodified + |alpha| alpha + ); + } + } +} + +/// Equalize the histogram of the color subimage by converting Rgb -> Lab, +/// equalizing the L (lightness) histogram, and converting back Lab -> Rgb. +pub fn equalize_histogram_color(sub_image: &mut SubImage<&mut RgbaImage>) { + let mut lab_pixels: Vec = rgb_to_lab(sub_image); + + let lab_hist = cumulative_histogram_lab(&lab_pixels); + let total = lab_hist[100] as f32; + + lab_pixels.iter_mut().for_each(|p: &mut Lab| { + // casting p.l from f32 to usize rounds towards 0 + // l is in range [0..100] inclusive, lab_hist has lenght 101 + let fraction = lab_hist[p.l as usize] as f32 / total; + p.l = 100. * fraction; + }); + lab_to_rgb_mut(&lab_pixels, sub_image); +} + +/// Returns a vector of Lab pixel values, alpha channel value is not used. +fn rgb_to_lab(sub_image: &mut SubImage<&mut RgbaImage>) -> Vec { + sub_image.pixels().map(|(_x, _y, p)| { + let rgb: [u8; 3] = p.channels()[..3].try_into().unwrap(); + Lab::from_rgb(&rgb) + }).collect() +} + +/// Converts Lab to Rgb and modifies the R, B, G values of pixels +/// in the original subimage. The value of the alpha channel is unmodified. +fn lab_to_rgb_mut(lab_pixels: &Vec, sub_image: &mut SubImage<&mut RgbaImage>) { + let rgb_pixels: Vec<[u8; 3]> = lab_pixels.iter() + .map(|x: &Lab| x.to_rgb()).collect(); + + let height = sub_image.height(); + let width = sub_image.width(); + + for y in 0..height { + for x in 0..width { + let p = sub_image.get_pixel_mut(x, y); + let [r, g, b] = rgb_pixels[(y * width + x) as usize]; + let a = p.channels()[3]; // get original alpha channel + *p = Pixel::from_channels(r, g, b, a); + } + } +} + +/// Calculates the cumulative histograms for each channel of the subimage. +fn cumulative_histogram_rgba( + sub_image: &mut SubImage<&mut RgbaImage> +) -> CumulativeChannelHistogram { + let mut hist = histogram_rgba(sub_image); + for c in 0..hist.channels.len() { + for i in 1..hist.channels[c].len() { + hist.channels[c][i] += hist.channels[c][i - 1]; + } + } + CumulativeChannelHistogram { + channels: hist.channels, + } +} + +/// Calculates the histograms for each channel of the subimage. +fn histogram_rgba(sub_image: &mut SubImage<&mut RgbaImage>) -> ChannelHistogram { + let mut hist = vec![[0u32; 256]; 4]; + + sub_image.pixels().for_each(|(_x, _y, p)| { + for (i, c) in p.channels().iter().enumerate() { + hist[i][*c as usize] += 1; + } + }); + ChannelHistogram { channels: hist } +} + +/// Calculates the cumulative histogram using the L (lightness) channel. +/// L values are in range [0..100] inclusive, so the resulting array +/// has 101 elements: `[u32; 101]` +fn cumulative_histogram_lab(lab_pixels: &Vec) -> [u32; 101] { + let mut hist = histogram_lab(lab_pixels); + for i in 1..hist.len() { + hist[i] += hist[i - 1]; + } + hist +} + +/// Calculates the histogram using the L (lightness) channel. +/// L values are in range [0..100] inclusive, so the resulting array +/// has 101 elements: `[u32; 101]`. +/// If the histogram for the other channels is needed in the future, +/// consider defining a struct similar to `ChannelHistogram`. +fn histogram_lab(lab_pixels: &Vec) -> [u32; 101] { + let mut hist = [0u32; 101]; + for p in lab_pixels { + hist[p.l as usize] += 1; // use L (lightness) channel + } + hist +} diff --git a/src/main.rs b/src/main.rs index de7aeaf..3ac27fe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,7 @@ mod context; mod decode; mod dsp; mod err; +mod imageext; mod filters; mod frequency; mod geo; @@ -88,7 +89,7 @@ fn inner_main() -> err::Result<()> { if !sync { match contrast_adjustment { - noaa_apt::Contrast::Telemetry | noaa_apt::Contrast::Histogram => + noaa_apt::Contrast::Telemetry | noaa_apt::Contrast::Histogram => warn!("Adjusting contrast without syncing, expect horrible results!"), _ => () } @@ -114,7 +115,6 @@ fn inner_main() -> err::Result<()> { let img = noaa_apt::process( &mut context, - &settings, &raw_data, contrast_adjustment, rotate, diff --git a/src/noaa_apt.rs b/src/noaa_apt.rs index be344ed..e84a35e 100644 --- a/src/noaa_apt.rs +++ b/src/noaa_apt.rs @@ -17,7 +17,8 @@ use crate::map; use crate::misc; use crate::processing; use crate::telemetry; -use crate::{config, wav}; +use crate::wav; +use image::GrayImage; pub type Image = image::RgbaImage; @@ -116,14 +117,13 @@ pub fn load(input_filename: &Path) -> err::Result<(Signal, Rate)> { pub fn process( context: &mut Context, - settings: &config::Settings, signal: &Signal, contrast_adjustment: Contrast, rotate: Rotate, color: Option, orbit: Option, ) -> err::Result { - let (low, high) = match contrast_adjustment { + let (mut low, mut high) = match contrast_adjustment { Contrast::Telemetry => { context.status(0.1, "Adjusting contrast from telemetry".to_string()); @@ -150,28 +150,41 @@ pub fn process( } }; + // for colorization & histogram equalization, + // always do 98% contrast adjust first, then colorize, + // then equalize histogram of color image if needed + if color.is_some() { + if let Contrast::Histogram = contrast_adjustment { + let (l, h) = misc::percent(&signal, 0.98)?; + low = l; + high = h; + } + } + // -------------------- context.status(0.3, "Generating image".to_string()); let height = signal.len() as u32 / PX_PER_ROW; - use image::GrayImage; - - let mut img: GrayImage = GrayImage::from_vec(PX_PER_ROW, height, map(&signal, low, high)) - .ok_or_else(|| { - err::Error::Internal("Could not create image, wrong buffer length".to_string()) - })?; - - if let Contrast::Histogram = contrast_adjustment { - img = processing::histogram_equalization(&img)?; - } + // grayscale image obtained by mapping signal values to 0..255 + // based on the selected contrast adjustment + let img: GrayImage = GrayImage::from_vec( + PX_PER_ROW, height, map_signal_u8(&signal, low, high) + ).ok_or_else(|| { + err::Error::Internal("Could not create image, wrong buffer length".to_string()) + })?; let mut img: Image = image::DynamicImage::ImageLuma8(img).into_rgba(); // convert to RGBA - if let Some(color_settings) = color { + if let Some(color_settings) = &color { processing::false_color(&mut img, color_settings); } + + if let Contrast::Histogram = contrast_adjustment { + processing::histogram_equalization(&mut img, color.is_some()); + } + // -------------------- if let Some(orbit_settings) = orbit.clone() { @@ -220,7 +233,7 @@ pub fn process( /// /// `low` becomes 0 and `high` becomes 255. Values are clamped to prevent `u8` /// overflow. -fn map(signal: &Signal, low: f32, high: f32) -> Vec { +fn map_signal_u8(signal: &Signal, low: f32, high: f32) -> Vec { let range = high - low; let raw_data: Vec = signal .iter() @@ -252,6 +265,6 @@ mod tests { let low = 0. * 123.123 - 234.234; let high = 255. * 123.123 - 234.234; - assert_eq!(expected, map(&shifted_values, low, high)); + assert_eq!(expected, map_signal_u8(&shifted_values, low, high)); } } diff --git a/src/processing.rs b/src/processing.rs index 65164c1..d9bcc79 100644 --- a/src/processing.rs +++ b/src/processing.rs @@ -1,13 +1,14 @@ //! Image processing functions. -use image::{GenericImageView, GenericImage, GrayImage, ImageBuffer, Rgba}; +use image::{GenericImage, Rgba, RgbaImage}; use log::{warn, info}; use crate::decode::{PX_PER_CHANNEL, PX_SYNC_FRAME, PX_SPACE_DATA, PX_CHANNEL_IMAGE_DATA}; use crate::err; +use crate::imageext; use crate::geo; use crate::misc; -use crate::noaa_apt::{Image, ColorSettings, OrbitSettings, RefTime}; +use crate::noaa_apt::{ColorSettings, OrbitSettings, RefTime}; /// Rotates the channels in place, keeping the sync bands and telemetry intact. @@ -18,24 +19,24 @@ use crate::noaa_apt::{Image, ColorSettings, OrbitSettings, RefTime}; /// Care is taken to leave lines from the A channel at the same height as the B /// channel. Otherwise there can be a vertical offset of one pixel between each /// channel. -pub fn rotate(img: &mut Image) { +pub fn rotate(img: &mut RgbaImage) { info!("Rotating image"); // where the actual image data starts, past the sync frames and deep space band - let x_offset = PX_SYNC_FRAME + PX_SPACE_DATA; // ! + let x_offset = PX_SYNC_FRAME + PX_SPACE_DATA; let mut channel_a = img.sub_image( - x_offset, 0, PX_CHANNEL_IMAGE_DATA, img.height() // ! + x_offset, 0, PX_CHANNEL_IMAGE_DATA, img.height() ); image::imageops::rotate180_in_place(&mut channel_a); let mut channel_b = img.sub_image( - x_offset + PX_PER_CHANNEL, 0, PX_CHANNEL_IMAGE_DATA, img.height() // ! + x_offset + PX_PER_CHANNEL, 0, PX_CHANNEL_IMAGE_DATA, img.height() ); image::imageops::rotate180_in_place(&mut channel_b); } -/// Rotate image if the pass was south to north. +/// Returns true if this was a south to north pass, and the image needs to be rotated. pub fn south_to_north_pass(orbit_settings: &OrbitSettings) -> err::Result { let tle = match &orbit_settings.custom_tle { @@ -78,32 +79,31 @@ pub fn south_to_north_pass(orbit_settings: &OrbitSettings) -> err::Result return Ok(azimuth < PI / 4. || azimuth > 3. * PI / 4.); } -/// Histogram equalization, for each channel separately. -/// Works only on the grayscale image, -/// needs to be done before the RGBA conversion. -pub fn histogram_equalization(img: &GrayImage) -> err::Result { - info!("Performing histogram equalization"); - - let mut output = GrayImage::new(img.width(), img.height()); - let mut channel_a = img.view(0, 0, PX_PER_CHANNEL, img.height()).to_image(); - let mut channel_b = img - .view(PX_PER_CHANNEL, 0, PX_PER_CHANNEL, img.height()) - .to_image(); - - imageproc::contrast::equalize_histogram_mut(&mut channel_a); - imageproc::contrast::equalize_histogram_mut(&mut channel_b); - - output.copy_from(&channel_a, 0, 0)?; - output.copy_from(&channel_b, PX_PER_CHANNEL, 0)?; +/// Histogram equalization, in place, for each channel (A, B) separately. +/// If `has_color=false`, it will treat the image as grayscale (R = G = B, A = 255). +/// If `has_color=true`, it will convert image from Rgba to Lab, equalize the histogram +/// for L (lightness) channel, convert back to Rgb and adjust image values accordingly. +pub fn histogram_equalization(img: &mut RgbaImage, has_color: bool) { + info!("Performing histogram equalization, has color: {}", has_color); + let height = img.height(); + + let mut channel_a = img.sub_image(0, 0, PX_PER_CHANNEL, height); + if has_color { + imageext::equalize_histogram_color(&mut channel_a); + } else { + imageext::equalize_histogram_grayscale(&mut channel_a); + } - Ok(output) + let mut channel_b = img.sub_image(PX_PER_CHANNEL, 0, PX_PER_CHANNEL, height); + imageext::equalize_histogram_grayscale(&mut channel_b); } + /// Attempts to produce a colored image from grayscale channel and IR data. -/// Works best when contrast is set to "telemetry". +/// Works best when contrast is set to "telemetry" or "98 percent". /// Needs a way to allow tweaking hardcoded values for water, land, ice /// and dirt detection, from the UI or command line. -pub fn false_color(img: &mut ImageBuffer, Vec>, color_settings: ColorSettings) { +pub fn false_color(img: &mut RgbaImage, color_settings: &ColorSettings) { let water = color_settings.water_threshold; let vegetation = color_settings.vegetation_threshold; let clouds = color_settings.clouds_threshold;