diff options
Diffstat (limited to 'evc')
33 files changed, 0 insertions, 2765 deletions
diff --git a/evc/.gitignore b/evc/.gitignore deleted file mode 100644 index b88f3af..0000000 --- a/evc/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/target -/samples -/reports -/flamegraph.svg -/perf.data* - diff --git a/evc/Cargo.lock b/evc/Cargo.lock deleted file mode 100644 index 727d55e..0000000 --- a/evc/Cargo.lock +++ /dev/null @@ -1,663 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aho-corasick" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" -dependencies = [ - "memchr", -] - -[[package]] -name = "anyhow" -version = "1.0.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clap" -version = "4.0.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d" -dependencies = [ - "bitflags 1.3.2", - "clap_derive", - "clap_lex", - "is-terminal", - "once_cell", - "strsim", - "termcolor", -] - -[[package]] -name = "clap_derive" -version = "4.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" -dependencies = [ - "os_str_bytes", -] - -[[package]] -name = "console" -version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9b6515d269224923b26b5febea2ed42b2d5f2ce37284a4dd670fedd6cb8347a" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "unicode-width", - "windows-sys 0.42.0", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "either" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" - -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - -[[package]] -name = "env_logger" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "errno" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] - -[[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.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "indicatif" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4295cbb7573c16d310e99e713cf9e75101eb190ab31fccd35f2d2691b4352b19" -dependencies = [ - "console", - "number_prefix", - "portable-atomic", - "unicode-width", -] - -[[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.48.0", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.150" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" - -[[package]] -name = "libreschmux" -version = "0.1.0" -dependencies = [ - "anyhow", - "clap", - "env_logger", - "indicatif", - "log", - "proc-macro2", - "rayon", - "rustdct", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" - -[[package]] -name = "log" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "memchr" -version = "2.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num-complex" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - -[[package]] -name = "number_prefix" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" - -[[package]] -name = "once_cell" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" - -[[package]] -name = "os_str_bytes" -version = "6.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" - -[[package]] -name = "portable-atomic" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f6a7b87c2e435a3241addceeeff740ff8b7e76b74c13bf9acb17fa454ea00b" - -[[package]] -name = "primal-check" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9df7f93fd637f083201473dab4fee2db4c429d32e55e3299980ab3957ab916a0" -dependencies = [ - "num-integer", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rayon" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "regex" -version = "1.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" - -[[package]] -name = "rustdct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b61555105d6a9bf98797c063c362a1d24ed8ab0431655e38f1cf51e52089551" -dependencies = [ - "rustfft", -] - -[[package]] -name = "rustfft" -version = "6.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17d4f6cbdb180c9f4b2a26bbf01c4e647f1e1dea22fe8eb9db54198b32f9434" -dependencies = [ - "num-complex", - "num-integer", - "num-traits", - "primal-check", - "strength_reduce", - "transpose", - "version_check", -] - -[[package]] -name = "rustix" -version = "0.38.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" -dependencies = [ - "bitflags 2.4.1", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.48.0", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "strength_reduce" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "syn" -version = "1.0.105" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "termcolor" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "transpose" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6522d49d03727ffb138ae4cbc1283d3774f0d10aa7f9bf52e6784c45daf9b23" -dependencies = [ - "num-integer", - "strength_reduce", -] - -[[package]] -name = "unicode-ident" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" - -[[package]] -name = "unicode-width" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/evc/Cargo.toml b/evc/Cargo.toml deleted file mode 100644 index 84df2aa..0000000 --- a/evc/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "libreschmux" -version = "0.1.0" -edition = "2021" - -[dependencies] -clap = { version = "*", features = ["derive"] } -anyhow = "1.0.82" -log = "0.4.21" -rayon = "1.10.0" -env_logger = "0.11.3" -rustdct = "0.7.1" -indicatif = "*" -proc-macro2 = "1.0.81" - -[[bin]] -path = "src/bin/encode.rs" -name = "reschmux-encode" - -[[bin]] -path = "src/bin/decode.rs" -name = "reschmux-decode" - -[[bin]] -path = "src/bin/info.rs" -name = "reschmux-info" diff --git a/evc/scripts/bench_modes b/evc/scripts/bench_modes deleted file mode 100755 index 2e66454..0000000 --- a/evc/scripts/bench_modes +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/fish -set w $argv[1] -set h $argv[2] -set t $argv[3] - -ffmpeg -hide_banner -i $argv[4] -to {$t} -vf scale={$w}x{$h},fps=30,format=rgb24 -f rawvideo pipe:1 >samples/raw -# ffmpeg -hide_banner -y -i $argv[4] -to {$t} -vf scale={$w}x{$h},fps=30,format=rgb24 -c:v vp9 samples/reference.webm - -echo -echo "file: "$argv[4] -echo "resolution: "{$w}x{$h} -echo "frames: "(math $t \* 30) -echo "reference (raw): "(du -h samples/raw | cut -f 1) -echo "reference (input): "(du -h $argv[4] | cut -f 1) -# echo "reference (vp8): "(du -h samples/reference.webm | cut -f 1) -# for mode in trivial simple-exhaustive simple-fast advanced advanced-partial -for mode in trivial simple-fast advanced - echo ----------- - echo "mode: $mode" - echo "time: $(command time -f %U ./target/release/reschmux-encode -W {$w} -H {$h} --mode $mode $argv[5..] <samples/raw >samples/encoded-$mode 2>| tail -n 1)s" - echo "size: $(du -h samples/encoded-$mode | cut -f 1)" -end diff --git a/evc/scripts/bench_out b/evc/scripts/bench_out deleted file mode 100755 index d55cf08..0000000 --- a/evc/scripts/bench_out +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/fish -set w $argv[1] -set h $argv[2] - -# for mode in trivial simple-exhaustive simple-fast advanced advanced-partial -for mode in trivial simple-fast advanced - cargo run --release --bin reschmux-decode -- --debug < samples/encoded-$mode | - ffmpeg -y -hide_banner -framerate 25 -video_size {$w}x{$h} -pixel_format rgb24 -f rawvideo -i pipe:0 samples/decoded-$mode-debug.mp4 - cargo run --release --bin reschmux-decode -- < samples/encoded-$mode | - ffmpeg -y -hide_banner -framerate 25 -video_size {$w}x{$h} -pixel_format rgb24 -f rawvideo -i pipe:0 samples/decoded-$mode.mp4 -end diff --git a/evc/scripts/gen b/evc/scripts/gen deleted file mode 100755 index 6c8fa3c..0000000 --- a/evc/scripts/gen +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/fish -set w $argv[1] -set h $argv[2] -ffmpeg -hide_banner -i $argv[3] -vf scale={$w}x{$h},fps=30,format=rgb24 -f rawvideo pipe:1 | - LOG=info cargo run --release --bin reschmux-encode -- -W {$w} -H {$h} $argv[4..] >samples/encoded -ffmpeg -hide_banner -y -i $argv[3] -vf scale={$w}x{$h},fps=30,format=rgb24 samples/reference.webm -LOG=info cargo run --release --bin decode -- <samples/encoded | - ffmpeg -hide_banner -y -framerate 30 -video_size {$w}x{$h} -pixel_format rgb24 -f rawvideo -i pipe:0 samples/decoded.webm -LOG=info cargo run --release --bin decode -- --debug <samples/encoded | - ffmpeg -hide_banner -y -framerate 30 -video_size {$w}x{$h} -pixel_format rgb24 -f rawvideo -i pipe:0 samples/decoded-debug.webm diff --git a/evc/scripts/report b/evc/scripts/report deleted file mode 100755 index 06a5517..0000000 --- a/evc/scripts/report +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/fish -cargo build --release -begin - echo "version: $argv[1]" - echo "commit: $(cat ../.git/refs/heads/master | head -c 10)" - echo "encode: $(command time -f %U ./target/release/reschmux-encode -W (math 1920 / 2) -H (math 1080 / 2) <samples/raw >samples/encoded 2>| tail -n 1)s" - echo "decode: $(command time -f %U ./target/release/reschmux-decode <samples/encoded >samples/decoded 2>| tail -n 1)s" - echo "size: $(du -h samples/encoded | cut -f 1)" -end | tee -a reports/(date) diff --git a/evc/scripts/stream b/evc/scripts/stream deleted file mode 100755 index 7e9400d..0000000 --- a/evc/scripts/stream +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/fish -set w $argv[1] -set h $argv[2] -ffmpeg -hide_banner -i $argv[3] -vf scale={$w}x{$h},fps=30,format=rgb24 -f rawvideo pipe:1 | - cargo run --release --bin reschmux-encode -- -W {$w} -H {$h} $argv[4..] | - cargo run --release --bin reschmux-decode -- --debug | - ffplay -hide_banner -framerate 30 -video_size {$w}x{$h} -pixel_format rgb24 -f rawvideo pipe:0 diff --git a/evc/scripts/stream-nodebug b/evc/scripts/stream-nodebug deleted file mode 100755 index 380ec5f..0000000 --- a/evc/scripts/stream-nodebug +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/fish -set w $argv[1] -set h $argv[2] -ffmpeg -hide_banner -i $argv[3] -vf scale={$w}x{$h},fps=30,format=rgb24 -f rawvideo pipe:1 | - cargo run --release --bin reschmux-encode -- -W {$w} -H {$h} $argv[4..] | - cargo run --release --bin reschmux-decode -- | - ffplay -hide_banner -framerate 30 -video_size {$w}x{$h} -pixel_format rgb24 -f rawvideo pipe:0 diff --git a/evc/spec.md b/evc/spec.md deleted file mode 100644 index 42be71f..0000000 --- a/evc/spec.md +++ /dev/null @@ -1,60 +0,0 @@ -# Low-Efficiency Video Codec - -The codec compresses image sequences by avoiding redundancies by reusing parts -of previous frames. A frame is one block that is then subdivided further as -needed. - -## Literal-Block - -Stores the pixels' RGB values as is. - -## Split-Block - -Delegates to two sub-blocks. The block is split orthorgonally on the longest -axis. If needed, the left/top block is rounded down and the right/bottom. - -## Reference-Block - -Indicates that parts of the last frame are reused. The data reused is at the -position of this block in the last frame with the translation added. - -## Advanced-Reference-Block - -Like Reference-Block but instead translates by non-integer amount of pixels, -applying a 2x2 matrix from the center of the block and multiplying the color -value of each component, interpolating if necessary. - -## Compressed-Literal-Block - -_**JPEG? just DCT? idk**_ - -## File format - -- magic bytes: `5e b1 c3 08` -- resolution: _`u16, u16`_ -- frame count: _`u64`_ -- frames (repeated [frame count]-times) - - block kind: _`u8` (see tags below)_ - - block: _one of the following_ - - 0 **Literal-Block** - - pixels: _`[[u8; 3]; (inferred)]`_ (stored line-by-line) - - 1 **Compressed-Literal-Block** - - length: _`u32`_ - - data: _`[[u8; length]`_ - - 2 **Split-Block** - - sub-blocks: _`[block; 2]` (see above)_ - - 3 **Reference-Block** - - translation: _`i8, i8`_ - - 4 **Advanced-Reference-Block** - - translation: _`s8, s8`_ (translation) - - transform: _`s8, s8, s8, s8`_ (2x2-matrix applied before sampling - relative to the center) - - value_scale: _`i8`_ (multiplication of each color component by $1.05^n$) - -### Data Types - -- _`u<n>`_: unsigned n-bit integer (little-endian) -- _`i<n>`_: signed n-bit integer using twos-complement (little-endian) -- _`s8`_: 8-bit scalar. When read as _`i8`_ represents a value of - $\frac{x}{|x|} * \sqrt{2}^{|{x}| - 4}$ for $x \neq 0$, otherwise 0 -- _`[<T>; <N>]`_: Array of T with length N diff --git a/evc/src/bin/decode.rs b/evc/src/bin/decode.rs deleted file mode 100644 index fbf5624..0000000 --- a/evc/src/bin/decode.rs +++ /dev/null @@ -1,63 +0,0 @@ -#![feature(box_patterns)] -use anyhow::Context; -use clap::Parser; -use indicatif::ProgressBar; -use libreschmux::{ - block::Block, - codec::decode::{decode_block, DecodeConfig}, - debug::draw_debug, - format::{header::Header, ser::Source}, - frame::Frame, -}; -use log::{info, warn}; -use std::io::{BufReader, BufWriter}; - -#[derive(Parser)] -#[clap(about, version)] -pub struct DecodeArgs { - #[arg(long)] - debug: bool, -} - -fn main() -> anyhow::Result<()> { - env_logger::init_from_env("LOG"); - let args = DecodeArgs::parse(); - - let mut input = BufReader::new(std::io::stdin()); - let mut output = BufWriter::new(std::io::stdout()); - - let header = input.get::<Header>().context("reading header")?; - info!("{header:?}"); - if header.resolution.x * header.resolution.y > 100_000_000 { - warn!("resolution is quite big. video is likely corrupt."); - } - let size = header.resolution; - - let config = DecodeConfig {}; - - let progress_bar = ProgressBar::new(header.frame_count as u64); - - let mut prev = Frame::new(size); - for i in 0..header.frame_count { - info!("decode frame {i}"); - - let block = Block::read(&mut input, size).context("reading encoded frame")?; - let mut frame = Frame::new(size); - - decode_block(&block, frame.view_mut(), prev.view(), &config); - - progress_bar.inc(1); - - if args.debug { - let mut f2 = frame.clone(); - draw_debug(&block, f2.view_mut()); - f2.write(&mut output).context("writing raw frame")?; - } else { - frame.write(&mut output).context("writing raw frame")?; - } - - prev = frame; - } - drop(input); - Ok(()) -} diff --git a/evc/src/bin/encode.rs b/evc/src/bin/encode.rs deleted file mode 100644 index 43f2c57..0000000 --- a/evc/src/bin/encode.rs +++ /dev/null @@ -1,111 +0,0 @@ -use anyhow::Context; -use clap::Parser; -use indicatif::ProgressBar; -use libreschmux::{ - codec::{ - decode::{decode_block, DecodeConfig}, - encode::{encode_block, EncodeConfig, EncodeMode}, - }, - format::{header::Header, ser::Sink}, - frame::Frame, - helpers::vector::Vec2, -}; -use log::info; -use std::io::{BufReader, BufWriter}; - -#[derive(Parser)] -#[clap(about, version)] -pub struct EncodeArgs { - #[arg(short = 'W', long)] - width: usize, - #[arg(short = 'H', long)] - height: usize, - - #[arg(short, long)] - mode: EncodeMode, - - #[arg(long)] - no_linear_transform: bool, - #[arg(long)] - no_value_scale: bool, - #[arg(long)] - no_translate: bool, - - #[arg[short = 'L', long]] - length: Option<usize>, - - #[arg(short, long, default_value = "8")] - min_block_size: isize, - - #[arg(short = 't', long, default_value = "200")] - ref_thres: f64, -} - -fn main() -> anyhow::Result<()> { - env_logger::init_from_env("LOG"); - let args = EncodeArgs::parse(); - - let mut input = BufReader::new(std::io::stdin()); - let mut output = BufWriter::new(std::io::stdout()); - - let config = EncodeConfig { - mode: args.mode, - ref_thres: args.ref_thres, - weight_factor: 50.0, - max_diff_area: 10_000, - min_block_size: args.min_block_size, - do_translate: !args.no_translate, - do_linear_transform: !args.no_linear_transform, - do_value_scale: !args.no_value_scale, - }; - - let size = Vec2 { - x: args.width as isize, - y: args.height as isize, - }; - output - .put(Header { - resolution: size, - frame_count: args.length.unwrap_or(usize::MAX), - }) - .context("writing header")?; - - let progress_bar = args.length.map(|len| ProgressBar::new(len as u64)); - let mut prev_frame = Frame::new(size); - - for i in 0.. { - info!("encode frame {i}"); - let mut frame = Frame::read(&mut input, size).context("reading raw frame")?; - - let v1 = frame.view(); - let v2 = prev_frame.view(); - - let (error, root) = encode_block(v1, v2, &config); - - // compress_block( - // &mut root, - // Vec2 { - // x: size.x as usize, - // y: size.y as usize, - // }, - // ); - - root.write(&mut output, size) - .context("writing encoded frame")?; - - info!( - "cumulative error: {error} ({} per pixel)", - error / frame.view().area() as f64 - ); - - if let Some(progress_bar) = &progress_bar { - progress_bar.inc(1); - } - - decode_block(&root, frame.view_mut(), prev_frame.view(), &DecodeConfig {}); - - prev_frame = frame; - } - - Ok(()) -} diff --git a/evc/src/bin/info.rs b/evc/src/bin/info.rs deleted file mode 100644 index ebd8442..0000000 --- a/evc/src/bin/info.rs +++ /dev/null @@ -1,10 +0,0 @@ -use anyhow::Context; -use libreschmux::format::{header::Header, ser::Source}; -use std::io::BufReader; - -fn main() { - env_logger::init_from_env("LOG"); - let mut input = BufReader::new(std::io::stdin()); - let header = input.get::<Header>().context("reading header").unwrap(); - eprintln!("{header:#?}") -} diff --git a/evc/src/block.rs b/evc/src/block.rs deleted file mode 100644 index d0f940b..0000000 --- a/evc/src/block.rs +++ /dev/null @@ -1,123 +0,0 @@ -use crate::{ - format::ser::{ConstSizeSerExt, Ser, Sink, Small, Source}, - helpers::vector::Vec2, - helpers::{matrix::Mat2, pixel::Pixel}, -}; -use anyhow::bail; - -#[derive(Clone, Debug, PartialEq)] -pub enum Block { - Literal(Vec<Pixel>), - CompressedLiteral(Vec<u8>), - Split(Box<[Block; 2]>), - Reference { translation: Vec2<isize> }, - AdvancedReference(AdvancedReference), -} - -#[derive(Clone, Debug, PartialEq)] -pub struct AdvancedReference { - pub translation: Vec2<i8>, - pub transform: Mat2<i8>, - pub value_scale: i8, -} - -impl Block { - pub const REFZERO: Block = Block::Reference { - translation: Vec2::<isize>::ZERO, - }; - - pub fn write(&self, sink: &mut impl std::io::Write, size: Vec2<isize>) -> anyhow::Result<()> { - match &self { - Block::Literal(pixels) => { - sink.put(0u8)?; - pixels.write_const_size(sink, size.area() as usize)?; - } - Block::CompressedLiteral(data) => { - sink.put(1u8)?; - data.write(sink)?; - } - Block::Split(box [a, b]) => { - sink.put(2u8)?; - let [asize, bsize] = split_size(size); - a.write(sink, asize)?; - b.write(sink, bsize)?; - } - Block::Reference { translation } => { - sink.put(3u8)?; - sink.put(Small(*translation))?; - } - Block::AdvancedReference(AdvancedReference { - translation, - transform, - value_scale, - }) => { - sink.put(4u8)?; - sink.put((*translation, *transform, *value_scale))?; - } - } - Ok(()) - } - - pub fn read(source: &mut impl std::io::Read, size: Vec2<isize>) -> anyhow::Result<Self> { - let variant = source.get::<u8>()?; - Ok(match variant { - 0 => Block::Literal(Vec::read_const_size(source, size.area() as usize)?), - 1 => Block::CompressedLiteral(Vec::read(source)?), - 2 => Block::Split(Box::new({ - let [asize, bsize] = split_size(size); - let a = Block::read(source, asize)?; - let b = Block::read(source, bsize)?; - [a, b] - })), - 3 => Block::Reference { - translation: source.get::<Small<Vec2<isize>>>()?.0, - }, - 4 => Block::AdvancedReference(AdvancedReference { - translation: source.get()?, - transform: source.get()?, - value_scale: source.get()?, - }), - x => bail!("corrupt block type ({})", x), - }) - } -} - -pub fn split_size(size: Vec2<isize>) -> [Vec2<isize>; 2] { - let vert = size.x > size.y; - [ - if vert { - (size.x / 2, size.y).into() - } else { - (size.x, size.y / 2).into() - }, - if vert { - (size.x - size.x / 2, size.y).into() - } else { - (size.x, size.y - size.y / 2).into() - }, - ] -} - -impl Block { - pub fn is_literal(&self) -> bool { - matches!(self, Block::Literal(..)) - } - pub fn identical_ref(a: &Self, b: &Self) -> bool { - matches!(a, Block::Reference { .. }) && a == b - } -} - -impl Default for AdvancedReference { - fn default() -> Self { - Self { - translation: Vec2 { x: 0, y: 0 }, - transform: Mat2 { - a: 4, - b: 0, - c: 0, - d: 4, - }, - value_scale: 0, - } - } -} diff --git a/evc/src/codec/compress.rs b/evc/src/codec/compress.rs deleted file mode 100644 index 09d1f29..0000000 --- a/evc/src/codec/compress.rs +++ /dev/null @@ -1,155 +0,0 @@ -use crate::{ - block::Block, - frame::Frame, - helpers::{pixel::Pixel, vector::Vec2}, - view::View, -}; -use rustdct::DctPlanner; - -pub fn compress_block(block: &mut Block, size: Vec2<usize>) { - match block { - Block::Literal(p) => { - let comp = lit_compress(size.x, size.y, &p); - *block = Block::CompressedLiteral(comp) - } - Block::Split(box [a, b]) => { - let vert = size.x > size.y; - compress_block( - a, - if vert { - Vec2 { - x: size.x / 2, - y: size.y, - } - } else { - Vec2 { - x: size.x, - y: size.y / 2, - } - }, - ); - compress_block( - b, - if vert { - Vec2 { - x: size.x - size.x / 2, - y: size.y, - } - } else { - Vec2 { - x: size.x, - y: size.y - size.y / 2, - } - }, - ); - } - _ => (), - } -} - -pub fn lit_compress(w: usize, h: usize, pixels: &[Pixel]) -> Vec<u8> { - let mut out = vec![]; - for ci in 0..3 { - let mut ch = vec![0.; w * h]; - for y in 0..h { - for x in 0..w { - let p = pixels[x + y * w]; - ch[x + y * w] = match ci { - 0 => p.r, - 1 => p.g, - 2 => p.b, - _ => unreachable!(), - } as f32 - } - } - - norm_dct_channel(w, h, &mut ch); - for i in 0..w * h { - out.extend(unsafe { std::mem::transmute::<_, [u8; 4]>(ch[i]) }); - } - } - out -} - -pub fn lit_decompress(compressed: &[u8], mut target: View<&mut Frame>) { - let (w, h) = (target.size.x as usize, target.size.y as usize); - for ci in 0..3 { - let mut ch = compressed[ci * w * h..(ci + 1) * w * h] - .chunks_exact(4) - .map(|v| unsafe { - std::mem::transmute::<_, f32>(TryInto::<[u8; 4]>::try_into(v).unwrap()) - }) - .collect::<Vec<_>>(); - norm_idct_channel(w, h, &mut ch); - for y in 0..h { - for x in 0..w { - let p = &mut target[Vec2 { - x: x as isize, - y: y as isize, - }]; - *(match ci { - 0 => &mut p.r, - 1 => &mut p.g, - 2 => &mut p.b, - _ => unreachable!(), - }) = ch[x + y * w] as u8 - } - } - } -} - -fn norm_dct_channel(w: usize, h: usize, values: &mut [f32]) { - let d = DctPlanner::new().plan_dct2(w); - let mut temp = vec![0.; d.get_scratch_len()]; - for c in values.chunks_exact_mut(w) { - d.process_dct2_with_scratch(c, &mut temp) - } - - let mut values_trans = transpose(w, h, values); - let d = DctPlanner::new().plan_dct2(h); - let mut temp = vec![0.; d.get_scratch_len()]; - for c in values_trans.chunks_exact_mut(h) { - d.process_dct2_with_scratch(c, &mut temp) - } - - let scale = 2. / (w as f32 * h as f32).sqrt(); - for (i, v) in values_trans.iter().enumerate() { - values[i] = *v * scale * 127.0 - } -} - -fn norm_idct_channel(h: usize, w: usize, values: &mut [f32]) { - let scale = 2. / (w as f32 * h as f32).sqrt(); - for v in values.iter_mut() { - *v /= scale * 127.0 - } - - let d = DctPlanner::new().plan_dct2(w); - let mut temp = vec![0.; d.get_scratch_len()]; - for c in values.chunks_exact_mut(w) { - d.process_dct3_with_scratch(c, &mut temp) - } - - let mut values_trans = transpose(w, h, values); - let d = DctPlanner::new().plan_dct2(h); - let mut temp = vec![0.; d.get_scratch_len()]; - for c in values_trans.chunks_exact_mut(h) { - d.process_dct3_with_scratch(c, &mut temp) - } - values.copy_from_slice(&values_trans) -} - -fn transpose(w: usize, h: usize, values: &[f32]) -> Vec<f32> { - let mut io = 0; - let mut it; - let mut transposed = vec![0.; values.len()]; - for row in 0..h { - it = row; - for _ in 0..w { - transposed[it] = values[io]; - io += 1; - it += h; - } - } - transposed -} diff --git a/evc/src/codec/decode.rs b/evc/src/codec/decode.rs deleted file mode 100644 index c042278..0000000 --- a/evc/src/codec/decode.rs +++ /dev/null @@ -1,34 +0,0 @@ -use super::compress::lit_decompress; -use crate::{block::Block, frame::Frame, refsampler::Sampler, view::View}; - -pub struct DecodeConfig {} - -pub fn decode_block( - block: &Block, - mut target: View<&mut Frame>, - prev: View<&Frame>, - config: &DecodeConfig, -) { - match &block { - Block::Literal(pixels) => target.set_pixels(pixels), - Block::Split(box [a, b]) => { - let [a, b] = unsafe { std::mem::transmute::<_, [&'static Block; 2]>([a, b]) }; - let [at, bt] = unsafe { - std::mem::transmute::<_, [View<&'static mut Frame>; 2]>(target.split_mut_unsafe()) - }; - let [ap, bp] = - unsafe { std::mem::transmute::<_, [View<&'static Frame>; 2]>(prev.split()) }; - let config = unsafe { std::mem::transmute::<_, &'static DecodeConfig>(config) }; - - rayon::join( - move || decode_block(a, at, ap, config), - move || decode_block(b, bt, bp, config), - ); - } - Block::CompressedLiteral(data) => { - lit_decompress(&data, target); - } - Block::Reference { translation } => target.copy_from(&prev.offset(*translation)), - Block::AdvancedReference(r) => target.copy_from_sampler(&Sampler::from_refblock(prev, r)), - } -} diff --git a/evc/src/codec/encode/advanced.rs b/evc/src/codec/encode/advanced.rs deleted file mode 100644 index 0e45176..0000000 --- a/evc/src/codec/encode/advanced.rs +++ /dev/null @@ -1,115 +0,0 @@ -use super::EncodeConfig; -use crate::{ - block::{AdvancedReference, Block}, - frame::Frame, - refsampler::Sampler, - view::View, -}; - -pub fn default( - view: &View<&Frame>, - prev: &View<&Frame>, - config: &EncodeConfig, - max_diff: f64, -) -> (f64, Block) { - let mut pm = AdvancedReference::default(); - let sampler = Sampler::from_refblock(prev.clone(), &pm); - let mut diff = View::diff_sampler(&view, &sampler); - if diff < max_diff { - (diff, Block::REFZERO) - } else { - loop { - let (mut d, mut p) = (diff, pm.clone()); - - if config.do_translate { - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x += 4); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x -= 4); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y += 4); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y -= 4); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x += 2); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x -= 2); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y += 2); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y -= 2); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x += 1); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x -= 1); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y += 1); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y -= 1); - } - if config.do_value_scale { - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.value_scale += 1); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.value_scale -= 1); - } - if config.do_linear_transform { - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.transform.a -= 1); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.transform.a += 1); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.transform.b -= 1); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.transform.b += 1); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.transform.c -= 1); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.transform.c += 1); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.transform.d -= 1); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.transform.d += 1); - } - - if d >= diff { - break (diff, Block::AdvancedReference(pm)); - } - - diff = d; - pm = p; - } - } -} - -pub fn partial( - view: &View<&Frame>, - prev: &View<&Frame>, - _config: &EncodeConfig, - max_diff: f64, -) -> (f64, Block) { - let mut pm = AdvancedReference::default(); - let sampler = Sampler::from_refblock(prev.clone(), &pm); - let mut diff = View::diff_sampler(&view, &sampler); - if diff < max_diff { - (diff, Block::REFZERO) - } else { - loop { - let (mut d, mut p) = (diff, pm.clone()); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x += 2); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x -= 2); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y += 2); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y -= 2); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x += 1); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.x -= 1); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y += 1); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.translation.y -= 1); - - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.value_scale += 1); - pk(&view, &prev, &mut d, &mut p, &pm, |p| p.value_scale -= 1); - - if d >= diff { - break (diff, Block::AdvancedReference(pm)); - } - diff = d; - pm = p; - } - } -} - -#[inline] -fn pk<F: FnMut(&mut AdvancedReference) -> ()>( - view: &View<&Frame>, - prev: &View<&Frame>, - diff: &mut f64, - params: &mut AdvancedReference, - initial_params: &AdvancedReference, - mut f: F, -) { - let mut p = initial_params.clone(); - f(&mut p); - let sampler = Sampler::from_refblock(prev.clone(), &p); - let d = View::diff_sampler(view, &sampler); - if d < *diff { - *diff = d; - *params = p; - } -} diff --git a/evc/src/codec/encode/mod.rs b/evc/src/codec/encode/mod.rs deleted file mode 100644 index 30342f0..0000000 --- a/evc/src/codec/encode/mod.rs +++ /dev/null @@ -1,112 +0,0 @@ -pub mod advanced; -pub mod simple; - -use crate::{ - block::Block, - frame::Frame, - helpers::{pixel::Pixel, vector::Vec2}, - view::View, -}; -use clap::ValueEnum; - -#[derive(Debug, Clone)] -pub struct EncodeConfig { - pub mode: EncodeMode, - pub ref_thres: f64, - pub max_diff_area: isize, - pub min_block_size: isize, - pub weight_factor: f64, - - pub do_translate: bool, - pub do_value_scale: bool, - pub do_linear_transform: bool, -} - -#[derive(Debug, Clone, ValueEnum)] -pub enum EncodeMode { - Trivial, - SimpleFast, - SimpleExhaustive, - Advanced, - AdvancedPartial, -} - -pub fn encode_block(view: View<&Frame>, prev: View<&Frame>, config: &EncodeConfig) -> (f64, Block) { - let (diff, refblock) = if view.area() > config.max_diff_area { - ( - f64::INFINITY, - Block::Reference { - translation: Vec2::<isize>::ZERO, - }, - ) - } else { - let weight = importance(&view).max(0.5); - let irrelevance = config.weight_factor / weight; - let max_diff = config.ref_thres - irrelevance; - let (diff, refblock) = match config.mode { - EncodeMode::Trivial => ( - View::diff(&view, &prev), - Block::Reference { - translation: Vec2::<isize>::ZERO, - }, - ), - EncodeMode::SimpleExhaustive => simple::exhaustive(&view, &prev, config, max_diff), - EncodeMode::SimpleFast => simple::fast(&view, &prev, config, max_diff), - EncodeMode::Advanced => advanced::default(&view, &prev, config, max_diff), - EncodeMode::AdvancedPartial => advanced::partial(&view, &prev, config, max_diff), - }; - (diff - irrelevance, refblock) - }; - if diff < config.ref_thres { - (diff, refblock) - } else { - if view.size.x < config.min_block_size || view.size.y < config.min_block_size { - (0.0, Block::Literal(view.pixels())) - } else { - let [av, bv] = - unsafe { std::mem::transmute::<_, [View<&'static Frame>; 2]>(view.split()) }; - let [ap, bp] = - unsafe { std::mem::transmute::<_, [View<&'static Frame>; 2]>(prev.split()) }; - let config = unsafe { std::mem::transmute::<_, &'static EncodeConfig>(config) }; - - // only bother to do multithreading, when the block is big. - let ((ad, a), (bd, b)) = if view.area() > 100 { - rayon::join( - || encode_block(av, ap, config), - || encode_block(bv, bp, config), - ) - } else { - (encode_block(av, ap, config), encode_block(bv, bp, config)) - }; - - ( - ad + bd, - if a.is_literal() && b.is_literal() { - Block::Literal(view.pixels()) - } else if Block::identical_ref(&a, &b) { - Block::Reference { - translation: Vec2::<isize>::ZERO, - } - } else { - Block::Split(Box::new([a, b])) - }, - ) - } - } -} - -pub fn importance(view: &View<&Frame>) -> f64 { - let mut acc = 0; - for x in 0..view.size.x { - for y in 0..view.size.y { - let p = Vec2 { x, y }; - if x > 0 { - acc += Pixel::distance(view[p], view[p + Vec2::<isize>::LEFT]); - } - if y > 0 { - acc += Pixel::distance(view[p], view[p + Vec2::<isize>::UP]); - } - } - } - (acc / view.area() as usize) as f64 -} diff --git a/evc/src/codec/encode/simple.rs b/evc/src/codec/encode/simple.rs deleted file mode 100644 index 2a971af..0000000 --- a/evc/src/codec/encode/simple.rs +++ /dev/null @@ -1,65 +0,0 @@ -use crate::{block::Block, frame::Frame, helpers::vector::Vec2, view::View}; - -use super::EncodeConfig; - -pub fn exhaustive( - view: &View<&Frame>, - prev: &View<&Frame>, - _config: &EncodeConfig, - _max_diff: f64, -) -> (f64, Block) { - let mut diff = f64::INFINITY; - let mut translation = Vec2::<isize>::ZERO; - const OFFSETS: &[isize] = &[-64, -32, -16, -8, -4, -2, -1, 0, 1, 2, 4, 8, 16, 32, 64]; - for x in OFFSETS { - for y in OFFSETS { - let t = Vec2 { x: *x, y: *y }; - let d = View::diff(&view, &prev.offset(t)); - if d < diff { - translation = t; - diff = d; - } - } - } - (diff, Block::Reference { translation }) -} - -pub fn fast( - view: &View<&Frame>, - prev: &View<&Frame>, - _config: &EncodeConfig, - max_diff: f64, -) -> (f64, Block) { - let mut offset = Vec2::<isize>::ZERO; - let mut diff = View::diff(&view, &prev); - if diff < max_diff { - (diff, Block::REFZERO) - } else { - loop { - let (mut d, mut o) = (diff, offset); - let mut probe = |test_o: Vec2<isize>| { - let test_d = View::diff(&prev.clone().offset(test_o), &view); - if test_d < d { - d = test_d; - o = test_o; - } - }; - - probe(offset + Vec2 { x: 8, y: 0 }); - probe(offset + Vec2 { x: -8, y: 0 }); - probe(offset + Vec2 { x: 0, y: 8 }); - probe(offset + Vec2 { x: 0, y: -8 }); - - probe(offset + Vec2 { x: 1, y: 0 }); - probe(offset + Vec2 { x: -1, y: 0 }); - probe(offset + Vec2 { x: 0, y: 1 }); - probe(offset + Vec2 { x: 0, y: -1 }); - - if d >= diff { - break (diff, Block::Reference { translation: o }); - } - diff = d; - offset = o; - } - } -} diff --git a/evc/src/codec/mod.rs b/evc/src/codec/mod.rs deleted file mode 100644 index 3203e6e..0000000 --- a/evc/src/codec/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod decode; -pub mod encode; -pub mod compress; diff --git a/evc/src/debug.rs b/evc/src/debug.rs deleted file mode 100644 index a7a9545..0000000 --- a/evc/src/debug.rs +++ /dev/null @@ -1,103 +0,0 @@ -use crate::{ - block::Block, - format::ser::map_scalar8, - frame::Frame, - helpers::vector::Vec2, - helpers::{matrix::Mat2, pixel::Pixel}, - view::View, -}; - -impl View<&mut Frame> { - pub fn draw_box(&mut self, color: Pixel) { - let w = self.size.x; - let h = self.size.y; - for x in 0..w { - self[(x, 0)] = color; - self[(x, h - 1)] = color; - } - for y in 0..h { - self[(0, y)] = color; - self[(w - 1, y)] = color; - } - } -} - -impl Frame { - pub fn draw_line(&mut self, start: Vec2<f32>, end: Vec2<f32>, color: Pixel) { - let diff = end - start; - let len = (diff.x * diff.x + diff.y * diff.y).sqrt(); - let normal = Vec2 { - x: diff.x / len, - y: diff.y / len, - }; - let mut cursor = start.clone(); - let mut lc = 0.0; - while lc < len { - self.set(cursor.into(), color); - lc += 0.5; - cursor = cursor + normal.scale(0.5); - } - } -} - -impl Pixel { - pub const RED: Pixel = Pixel { r: 255, g: 0, b: 0 }; - pub const GREEN: Pixel = Pixel { r: 0, g: 255, b: 0 }; - pub const BLUE: Pixel = Pixel { r: 0, g: 0, b: 255 }; - pub const MAGENTA: Pixel = Pixel { - r: 255, - g: 0, - b: 255, - }; - pub const CYAN: Pixel = Pixel { - r: 0, - g: 255, - b: 255, - }; -} - -pub fn draw_debug(block: &Block, mut target: View<&mut Frame>) { - match &block { - Block::Literal(_) | Block::CompressedLiteral(_) => { - target.draw_box(Pixel::GREEN); - } - Block::Split(box [a, b]) => { - let [at, bt] = target.split_mut_unsafe(); - draw_debug(a, at); - draw_debug(b, bt); - } - Block::Reference { translation } => { - target.draw_box(Pixel::BLUE); - target.frame.draw_line( - target.center().into(), - (target.center() + *translation).into(), - Pixel::RED, - ) - } - Block::AdvancedReference(r) => { - let mat = Mat2 { - a: map_scalar8(r.transform.a), - b: map_scalar8(r.transform.b), - c: map_scalar8(r.transform.c), - d: map_scalar8(r.transform.d), - }; - let translation = Vec2 { - x: map_scalar8(r.translation.x), - y: map_scalar8(r.translation.y), - }; - let halfsize = Into::<Vec2<f32>>::into(target.size).scale(0.5); - let transform = |p| translation + mat.transform(p - halfsize) + halfsize; - let (tl, tr, bl, br) = ( - transform(Vec2::<f32>::ZERO) + target.offset.into(), - transform(target.size.x_only().into()) + target.offset.into(), - transform(target.size.y_only().into()) + target.offset.into(), - transform(target.size.into()) + target.offset.into(), - ); - target.draw_box(Pixel::CYAN); - target.frame.draw_line(tl, tr, Pixel::MAGENTA); - target.frame.draw_line(tr, br, Pixel::MAGENTA); - target.frame.draw_line(bl, br, Pixel::MAGENTA); - target.frame.draw_line(tl, bl, Pixel::MAGENTA); - } - }; -} diff --git a/evc/src/format/header.rs b/evc/src/format/header.rs deleted file mode 100644 index ecbae89..0000000 --- a/evc/src/format/header.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::{ - format::ser::{Ser, Sink, Source}, - helpers::vector::Vec2, -}; - -#[derive(Debug, Clone, PartialEq, Copy)] -pub struct Header { - pub resolution: Vec2<isize>, - pub frame_count: usize, -} - -pub const MAGIC: [u8; 4] = [0x5eu8, 0xb1u8, 0xc3u8, 0x08u8]; - -impl Ser for Header { - fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> { - sink.put(MAGIC)?; - sink.put((Into::<Vec2<u16>>::into(self.resolution), self.frame_count))?; - Ok(()) - } - - fn read(source: &mut impl std::io::Read) -> anyhow::Result<Self> { - assert_eq!(source.get::<[u8; 4]>()?, MAGIC); - let (resolution, frame_count): (Vec2<u16>, usize) = source.get()?; - Ok(Self { - resolution: resolution.into(), - frame_count, - }) - } -} diff --git a/evc/src/format/mod.rs b/evc/src/format/mod.rs deleted file mode 100644 index d4fb18c..0000000 --- a/evc/src/format/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod header; -pub mod ser;
\ No newline at end of file diff --git a/evc/src/format/ser.rs b/evc/src/format/ser.rs deleted file mode 100644 index f063377..0000000 --- a/evc/src/format/ser.rs +++ /dev/null @@ -1,335 +0,0 @@ -use anyhow::Context; -use std::io::{Read, Write}; - -use crate::helpers::{matrix::Mat2, vector::Vec2}; - -pub trait Sink { - fn put<V: Ser>(&mut self, value: V) -> anyhow::Result<()>; -} -pub trait Source { - fn get<V: Ser>(&mut self) -> anyhow::Result<V>; -} - -impl<T: Write> Sink for T { - fn put<V: Ser>(&mut self, value: V) -> anyhow::Result<()> { - value.write(self) - } -} -impl<T: Read> Source for T { - fn get<V: Ser>(&mut self) -> anyhow::Result<V> { - V::read(self) - } -} - -pub trait Ser: Sized { - fn write(&self, sink: &mut impl Write) -> anyhow::Result<()>; - fn read(source: &mut impl Read) -> anyhow::Result<Self>; -} - -impl<A: Ser, B: Ser> Ser for (A, B) { - fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { - self.0.write(sink).context("first tuple field")?; - self.1.write(sink).context("second tuple field")?; - Ok(()) - } - - fn read(source: &mut impl Read) -> anyhow::Result<Self> { - Ok((A::read(source)?, B::read(source)?)) - } -} -impl<A: Ser, B: Ser, C: Ser> Ser for (A, B, C) { - fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { - self.0.write(sink).context("first tuple field")?; - self.1.write(sink).context("second tuple field")?; - self.2.write(sink).context("third tuple field")?; - Ok(()) - } - - fn read(source: &mut impl Read) -> anyhow::Result<Self> { - Ok((A::read(source)?, B::read(source)?, C::read(source)?)) - } -} -impl<A: Ser, B: Ser, C: Ser, D: Ser> Ser for (A, B, C, D) { - fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { - self.0.write(sink).context("first tuple field")?; - self.1.write(sink).context("second tuple field")?; - self.2.write(sink).context("third tuple field")?; - self.3.write(sink).context("fourth tuple field")?; - Ok(()) - } - - fn read(source: &mut impl Read) -> anyhow::Result<Self> { - Ok(( - A::read(source)?, - B::read(source)?, - C::read(source)?, - D::read(source)?, - )) - } -} - -impl<A: Ser, const N: usize> Ser for [A; N] { - fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { - for e in self { - e.write(sink).context("some array")?; - } - Ok(()) - } - - fn read(source: &mut impl Read) -> anyhow::Result<Self> { - let mut k: [A; N] = unsafe { std::mem::zeroed() }; - for i in 0..N { - k[i] = A::read(source)?; - } - Ok(k) - } -} - -impl<T: Ser> Ser for Vec<T> { - fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { - self.len().write(sink)?; - for e in self { - e.write(sink).context("some vec")?; - } - Ok(()) - } - - fn read(source: &mut impl Read) -> anyhow::Result<Self> { - let mut v = vec![]; - for _ in 0..usize::read(source)? { - v.push(T::read(source)?) - } - Ok(v) - } -} - -pub trait ConstSizeSerExt: Sized { - fn write_const_size(&self, sink: &mut impl Write, size: usize) -> anyhow::Result<()>; - fn read_const_size(source: &mut impl Read, size: usize) -> anyhow::Result<Self>; -} -impl<T: Ser> ConstSizeSerExt for Vec<T> { - fn write_const_size(&self, sink: &mut impl Write, size: usize) -> anyhow::Result<()> { - assert_eq!(self.len(), size); - for e in self { - e.write(sink).context("some const-size vec")?; - } - Ok(()) - } - - fn read_const_size(source: &mut impl Read, size: usize) -> anyhow::Result<Self> { - let mut v = vec![]; - for _ in 0..size { - v.push(T::read(source)?) - } - Ok(v) - } -} - -impl Ser for u8 { - fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { - Ok(sink.write_all(&[*self]).context("write u8")?) - } - fn read(source: &mut impl Read) -> anyhow::Result<Self> { - let mut buf = [0u8; 1]; - source.read_exact(&mut buf)?; - Ok(buf[0]) - } -} -impl Ser for i8 { - fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { - Ok(sink - .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 1]>(self) }) - .context("write i8")?) - } - fn read(source: &mut impl Read) -> anyhow::Result<Self> { - let mut buf = [0u8; 1]; - source.read_exact(&mut buf)?; - Ok(unsafe { std::mem::transmute_copy(&buf) }) - } -} -impl Ser for u16 { - fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { - Ok(sink - .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 2]>(self) }) - .context("write u16")?) - } - fn read(source: &mut impl Read) -> anyhow::Result<Self> { - let mut buf = [0u8; 2]; - source.read_exact(&mut buf)?; - Ok(unsafe { std::mem::transmute_copy(&buf) }) - } -} -impl Ser for u32 { - fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { - Ok(sink - .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 4]>(self) }) - .context("write u32")?) - } - fn read(source: &mut impl Read) -> anyhow::Result<Self> { - let mut buf = [0u8; 4]; - source.read_exact(&mut buf)?; - Ok(unsafe { std::mem::transmute_copy(&buf) }) - } -} -impl Ser for u64 { - fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { - Ok(sink - .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) }) - .context("write u64")?) - } - fn read(source: &mut impl Read) -> anyhow::Result<Self> { - let mut buf = [0u8; 8]; - source.read_exact(&mut buf)?; - Ok(unsafe { std::mem::transmute_copy(&buf) }) - } -} -impl Ser for usize { - fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { - Ok(sink - .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) }) - .context("write usize")?) - } - fn read(source: &mut impl Read) -> anyhow::Result<Self> { - let mut buf = [0u8; 8]; - source.read_exact(&mut buf)?; - Ok(unsafe { std::mem::transmute_copy(&buf) }) - } -} -impl Ser for isize { - fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { - Ok(sink - .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) }) - .context("write isize")?) - } - fn read(source: &mut impl Read) -> anyhow::Result<Self> { - let mut buf = [0u8; 8]; - source.read_exact(&mut buf)?; - Ok(unsafe { std::mem::transmute_copy(&buf) }) - } -} -impl Ser for f32 { - fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { - Ok(sink - .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 4]>(self) }) - .context("write f32")?) - } - fn read(source: &mut impl Read) -> anyhow::Result<Self> { - let mut buf = [0u8; 4]; - source.read_exact(&mut buf)?; - Ok(unsafe { std::mem::transmute_copy(&buf) }) - } -} -impl Ser for f64 { - fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> { - Ok(sink - .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) }) - .context("write f64")?) - } - fn read(source: &mut impl Read) -> anyhow::Result<Self> { - let mut buf = [0u8; 8]; - source.read_exact(&mut buf)?; - Ok(unsafe { std::mem::transmute_copy(&buf) }) - } -} - -impl<T: Ser + Copy> Ser for Vec2<T> { - fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> { - sink.put((self.x, self.y)) - } - - fn read(source: &mut impl std::io::Read) -> anyhow::Result<Self> { - let (x, y) = source.get()?; - Ok(Vec2 { x, y }) - } -} -impl<T: Ser + Copy> Ser for Mat2<T> { - fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> { - sink.put((self.a, self.b, self.c, self.d)) - } - - fn read(source: &mut impl std::io::Read) -> anyhow::Result<Self> { - let (a, b, c, d) = source.get()?; - Ok(Mat2 { a, b, c, d }) - } -} - -pub struct Small<T>(pub T); -impl Ser for Small<Vec2<isize>> { - fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> { - sink.put((self.0.x as i8, self.0.y as i8)) - } - - fn read(source: &mut impl std::io::Read) -> anyhow::Result<Self> { - let (x, y): (i8, i8) = source.get()?; - Ok(Small(Vec2 { - x: x as isize, - y: y as isize, - })) - } -} - -pub fn map_scalar8(v: i8) -> f32 { - match v { - 0 => 0.0, - x if x > 0 => 2f32.powf((x as f32).abs() / 2.0 - 2.0), - x => -2f32.powf((-x as f32).abs() / 2.0 - 2.0), - } -} -// const SCALAR8: [f32; 256] = gen_scalar8_lookup(); -// const fn gen_scalar8_lookup() -> [f32; 256] { -// let mut a = [0.0; 256]; -// let mut i = 0usize; -// while i < 256 { -// a[i as usize] = if i == 0 { -// 0.0 -// } else { -// let x = i as i8 as f32; -// x.signum() * 2f32.powf(x.abs() / 2.0 - 2.0) -// }; -// i += 1; -// } -// a -// } - -#[cfg(test)] -mod test { - use super::{Ser, Sink}; - use crate::format::header::Header; - use crate::{format::ser::Source, helpers::vector::Vec2}; - use std::fmt::Debug; - use std::io::Cursor; - - fn test_ser<T: PartialEq + Ser + Debug + Clone>(value: T) { - let mut buf = vec![]; - Cursor::new(&mut buf).put(value.clone()).unwrap(); - assert_eq!(value, Cursor::new(&mut buf).get().unwrap()); - } - - #[test] - fn simple() { - let mut buf = vec![]; - Cursor::new(&mut buf).put(10usize).unwrap(); - assert_eq!(10usize, Cursor::new(&mut buf).get().unwrap()); - } - #[test] - fn tuple() { - let mut buf = vec![]; - Cursor::new(&mut buf).put((10usize, 5u8, 3u16)).unwrap(); - assert_eq!((10usize, 5u8, 3u16), Cursor::new(&mut buf).get().unwrap()); - } - #[test] - fn header() { - test_ser(Header { - frame_count: 123, - resolution: Vec2 { x: 13, y: 37 }, - }); - } - #[test] - fn vec() { - test_ser(vec![1u16, 2, 3, 4]); - } - #[test] - fn array() { - test_ser([1u16, 2, 3, 4]); - } -} diff --git a/evc/src/frame.rs b/evc/src/frame.rs deleted file mode 100644 index 78d0e73..0000000 --- a/evc/src/frame.rs +++ /dev/null @@ -1,109 +0,0 @@ -use crate::{ - format::ser::{Sink, Source}, - helpers::{pixel::Pixel, vector::Vec2}, - view::View, -}; -use std::ops::{Index, IndexMut}; - -#[derive(Debug, Clone)] -pub struct Frame { - pub size: Vec2<isize>, - buffer: Vec<Pixel>, -} - -impl Frame { - pub fn new(size: Vec2<isize>) -> Self { - Self { - size, - buffer: (0..size.x * size.y).map(|_| Pixel::default()).collect(), - } - } - pub fn read(source: &mut impl Source, size: Vec2<isize>) -> anyhow::Result<Self> { - let mut frame = Frame::new(size); - for y in 0..size.y { - for x in 0..size.x { - let pixel = source.get::<Pixel>()?; - frame[(x, y)] = pixel; - } - } - Ok(frame) - } - pub fn write(&self, sink: &mut impl Sink) -> anyhow::Result<()> { - for y in 0..self.size.y { - for x in 0..self.size.x { - sink.put(self[(x, y)])?; - } - } - Ok(()) - } - pub fn view<'a>(&'a self) -> View<&'a Frame> { - View::new(self, Vec2::<isize>::ZERO, self.size) - } - pub fn view_mut<'a>(&'a mut self) -> View<&'a mut Frame> { - View::new(self, Vec2::<isize>::ZERO, self.size) - } - pub fn view_area<'a>(&'a self, offset: Vec2<isize>, size: Vec2<isize>) -> View<&'a Frame> { - View::new(self, offset, size) - } - pub fn view_area_mut<'a>( - &'a mut self, - offset: Vec2<isize>, - size: Vec2<isize>, - ) -> View<&'a mut Frame> { - View::new(self, offset, size) - } - pub fn set(&mut self, pos: Vec2<isize>, color: Pixel) { - if pos.x >= 0 && pos.y >= 0 && pos.x < self.size.x && pos.y < self.size.y { - self[pos] = color - } - } -} - -impl Index<Vec2<isize>> for Frame { - type Output = Pixel; - #[inline] - fn index(&self, Vec2 { x, y }: Vec2<isize>) -> &Self::Output { - &self.buffer - [(x.clamp(0, self.size.x - 1) + y.clamp(0, self.size.y - 1) * self.size.x) as usize] - } -} -impl IndexMut<Vec2<isize>> for Frame { - #[inline] - fn index_mut(&mut self, Vec2 { x, y }: Vec2<isize>) -> &mut Self::Output { - &mut self.buffer[(x + y * self.size.x) as usize] - } -} - -impl Frame { - #[inline] - pub fn sample(&self, p: Vec2<f32>) -> Pixel { - self[Vec2 { - x: p.x as isize, - y: p.y as isize, - }] - // let fx = p.x.floor() as isize; - // let fy = p.y.floor() as isize; - // let cx = p.x.ceil() as isize; - // let cy = p.y.ceil() as isize; - - // // TODO dont loose accuracy here - // Pixel::average( - // Pixel::average(self[Vec2 { x: fx, y: fy }], self[Vec2 { x: fx, y: cy }]), - // Pixel::average(self[Vec2 { x: cx, y: fx }], self[Vec2 { x: cx, y: fy }]), - // ) - } -} - -impl Index<(isize, isize)> for Frame { - type Output = Pixel; - #[inline] - fn index(&self, (x, y): (isize, isize)) -> &Self::Output { - &self[Vec2 { x, y }] - } -} -impl IndexMut<(isize, isize)> for Frame { - #[inline] - fn index_mut(&mut self, (x, y): (isize, isize)) -> &mut Self::Output { - &mut self[Vec2 { x, y }] - } -} diff --git a/evc/src/helpers/matrix.rs b/evc/src/helpers/matrix.rs deleted file mode 100644 index 0007440..0000000 --- a/evc/src/helpers/matrix.rs +++ /dev/null @@ -1,33 +0,0 @@ -use crate::helpers::vector::Vec2; - -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct Mat2<T> { - pub a: T, - pub b: T, - pub c: T, - pub d: T, -} - -impl<T: std::ops::Mul<Output = T> + std::ops::Add<Output = T> + Copy> Mat2<T> { - #[inline] - pub fn transform(&self, v: Vec2<T>) -> Vec2<T> { - Vec2 { - x: self.a * v.x + self.b * v.y, - y: self.c * v.x + self.d * v.y, - } - } -} - -impl<T: std::ops::Mul<Output = T> + std::ops::Add<Output = T> + Copy> std::ops::Mul for Mat2<T> { - type Output = Mat2<T>; - #[inline] - fn mul(self, rhs: Mat2<T>) -> Mat2<T> { - let (x, y) = (self, rhs); - Mat2 { - a: x.a * y.a + x.b * y.c, - b: x.a * y.b + x.b * y.d, - c: x.c * y.a + x.d * y.c, - d: x.c * y.b + x.d * y.d, - } - } -} diff --git a/evc/src/helpers/mod.rs b/evc/src/helpers/mod.rs deleted file mode 100644 index d3aa3d2..0000000 --- a/evc/src/helpers/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod vector; -pub mod threading; -pub mod matrix; -pub mod pixel; diff --git a/evc/src/helpers/pixel.rs b/evc/src/helpers/pixel.rs deleted file mode 100644 index 39fe98c..0000000 --- a/evc/src/helpers/pixel.rs +++ /dev/null @@ -1,81 +0,0 @@ -use crate::format::ser::{Ser, Sink, Source}; - -#[derive(Copy, Clone, Debug, Default, PartialEq)] -pub struct Pixel { - pub r: u8, - pub g: u8, - pub b: u8, -} - -impl Ser for Pixel { - fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> { - sink.put((self.r, self.g, self.b)) - } - - fn read(source: &mut impl std::io::Read) -> anyhow::Result<Self> { - let (r, g, b) = source.get()?; - Ok(Self { r, g, b }) - } -} - -impl Pixel { - pub const BLACK: Pixel = Pixel { r: 0, g: 0, b: 0 }; - #[inline] - pub fn distance(a: Pixel, b: Pixel) -> usize { - let (rd, gd, bd) = ( - a.r.abs_diff(b.r) as usize, - a.g.abs_diff(b.g) as usize, - a.b.abs_diff(b.b) as usize, - ); - // fast_sqrt(rd * rd + gd * gd + bd * bd) - // SQRT[rd + gd + bd] - rd + gd + bd - } - - #[inline] - pub fn average(a: Pixel, b: Pixel) -> Pixel { - Pixel { - r: ((a.r as u16 + b.r as u16) >> 1) as u8, - g: ((a.g as u16 + b.g as u16) >> 1) as u8, - b: ((a.b as u16 + b.b as u16) >> 1) as u8, - } - } - - #[inline] - pub fn scale(&self, factor: f32) -> Pixel { - Pixel { - r: ((self.r as f32) * factor).clamp(0.0, 255.0) as u8, - g: ((self.g as f32) * factor).clamp(0.0, 255.0) as u8, - b: ((self.b as f32) * factor).clamp(0.0, 255.0) as u8, - } - } -} - -pub const SQRT: [usize; 256 * 3] = gen_sqrt_lookup(); - -const fn gen_sqrt_lookup<const N: usize>() -> [usize; N] { - let mut arr = [0; N]; - let mut i = 0; - while i < N { - arr[i] = sqrt(i as f32) as usize; - i += 1; - } - arr -} - -const fn sqrt(x: f32) -> f32 { - let a = 1.0; - let a = (a + x / a) * 0.5; - let a = (a + x / a) * 0.5; - let a = (a + x / a) * 0.5; - a -} - -pub fn fast_sqrt(x: usize) -> usize { - let a = 1; - let a = (a + x / (a + 1)) / 2; - let a = (a + x / (a + 1)) / 2; - // let a = (a + x / (a + 1)) / 2; - // let a = (a + x / (a + 1)) / 2; - a -} diff --git a/evc/src/helpers/threading.rs b/evc/src/helpers/threading.rs deleted file mode 100644 index 3291172..0000000 --- a/evc/src/helpers/threading.rs +++ /dev/null @@ -1,26 +0,0 @@ -use std::{ - sync::atomic::{AtomicUsize, Ordering}, - thread, -}; - -static THREADS_RUNNING: AtomicUsize = AtomicUsize::new(0); - -pub fn both_par<F1, F2, O1, O2>(f1: F1, f2: F2, max_threads: usize) -> (O1, O2) -where - F1: FnOnce() -> O1 + Send + 'static, - O1: Send + 'static, - F2: FnOnce() -> O2, -{ - if THREADS_RUNNING.load(Ordering::Relaxed) < max_threads { - THREADS_RUNNING.fetch_add(1, Ordering::Relaxed); - - let o1h = thread::spawn(move || f1()); - let o2 = f2(); - let o1 = o1h.join().unwrap(); - - THREADS_RUNNING.fetch_sub(1, Ordering::Relaxed); - (o1, o2) - } else { - (f1(), f2()) - } -} diff --git a/evc/src/helpers/vector.rs b/evc/src/helpers/vector.rs deleted file mode 100644 index a4766d1..0000000 --- a/evc/src/helpers/vector.rs +++ /dev/null @@ -1,126 +0,0 @@ -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub struct Vec2<T> { - pub x: T, - pub y: T, -} - -impl From<Vec2<isize>> for Vec2<u16> { - fn from(value: Vec2<isize>) -> Self { - Self { - x: value.x as u16, - y: value.y as u16, - } - } -} -impl From<Vec2<u16>> for Vec2<isize> { - fn from(value: Vec2<u16>) -> Self { - Self { - x: value.x as isize, - y: value.y as isize, - } - } -} -impl From<Vec2<f32>> for Vec2<isize> { - fn from(value: Vec2<f32>) -> Self { - Self { - x: value.x as isize, - y: value.y as isize, - } - } -} - -impl Vec2<isize> { - pub const ZERO: Vec2<isize> = Vec2 { x: 0, y: 0 }; - pub const UP: Vec2<isize> = Vec2 { x: 0, y: -1 }; - pub const LEFT: Vec2<isize> = Vec2 { x: -1, y: 0 }; -} -impl Vec2<f32> { - pub const ZERO: Vec2<f32> = Vec2 { x: 0.0, y: 0.0 }; - pub const UP: Vec2<f32> = Vec2 { x: 0.0, y: -1.0 }; - pub const LEFT: Vec2<f32> = Vec2 { x: -1.0, y: 0.0 }; -} - -impl<T: std::ops::Div<Output = T> + Copy> Vec2<T> { - pub fn downscale(&self, f: T) -> Self { - Self { - x: self.x / f, - y: self.y / f, - } - } -} - -impl<T: std::ops::Mul<Output = T> + Copy> Vec2<T> { - pub fn scale(&self, f: T) -> Self { - Self { - x: self.x * f, - y: self.y * f, - } - } - pub fn area(&self) -> T { - self.x * self.y - } -} - -impl Vec2<isize> { - pub fn x_only(&self) -> Self { - Self { x: self.x, y: 0 } - } - pub fn y_only(&self) -> Self { - Self { x: 0, y: self.y } - } -} - -impl Into<Vec2<f32>> for Vec2<isize> { - fn into(self) -> Vec2<f32> { - Vec2 { - x: self.x as f32, - y: self.y as f32, - } - } -} -impl From<(isize, isize)> for Vec2<f32> { - fn from((x, y): (isize, isize)) -> Self { - Vec2 { - x: x as f32, - y: y as f32, - } - } -} - -impl<T: std::ops::Add> std::ops::Add for Vec2<T> { - type Output = Vec2<T::Output>; - #[inline] - fn add(self, rhs: Self) -> Self::Output { - Vec2 { - x: self.x + rhs.x, - y: self.y + rhs.y, - } - } -} -impl<T: std::ops::Sub> std::ops::Sub for Vec2<T> { - type Output = Vec2<T::Output>; - #[inline] - fn sub(self, rhs: Self) -> Self::Output { - Vec2 { - x: self.x - rhs.x, - y: self.y - rhs.y, - } - } -} -impl<T: std::ops::Mul> std::ops::Mul for Vec2<T> { - type Output = Vec2<T::Output>; - #[inline] - fn mul(self, rhs: Self) -> Self::Output { - Vec2 { - x: self.x * rhs.x, - y: self.y * rhs.y, - } - } -} - -impl<T> From<(T, T)> for Vec2<T> { - #[inline] - fn from((x, y): (T, T)) -> Self { - Vec2 { x, y } - } -} diff --git a/evc/src/lib.rs b/evc/src/lib.rs deleted file mode 100644 index d269471..0000000 --- a/evc/src/lib.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![feature(box_patterns)] -#![feature(const_fn_floating_point_arithmetic)] -// #![feature(const_for)] -// #![feature(const_mut_refs)] - -pub mod block; -pub mod codec; -pub mod debug; -pub mod frame; -pub mod view; -pub mod refsampler; -pub mod helpers; -pub mod format; diff --git a/evc/src/refsampler.rs b/evc/src/refsampler.rs deleted file mode 100644 index 8a8f44f..0000000 --- a/evc/src/refsampler.rs +++ /dev/null @@ -1,51 +0,0 @@ -use crate::{ - block::AdvancedReference, - format::ser::map_scalar8, - frame::Frame, - helpers::{matrix::Mat2, pixel::Pixel, vector::Vec2}, - view::View, -}; - -#[derive(Debug, Clone)] -pub struct Sampler<'a> { - pub view: View<&'a Frame>, - pub halfsize: Vec2<f32>, - - pub translation: Vec2<f32>, - pub transform: Mat2<f32>, - - pub value_scale: f32, -} - -impl<'a> Sampler<'a> { - #[inline] - pub fn sample(&self, p: Vec2<f32>) -> Pixel { - self.view - .sample(self.translation + self.transform.transform(p - self.halfsize) + self.halfsize) - .scale(self.value_scale) - } - pub fn from_refblock( - view: View<&'a Frame>, - AdvancedReference { - translation, - transform, - value_scale, - }: &AdvancedReference, - ) -> Self { - Self { - transform: Mat2 { - a: map_scalar8(transform.a), - b: map_scalar8(transform.b), - c: map_scalar8(transform.c), - d: map_scalar8(transform.d), - }, - halfsize: Into::<Vec2<f32>>::into(view.size).scale(0.5), - translation: Vec2 { - x: map_scalar8(translation.x), - y: map_scalar8(translation.y), - }, - value_scale: 1.05f32.powf(*value_scale as f32), - view, - } - } -} diff --git a/evc/src/view.rs b/evc/src/view.rs deleted file mode 100644 index 6f34965..0000000 --- a/evc/src/view.rs +++ /dev/null @@ -1,241 +0,0 @@ -use crate::{ - frame::Frame, - helpers::{pixel::Pixel, vector::Vec2}, - refsampler::Sampler, -}; -use std::ops::{Index, IndexMut}; - -#[derive(Debug, Clone)] -pub struct View<T> { - pub frame: T, - pub offset: Vec2<isize>, - pub size: Vec2<isize>, -} - -impl<T> View<T> { - pub fn new(frame: T, offset: Vec2<isize>, size: Vec2<isize>) -> Self { - Self { - frame, - offset, - size, - } - } - pub fn area(&self) -> isize { - self.size.x * self.size.y - } - pub fn center(&self) -> Vec2<isize> { - self.offset + self.size.downscale(2) - } -} - -impl<T> View<&mut T> { - pub fn split_mut_unsafe(&mut self) -> [Self; 2] { - let vert = self.size.x > self.size.y; - [ - Self { - frame: unsafe { std::mem::transmute::<&mut T, &mut T>(&mut self.frame) }, - offset: self.offset, - size: if vert { - Vec2 { - x: self.size.x / 2, - y: self.size.y, - } - } else { - Vec2 { - x: self.size.x, - y: self.size.y / 2, - } - }, - }, - Self { - frame: unsafe { std::mem::transmute::<&mut T, &mut T>(&mut self.frame) }, - offset: if vert { - Vec2 { - x: self.offset.x + self.size.x / 2, - y: self.offset.y, - } - } else { - Vec2 { - x: self.offset.x, - y: self.offset.y + self.size.y / 2, - } - }, - size: if vert { - Vec2 { - x: self.size.x - self.size.x / 2, - y: self.size.y, - } - } else { - Vec2 { - x: self.size.x, - y: self.size.y - self.size.y / 2, - } - }, - }, - ] - } -} -impl<T: Copy> View<T> { - pub fn offset(&self, offset: Vec2<isize>) -> Self { - Self { - frame: self.frame, - offset: self.offset + offset, - size: self.size, - } - } - pub fn split(&self) -> [Self; 2] { - let vert = self.size.x > self.size.y; - [ - Self { - frame: self.frame, - offset: self.offset, - size: if vert { - Vec2 { - x: self.size.x / 2, - y: self.size.y, - } - } else { - Vec2 { - x: self.size.x, - y: self.size.y / 2, - } - }, - }, - Self { - frame: self.frame, - offset: if vert { - Vec2 { - x: self.offset.x + self.size.x / 2, - y: self.offset.y, - } - } else { - Vec2 { - x: self.offset.x, - y: self.offset.y + self.size.y / 2, - } - }, - size: if vert { - Vec2 { - x: self.size.x - self.size.x / 2, - y: self.size.y, - } - } else { - Vec2 { - x: self.size.x, - y: self.size.y - self.size.y / 2, - } - }, - }, - ] - } -} -impl<T: Index<Vec2<isize>, Output = Pixel>> View<&T> { - pub fn diff(va: &Self, vb: &Self) -> f64 { - assert_eq!(va.size, vb.size); - let mut acc = 0; - for x in 0..va.size.x { - for y in 0..va.size.y { - let a = va[(x, y)]; - let b = vb[(x, y)]; - acc += Pixel::distance(a, b); - } - } - acc as f64 - } - pub fn diff_sampler(va: &Self, vb: &Sampler<'_>) -> f64 { - assert_eq!(va.size, vb.view.size); - let mut acc = 0; - for x in 0..va.size.x { - for y in 0..va.size.y { - let a = va[(x, y)]; - let b = vb.sample(Vec2 { - x: x as f32, - y: y as f32, - }); - acc += Pixel::distance(a, b); - } - } - acc as f64 - } - - pub fn pixels(&self) -> Vec<Pixel> { - let mut v = vec![]; - for y in 0..self.size.y { - for x in 0..self.size.x { - v.push(self[(x, y)]); - } - } - v - } -} -impl View<&mut Frame> { - pub fn copy_from(&mut self, other: &View<&Frame>) { - for x in 0..self.size.x { - for y in 0..self.size.y { - self[(x, y)] = other[(x, y)]; - } - } - } - pub fn copy_from_sampler(&mut self, other: &Sampler) { - for x in 0..self.size.x { - for y in 0..self.size.y { - self[(x, y)] = other.sample((x, y).into()); - } - } - } - - pub fn set_pixels(&mut self, pixels: &Vec<Pixel>) { - for y in 0..self.size.y { - for x in 0..self.size.x { - self[(x, y)] = pixels[(y * self.size.x + x) as usize] - } - } - } -} -impl View<&Frame> { - pub fn sample(&self, p: Vec2<f32>) -> Pixel { - self.frame.sample(p + self.offset.into()) - } -} - -impl<T: Index<Vec2<isize>, Output = Pixel>> Index<Vec2<isize>> for View<&T> { - type Output = Pixel; - #[inline] - fn index(&self, p: Vec2<isize>) -> &Self::Output { - &self.frame[self.offset + p] - } -} -impl<T: Index<Vec2<isize>, Output = Pixel>> Index<Vec2<isize>> for View<&mut T> { - type Output = Pixel; - #[inline] - fn index(&self, p: Vec2<isize>) -> &Self::Output { - &self.frame[self.offset + p] - } -} -impl<T: IndexMut<Vec2<isize>, Output = Pixel>> IndexMut<Vec2<isize>> for View<&mut T> { - #[inline] - fn index_mut(&mut self, p: Vec2<isize>) -> &mut Self::Output { - &mut self.frame[self.offset + p] - } -} - -impl<T: Index<Vec2<isize>, Output = Pixel>> Index<(isize, isize)> for View<&T> { - type Output = Pixel; - #[inline] - fn index(&self, (x, y): (isize, isize)) -> &Self::Output { - &self[Vec2 { x, y }] - } -} -impl<T: Index<Vec2<isize>, Output = Pixel>> Index<(isize, isize)> for View<&mut T> { - type Output = Pixel; - #[inline] - fn index(&self, (x, y): (isize, isize)) -> &Self::Output { - &self[Vec2 { x, y }] - } -} -impl<T: IndexMut<Vec2<isize>, Output = Pixel>> IndexMut<(isize, isize)> for View<&mut T> { - #[inline] - fn index_mut(&mut self, (x, y): (isize, isize)) -> &mut Self::Output { - &mut self[Vec2 { x, y }] - } -} |