Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added rust translation of nm2rgb.py #1

Open
wants to merge 12 commits into
base: tint
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.stscreds
.DS_Store
._.DS_Store
**/.DS_Store
**/._.DS_Store
**/.terraform
**/terraform.tfstate.backup
**/node_modules
node_modules
**/tint/target
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
7 changes: 7 additions & 0 deletions tint/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions tint/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "tint"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
19 changes: 13 additions & 6 deletions tint/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Tint
Rust binary will use colors to indicate progress on output listings, faster then the included python version.

This python and shell code use colors to indicate progress on output listings. It is rather slow
and a lot more useful ported to Clang.
shell code use colors to indicate progress on output listings.

The python program nm2rgb.py converts light wavelengths (approx 400nm to 800nm) into RGB colors for display.
The program nm2rgb converts light wavelengths (approx 400nm to 800nm) into RGB colors for display.
In `fn.bash`, the `color_dark` function accepts a numerator (arg1), and denominator (arg2) of a number between
0 and 1 and converts it to terminal color control codes for a dimmed background indicating progress:

Expand All @@ -15,12 +15,19 @@ If you have 150 items to list `color_dark $n 150` will set the nth tint of 150 c
Red has a longer wavelength than blue but the orientation is reversed for aesthetics. The
`color_dark` function also darkens the background colors to work well with light text.

Some shell script to generate this example is in `fn.bash` too, it takes a whole second
to write out 29 colored lines... (!)
Some shell script to generate this example is in `fn.bash` too.

<img src="29cps.png" width="30%">

A translation to C for the `color_dark` function and the `nm2rgb.py` python could
A translation for the `color_dark` function could
make the colors useful, anytime you want to display progress while printing output...

Rust build examples
cargo build
cargo build --release

