diff --git a/Cargo.lock b/Cargo.lock index 0d7fe19..9d188b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,6 +33,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + [[package]] name = "ahash" version = "0.7.6" @@ -77,7 +83,7 @@ checksum = "7915e26e0786f91768d23de32afafa4ee5e2ea76be21c0ecd8e14441543c1655" dependencies = [ "enumflags2", "futures", - "rand 0.8.4", + "rand", "serde", "serde_repr", "zbus", @@ -215,10 +221,10 @@ dependencies = [ ] [[package]] -name = "bitflags" -version = "0.7.0" +name = "bit_field" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" [[package]] name = "bitflags" @@ -239,10 +245,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] -name = "byteorder" -version = "0.5.3" +name = "bytemuck" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" +checksum = "439989e6b8c38d1b6570a384ef1e49c8848128f5a97f3914baef02920842712f" [[package]] name = "byteorder" @@ -328,7 +334,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" dependencies = [ - "bitflags 1.3.2", + "bitflags", "block", "cocoa-foundation", "core-foundation 0.9.2", @@ -344,7 +350,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" dependencies = [ - "bitflags 1.3.2", + "bitflags", "block", "core-foundation 0.9.2", "core-graphics-types", @@ -355,9 +361,9 @@ dependencies = [ [[package]] name = "color_quant" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a475fc4af42d83d28adf72968d9bcfaf035a1a9381642d8e85d8a04957767b0d" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "concurrent-queue" @@ -420,7 +426,7 @@ version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" dependencies = [ - "bitflags 1.3.2", + "bitflags", "core-foundation 0.7.0", "foreign-types", "libc", @@ -432,7 +438,7 @@ version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" dependencies = [ - "bitflags 1.3.2", + "bitflags", "core-foundation 0.9.2", "core-graphics-types", "foreign-types", @@ -445,7 +451,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" dependencies = [ - "bitflags 1.3.2", + "bitflags", "core-foundation 0.9.2", "foreign-types", "libc", @@ -464,6 +470,59 @@ dependencies = [ "objc", ] +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" +dependencies = [ + "cfg-if 1.0.0", + "lazy_static", +] + [[package]] name = "cty" version = "0.2.2" @@ -506,12 +565,21 @@ dependencies = [ ] [[package]] -name = "deque" -version = "0.3.1" +name = "deflate" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf" +checksum = "5f95bf05dffba6e6cce8dfbb30def788154949ccd9aed761b472119c21e01c70" dependencies = [ - "rand 0.3.14", + "adler32", +] + +[[package]] +name = "deflate" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f" +dependencies = [ + "adler32", ] [[package]] @@ -615,6 +683,12 @@ dependencies = [ "web-sys", ] +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + [[package]] name = "emath" version = "0.16.0" @@ -622,14 +696,69 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55673de2eb96660dde25ba7b2d36a7054beead1a2bec74dcfd5eb05a1e1ba76d" [[package]] -name = "enum_primitive" -version = "0.1.0" +name = "encoding" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f79eff5be92a4d7d5bddf7daa7d650717ea71628634efe6ca7bcda85b2183c23" +checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" dependencies = [ - "num", + "encoding-index-japanese", + "encoding-index-korean", + "encoding-index-simpchinese", + "encoding-index-singlebyte", + "encoding-index-tradchinese", ] +[[package]] +name = "encoding-index-japanese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-korean" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-simpchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-singlebyte" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-tradchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding_index_tests" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" + [[package]] name = "enumflags2" version = "0.7.3" @@ -679,6 +808,22 @@ version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" +[[package]] +name = "exr" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4badb9489a465cb2c555af1f00f0bfd8cecd6fc12ac11da9d5b40c5dd5f0200" +dependencies = [ + "bit_field", + "deflate 1.0.0", + "flume", + "half", + "inflate", + "lebe", + "smallvec", + "threadpool", +] + [[package]] name = "fastrand" version = "1.7.0" @@ -690,12 +835,27 @@ dependencies = [ [[package]] name = "flate2" -version = "0.2.14" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eeb481e957304178d2e782f2da1257f1434dfecbae883bafb61ada2a9fea3bb" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" dependencies = [ + "cfg-if 1.0.0", + "crc32fast", "libc", - "miniz-sys", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.10.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d04dafd11240188e146b6f6476a898004cace3be31d4ec5e08e216bf4947ac0" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "pin-project", + "spin", ] [[package]] @@ -823,12 +983,6 @@ dependencies = [ "slab", ] -[[package]] -name = "gcc" -version = "0.3.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "553f11439bdefe755bf366b264820f1da70f3aaf3924e594b886beb9c831bcf5" - [[package]] name = "gdk-pixbuf-sys" version = "0.15.1" @@ -866,18 +1020,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" dependencies = [ "cfg-if 1.0.0", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] name = "gif" -version = "0.9.0" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c7c19a035de94bd7afbaa62c241aadfbdf1a70f560b348d2312eafa566ca16" +checksum = "c3a7187e78088aead22ceedeee99779455b23fc231fe13ec443f99bb71694e5b" dependencies = [ "color_quant", - "lzw", + "weezl", ] [[package]] @@ -936,12 +1092,6 @@ dependencies = [ "takeable-option", ] -[[package]] -name = "glob" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" - [[package]] name = "glutin" version = "0.28.0" @@ -1043,12 +1193,27 @@ dependencies = [ "system-deps", ] +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + [[package]] name = "heck" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "hex" version = "0.4.3" @@ -1069,27 +1234,32 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "image" -version = "0.10.3" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "559d5ebbe9ec73111799e49c07717944b244f8accf5de33a8a8128bc3ecd2e00" +checksum = "e94ac3d41f882c624a82d7945952032388488681f45f9d4077999a6c85688d61" dependencies = [ - "byteorder 0.5.3", - "enum_primitive", + "bytemuck", + "byteorder", + "color_quant", + "exr", "gif", - "glob", - "jpeg-decoder", + "jpeg-decoder 0.2.1", "num-iter", "num-rational", - "num-traits", + "num-traits 0.2.14", "png", "scoped_threadpool", + "tiff", ] [[package]] name = "inflate" -version = "0.1.1" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7e0062d2dc2f17d2f13750d95316ae8a2ff909af0fda957084f5defd87c43bb" +checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff" +dependencies = [ + "adler32", +] [[package]] name = "instant" @@ -1111,11 +1281,16 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jpeg-decoder" -version = "0.1.8" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be50b418a1fc5d198588d9a4f682ef808a55db4084dce39d09bb0562525bb8c" +checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2" + +[[package]] +name = "jpeg-decoder" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbcf0244f6597be39ab8d9203f574cafb529ae8c698afa2182f7b3c3205a4a9c" dependencies = [ - "byteorder 0.5.3", "rayon", ] @@ -1146,6 +1321,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lebe" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7efd1d698db0759e6ef11a7cd44407407399a910c774dd804c64c032da7826ff" + [[package]] name = "libc" version = "0.2.117" @@ -1180,12 +1361,6 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "lzw" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" - [[package]] name = "malloc_buf" version = "0.0.6" @@ -1225,16 +1400,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz-sys" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1f4d337a01c32e1f2122510fed46393d53ca35a7f429cb0450abaedfa3ed54" -dependencies = [ - "gcc", - "libc", -] - [[package]] name = "miniz_oxide" version = "0.4.4" @@ -1267,13 +1432,22 @@ dependencies = [ "winapi", ] +[[package]] +name = "nanorand" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "729eb334247daa1803e0a094d0a5c55711b85571179f5ec6e53eccfdf7008958" +dependencies = [ + "getrandom", +] + [[package]] name = "ndk" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d868f654c72e75f8687572699cdabe755f03effbb62542768e995d5b8d699d" dependencies = [ - "bitflags 1.3.2", + "bitflags", "jni-sys", "ndk-sys", "num_enum", @@ -1319,7 +1493,7 @@ version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cc", "cfg-if 1.0.0", "libc", @@ -1332,7 +1506,7 @@ version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cc", "cfg-if 1.0.0", "libc", @@ -1365,36 +1539,14 @@ dependencies = [ "winapi", ] -[[package]] -name = "num" -version = "0.1.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde7c03b09e7c6a301ee81f6ddf66d7a28ec305699e3d3b056d2fc56470e3120" -dependencies = [ - "num-integer", - "num-iter", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.1.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b14378471f7c2adc5262f05b4701ef53e8da376453a8d8fee48e51db745e49" -dependencies = [ - "num-integer", - "num-traits", - "rand 0.3.14", - "rustc-serialize", -] - [[package]] name = "num-integer" -version = "0.1.32" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb24d9bfb3f222010df27995441ded1e954f8f69cd35021f6bef02ca9552fb92" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ - "num-traits", + "autocfg", + "num-traits 0.2.14", ] [[package]] @@ -1404,19 +1556,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "287a1c9969a847055e1122ec0ea7a5c5d6f72aad97934e131c83d5c08ab4e45c" dependencies = [ "num-integer", - "num-traits", + "num-traits 0.1.36", ] [[package]] name = "num-rational" -version = "0.1.35" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54ff603b8334a72fbb27fe66948aac0abaaa40231b3cecd189e76162f6f38aaf" +checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" dependencies = [ - "num-bigint", + "autocfg", "num-integer", - "num-traits", - "rustc-serialize", + "num-traits 0.2.14", ] [[package]] @@ -1426,11 +1577,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a16a42856a256b39c6d3484f097f6713e14feacd9bfb02290917904fae46c81c" [[package]] -name = "num_cpus" -version = "1.1.0" +name = "num-traits" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8890e6084723d57d0df8d2720b0d60c6ee67d6c93e7169630e4371e88765dcad" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", "libc", ] @@ -1576,6 +1737,26 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "pin-project" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.8" @@ -1596,14 +1777,15 @@ checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" [[package]] name = "png" -version = "0.5.2" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06208e2ee243e3118a55dda9318f821f206d8563fb8d4df258767f8e62bb0997" +checksum = "c845088517daa61e8a57eee40309347cea13f273694d1385c553e7a57127763b" dependencies = [ - "bitflags 0.7.0", - "flate2", - "inflate", - "num-iter", + "bitflags", + "crc32fast", + "deflate 0.9.1", + "encoding", + "miniz_oxide", ] [[package]] @@ -1668,15 +1850,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5" -dependencies = [ - "libc", -] - [[package]] name = "rand" version = "0.8.4" @@ -1728,14 +1901,27 @@ dependencies = [ [[package]] name = "rayon" -version = "0.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b6a6e05e0e6b703e9f2ad266eb63f3712e693a17a2702b95a23de14ce8defa9" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" dependencies = [ - "deque", - "libc", + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", "num_cpus", - "rand 0.3.14", ] [[package]] @@ -1744,7 +1930,7 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" dependencies = [ - "bitflags 1.3.2", + "bitflags", ] [[package]] @@ -1796,12 +1982,6 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" -[[package]] -name = "rustc-serialize" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff9fc1c79f2dec76b253273d07682e94a978bd8f132ded071188122b2af9818" - [[package]] name = "scoped-tls" version = "1.0.0" @@ -1894,7 +2074,7 @@ version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1325f292209cee78d5035530932422a30aa4c8fda1a16593ac083c1de211e68a" dependencies = [ - "bitflags 1.3.2", + "bitflags", "calloop", "dlib", "lazy_static", @@ -1927,6 +2107,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "spin" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "511254be0c5bcf062b019a6c89c01a664aa359ded62f78aa72c6fc137c0590e5" +dependencies = [ + "lock_api", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -1989,6 +2178,26 @@ dependencies = [ "syn", ] +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "tiff" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0247608e998cb6ce39dfc8f4a16c50361ce71e5b52e6d24ea1227ea8ea8ee0b2" +dependencies = [ + "flate2", + "jpeg-decoder 0.1.22", + "weezl", +] + [[package]] name = "toml" version = "0.5.8" @@ -2106,7 +2315,7 @@ version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91223460e73257f697d9e23d401279123d36039a3f7a449e983f123292d4458f" dependencies = [ - "bitflags 1.3.2", + "bitflags", "downcast-rs", "libc", "nix 0.22.3", @@ -2155,7 +2364,7 @@ version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60147ae23303402e41fe034f74fb2c35ad0780ee88a1c40ac09a3be1e7465741" dependencies = [ - "bitflags 1.3.2", + "bitflags", "wayland-client", "wayland-commons", "wayland-scanner", @@ -2204,6 +2413,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "weezl" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b77fdfd5a253be4ab714e4ffa3c49caf146b4de743e97510c0656cf90f1e8e" + [[package]] name = "wepoll-ffi" version = "0.1.2" @@ -2290,7 +2505,7 @@ version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b43cc931d58b99461188607efd7acb2a093e65fc621f54cad78517a6063e73a" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cocoa", "core-foundation 0.9.2", "core-graphics 0.22.3", @@ -2377,7 +2592,7 @@ dependencies = [ "async-recursion", "async-task", "async-trait", - "byteorder 1.4.3", + "byteorder", "derivative", "enumflags2", "event-listener", @@ -2389,7 +2604,7 @@ dependencies = [ "nix 0.23.1", "once_cell", "ordered-stream", - "rand 0.8.4", + "rand", "serde", "serde_repr", "sha1", @@ -2430,7 +2645,7 @@ version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49ea5dc38b2058fae6a5b79009388143dadce1e91c26a67f984a0fc0381c8033" dependencies = [ - "byteorder 1.4.3", + "byteorder", "enumflags2", "libc", "serde", diff --git a/Cargo.toml b/Cargo.toml index dc7860f..8a7123f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,6 @@ authors = ["Sebastian "] [dependencies] hound = "*" -image = "*" +image = "0.24.0" eframe = "0.16.0" rfd = "0.7.0" diff --git a/src/decoder.rs b/src/decoder.rs new file mode 100644 index 0000000..c60a71d --- /dev/null +++ b/src/decoder.rs @@ -0,0 +1,190 @@ +use std::fs::File; +use std::io::prelude::*; +use std::path::Path; +use std::sync::{Arc, Mutex}; +use std::time; + +use amdemod::SquaringAMDemodulator; +use aptsyncer::{APTSyncer, SyncedSample}; +use firfilter::FIRFilter; +use resamplers::{Downsampler, Upsampler}; +use utils::float_sample_iterator; + +const LINES_PER_SECOND: u32 = 2; +const PIXELS_PER_LINE: u32 = 2080; + +const LOWPASS_COEFFS: [f32; 63] = [ + -7.383784e-03, + -3.183046e-03, + 2.255039e-03, + 7.461166e-03, + 1.091908e-02, + 1.149109e-02, + 8.769802e-03, + 3.252932e-03, + -3.720606e-03, + -1.027446e-02, + -1.447403e-02, + -1.486427e-02, + -1.092423e-02, + -3.307958e-03, + 6.212477e-03, + 1.511364e-02, + 2.072873e-02, + 2.096037e-02, + 1.492345e-02, + 3.347624e-03, + -1.138407e-02, + -2.560252e-02, + -3.507114e-02, + -3.591225e-02, + -2.553830e-02, + -3.371569e-03, + 2.882645e-02, + 6.711368e-02, + 1.060042e-01, + 1.394643e-01, + 1.620650e-01, + 1.700462e-01, + 1.620650e-01, + 1.394643e-01, + 1.060042e-01, + 6.711368e-02, + 2.882645e-02, + -3.371569e-03, + -2.553830e-02, + -3.591225e-02, + -3.507114e-02, + -2.560252e-02, + -1.138407e-02, + 3.347624e-03, + 1.492345e-02, + 2.096037e-02, + 2.072873e-02, + 1.511364e-02, + 6.212477e-03, + -3.307958e-03, + -1.092423e-02, + -1.486427e-02, + -1.447403e-02, + -1.027446e-02, + -3.720606e-03, + 3.252932e-03, + 8.769802e-03, + 1.149109e-02, + 1.091908e-02, + 7.461166e-03, + 2.255039e-03, + -3.183046e-03, + -7.383784e-03, +]; + +pub fn decode(input_file: &str, output_file: &str, progress_update: T) -> Result<(), String> +where + T: Fn(f32, image::GrayImage) -> bool, +{ + let mut reader = hound::WavReader::open(input_file) + .map_err(|err| format!("Could not open inputfile: {}", err))?; + + if reader.spec().channels != 1 { + panic!("Expected a mono file"); + } + + let sample_rate = reader.spec().sample_rate; + println!("Samplerate: {}", sample_rate); + if sample_rate != 48000 { + return Err("Expected a 48kHz sample rate".to_owned()); + } + + let sample_count = reader.len(); + let seconds = (sample_count as f32) / (sample_rate as f32); + let lines = (seconds.ceil() as u32) * LINES_PER_SECOND; + println!("File contains {} seconds or {} lines", seconds, lines); + + let mut img = image::ImageBuffer::new(PIXELS_PER_LINE, lines); + + let coeffs = &LOWPASS_COEFFS; + + let samples = float_sample_iterator(&mut reader); + + let demod = SquaringAMDemodulator::from(samples); + let filter = FIRFilter::from(demod, coeffs); + let upsampler = Upsampler::from(filter, 13); + let downsampler = Downsampler::from(upsampler, 150); + let syncer = APTSyncer::from(downsampler); + + let mut x = 0; + let mut y = 0; + let mut max_level = 0.0; + let mut has_sync = false; + + let mut progress = 0; + let step = sample_count * 13 / 150 / 10; + + let mut previous_sample = 0.0; + + print!("0%"); + std::io::stdout().flush().unwrap(); + for synced_sample in syncer { + progress += 1; + + if progress % step == 0 { + print!("...{}%", progress / step * 10); + std::io::stdout().flush().unwrap(); + } + + let sample = match synced_sample { + SyncedSample::Sample(s) => s, + SyncedSample::SyncA(s) => { + if !has_sync { + max_level = 0.0; + has_sync = true; + } + x = 0; + s + } + SyncedSample::SyncB(s) => { + if x < (PIXELS_PER_LINE / 2) { + let skip_distance = (PIXELS_PER_LINE / 2) - x; + let color = (previous_sample / max_level * 255.0) as u8; + for i in 0..skip_distance { + img.put_pixel(x + i, y, image::Luma([color])); + } + } + if !has_sync { + max_level = 0.0; + has_sync = true; + } + x = PIXELS_PER_LINE / 2; + s + } + }; + + max_level = f32::max(sample, max_level); + let color = (sample / max_level * 255.0) as u8; + + if y < lines { + img.put_pixel(x, y, image::Luma([color])); + } + + x += 1; + if x >= PIXELS_PER_LINE { + x = 0; + y += 1; + } + + previous_sample = sample; + + if !progress_update((progress as f32) / (step * 10) as f32, img.clone()) { + return Ok(()); + } + } + println!(""); + + img.save_with_format(&Path::new(output_file), image::ImageFormat::Png) + .map_err(|err| format!("Could not save outputfile: {}", err))?; + + println!("Done !"); + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index 50ba40b..075c5a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,367 +5,25 @@ extern crate rfd; mod amdemod; mod aptsyncer; +mod decoder; mod firfilter; mod resamplers; +mod ui; mod utils; -use std::fs::File; -use std::io::prelude::*; -use std::path::Path; -use std::sync::{Arc, Mutex}; -use std::time; - -use amdemod::SquaringAMDemodulator; -use aptsyncer::{APTSyncer, SyncedSample}; -use firfilter::FIRFilter; -use resamplers::{Downsampler, Upsampler}; -use utils::float_sample_iterator; - -const LINES_PER_SECOND: u32 = 2; -const PIXELS_PER_LINE: u32 = 2080; - -const LOWPASS_COEFFS: [f32; 63] = [ - -7.383784e-03, - -3.183046e-03, - 2.255039e-03, - 7.461166e-03, - 1.091908e-02, - 1.149109e-02, - 8.769802e-03, - 3.252932e-03, - -3.720606e-03, - -1.027446e-02, - -1.447403e-02, - -1.486427e-02, - -1.092423e-02, - -3.307958e-03, - 6.212477e-03, - 1.511364e-02, - 2.072873e-02, - 2.096037e-02, - 1.492345e-02, - 3.347624e-03, - -1.138407e-02, - -2.560252e-02, - -3.507114e-02, - -3.591225e-02, - -2.553830e-02, - -3.371569e-03, - 2.882645e-02, - 6.711368e-02, - 1.060042e-01, - 1.394643e-01, - 1.620650e-01, - 1.700462e-01, - 1.620650e-01, - 1.394643e-01, - 1.060042e-01, - 6.711368e-02, - 2.882645e-02, - -3.371569e-03, - -2.553830e-02, - -3.591225e-02, - -3.507114e-02, - -2.560252e-02, - -1.138407e-02, - 3.347624e-03, - 1.492345e-02, - 2.096037e-02, - 2.072873e-02, - 1.511364e-02, - 6.212477e-03, - -3.307958e-03, - -1.092423e-02, - -1.486427e-02, - -1.447403e-02, - -1.027446e-02, - -3.720606e-03, - 3.252932e-03, - 8.769802e-03, - 1.149109e-02, - 1.091908e-02, - 7.461166e-03, - 2.255039e-03, - -3.183046e-03, - -7.383784e-03, -]; - -use eframe::egui::text_edit::TextEdit; -use eframe::egui::widgets::{Button, ProgressBar}; -use eframe::egui::{Color32, RichText}; -use eframe::{egui, epi}; - -#[derive(PartialEq)] -enum DecoderRunState { - RUNNING, - CANCELED, - DONE, -} - -struct DecoderJobState { - progress: f32, - run_state: DecoderRunState, -} - -impl DecoderJobState { - fn is_running(&self) -> bool { - self.run_state == DecoderRunState::RUNNING - } -} - -impl Default for DecoderJobState { - fn default() -> Self { - Self { - progress: 0.0, - run_state: DecoderRunState::DONE, - } - } -} - -pub struct DecoderApp { - input_path: String, - output_path: String, - decoding_state: Arc>, -} - -impl Default for DecoderApp { - fn default() -> Self { - Self { - // Example stuff: - input_path: "input.wav".to_owned(), - output_path: "output.png".to_owned(), - decoding_state: Arc::new(Mutex::new(DecoderJobState::default())), - } - } -} - -impl epi::App for DecoderApp { - fn name(&self) -> &str { - "eframe template" - } - - /// Called once before the first frame. - fn setup( - &mut self, - _ctx: &egui::CtxRef, - _frame: &epi::Frame, - _storage: Option<&dyn epi::Storage>, - ) { - } - - /// Called each time the UI needs repainting, which may be many times per second. - /// Put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`. - fn update(&mut self, ctx: &egui::CtxRef, frame: &epi::Frame) { - let Self { - input_path, - output_path, - decoding_state, - } = self; - - { - let mut state = decoding_state.lock().unwrap(); - - if !ctx.input().raw.dropped_files.is_empty() && !state.is_running() { - if let Some(path) = ctx.input().raw.dropped_files[0].clone().path { - *input_path = path.display().to_string(); - } - } - - egui::CentralPanel::default().show(ctx, |ui| { - ui.heading("APT-Decoder"); - - egui::Grid::new("form_grid").num_columns(3).show(ui, |ui| { - ui.label("Input Wav File:"); - ui.add_sized([300.0, 20.0], TextEdit::singleline(input_path)); - - if ui - .add_enabled(!state.is_running(), Button::new("Open")) - .clicked() - { - if let Some(path) = rfd::FileDialog::new().pick_file() { - *input_path = path.display().to_string(); - } - }; - ui.end_row(); - - ui.label("Output PNG File:"); - ui.add_sized([300.0, 20.0], TextEdit::singleline(output_path)); - if ui - .add_enabled(!state.is_running(), Button::new("Save")) - .clicked() - { - if let Some(path) = rfd::FileDialog::new().save_file() { - *output_path = path.display().to_string(); - } - }; - ui.end_row(); - }); - - ui.horizontal(|ui| { - if ui - .add_enabled(!state.is_running(), Button::new("Decode")) - .clicked() - { - let frame = frame.clone(); - let decoding_state = decoding_state.clone(); - state.run_state = DecoderRunState::RUNNING; - let thread = std::thread::spawn(move || { - for i in 0..101 { - { - let mut state = decoding_state.lock().unwrap(); - if state.run_state == DecoderRunState::CANCELED { - frame.request_repaint(); - return; - } - state.progress = (i as f32) / 100.0; - } - frame.request_repaint(); - - std::thread::sleep(time::Duration::from_millis(200)); - } - - { - let mut state = decoding_state.lock().unwrap(); - state.progress = 100.0; - state.run_state = DecoderRunState::DONE; - } - }); - } - if ui - .add_enabled( - state.is_running(), - Button::new(RichText::new("Cancel").color(Color32::RED)), - ) - .clicked() - { - state.run_state = DecoderRunState::CANCELED; - } - }); - - let progressbar = ProgressBar::new(state.progress).show_percentage(); - ui.add(progressbar); - - ui.separator(); - }); - } - } -} +use ui::DecoderApp; fn main() { let app = DecoderApp::default(); let native_options = eframe::NativeOptions::default(); eframe::run_native(Box::new(app), native_options); + //let args: Vec = std::env::args().collect(); + /* - let args : Vec = std::env::args().collect(); - - if args.len() != 3 { - println!("Usage: {} ", args[0]); - return; - } - - let mut reader = match hound::WavReader::open(&args[1]) { - Err(e) => panic!("Could not open inputfile: {}", e), - Ok(r) => r - }; - - if reader.spec().channels != 1 { - panic!("Expected a mono file"); - } - - let sample_rate = reader.spec().sample_rate; - println!("Samplerate: {}", sample_rate); - if sample_rate != 48000 { - panic!("Expected a 48kHz sample rate"); - } - - let sample_count = reader.len(); - let seconds = (sample_count as f32) / (sample_rate as f32); - let lines = (seconds.ceil() as u32) * LINES_PER_SECOND; - println!("File contains {} seconds or {} lines", seconds, lines); - - let mut img = image::ImageBuffer::new(PIXELS_PER_LINE, lines); - - let coeffs = &LOWPASS_COEFFS; - - let samples = float_sample_iterator(&mut reader); - - let demod = SquaringAMDemodulator::from(samples); - let filter = FIRFilter::from(demod, coeffs); - let upsampler = Upsampler::from(filter, 13); - let downsampler = Downsampler::from(upsampler, 150); - let syncer = APTSyncer::from(downsampler); - - let mut x = 0; - let mut y = 0; - let mut max_level = 0.0; - let mut has_sync = false; - - let mut progress = 0; - let step = sample_count * 13 / 150 / 10; - - let mut previous_sample = 0.0; - - print!("0%"); - std::io::stdout().flush().unwrap(); - for synced_sample in syncer { - progress += 1; - - if progress % step == 0 { - print!("...{}%", progress / step * 10); - std::io::stdout().flush().unwrap(); - } - - let sample = match synced_sample { - SyncedSample::Sample(s) => s, - SyncedSample::SyncA(s) =>{ - if !has_sync { - max_level = 0.0; - has_sync = true; - } - x = 0; - s - } - SyncedSample::SyncB(s) =>{ - if x < (PIXELS_PER_LINE / 2) { - let skip_distance = (PIXELS_PER_LINE / 2) - x; - let color = (previous_sample / max_level * 255.0) as u8; - for i in 0..skip_distance { - img.put_pixel(x + i,y,image::Luma([color])); - } - } - if !has_sync { - max_level = 0.0; - has_sync = true; - } - x = PIXELS_PER_LINE / 2; - s - } - }; - - max_level = f32::max(sample, max_level); - let color = (sample / max_level * 255.0) as u8; - - if y < lines { - img.put_pixel(x,y,image::Luma([color])); - } - - x += 1; - if x >= PIXELS_PER_LINE { - x = 0; - y += 1; - } - - previous_sample = sample; - } - println!(""); - - let ref mut fout = match File::create(&Path::new(&args[2])) { - Err(e) => panic!("Could not open outputfile: {}", e), - Ok(f) => f - }; - - image::ImageLuma8(img).save(fout, image::PNG).unwrap(); + if args.len() != 3 { + println!("Usage: {} ", args[0]); + return; + } */ - println!("Done !"); } diff --git a/src/ui.rs b/src/ui.rs new file mode 100644 index 0000000..2c6a092 --- /dev/null +++ b/src/ui.rs @@ -0,0 +1,179 @@ +use std::sync::{Arc, Mutex}; +use std::time; + +use eframe::egui::text_edit::TextEdit; +use eframe::egui::widgets::{Button, ProgressBar}; +use eframe::egui::{Color32, RichText}; +use eframe::{egui, epi}; + +use decoder; + +#[derive(PartialEq)] +enum DecoderRunState { + RUNNING, + CANCELED, + DONE, +} + +struct DecoderJobState { + progress: f32, + image: image::GrayImage, + run_state: DecoderRunState, +} + +impl DecoderJobState { + fn is_running(&self) -> bool { + self.run_state == DecoderRunState::RUNNING + } +} + +impl Default for DecoderJobState { + fn default() -> Self { + Self { + progress: 0.0, + image: image::GrayImage::new(1, 1), + run_state: DecoderRunState::DONE, + } + } +} + +pub struct DecoderApp { + input_path: String, + output_path: String, + decoding_state: Arc>, +} + +impl Default for DecoderApp { + fn default() -> Self { + Self { + // Example stuff: + input_path: "input.wav".to_owned(), + output_path: "output.png".to_owned(), + decoding_state: Arc::new(Mutex::new(DecoderJobState::default())), + } + } +} + +impl epi::App for DecoderApp { + fn name(&self) -> &str { + "eframe template" + } + + /// Called once before the first frame. + fn setup( + &mut self, + _ctx: &egui::CtxRef, + _frame: &epi::Frame, + _storage: Option<&dyn epi::Storage>, + ) { + } + + /// Called each time the UI needs repainting, which may be many times per second. + /// Put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`. + fn update(&mut self, ctx: &egui::CtxRef, frame: &epi::Frame) { + let Self { + input_path, + output_path, + decoding_state, + } = self; + + { + let mut state = decoding_state.lock().unwrap(); + + if !ctx.input().raw.dropped_files.is_empty() && !state.is_running() { + if let Some(path) = ctx.input().raw.dropped_files[0].clone().path { + *input_path = path.display().to_string(); + } + } + + egui::CentralPanel::default().show(ctx, |ui| { + ui.heading("APT-Decoder"); + + egui::Grid::new("form_grid").num_columns(3).show(ui, |ui| { + ui.label("Input Wav File:"); + ui.add_sized( + [300.0, 20.0], + TextEdit::singleline(input_path).interactive(!state.is_running()), + ); + + if ui + .add_enabled(!state.is_running(), Button::new("Open")) + .clicked() + { + if let Some(path) = rfd::FileDialog::new().pick_file() { + *input_path = path.display().to_string(); + } + }; + ui.end_row(); + + ui.label("Output PNG File:"); + ui.add_sized( + [300.0, 20.0], + TextEdit::singleline(output_path).interactive(!state.is_running()), + ); + if ui + .add_enabled(!state.is_running(), Button::new("Save")) + .clicked() + { + if let Some(path) = rfd::FileDialog::new().save_file() { + *output_path = path.display().to_string(); + } + }; + ui.end_row(); + }); + + ui.horizontal(|ui| { + if ui + .add_enabled(!state.is_running(), Button::new("Decode")) + .clicked() + { + let frame = frame.clone(); + let decoding_state = decoding_state.clone(); + let input_path = input_path.clone(); + let output_path = output_path.clone(); + state.run_state = DecoderRunState::RUNNING; + std::thread::spawn(move || { + decoder::decode(&input_path, &output_path, |progress, image| { + let mut state = decoding_state.lock().unwrap(); + state.progress = progress; + state.image = image; + + frame.request_repaint(); + return state.is_running(); + }) + .unwrap(); + + let mut state = decoding_state.lock().unwrap(); + state.run_state = DecoderRunState::DONE; + }); + } + if ui + .add_enabled( + state.is_running(), + Button::new(RichText::new("Cancel").color(Color32::RED)), + ) + .clicked() + { + state.run_state = DecoderRunState::CANCELED; + } + }); + + let progressbar = ProgressBar::new(state.progress).show_percentage(); + ui.add(progressbar); + + ui.separator(); + + let size = [state.image.width() as _, state.image.height() as _]; + let image_buffer = + image::DynamicImage::ImageLuma8(state.image.clone()).into_rgba8(); + let pixels = image_buffer.as_flat_samples(); + let epi_img = epi::Image::from_rgba_unmultiplied(size, pixels.as_slice()); + + let texture = frame.alloc_texture(epi_img); + let size = egui::Vec2::new(size[0] as f32, size[1] as f32); + + ui.image(texture, size); + }); + } + } +}