From 5a2fc9c2a63480bdaa0d75b40473b8fe969d7194 Mon Sep 17 00:00:00 2001 From: stefanos kouroupis Date: Sat, 3 Jun 2023 23:12:47 +0100 Subject: [PATCH] first commit --- .gitignore | 1 + Cargo.lock | 710 +++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 11 + README.md | 8 + examples/001.png | Bin 0 -> 30341 bytes examples/002.png | Bin 0 -> 28501 bytes src/main.rs | 164 +++++++++++ 7 files changed, 894 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 README.md create mode 100644 examples/001.png create mode 100644 examples/002.png create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..4e7c255 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,710 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "bytemuck" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[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.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + +[[package]] +name = "exr" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdd2162b720141a91a054640662d3edce3d50a944a50ffca5313cd951abb35b4" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide 0.6.2", + "rayon-core", + "smallvec", + "zune-inflate", +] + +[[package]] +name = "fdeflate" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +dependencies = [ + "crc32fast", + "miniz_oxide 0.7.1", +] + +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "pin-project", + "spin", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "getrandom" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gif" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "half" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" +dependencies = [ + "crunchy", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "image" +version = "0.24.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-rational", + "num-traits", + "png", + "qoi", + "tiff", +] + +[[package]] +name = "image-peek" +version = "0.1.0" +dependencies = [ + "image", + "termsize", + "yansi", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" +dependencies = [ + "rayon", +] + +[[package]] +name = "js-sys" +version = "0.3.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + +[[package]] +name = "libc" +version = "0.2.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" + +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", + "simd-adler32", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + +[[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-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-integer", + "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 = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi 0.2.6", + "libc", +] + +[[package]] +name = "numtoa" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" + +[[package]] +name = "once_cell" +version = "1.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" + +[[package]] +name = "pin-project" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "png" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaeebc51f9e7d2c150d3f3bfeb667f2aa985db5ef1e3d212847bdedb488beeaa" +dependencies = [ + "bitflags", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide 0.7.1", +] + +[[package]] +name = "proc-macro2" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quote" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_termios" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8440d8acb4fd3d277125b4bd01a6f38aee8d814b3b5fc09b3f2b825d37d3fe8f" +dependencies = [ + "redox_syscall", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "simd-adler32" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f" + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "syn" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termion" +version = "1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "077185e2eac69c3f8379a4298e1e07cd36beb962290d4a51199acf0fdc10607e" +dependencies = [ + "libc", + "numtoa", + "redox_syscall", + "redox_termios", +] + +[[package]] +name = "termsize" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e86d824a8e90f342ad3ef4bd51ef7119a9b681b0cc9f8ee7b2852f02ccd2517" +dependencies = [ + "atty", + "kernel32-sys", + "libc", + "termion", + "winapi 0.2.8", +] + +[[package]] +name = "tiff" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + +[[package]] +name = "unicode-ident" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" + +[[package]] +name = "weezl" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + +[[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-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + +[[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-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..ba52df6 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "image-peek" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +image = "0.24.6" +termsize = "0.1.6" +yansi = "0.5.1" diff --git a/README.md b/README.md new file mode 100644 index 0000000..4bf3562 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# image peek + +this is a small utility application written in rust to preview images in the terminal. + +![Image](./examples/001.png) + +![Image](./examples/002.png) + diff --git a/examples/001.png b/examples/001.png new file mode 100644 index 0000000000000000000000000000000000000000..8c83a68cbf057b0d724dc18e12a3cee89cae0da0 GIT binary patch literal 30341 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 literal 0 HcmV?d00001 diff --git a/examples/002.png b/examples/002.png new file mode 100644 index 0000000000000000000000000000000000000000..ee47fe60d25346b00578f8598d591c180f26564e GIT binary patch literal 28501 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 = env::args().collect(); + let filename = &args[1]; + let vip_char = '█'; + + let img = image::open(filename).unwrap(); + + let (term_height, term_width) = termsize::get().map(|size| (size.rows, size.cols)).unwrap(); + let (image_width, image_height) = img.dimensions(); + + let scaler = if image_height > image_width && term_height > term_width { + ( + MatchDimension::BBh, + image_height, + term_height, + image_width as f32 / image_height as f32, + ) + } else if image_height < image_width && term_height > term_width { + ( + MatchDimension::BS, + image_width, + term_height, + image_height as f32 / image_width as f32, + ) + } else if image_height > image_width && term_height < term_width { + ( + MatchDimension::SB, + image_height, + term_width, + image_width as f32 / image_height as f32, + ) + } else if image_height < image_width && term_height < term_width { + ( + MatchDimension::BBw, + image_width, + term_width, + image_height as f32 / image_width as f32, + ) + } else { + panic!("Something went wrong") + }; + + match scaler.0 { + MatchDimension::BBh => { + let ratio: f32 = image_height as f32 / term_height as f32; + + for y in 0..term_height as u32 { + if y % 2 == 0 { + continue; + } + + for x in 0..(term_height as f32 * scaler.3) as u32 { + let new_x = (x as f32 * ratio) as u32; + let new_y = (y as f32 * ratio) as u32; + + let x_d = if new_x < img.dimensions().0 { + new_x + } else { + img.dimensions().0 - 1 + }; + let y_d = if new_y < img.dimensions().1 { + new_y + } else { + img.dimensions().1 - 1 + }; + + let pixel = img.get_pixel(x_d, y_d); + print!("{}", Paint::rgb(pixel[0], pixel[1], pixel[2], vip_char)); + } + } + } + MatchDimension::BS => { + let ratio: f32 = image_width as f32 / term_width as f32; + + for y in 0..(term_width as f32 * scaler.3) as u32 { + if y % 2 == 0 { + continue; + } + for x in 0..term_width as u32 { + let new_x = (x as f32 * ratio) as u32; + let new_y = (y as f32 * ratio) as u32; + let x_d = if new_x < img.dimensions().0 { + new_x + } else { + img.dimensions().0 - 1 + }; + let y_d = if new_y < img.dimensions().1 { + new_y + } else { + img.dimensions().1 - 1 + }; + let pixel = img.get_pixel(x_d, y_d); + print!("{}", Paint::rgb(pixel[0], pixel[1], pixel[2], vip_char)); + } + println!(); + } + } + MatchDimension::SB => { + let ratio: f32 = image_height as f32 / term_height as f32; + + for y in 0..term_height as u32 { + if y % 2 == 0 { + continue; + } + + for x in 0..(term_height as f32 * scaler.3) as u32 { + let new_x = (x as f32 * ratio) as u32; + let new_y = (y as f32 * ratio) as u32; + let x_d = if new_x < img.dimensions().0 { + new_x + } else { + img.dimensions().0 - 1 + }; + let y_d = if new_y < img.dimensions().1 { + new_y + } else { + img.dimensions().1 - 1 + }; + let pixel = img.get_pixel(x_d, y_d); + print!("{}", Paint::rgb(pixel[0], pixel[1], pixel[2], vip_char)); + } + println!(); + } + } + MatchDimension::BBw => { + let ratio: f32 = image_height as f32 / term_height as f32; + + for y in 0..(term_height as f32 * scaler.3) as u32 { + if y % 2 == 0 { + continue; + } + for x in 0..term_height as u32 { + let new_x = (x as f32 * ratio) as u32; + let new_y = (y as f32 * ratio) as u32; + let x_d = if new_x < img.dimensions().0 { + new_x + } else { + img.dimensions().0 - 1 + }; + let y_d = if new_y < img.dimensions().1 { + new_y + } else { + img.dimensions().1 - 1 + }; + let pixel = img.get_pixel(x_d, y_d); + print!("{}", Paint::rgb(pixel[0], pixel[1], pixel[2], vip_char)); + } + println!(); + } + } + } +}