Swift build example from the tint dir (docker linux)
docker pull swift
docker run -it --rm -v $(pwd)/src:/src swift
swiftc ./src/*.swift -o ./tint
./tint -w 500
12 changes: 8 additions & 4 deletions tint/fn.bash
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@ color_dark () { # numerator (arg1) and denominator (arg2) of a number 0<x<1
local a n="$1" d="$2"
shift 2
# of seq 400 $(dc -e "7k 1 $n / 400 * p") 800
set $(./nm2rgb.py $(dc -e "7k 1 $d / $n * 2 - _400 * p") )
# set $(/Users/ec2-user/Library/Developer/Xcode/DerivedData/tint-gjfmhunlmoqvhfbnhlkhjywvxeie/Build/Products/Debug/tint -n $n -d $d)
# set $(./target/release/tint $(dc -e "7k 1 $d / $n * 2 - _400 * p") )
set $(./target/debug/tint $n $d)
# set the background, with tinted modifications
printf '\033[48;2;%d;%d;%dm' $(( $1 *1000 *47/100 /1000 )) $(( $2 *1000 *33/100 /1000 )) $(( $3 *1000 *59/100 /1000 ))
}
}

export color_reset="\033[0m"

for d in 3 29 ; do
for d in 3 150 ; do
export d
time seq 1 $d | while read n ; do
# echo "n:$n"
# echo "d:$d"
printf "%02x $(color_dark $n $d)%24s${color_reset} %s\n" "$n" "${RANDOM}${RANDOM}${RANDOM}${RANDOM}" "${RANDOM}"
done # n
echo
done # e
done # e

14 changes: 7 additions & 7 deletions tint/nm2rgb.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,32 +59,32 @@ def nm2rgb(wavelength, gamma=0.62):
wavelength = float(wavelength)
if wavelength >= 354.4 and wavelength <= 440: # vs 380-440
attenuation = 0.3 + 0.7 * (wavelength - 380) / (440 - 380)
R = ((-(wavelength - 440) / (440 - 380)) * attenuation) ** gamma
r = ((-(wavelength - 440) / (440 - 380)) * attenuation) ** gamma
G = 0.0
B = (1.0 * attenuation) ** gamma
elif wavelength >= 440 and wavelength <= 490:
R = 0.0
r = 0.0
G = ((wavelength - 440) / (490 - 440)) ** gamma
B = 1.0
elif wavelength >= 490 and wavelength <= 510:
R = 0.0
r = 0.0
G = 1.0
B = (-(wavelength - 510) / (510 - 490)) ** gamma
elif wavelength >= 510 and wavelength <= 580:
R = ((wavelength - 510) / (580 - 510)) ** gamma
r = ((wavelength - 510) / (580 - 510)) ** gamma
G = 1.0
B = 0.0
elif wavelength >= 580 and wavelength <= 645:
R = 1.0
r = 1.0
G = (-(wavelength - 645) / (645 - 580)) ** gamma
B = 0.0
elif wavelength >= 645 and wavelength <= 794.5 : # vs 620-750
attenuation = 0.3 + 0.7 * (750 - wavelength) / (750 - 645)
R = (1.0 * attenuation) ** gamma
r = (1.0 * attenuation) ** gamma
G = 0.0
B = 0.0
else:
R = 0.0
r = 0.0
G = 0.0
B = 0.0
R *= 255
Expand Down
38 changes: 38 additions & 0 deletions tint/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use std::env;
mod nm2rgb;

fn help() {
println!("usage: tint <wavelength> ");
println!("or usage: tint <numerator> <denominator> ");
}

fn main() {
let args: Vec<String> = env::args().collect();

match args.len() {
// no arguments passed
1 => {
help();
println!("Try passing a argument.");
},
// one argument passed
2 => {
let wavelength = args[1].parse::<f32>().unwrap();
nm2rgb::nm2rgb(wavelength);
},
// two arguments passed
3 => {
let n = args[1].parse::<f32>().unwrap();
let d = args[2].parse::<f32>().unwrap();
// wavelength=$(dc -e "7k 1 $d / $n * 2.0 - _400 * p")
let wavelength = (((1.0/d) * n) - 2.0) * -400.0;
//println!("n:{} d:{} wavelength:{}", n,d,wavelength);
nm2rgb::nm2rgb(wavelength);
}
// all the other cases
_ => {
// show a help message
help();
}
}
}
58 changes: 58 additions & 0 deletions tint/src/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// main.swift
// tint
//

//import Foundation
var gamma = 0.62
//print("Start")
let arguments = CommandLine.arguments
func help() {
print("usage: tint -w <wavelength> ");
print(" or: tint -n <numerator> -d <denominator> ");
}

switch arguments.count {
case 1:
help()
case 2:
help()
default:
arguments
}

for argument in arguments {
switch argument {
case "-w":
let i: Int = arguments.firstIndex(of: "-w")!
let wavelength = arguments[(i+1)]
//print("wavelength:" + wavelength)
if let wd = Double(wavelength) {
//print("Float value = \(f)")
if arguments.contains("-g") {
let ig: Int = arguments.firstIndex(of: "-g")!
gamma = Double(arguments[(ig+1)])!
}
print(nm2rgb(wavelength:wd, gamma:gamma).joined(separator: " "))
} else {
print("-w is not followed by a number!")
}
case "-n":
if arguments.contains("-d") {
calcWavelength()
} else {
print("-d required for -n")
}
case "-d":
if arguments.contains("-n") {
continue
} else {
print("-n required for -d")
}
default:
continue
//print(CommandLine.arguments)
//let indexOfArg = CommandLine.arguments.lastIndex(of: argument)
//print(indexOfArg)
}
}
50 changes: 50 additions & 0 deletions tint/src/nm2rgb.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// mod nm2rgb;

/*
This converts a given wavelength of light to an
approximate rGB color value. The wavelength must be given
in nanometers in the range from 380 nm through 750 nm
(789 THz through 400 THz).

Based on code by Dan Bruton
http://www.physics.sfasu.edu/astro/color/spectra.html
and implementation by Noah Spurrier
http://www.noah.org/wiki/Wavelength_to_rGB_in_Python
http://www.noah.org/wiki/canvas.py
*/

pub fn nm2rgb(wavelength: f32) {
//nm2rgb::nm2rgb(wavelength);
let gamma = 0.62;
let mut r = 0.0;
let mut g = 0.0;
let mut b = 0.0;

if wavelength >= 354.4 && wavelength <= 440.0 {
let attenuation = 0.3 + 0.7 * (wavelength - 380.0) / (440.0 - 380.0);
r = f32::powf((-(wavelength - 440.0) / (440.0 - 380.0)) * attenuation, gamma);
b = f32::powf(1.0 * attenuation, gamma);
} else if wavelength >= 440.0 && wavelength <= 490.0 {
g = f32::powf((wavelength - 440.0) / (490.0 - 440.0), gamma);
b = 1.0;
} else if wavelength >= 490.0 && wavelength <= 510.0 {
g = 1.0;
b = f32::powf(-(wavelength - 510.0) / (510.0 - 490.0), gamma);
} else if wavelength >= 510.0 && wavelength <= 580.0 {
r = f32::powf((wavelength - 510.0) / (580.0 - 510.0), gamma);
g = 1.0;
} else if wavelength >= 580.0 && wavelength <= 645.0 {
r = 1.0;
g = f32::powf(-(wavelength - 645.0) / (645.0 - 580.0), gamma);
} else if wavelength >= 645.0 && wavelength <= 794.5 {
let attenuation = 0.3 + 0.7 * (750.0 - wavelength) / (750.0 - 645.0);
r = f32::powf(1.0 * attenuation, gamma);
}

r=(r*255.0).round();
g=(g*255.0).round();
b=(b*255.0).round();

println!("{} {} {} {}", r,g,b,wavelength);
}

