diff --git a/Cargo.lock b/Cargo.lock index 3a64a40..b5d84cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,6 +38,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "aligned-vec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" + [[package]] name = "allocator-api2" version = "0.2.16" @@ -107,6 +113,35 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.50", +] + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "asn1-codecs" version = "0.6.1" @@ -128,7 +163,7 @@ dependencies = [ "bitvec", "clap", "env_logger", - "heck", + "heck 0.4.1", "lazy_static", "log", "proc-macro2", @@ -168,6 +203,29 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" +dependencies = [ + "arrayvec", +] + [[package]] name = "axum" version = "0.7.4" @@ -238,12 +296,24 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitstream-io" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c12d1856e42f0d817a835fe55853957c85c8c8a470114029143d3f12671446e" + [[package]] name = "bitvec" version = "1.0.1" @@ -257,18 +327,36 @@ dependencies = [ "wyz", ] +[[package]] +name = "built" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6a6c0b39c38fd754ac338b00a88066436389c0f029da5d37d1e01091d9b7c17" + [[package]] name = "bumpalo" version = "3.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" +[[package]] +name = "bytemuck" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" + [[package]] name = "byteorder" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "byteorder_slice" version = "3.0.0" @@ -289,6 +377,19 @@ name = "cc" version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f9fa1897e4325be0d68d48df6aa1a71ac2ed4d27723887e7754192705350730" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] [[package]] name = "cfg-if" @@ -339,7 +440,7 @@ version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "syn 2.0.50", @@ -351,6 +452,12 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "colorchoice" version = "1.0.0" @@ -378,6 +485,46 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "darling" version = "0.14.4" @@ -448,6 +595,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "either" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" + [[package]] name = "env_logger" version = "0.10.2" @@ -467,6 +620,50 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "exr" +version = "1.72.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + +[[package]] +name = "fdeflate" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -583,6 +780,27 @@ dependencies = [ "slab", ] +[[package]] +name = "getrandom" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "gimli" version = "0.28.1" @@ -608,6 +826,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -624,6 +852,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.6" @@ -747,6 +981,45 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "image" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "image-webp", + "num-traits", + "png", + "qoi", + "ravif", + "rayon", + "rgb", + "tiff", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d730b085583c4d789dfd07fdcf185be59501666a90c97c40162b37e4fdad272d" +dependencies = [ + "byteorder-lite", + "thiserror", +] + +[[package]] +name = "imgref" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" + [[package]] name = "include_dir" version = "0.7.3" @@ -776,6 +1049,17 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.50", +] + [[package]] name = "is-terminal" version = "0.4.12" @@ -787,12 +1071,27 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" + [[package]] name = "js-sys" version = "0.3.68" @@ -808,12 +1107,29 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + [[package]] name = "libc" version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libfuzzer-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + [[package]] name = "libusb1-sys" version = "0.6.4" @@ -842,12 +1158,31 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + [[package]] name = "matchit" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + [[package]] name = "memchr" version = "2.7.1" @@ -870,6 +1205,12 @@ dependencies = [ "unicase", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.2" @@ -877,6 +1218,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", + "simd-adler32", ] [[package]] @@ -890,6 +1232,69 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + +[[package]] +name = "num-bigint" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.50", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.18" @@ -947,6 +1352,12 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "pcap-file" version = "2.0.0" @@ -1017,6 +1428,25 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "png" +version = "0.17.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +dependencies = [ + "bitflags", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro-crate" version = "1.3.1" @@ -1036,6 +1466,40 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "profiling" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" +dependencies = [ + "quote", + "syn 2.0.50", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quote" version = "1.0.35" @@ -1064,6 +1528,27 @@ dependencies = [ "winapi", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + [[package]] name = "rand_core" version = "0.3.1" @@ -1079,6 +1564,65 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rav1e" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +dependencies = [ + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "once_cell", + "paste", + "profiling", + "rand 0.8.5", + "rand_chacha", + "simd_helpers", + "system-deps", + "thiserror", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc13288f5ab39e6d7c9d501759712e6969fcc9734220846fc9ed26cae2cc4234" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + [[package]] name = "rayhunter" version = "0.1.0" @@ -1110,6 +1654,7 @@ dependencies = [ "futures", "futures-core", "futures-macro", + "image", "include_dir", "log", "mime_guess", @@ -1124,6 +1669,26 @@ dependencies = [ "toml", ] +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "rdrand" version = "0.4.0" @@ -1180,6 +1745,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "rgb" +version = "0.8.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" +dependencies = [ + "bytemuck", +] + [[package]] name = "rootshell" version = "0.1.0" @@ -1296,6 +1870,21 @@ dependencies = [ "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + [[package]] name = "slab" version = "0.4.9" @@ -1321,6 +1910,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + [[package]] name = "strsim" version = "0.10.0" @@ -1361,12 +1959,31 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck 0.5.0", + "pkg-config", + "toml", + "version-compare", +] + [[package]] name = "tap" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "target-lexicon" +version = "0.12.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" + [[package]] name = "telcom-parser" version = "0.1.0" @@ -1386,7 +2003,7 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" dependencies = [ - "rand", + "rand 0.4.6", "remove_dir_all", ] @@ -1419,6 +2036,17 @@ dependencies = [ "syn 2.0.50", ] +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "tokio" version = "1.36.0" @@ -1606,12 +2234,29 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "v_frame" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + [[package]] name = "version_check" version = "0.9.4" @@ -1678,6 +2323,12 @@ version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + [[package]] name = "winapi" version = "0.3.9" @@ -1896,3 +2547,27 @@ dependencies = [ "quote", "syn 2.0.50", ] + +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zune-jpeg" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448" +dependencies = [ + "zune-core", +] diff --git a/README.md b/README.md index 500ac8a..347e4d1 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ _ _ _ _ _ _ _ _ \ | apc '._| \__; ``` -![Tests](https://github.com/EFForg/rayhunter/actions/workflows/rust.yml/badge.svg) +![Tests](https://github.com/EFForg/rayhunter/actions/workflows/check-and-test.yml/badge.svg) Rayhunter is an IMSI Catcher Catcher for the Orbic mobile hotspot. diff --git a/bin/Cargo.toml b/bin/Cargo.toml index c59b46f..424e243 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -31,3 +31,4 @@ tokio-stream = "0.1.14" futures = "0.3.30" clap = { version = "4.5.2", features = ["derive"] } serde_json = "1.0.114" +image = "0.25.1" diff --git a/bin/src/config.rs b/bin/src/config.rs index ef910ac..c554b02 100644 --- a/bin/src/config.rs +++ b/bin/src/config.rs @@ -7,6 +7,7 @@ struct ConfigFile { qmdl_store_path: Option, port: Option, readonly_mode: Option, + ui_level: Option, } #[derive(Debug)] @@ -14,6 +15,7 @@ pub struct Config { pub qmdl_store_path: String, pub port: u16, pub readonly_mode: bool, + pub ui_level: u8, } impl Default for Config { @@ -22,6 +24,7 @@ impl Default for Config { qmdl_store_path: "/data/rayhunter/qmdl".to_string(), port: 8080, readonly_mode: false, + ui_level: 1, } } } @@ -34,6 +37,7 @@ pub fn parse_config

(path: P) -> Result where P: AsRef if let Some(path) = parsed_config.qmdl_store_path { config.qmdl_store_path = path } if let Some(port) = parsed_config.port { config.port = port } if let Some(readonly_mode) = parsed_config.readonly_mode { config.readonly_mode = readonly_mode } + if let Some(ui_level) = parsed_config.ui_level { config.ui_level = ui_level } } Ok(config) } diff --git a/bin/src/daemon.rs b/bin/src/daemon.rs index e1771da..bec950b 100644 --- a/bin/src/daemon.rs +++ b/bin/src/daemon.rs @@ -5,6 +5,7 @@ mod server; mod stats; mod qmdl_store; mod diag; +mod framebuffer; use crate::config::{parse_config, parse_args}; use crate::diag::run_diag_read_thread; @@ -13,6 +14,7 @@ use crate::server::{ServerState, get_qmdl, serve_static}; use crate::pcap::get_pcap; use crate::stats::get_system_stats; use crate::error::RayhunterError; +use crate::framebuffer::Framebuffer; use axum::response::Redirect; use diag::{get_analysis_report, start_recording, stop_recording, DiagDeviceCtrlMessage}; @@ -22,12 +24,16 @@ use axum::routing::{get, post}; use axum::Router; use stats::get_qmdl_manifest; use tokio::sync::mpsc::{self, Sender}; +use tokio::sync::oneshot::error::TryRecvError; use tokio::task::JoinHandle; use tokio_util::task::TaskTracker; use std::net::SocketAddr; +use std::thread::sleep; +use std::time::Duration; use tokio::net::TcpListener; use tokio::sync::{RwLock, oneshot}; use std::sync::Arc; +use include_dir::{include_dir, Dir}; // Runs the axum server, taking all the elements needed to build up our // ServerState and a oneshot Receiver that'll fire when it's time to shutdown @@ -88,6 +94,7 @@ fn run_ctrl_c_thread( task_tracker: &TaskTracker, diag_device_sender: Sender, server_shutdown_tx: oneshot::Sender<()>, + ui_shutdown_tx: oneshot::Sender<()>, qmdl_store_lock: Arc> ) -> JoinHandle> { task_tracker.spawn(async move { @@ -102,6 +109,9 @@ fn run_ctrl_c_thread( server_shutdown_tx.send(()) .expect("couldn't send server shutdown signal"); + info!("sending UI shutdown"); + ui_shutdown_tx.send(()) + .expect("couldn't send ui shutdown signal"); diag_device_sender.send(DiagDeviceCtrlMessage::Exit).await .expect("couldn't send Exit message to diag thread"); }, @@ -113,6 +123,56 @@ fn run_ctrl_c_thread( }) } +async fn update_ui(task_tracker: &TaskTracker, config: &config::Config, mut ui_shutdown_rx: oneshot::Receiver<()>){ + static IMAGE_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/static/images/"); + let display_level = config.ui_level; + if display_level == 0 { + info!("Invisible mode, not spawning UI."); + } + + task_tracker.spawn_blocking(move || { + let mut fb: Framebuffer = Framebuffer::new(); + // this feels wrong, is there a more rusty way to do this? + let mut img: Option<&[u8]> = None; + if display_level == 2 { + img = Some(IMAGE_DIR.get_file("orca.gif").expect("failed to read orca.gif").contents()); + } else if display_level == 3 { + img = Some(IMAGE_DIR.get_file("eff.png").expect("failed to read eff.png").contents()); + } + loop { + match ui_shutdown_rx.try_recv() { + Ok(_) => { + info!("received UI shutdown"); + break; + }, + Err(TryRecvError::Empty) => {}, + Err(e) => panic!("error receiving shutdown message: {e}") + + } + match display_level { + 2 => { + fb.draw_gif(img.unwrap()); + }, + 3 => { + fb.draw_img(img.unwrap()) + }, + 128 => { + fb.draw_line(framebuffer::Color565::Cyan, 128); + fb.draw_line(framebuffer::Color565::Pink, 102); + fb.draw_line(framebuffer::Color565::White, 76); + fb.draw_line(framebuffer::Color565::Pink, 50); + fb.draw_line(framebuffer::Color565::Cyan, 25); + }, + 1 | _ => { + fb.draw_line(framebuffer::Color565::Green, 2); + }, + }; + sleep(Duration::from_millis(100)); + } + }).await.unwrap(); + +} + #[tokio::main] async fn main() -> Result<(), RayhunterError> { env_logger::init(); @@ -134,10 +194,11 @@ async fn main() -> Result<(), RayhunterError> { run_diag_read_thread(&task_tracker, dev, rx, qmdl_store_lock.clone()); } - + let (ui_shutdown_tx, ui_shutdown_rx) = oneshot::channel(); let (server_shutdown_tx, server_shutdown_rx) = oneshot::channel::<()>(); - run_ctrl_c_thread(&task_tracker, tx.clone(), server_shutdown_tx, qmdl_store_lock.clone()); + run_ctrl_c_thread(&task_tracker, tx.clone(), server_shutdown_tx, ui_shutdown_tx, qmdl_store_lock.clone()); run_server(&task_tracker, &config, qmdl_store_lock.clone(), server_shutdown_rx, tx).await; + update_ui(&task_tracker, &config, ui_shutdown_rx).await; task_tracker.close(); task_tracker.wait().await; diff --git a/bin/src/framebuffer.rs b/bin/src/framebuffer.rs new file mode 100644 index 0000000..13fd614 --- /dev/null +++ b/bin/src/framebuffer.rs @@ -0,0 +1,92 @@ +use image::{codecs::gif::GifDecoder, imageops::FilterType, AnimationDecoder, DynamicImage}; +use std::{io::Cursor, time::Duration}; + +const FB_PATH:&str = "/dev/fb0"; + +#[derive(Copy, Clone)] +// TODO actually poll for this, maybe w/ fbset? +struct Dimensions { + height: u32, + width: u32, +} + +#[allow(dead_code)] +pub enum Color565 { + Red = 0b1111100000000000, + Green = 0b0000011111100000, + Blue = 0b0000000000011111, + White = 0b1111111111111111, + Black = 0b0000000000000000, + Cyan = 0b0000011111111111, + Yellow = 0b1111111111100000, + Pink = 0b1111010010011111, +} + +#[derive(Copy, Clone)] +pub struct Framebuffer<'a> { + dimensions: Dimensions, + path: &'a str, +} + +impl Framebuffer<'_>{ + pub const fn new() -> Self { + Framebuffer{ + dimensions: Dimensions{height: 128, width: 128}, + path: FB_PATH, + } + } + + fn write(&mut self, img: DynamicImage) { + let mut width = img.width(); + let mut height = img.height(); + let resized_img: DynamicImage; + if height > self.dimensions.height || + width > self.dimensions.width { + resized_img = img.resize( self.dimensions.width, self.dimensions.height, FilterType::CatmullRom); + width = self.dimensions.width.min(resized_img.width()); + height = self.dimensions.height.min(resized_img.height()); + } else { + resized_img = img; + } + let img_rgba8 = resized_img.as_rgba8().unwrap(); + let mut buf = Vec::new(); + for y in 0..height { + for x in 0..width { + let px = img_rgba8.get_pixel(x, y); + let mut rgb565: u16 = (px[0] as u16 & 0b11111000) << 8; + rgb565 |= (px[1] as u16 & 0b11111100) << 3; + rgb565 |= (px[2] as u16) >> 3; + buf.extend(rgb565.to_le_bytes()); + } + } + std::fs::write(self.path, &buf).unwrap(); + } + + pub fn draw_gif(&mut self, img_buffer: &[u8]) { + // this is dumb and i'm sure there's a better way to loop this + let cursor = Cursor::new(img_buffer); + let decoder = GifDecoder::new(cursor).unwrap(); + for maybe_frame in decoder.into_frames() { + let frame = maybe_frame.unwrap(); + let (numerator, _) = frame.delay().numer_denom_ms(); + let img = DynamicImage::from(frame.into_buffer()); + self.write(img); + std::thread::sleep(Duration::from_millis(numerator as u64)); + } + } + + pub fn draw_img(&mut self, img_buffer: &[u8]) { + let img = image::load_from_memory(img_buffer).unwrap(); + self.write(img); + } + + pub fn draw_line(&mut self, color: Color565, height: u32){ + let px_num= height * self.dimensions.width; + let color: u16 = color as u16; + let mut buffer: Vec = Vec::new(); + for _ in 0..px_num { + buffer.extend(color.to_le_bytes()); + } + std::fs::write(self.path, &buffer).unwrap(); + } +} \ No newline at end of file diff --git a/bin/static/images/eff.png b/bin/static/images/eff.png new file mode 100644 index 0000000..0b1e44d Binary files /dev/null and b/bin/static/images/eff.png differ diff --git a/bin/static/images/orca.gif b/bin/static/images/orca.gif new file mode 100644 index 0000000..d700048 Binary files /dev/null and b/bin/static/images/orca.gif differ diff --git a/dist/config.toml.example b/dist/config.toml.example index cd911e4..1492ccd 100644 --- a/dist/config.toml.example +++ b/dist/config.toml.example @@ -2,3 +2,9 @@ qmdl_store_path = "/data/rayhunter/qmdl" port = 8080 readonly_mode = false +# UI Levels: +# 0 = invisible mode, no indicator that rayhunter is running +# 1 = Subtle mode, display a green line at the top of the screen when rayhunter is running +# 2 = Demo Mode, display a fun orca gif +# 3 = display the EFF logo +ui_level = 1