diff --git a/Cargo.lock b/Cargo.lock index 4e7c18ad..0f0069ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -78,6 +78,21 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "allocator-api2" version = "0.2.21" @@ -219,7 +234,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -291,9 +306,9 @@ dependencies = [ [[package]] name = "async-broadcast" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" dependencies = [ "event-listener", "event-listener-strategy", @@ -405,7 +420,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -440,7 +455,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -467,7 +482,7 @@ dependencies = [ "derive_utils", "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -570,7 +585,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.91", + "syn 2.0.92", "which", ] @@ -697,6 +712,16 @@ dependencies = [ "cfg_aliases", ] +[[package]] +name = "brotli-decompressor" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "built" version = "0.7.5" @@ -738,7 +763,7 @@ checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -859,9 +884,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.5" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" +checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" dependencies = [ "jobserver", "libc", @@ -1028,7 +1053,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -1131,7 +1156,7 @@ checksum = "5387f5bbc9e9e6c96436ea125afa12614cebf8ac67f49abc08c1e7a891466c90" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -1665,7 +1690,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -1685,7 +1710,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", "unicode-xid", ] @@ -1697,7 +1722,7 @@ checksum = "65f152f4b8559c4da5d574bafc7af85454d706b4c5fe8b530d508cacbb6807ea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -1746,7 +1771,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -1932,7 +1957,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -1943,7 +1968,7 @@ checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -2079,9 +2104,9 @@ dependencies = [ [[package]] name = "femtovg" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eafc3dd3c956423a6669e1f6f9ab23261dbe45cdb24ce23dba38b0389b8a8ff8" +checksum = "36d63bc3ab69493186eefc2568dddc21d2fe5f3c552edc64def6c42297ec9bbd" dependencies = [ "bitflags 2.6.0", "bytemuck", @@ -2284,7 +2309,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -2412,7 +2437,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -2669,7 +2694,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -2884,7 +2909,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -3197,7 +3222,7 @@ checksum = "f83e6bd30e51baa7adb1c1e04111ac71713ce032ce16c36e62a334f8c45b734e" dependencies = [ "quote", "serde_json", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -3320,7 +3345,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.91", + "syn 2.0.92", "unic-langid", ] @@ -3334,7 +3359,7 @@ dependencies = [ "i18n-config", "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -3475,7 +3500,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -3709,7 +3734,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -3882,18 +3907,18 @@ dependencies = [ [[package]] name = "jxl-bitstream" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "116184a8c915e99b08c7a4abca038b05863980bbf9e433dc2883363853c99afe" +checksum = "f4587c2166a289ef21075fbf58e19d898f23833bd4d78691db36cdf0eee7f6cf" dependencies = [ "tracing", ] [[package]] name = "jxl-coding" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7ffdab0c48e989f23a8bd6113d88bd243ae45c7871e90cfdcb6997eacbfb2" +checksum = "2e8cf24db1cec3d7e703df9f5ef3f3b49650607432792ca988b66dd17bb640b2" dependencies = [ "jxl-bitstream", "tracing", @@ -3901,9 +3926,9 @@ dependencies = [ [[package]] name = "jxl-color" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4806c94be9e37c82e571684ad673af0a2e4049a74942c407034da6a087c4de7b" +checksum = "60c359391e571ef990c06e7af6131d305281402ca8d6d278660990544d89d263" dependencies = [ "jxl-bitstream", "jxl-coding", @@ -3915,9 +3940,9 @@ dependencies = [ [[package]] name = "jxl-frame" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1649956cb002031108e1fa44e0e483a770e2e95f4544137788c32265db0b8c71" +checksum = "3d47cd3bc265b570134ef8c1a52b08cf5db7992a65d020b332f6670e35f225a6" dependencies = [ "jxl-bitstream", "jxl-coding", @@ -3932,18 +3957,18 @@ dependencies = [ [[package]] name = "jxl-grid" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80f25f406f215f07f0b994801bc2d6adbfcd5710fcdd8f12d662e80700469e6c" +checksum = "5739f02add3d5c00320140bec6f5a80fac4baa630f88fe4c6a55a0d719718ce3" dependencies = [ "tracing", ] [[package]] name = "jxl-image" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1de3283303bb66b1742538f1a6947313596242598d6ddf325f301c2fbf01abd3" +checksum = "5199f6bce2f64494b91c510dfdeb8035bb405f6347837b6293e9eeb9d93f246b" dependencies = [ "jxl-bitstream", "jxl-color", @@ -3952,11 +3977,29 @@ dependencies = [ "tracing", ] +[[package]] +name = "jxl-jbr" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a806dbd24f1dfb0cd620c08395010243c7098a0b5900ca2a8c9b896519ffded6" +dependencies = [ + "brotli-decompressor", + "jxl-bitstream", + "jxl-frame", + "jxl-grid", + "jxl-image", + "jxl-modular", + "jxl-oxide-common", + "jxl-threadpool", + "jxl-vardct", + "tracing", +] + [[package]] name = "jxl-modular" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3f2fd5a3346deda8169f6b26aa6c955c32bd275377b527415ef2e5f362e00ad" +checksum = "9d4852fe37dee35f67b2e3912c3eecb7d053379aac0801b5cc489d58ea253af1" dependencies = [ "jxl-bitstream", "jxl-coding", @@ -3968,10 +4011,11 @@ dependencies = [ [[package]] name = "jxl-oxide" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a42a404a09f4704e60ad102eb995ac074cad467df48631c1a1269b97eef3c5" +checksum = "d14dc17856a54b3f13a1459eef32626415941c81909a195d0227888c703215b9" dependencies = [ + "brotli-decompressor", "bytemuck", "image 0.25.5", "jxl-bitstream", @@ -3979,6 +4023,7 @@ dependencies = [ "jxl-frame", "jxl-grid", "jxl-image", + "jxl-jbr", "jxl-oxide-common", "jxl-render", "jxl-threadpool", @@ -3987,19 +4032,20 @@ dependencies = [ [[package]] name = "jxl-oxide-common" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4efb65a6ef812eae1083e5d2d1a4358bd74cf7e08d112f6e939a40003a6a9920" +checksum = "8ccfd9c5f3807b9dbd0797788a577171bd78f5169a36f4bc3c7bbceaf3991507" dependencies = [ "jxl-bitstream", ] [[package]] name = "jxl-render" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9b7162076893570cdeaced01086893df132ff8b2eaf22d63ed3b066d9b88739" +checksum = "337635607131c2554bf4b93f2a5dff882e475b99dca81479a1555f1a598159b5" dependencies = [ + "bytemuck", "jxl-bitstream", "jxl-coding", "jxl-color", @@ -4026,9 +4072,9 @@ dependencies = [ [[package]] name = "jxl-vardct" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "737b4a65897907c644329c8a54e042cefdec2989e482698eea150d463e475fe5" +checksum = "f7a928cc48a6296257686b5ec81005b08cef0187922e12fafa9ab8066af2daab" dependencies = [ "jxl-bitstream", "jxl-coding", @@ -4329,7 +4375,7 @@ checksum = "28bd4b9d8a5af74808932492521cdd272019b056f75fcc70056bd2c09fceb550" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -4699,7 +4745,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -4761,7 +4807,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -5243,7 +5289,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -5392,7 +5438,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -5432,7 +5478,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -5460,7 +5506,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" dependencies = [ "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -5489,9 +5535,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -5839,7 +5885,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.91", + "syn 2.0.92", "walkdir", ] @@ -5913,9 +5959,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" [[package]] name = "rusty-chromaprint" @@ -6041,22 +6087,22 @@ checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" [[package]] name = "serde" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -6090,7 +6136,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -6495,7 +6541,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -6722,9 +6768,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.91" +version = "2.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53cbcb5a243bd33b7858b1d7f4aca2153490815872d86d955d6ea29f743c035" +checksum = "70ae51629bf965c5c098cc9e87908a3df5301051a9e087d6f9bef5c9771ed126" dependencies = [ "proc-macro2", "quote", @@ -6739,7 +6785,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -6854,7 +6900,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -6865,7 +6911,7 @@ checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -7059,7 +7105,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -7237,9 +7283,9 @@ dependencies = [ [[package]] name = "unicase" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-bidi" @@ -7488,7 +7534,7 @@ checksum = "d8502f961cf2f1359fed21a70f67c831ccb3ab9e4c0b4dd3ad40387fbe8875db" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -7557,7 +7603,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", "wasm-bindgen-shared", ] @@ -7592,7 +7638,7 @@ checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -7862,7 +7908,7 @@ checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -7873,7 +7919,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -7884,7 +7930,7 @@ checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -7895,7 +7941,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -8344,9 +8390,9 @@ checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" [[package]] name = "xxhash-rust" -version = "0.8.13" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08fd76779ae1883bbf1e46c2c46a75a0c4e37c445e68a24b01479d438f26ae6" +checksum = "d7d48f1b18be023c95e7b75f481cac649d74be7c507ff4a407c55cfb957f7934" [[package]] name = "yaml-rust" @@ -8377,7 +8423,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", "synstructure", ] @@ -8464,7 +8510,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", "zvariant_utils 2.1.0", ] @@ -8477,7 +8523,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", "zbus_names 4.1.0", "zvariant 5.1.0", "zvariant_utils 3.0.2", @@ -8524,7 +8570,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -8544,7 +8590,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", "synstructure", ] @@ -8565,7 +8611,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -8587,7 +8633,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -8693,7 +8739,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", "zvariant_utils 2.1.0", ] @@ -8706,7 +8752,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", "zvariant_utils 3.0.2", ] @@ -8718,7 +8764,7 @@ checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" dependencies = [ "proc-macro2", "quote", - "syn 2.0.91", + "syn 2.0.92", ] [[package]] @@ -8731,6 +8777,6 @@ dependencies = [ "quote", "serde", "static_assertions", - "syn 2.0.91", + "syn 2.0.92", "winnow", ] diff --git a/Cargo.toml b/Cargo.toml index b1a74c97..2d5dd43e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ members = [ "krokiet" ] exclude = [ + "misc/test_read_perf", "ci_tester", ] resolver = "2" diff --git a/Changelog.md b/Changelog.md index f194d9e4..cdb76d80 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,27 @@ +## Version 9.0.0 - ? + +### Breaking changes +- Video cache is now incompatible with previous versions, and needs to be regenerated + +### Known regressions +- Crashes when using similar videos(when hashing invalid files) +- Crashes when reading exif data - reported here - https://github.com/mindeng/nom-exif/issues/created_by/qarmin + +### CI + +### Core +- Updated vid_dup_finder, now it is able to find similar videos shorter than 30 seconds - [#]() +- More supported jxl image formats(using built-in jxl -> image-rs converter) - [#]() +- Rotating all images by default, basin on exif orientation - [#]() +- Using resuable + +### Krokiet + +### GTK GUI + +### CLI + + ## Version 8.0.0 - 11.10.2024r ### Breaking changes diff --git a/Diff b/Diff new file mode 100644 index 00000000..57b40e76 --- /dev/null +++ b/Diff @@ -0,0 +1,13 @@ +Performance comparison of using Array and Vector with specific buffer sizes for reading files from disk and calculating their hashes. +This is quite realistic scenario which also uses rayon which sometimes sometimes mess with predictability of results. +My computer have quite good CPU, but cheap Sata SSD, so results shows disk + +(Time to read files and calculate hashes in parallel, smaller is better) +| Name | 250000 files ~50 KB(SSD) | 170 files 5MB-150MB(SSD) | 1 file 0.9 GB(SSD) | 6200 files 50KB - 50MB(HDD) | 1 file 671 MB(HDD) | +| --- | --- | --- | --- | --- | --- | --- | +| Array 16KB | Base | Base | Base | Base | +| Vector 16KB | 0% | 0% | 0% | 0% | 0% | +| Vector 1MB | -7% | -4% | -16% | -45% | 0% | +| Thread local Vector 1MB | -12% | -4% | -16% | -45% | 0% | + +I tried to \ No newline at end of file diff --git a/czkawka_core/Cargo.toml b/czkawka_core/Cargo.toml index ed6a60aa..7c683bc6 100644 --- a/czkawka_core/Cargo.toml +++ b/czkawka_core/Cargo.toml @@ -65,7 +65,7 @@ once_cell = "1.20" rawloader = "0.37" imagepipe = "0.5" libraw-rs = { version = "0.0.4", optional = true } -jxl-oxide = { version = "0.10.0", features = ["image"] } +jxl-oxide = { version = "0.11.0", features = ["image"] } # Checking for invalid extensions mime_guess = "2.0" diff --git a/czkawka_core/benches/hash_calculation_benchmark.rs b/czkawka_core/benches/hash_calculation_benchmark.rs index 4acefcac..c979c4b0 100644 --- a/czkawka_core/benches/hash_calculation_benchmark.rs +++ b/czkawka_core/benches/hash_calculation_benchmark.rs @@ -1,4 +1,3 @@ -use const_format::concatcp; use criterion::{black_box, criterion_group, criterion_main, Criterion}; use czkawka_core::duplicate::{hash_calculation, DuplicateEntry, HashType}; use std::env::temp_dir; diff --git a/czkawka_core/src/common_cache.rs b/czkawka_core/src/common_cache.rs index 9faa8c93..f071f4be 100644 --- a/czkawka_core/src/common_cache.rs +++ b/czkawka_core/src/common_cache.rs @@ -16,6 +16,7 @@ use crate::similar_images::{convert_algorithm_to_string, convert_filters_to_stri const CACHE_VERSION: &str = "70"; const CACHE_IMAGE_VERSION: &str = "90"; +const CACHE_VIDEO_VERSION: &str = "90"; pub fn get_broken_files_cache_file() -> String { format!("cache_broken_files_{CACHE_VERSION}.bin") @@ -30,7 +31,7 @@ pub fn get_similar_images_cache_file(hash_size: &u8, hash_alg: &HashAlg, image_f } pub fn get_similar_videos_cache_file() -> String { - format!("cache_similar_videos_{CACHE_VERSION}.bin") + format!("cache_similar_videos_{CACHE_VIDEO_VERSION}.bin") } pub fn get_similar_music_cache_file(checking_tags: bool) -> String { if checking_tags { diff --git a/czkawka_core/src/duplicate.rs b/czkawka_core/src/duplicate.rs index 696d55c1..6e06d3fd 100644 --- a/czkawka_core/src/duplicate.rs +++ b/czkawka_core/src/duplicate.rs @@ -1,3 +1,10 @@ +use crossbeam_channel::{Receiver, Sender}; +use fun_time::fun_time; +use humansize::{format_size, BINARY}; +use log::debug; +use rayon::prelude::*; +use serde::{Deserialize, Serialize}; +use std::cell::RefCell; use std::collections::{BTreeMap, HashMap, HashSet}; use std::fmt::Debug; use std::fs::File; @@ -9,13 +16,6 @@ use std::os::unix::fs::MetadataExt; use std::path::{Path, PathBuf}; use std::sync::atomic::Ordering; use std::{fs, mem}; - -use crossbeam_channel::{Receiver, Sender}; -use fun_time::fun_time; -use humansize::{format_size, BINARY}; -use log::debug; -use rayon::prelude::*; -use serde::{Deserialize, Serialize}; use xxhash_rust::xxh3::Xxh3; use crate::common::{check_if_stop_received, delete_files_custom, prepare_thread_handler_common, send_info_and_wait_for_ending_all_threads, WorkContinueStatus}; @@ -27,6 +27,10 @@ use crate::progress_data::{CurrentStage, ProgressData}; const TEMP_HARDLINK_FILE: &str = "rzeczek.rxrxrxl"; +thread_local! { + static THREAD_BUFFER: RefCell> = RefCell::new(vec![0u8; 1024 * 2024]); +} + #[derive(PartialEq, Eq, Clone, Debug, Copy, Default)] pub enum HashType { #[default] @@ -574,22 +578,24 @@ impl DuplicateFinder { .map(|(size, vec_file_entry)| { let mut hashmap_with_hash: BTreeMap> = Default::default(); let mut errors: Vec = Vec::new(); - let mut buffer = [0u8; 1024 * 32]; atomic_counter.fetch_add(vec_file_entry.len(), Ordering::Relaxed); if check_if_stop_received(stop_receiver) { check_was_stopped.store(true, Ordering::Relaxed); return None; } - for mut file_entry in vec_file_entry { - match hash_calculation(&mut buffer, &file_entry, check_type, 0) { - Ok(hash_string) => { - file_entry.hash = hash_string.clone(); - hashmap_with_hash.entry(hash_string).or_default().push(file_entry); + THREAD_BUFFER.with_borrow_mut(|buffer| { + for mut file_entry in vec_file_entry { + match hash_calculation(buffer, &file_entry, check_type, 1024 * 32) { + Ok(hash_string) => { + file_entry.hash = hash_string.clone(); + hashmap_with_hash.entry(hash_string).or_default().push(file_entry); + } + Err(s) => errors.push(s), } - Err(s) => errors.push(s), } - } + }); + Some((size, hashmap_with_hash, errors)) }) .while_some() @@ -781,23 +787,30 @@ impl DuplicateFinder { .map(|(size, vec_file_entry)| { let mut hashmap_with_hash: BTreeMap> = Default::default(); let mut errors: Vec = Vec::new(); - let mut buffer = [0u8; 1024 * 16]; - + let mut exam_stopped = false; atomic_counter.fetch_add(vec_file_entry.len(), Ordering::Relaxed); - for mut file_entry in vec_file_entry { - if check_if_stop_received(stop_receiver) { - check_was_stopped.store(true, Ordering::Relaxed); - return None; - } - match hash_calculation(&mut buffer, &file_entry, check_type, u64::MAX) { - Ok(hash_string) => { - file_entry.hash = hash_string.clone(); - hashmap_with_hash.entry(hash_string.clone()).or_default().push(file_entry); + THREAD_BUFFER.with_borrow_mut(|buffer| { + for mut file_entry in vec_file_entry { + if check_if_stop_received(stop_receiver) { + check_was_stopped.store(true, Ordering::Relaxed); + exam_stopped = true; + break; + } + + match hash_calculation(buffer, &file_entry, check_type, u64::MAX) { + Ok(hash_string) => { + file_entry.hash = hash_string.clone(); + hashmap_with_hash.entry(hash_string.clone()).or_default().push(file_entry); + } + Err(s) => errors.push(s), } - Err(s) => errors.push(s), } + }); + if exam_stopped { + return None; } + Some((size, hashmap_with_hash, errors)) }) .while_some() diff --git a/krokiet/ui/popup_select_results.slint b/krokiet/ui/popup_select_results.slint index ef7a171c..5d92cb1d 100644 --- a/krokiet/ui/popup_select_results.slint +++ b/krokiet/ui/popup_select_results.slint @@ -15,7 +15,7 @@ import { Preview } from "preview.slint"; export component PopupSelectResults inherits Rectangle { callback show_popup(); - property <[SelectModel]> model: GuiState.select_results_list; + property <[SelectModel]> model: GuiState.select_results_list; property item_height: 30px; out property item_width: 200px; out property all_items_height: item_height * model.length; @@ -35,7 +35,6 @@ export component PopupSelectResults inherits Rectangle { text: i.name; height: item_height; width: item_width; - clicked => { Callabler.select_items(i.data); popup_window.close(); @@ -48,4 +47,4 @@ export component PopupSelectResults inherits Rectangle { show_popup() => { popup_window.show(); } -} \ No newline at end of file +} diff --git a/misc/test_read_perf/Cargo.toml b/misc/test_read_perf/Cargo.toml new file mode 100644 index 00000000..8f83e1a7 --- /dev/null +++ b/misc/test_read_perf/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "test_read_perf" +version = "0.1.0" +edition = "2021" + +[dependencies] +czkawka_core = { path = "../../czkawka_core" } +walkdir = "2.5.0" +humansize = "2.1.3" +rayon = "1.10.0" +strum = { version = "0.26.3", features = ["strum_macros", "derive"] } \ No newline at end of file diff --git a/misc/test_read_perf/src/main.rs b/misc/test_read_perf/src/main.rs new file mode 100644 index 00000000..1fea4d3f --- /dev/null +++ b/misc/test_read_perf/src/main.rs @@ -0,0 +1,173 @@ +use czkawka_core::duplicate::{hash_calculation, DuplicateEntry, HashType}; +use humansize::{format_size, BINARY}; +use rayon::prelude::*; +use std::cell::RefCell; +use std::collections::HashMap; +use std::env; +use std::process::Command; +use std::time::UNIX_EPOCH; +use strum::Display; +use walkdir::WalkDir; + +const DIR_TO_CHECK: &str = "/media"; +const ITERATIONS: usize = 1; + +thread_local! { + static BUFFER: RefCell> = RefCell::new(vec![0u8; 1024 * 1024]); +} + +static GLOBAL_HDD_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); + +#[allow(unused)] +#[derive(Copy, Clone, Display, Hash, Eq, PartialEq)] +enum MODES { + ARR16, + ARR256, + VEC16, + VEC1024, + VEC1024LOCKING, + VEC1024THREAD, +} + +fn main() { + if !is_running_as_sudo() { + println!("Please run this program as root"); + return; + } + let files = collect_files_to_test(); + + clean_disk_cache(); + + let mut hashmap: HashMap> = HashMap::new(); + + let modes = [MODES::VEC1024, MODES::VEC1024LOCKING]; + for i in 0..ITERATIONS { + for mode in modes.iter() { + println!("Iteration {}/{} in mode {}", i, ITERATIONS, mode); + clean_disk_cache(); + + let start = std::time::Instant::now(); + match mode { + MODES::ARR16 => array16(&files), + MODES::ARR256 => array256(&files), + MODES::VEC16 => vec16(&files), + MODES::VEC1024 => vec1024(&files), + MODES::VEC1024THREAD => vec1024_thread(&files), + MODES::VEC1024LOCKING => vec1024_locking(&files), + } + + println!("Iteration {}/{} finished in mode {mode} with time: {} ms", i, ITERATIONS, start.elapsed().as_millis()); + + hashmap.entry(*mode).or_insert_with(Vec::new).push(start.elapsed().as_micros()); + } + } + + for (mode, times) in hashmap { + let results_to_remove = times.len() / 4; + + let total_time = times.iter().sum::(); + let all_iterations_time = total_time as f64 / 1000.0; + + let times = if ITERATIONS > 4 { + times + .iter() + .enumerate() + .filter(|(idx, _value)| idx < &results_to_remove || idx >= &(times.len() - results_to_remove)) + .map(|e| *e.1) + .collect::>() + } else { + times + }; + + let total_time_without_extremes = total_time - times.iter().min().unwrap_or_default() - times.iter().max().unwrap_or_default(); + let all_iterations_time_without_extremes = total_time_without_extremes as f64 / 1000.0; + println!( + "Mode {}, {} iterations, total time: {} ms, per iteration time {} ms, total time without extremes: {} ms, per iteration time without extremes {} ms", + mode, + ITERATIONS, + all_iterations_time, + all_iterations_time / ITERATIONS as f64, + all_iterations_time_without_extremes, + all_iterations_time_without_extremes / ITERATIONS as f64 + ); + } +} + +fn array16(files: &Vec) { + files.into_par_iter().for_each(|f| { + let mut buffer = [0u8; 16 * 1024]; + let _ = hash_calculation(&mut buffer, &f, HashType::Blake3, u64::MAX); + }); +} +fn array256(files: &Vec) { + files.into_par_iter().for_each(|f| { + let mut buffer = [0u8; 256 * 1024]; + let _ = hash_calculation(&mut buffer, &f, HashType::Blake3, u64::MAX); + }); +} +fn vec16(files: &Vec) { + files.into_par_iter().for_each(|f| { + let mut buffer = vec![0u8; 16 * 1024]; + let _ = hash_calculation(&mut buffer, &f, HashType::Blake3, u64::MAX); + }); +} +fn vec1024(files: &Vec) { + files.into_par_iter().for_each(|f| { + let mut buffer = vec![0u8; 1024 * 1024]; + let _ = hash_calculation(&mut buffer, &f, HashType::Blake3, u64::MAX); + }); +} +fn vec1024_locking(files: &Vec) { + files.into_par_iter().for_each(|f| { + let _lock = GLOBAL_HDD_LOCK.lock().unwrap(); + let mut buffer = vec![0u8; 1024 * 1024]; + let _ = hash_calculation(&mut buffer, &f, HashType::Blake3, u64::MAX); + }); +} +fn vec1024_thread(files: &Vec) { + files.into_par_iter().for_each(|f| { + BUFFER.with(|buffer| { + let _ = hash_calculation(&mut buffer.borrow_mut(), &f, HashType::Blake3, u64::MAX); + }); + }); +} + +fn collect_files_to_test() -> Vec { + let files = WalkDir::new(DIR_TO_CHECK) + .into_iter() + .flatten() + .filter(|e| e.file_type().is_file()) + .map(|e| DuplicateEntry { + path: e.path().to_path_buf(), + modified_date: e + .metadata() + .map(|e| e.modified().map(|e| e.duration_since(UNIX_EPOCH)).expect("TEST").expect("TEST").as_secs()) + .unwrap_or_default(), + size: e.metadata().map(|e| e.len()).unwrap_or_default(), + hash: "".to_string(), + }) + .collect::>(); + let size: u64 = files.iter().map(|f| f.size).sum(); + let size_str = format_size(size, BINARY); + println!("Collected {} files to test, total size: {}", files.len(), size_str); + files +} + +fn clean_disk_cache() { + let _sync = Command::new("sync").output().expect("Failed to execute sync"); + let _drop_caches = Command::new("sh") + .arg("-c") + .arg("echo 3 > /proc/sys/vm/drop_caches") + .output() + .expect("Failed to execute drop_caches"); +} + +fn is_running_as_sudo() -> bool { + match env::var("EUID") { + Ok(euid) => euid == "0", + Err(_) => match env::var("USER") { + Ok(user) => user == "root", + Err(_) => false, + }, + } +}