termimage/util.rs
1//! Module containing various utility functions.
2
3
4use std::iter;
5use image::Rgb;
6use std::ops::Index;
7
8
9/// Magic number used for determining whether an image is a BMP.
10///
11/// Source: [Wikipedia](https://en.wikipedia.org/wiki/List_of_file_signatures).
12pub static BMP_MAGIC: &[u8] = &[0x42, 0x4D];
13
14/// Magic number used for determining whether an image is an ICO.
15///
16/// Source: [Wikipedia](https://en.wikipedia.org/wiki/List_of_file_signatures).
17pub static ICO_MAGIC: &[u8] = &[0x00, 0x00, 0x01, 0x00];
18
19/// Magic number used for determining whether an image is a GIF.
20///
21/// Source: [Wikipedia](https://en.wikipedia.org/wiki/List_of_file_signatures).
22pub static GIF_MAGIC: &[u8] = &[0x47, 0x49, 0x46, 0x38];
23
24/// Magic number used for determining whether an image is a PNG.
25///
26/// Source: [Wikipedia](https://en.wikipedia.org/wiki/List_of_file_signatures).
27pub static PNG_MAGIC: &[u8] = &[0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A];
28
29/// Magic number used for determining whether an image is a JPEG.
30///
31/// Source: [Wikipedia](https://en.wikipedia.org/wiki/List_of_file_signatures).
32pub static JPEG_MAGIC: &[u8] = &[0xFF, 0xD8, 0xFF, 0xE0];
33
34
35/// ANSI colours for a white-background terminal, in the same order as `ANSI_COLOUR_ESCAPES`.
36///
37/// Acquired from screenshot provided by [@Ell](https://github.com/elliotpotts):
38///
39/// 
40pub static ANSI_COLOURS_WHITE_BG: [Rgb<u8>; 16] = [Rgb([0xEE, 0xE8, 0xD5]),
41 Rgb([0xDC, 0x32, 0x2F]),
42 Rgb([0x85, 0x99, 0x00]),
43 Rgb([0xB5, 0x89, 0x00]),
44 Rgb([0x26, 0x8B, 0xD2]),
45 Rgb([0xD3, 0x36, 0x82]),
46 Rgb([0x2A, 0xA1, 0x98]),
47 Rgb([0x07, 0x36, 0x42]),
48
49 Rgb([0xFD, 0xF6, 0xE3]),
50 Rgb([0xCB, 0x4B, 0x16]),
51 Rgb([0x93, 0xA1, 0xA1]),
52 Rgb([0x83, 0x94, 0x96]),
53 Rgb([0x65, 0x7B, 0x83]),
54 Rgb([0x6C, 0x71, 0xC4]),
55 Rgb([0x58, 0x6E, 0x75]),
56 Rgb([0x00, 0x2B, 0x36])];
57
58/// Linux-theme ANSI colours, in the same order as `ANSI_COLOUR_ESCAPES`.
59///
60/// Acquired from the [`colorname` table in st](https://git.suckless.org/st/file/config.def.h.html#l86),
61/// as decoded according to the [X11 colour names Wikipedia article](https://en.wikipedia.org/wiki/X11_color_names):
62///
63/// ```c
64/// static const char *colorname[] = {
65/// /* 8 normal colors */
66/// "black",
67/// "red3",
68/// "green3",
69/// "yellow3",
70/// "blue2",
71/// "magenta3",
72/// "cyan3",
73/// "gray90",
74///
75/// /* 8 bright colors */
76/// "gray50",
77/// "red",
78/// "green",
79/// "yellow",
80/// "#5c5cff",
81/// "magenta",
82/// "cyan",
83/// "white",
84///
85/// // …
86/// }
87/// ```
88pub static ANSI_COLOURS_BLACK_BG: [Rgb<u8>; 16] = [Rgb([0x00, 0x00, 0x00]),
89 Rgb([0xCD, 0x00, 0x00]),
90 Rgb([0x00, 0xCD, 0x00]),
91 Rgb([0xCD, 0xCD, 0x00]),
92 Rgb([0x00, 0x00, 0xEE]),
93 Rgb([0xCD, 0x00, 0xCD]),
94 Rgb([0x00, 0xCD, 0xCD]),
95 Rgb([0xE6, 0xE6, 0xE6]),
96
97 Rgb([0x80, 0x80, 0x80]),
98 Rgb([0xFF, 0x00, 0x00]),
99 Rgb([0x00, 0xFF, 0x00]),
100 Rgb([0xFF, 0xFF, 0x00]),
101 Rgb([0x5C, 0x5C, 0xFF]),
102 Rgb([0xFF, 0x00, 0xFF]),
103 Rgb([0x00, 0xFF, 0xFF]),
104 Rgb([0xFF, 0xFF, 0xFF])];
105
106/// ANSI background colour escapes.
107pub static ANSI_COLOUR_ESCAPES: [&str; 16] = ["\x1B[0;30m",
108 "\x1B[0;31m",
109 "\x1B[0;32m",
110 "\x1B[0;33m",
111 "\x1B[0;34m",
112 "\x1B[0;35m",
113 "\x1B[0;36m",
114 "\x1B[0;37m",
115 "\x1B[1;30m",
116 "\x1B[1;31m",
117 "\x1B[1;32m",
118 "\x1B[1;33m",
119 "\x1B[1;34m",
120 "\x1B[1;35m",
121 "\x1B[1;36m",
122 "\x1B[1;37m"];
123
124/// ANSI background colour escapes.
125pub static ANSI_BG_COLOUR_ESCAPES: [&str; 8] = ["\x1B[40m", "\x1B[41m", "\x1B[42m", "\x1B[43m", "\x1B[44m", "\x1B[45m", "\x1B[46m", "\x1B[47m"];
126
127/// Reset ANSI attributes
128pub static ANSI_RESET_ATTRIBUTES: &str = "\x1B[0m";
129
130
131/// Create a string consisting of `n` repetitions of `what`.
132///
133/// # Examples
134///
135/// ```
136/// # use termimage::util::mul_str;
137/// assert_eq!(mul_str("Го! ", 3), "Го! Го! Го! ".to_string());
138/// ```
139pub fn mul_str(what: &str, n: usize) -> String {
140 iter::repeat(what).take(n).collect()
141}
142
143/// Get the closest colour to the provided one out of the specified list of colours and retirn its index.
144///
145/// The formula is the last one from the
146/// [Euclidean section in the Color difference article on Wikipedia](https://en.wikipedia.org/wiki/Color_difference#Euclidean)
147pub fn closest_colour<P: Index<usize, Output = u8>>(to: Rgb<u8>, out_of: &[P]) -> usize {
148 let mut diffs = out_of.iter()
149 .enumerate()
150 .map(|(i, rgb)| {
151 let r = (rgb[0] as f32 + to[0] as f32) / 2.0;
152 ((2.0 + (r / 256.0)) * (rgb[0] as f32 - to[0] as f32).powi(2) + 4.0 * (rgb[1] as f32 - to[1] as f32).powi(2) +
153 (2.0 + ((255.0 - r) / 256.0)) * (rgb[2] as f32 - to[2] as f32).powi(2),
154 i)
155 })
156 .collect::<Vec<_>>();
157 diffs.sort_by(|&(lhs_diff, _), &(rhs_diff, _)| lhs_diff.partial_cmp(&rhs_diff).unwrap());
158 diffs[0].1
159}
160
161/// Get the background colour set for the specified foregournd colour set
162#[inline(always)]
163pub fn bg_colours_for<C: Index<usize, Output = u8>>(foreground_colours: &[C]) -> &[C] {
164 &foreground_colours[0..8]
165}