From 7fa6be6ff413472df9d15e0b2b3ef646b3afe2e0 Mon Sep 17 00:00:00 2001 From: Dennis Ranke Date: Mon, 24 Oct 2022 23:34:07 +0200 Subject: [PATCH] implement printing heatmap as hexdump --- Cargo.lock | 470 ++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 4 +- src/heatmap.rs | 89 ++++++++++ src/main.rs | 22 ++- 4 files changed, 567 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b35884..a9b7b51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,15 @@ checksum = "38d9ff5d688f1c13395289f67db01d4826b46dd694e7580accdc3e8430f2d98e" [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "cc" @@ -30,19 +36,34 @@ dependencies = [ "sacabase", ] +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + [[package]] name = "crossbeam-channel" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "crossbeam-utils", ] @@ -52,10 +73,95 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "lazy_static", ] +[[package]] +name = "crossterm" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "207a948d1b4ff59e5aec9bb9426cc4fd3d17b719e5c7b74e27f0a60c4cc2d095" +dependencies = [ + "bitflags", + "crossterm_winapi 0.6.2", + "lazy_static", + "libc", + "mio 0.6.23", + "parking_lot 0.10.2", + "signal-hook 0.1.17", + "winapi 0.3.9", +] + +[[package]] +name = "crossterm" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" +dependencies = [ + "bitflags", + "crossterm_winapi 0.9.0", + "libc", + "mio 0.8.4", + "parking_lot 0.12.1", + "signal-hook 0.3.14", + "signal-hook-mio", + "winapi 0.3.9", +] + +[[package]] +name = "crossterm_winapi" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2265c3f8e080075d9b6417aa72293fc71662f34b4af2612d8d1b074d29510db" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[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 = "lazy_static" version = "1.4.0" @@ -70,9 +176,91 @@ checksum = "478ee9e62aaeaf5b140bd4138753d1f109765488581444218d3ddda43234f3e8" [[package]] name = "libc" -version = "0.2.108" +version = "0.2.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119" +checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" + +[[package]] +name = "lock_api" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +dependencies = [ + "scopeguard", +] + +[[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.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "mio" +version = "0.6.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" +dependencies = [ + "cfg-if 0.1.10", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow", + "net2", + "slab", + "winapi 0.2.8", +] + +[[package]] +name = "mio" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.36.1", +] + +[[package]] +name = "miow" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + +[[package]] +name = "net2" +version = "0.2.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d0df99cfcd2530b2e694f6e17e7f37b8e26bb23983ac530c0c97408837c631" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "winapi 0.3.9", +] [[package]] name = "num-traits" @@ -83,6 +271,53 @@ dependencies = [ "autocfg", ] +[[package]] +name = "parking_lot" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" +dependencies = [ + "lock_api 0.3.4", + "parking_lot_core 0.7.2", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api 0.4.9", + "parking_lot_core 0.9.4", +] + +[[package]] +name = "parking_lot_core" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" +dependencies = [ + "cfg-if 0.1.10", + "cloudabi", + "libc", + "redox_syscall 0.1.57", + "smallvec", + "winapi 0.3.9", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "windows-sys 0.42.0", +] + [[package]] name = "pbr" version = "1.0.4" @@ -92,7 +327,7 @@ dependencies = [ "crossbeam-channel", "libc", "time", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -113,6 +348,21 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + [[package]] name = "sacabase" version = "2.0.0" @@ -122,6 +372,68 @@ dependencies = [ "num-traits", ] +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "signal-hook" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e31d442c16f047a671b5a71e2161d6e68814012b7f5379d269ebd915fac2729" +dependencies = [ + "libc", + "mio 0.6.23", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio 0.8.4", + "signal-hook 0.3.14", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + [[package]] name = "syn" version = "1.0.101" @@ -133,6 +445,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "terminal" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cd146db3fbe90911d0bb5498a393abda0af71a2c11e287ecb9ae30cf5d43667" +dependencies = [ + "bitflags", + "crossterm 0.15.0", +] + [[package]] name = "thiserror" version = "1.0.36" @@ -160,8 +482,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", - "wasi", - "winapi", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi 0.3.9", ] [[package]] @@ -176,8 +498,10 @@ version = "0.2.0" dependencies = [ "anyhow", "cdivsufsort", + "crossterm 0.25.0", "lexopt", "pbr", + "terminal", "thiserror", ] @@ -187,6 +511,18 @@ version = "0.10.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[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" @@ -197,6 +533,12 @@ dependencies = [ "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" @@ -208,3 +550,113 @@ 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.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", +] + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] diff --git a/Cargo.toml b/Cargo.toml index cea6a5c..9c46128 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,4 +11,6 @@ cdivsufsort = "2" lexopt = "0.2.1" anyhow = "1" thiserror = "1.0.36" -pbr = "1" \ No newline at end of file +pbr = "1" +crossterm = { version = "0.25.0", default-features = false } +terminal = { version = "0.2.1", default-features = false, features = ["crossterm-backend"] } diff --git a/src/heatmap.rs b/src/heatmap.rs index 9d507a6..663f649 100644 --- a/src/heatmap.rs +++ b/src/heatmap.rs @@ -71,4 +71,93 @@ impl Heatmap { pub fn byte(&self, index: usize) -> u8 { self.data[index] } + + pub fn print_as_hex(&self) -> std::io::Result<()> { + use crossterm::{ + style::{Attribute, Color, Print, SetAttribute, SetBackgroundColor}, + QueueableCommand, + }; + use std::io::{stdout, Write}; + + fn set_color( + mut out: impl QueueableCommand, + heatmap: &Heatmap, + index: usize, + num_colors: u16, + ) -> std::io::Result<()> { + let cost = heatmap.cost(index); + if num_colors < 256 { + let colors = [ + Color::Red, + Color::Yellow, + Color::Green, + Color::Cyan, + Color::Blue, + Color::DarkBlue, + Color::Black, + ]; + let color_index = (3. - cost.log2()) + .round() + .max(0.) + .min((colors.len() - 1) as f32) as usize; + out.queue(SetBackgroundColor(colors[color_index]))?; + } else { + let colors = [ + 196, 166, 136, 106, 76, 46, 41, 36, 31, 26, 21, 20, 19, 18, 17, 16, + ]; + let color_index = ((3. - cost.log2()) * 2.5) + .round() + .max(0.) + .min((colors.len() - 1) as f32) as usize; + out.queue(SetBackgroundColor(Color::AnsiValue(colors[color_index])))?; + } + out.queue(SetAttribute(if heatmap.is_literal(index) { + Attribute::Underlined + } else { + Attribute::NoUnderline + }))?; + Ok(()) + } + + let num_colors = crossterm::style::available_color_count(); + + let term_width = crossterm::terminal::size()?.0.min(120) as usize; + let bytes_per_row = (term_width - 8) / 4; + + for row_start in (0..self.data.len()).step_by(bytes_per_row) { + let row_range = row_start..self.data.len().min(row_start + bytes_per_row); + let mut stdout = stdout(); + + stdout.queue(Print(&format!("{:04x} ", row_start)))?; + + for i in row_range.clone() { + set_color(&mut stdout, self, i, num_colors)?; + stdout.queue(Print(&format!("{:02x} ", self.data[i])))?; + } + + let num_spaces = 1 + (bytes_per_row - (row_range.end - row_range.start)) * 3; + let gap: String = std::iter::repeat(' ').take(num_spaces).collect(); + stdout + .queue(SetAttribute(Attribute::Reset))? + .queue(Print(&gap))?; + + for i in row_range.clone() { + set_color(&mut stdout, self, i, num_colors)?; + let byte = self.data[i]; + if byte >= 32 && byte < 127 { + stdout.queue(Print(format!("{}", byte as char)))?; + } else { + stdout.queue(Print("."))?; + } + } + + stdout + .queue(SetAttribute(Attribute::Reset))? + .queue(Print("\n"))?; + + stdout.flush()?; + } + + Ok(()) + } } diff --git a/src/main.rs b/src/main.rs index 242f3c5..c03938f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,7 @@ fn main() -> Result<()> { let mut unpack = false; let mut calculate_margin = false; let mut create_heatmap = false; + let mut do_hexdump = false; let mut level = 2; let mut infile: Option = None; let mut outfile: Option = None; @@ -60,6 +61,7 @@ fn main() -> Result<()> { Short('u') | Long("unpack") => unpack = true, Long("margin") => calculate_margin = true, Long("heatmap") => create_heatmap = true, + Long("hexdump") => do_hexdump = true, Short('l') | Long("level") => level = parser.value()?.parse()?, Short(n) if n.is_ascii_digit() => level = n as u8 - b'0', Short('h') | Long("help") => print_help(0), @@ -160,15 +162,19 @@ fn main() -> Result<()> { if reverse { heatmap.reverse(); } - let mut heatmap_bin = Vec::with_capacity(heatmap.len()); - for i in 0..heatmap.len() { - let cost = (heatmap.cost(i).log2() * 8. + 64.) - .round() - .max(0.) - .min(127.) as u8; - heatmap_bin.push((cost << 1) | heatmap.is_literal(i) as u8); + if do_hexdump { + heatmap.print_as_hex()?; + } else { + let mut heatmap_bin = Vec::with_capacity(heatmap.len()); + for i in 0..heatmap.len() { + let cost = (heatmap.cost(i).log2() * 8. + 64.) + .round() + .max(0.) + .min(127.) as u8; + heatmap_bin.push((cost << 1) | heatmap.is_literal(i) as u8); + } + File::create(outfile(OutFileType::Heatmap))?.write_all(&heatmap_bin)?; } - File::create(outfile(OutFileType::Heatmap))?.write_all(&heatmap_bin)?; } if calculate_margin { println!("{}", upkr::calculate_margin(&data, &config)?);