67 changes: 67 additions & 0 deletions tint/src/nm2rgb.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
This converts a given wavelength of light to an
approximate RGB color value. The wavelength must be given
in nanometers in the range from 380 nm through 750 nm
(789 THz through 400 THz).

Based on code by Dan Bruton
http://www.physics.sfasu.edu/astro/color/spectra.html
and implementation by Noah Spurrier
http://www.noah.org/wiki/Wavelength_to_RGB_in_Python
http://www.noah.org/wiki/canvas.py
*/

import Foundation

func calcWavelength() {
let ni: Int = arguments.firstIndex(of: "-n")!
let n = Double(arguments[(ni+1)])!

let di: Int = arguments.firstIndex(of: "-d")!
let d = Double(arguments[(di+1)])!

if arguments.contains("-g") {
let ig: Int = arguments.firstIndex(of: "-g")!
gamma = Double(arguments[(ig+1)])!
}

let wavelength = (((1.0/d) * n) - 2.0) * -400.0

print(nm2rgb(wavelength:wavelength, gamma:gamma).joined(separator: " "))
}

func nm2rgb(wavelength: Double, gamma: Double = 0.62) -> Array<String> {
//print("nm2rgb wavelength:" + String(wavelength) )
var R = 0.0;
var G = 0.0;
var B = 0.0;

if wavelength >= 354.4 && wavelength <= 440.0 { // vs 380-440
let attenuation = 0.3 + 0.7 * (wavelength - 380.0) / (440.0 - 380.0);
//print("attenuation:\(attenuation)");
let rc = (-(wavelength - 440) / (440 - 380)) * attenuation
R = pow(Double(rc),gamma)
B = pow((1.0 * attenuation), gamma);
} else if wavelength >= 440.0 && wavelength <= 490.0 {
G = pow(((wavelength - 440.0) / (490.0 - 440.0)), gamma);
B = 1.0;
} else if wavelength >= 490.0 && wavelength <= 510.0 {
G = 1.0;
B = pow((-(wavelength - 510.0) / (510.0 - 490.0)), gamma);
} else if wavelength >= 510.0 && wavelength <= 580.0 {
R = pow(((wavelength - 510.0) / (580.0 - 510.0)), gamma);
G = 1.0;
} else if wavelength >= 580.0 && wavelength <= 645.0 {
R = 1.0;
G = pow((-(wavelength - 645.0) / (645.0 - 580.0)), gamma);
} else if wavelength >= 645.0 && wavelength <= 794.5 {
let attenuation = 0.3 + 0.7 * (750.0 - wavelength) / (750.0 - 645.0);
R = pow((1.0 * attenuation), gamma);
}

R=round(R*255)
G=round(G*255)
B=round(B*255)
//print("\(Int(R)) \(Int(G)) \(Int(B)) \(wavelength)")
return [String(Int(R)), String(Int(G)), String(Int(B)), String(wavelength)]
}
1 change: 1 addition & 0 deletions tint/target/.rustc_info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"rustc_fingerprint":13194118395114947436,"outputs":{"15697416045686424142":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n","stderr":""},"10376369925670944939":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n/Users/ec2-user/.rustup/toolchains/stable-x86_64-apple-darwin\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_feature=\"ssse3\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"macos\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"apple\"\nunix\n","stderr":""},"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.62.0 (a8314ef7d 2022-06-27)\nbinary: rustc\ncommit-hash: a8314ef7d0ec7b75c336af2c9857bfaf43002bfc\ncommit-date: 2022-06-27\nhost: x86_64-apple-darwin\nrelease: 1.62.0\nLLVM version: 14.0.5\n","stderr":""}},"successes":{}}