Implement the correct Brightness/Contrast node algorithm (#1130)

Implement correct brightness/contrast algorithm
This commit is contained in:
Keavon Chambers 2023-04-15 05:15:58 -07:00
parent 0e97f352e9
commit 0ba0b2e309
8 changed files with 398 additions and 25 deletions

View file

@ -5,10 +5,11 @@ use crate::Node;
#[cfg(target_arch = "spirv")]
use spirv_std::num_traits::float::Float;
pub mod color;
pub use self::color::Color;
pub mod adjustments;
pub mod brightness_contrast;
pub mod color;
pub use adjustments::*;
#[derive(Debug, Default)]

View file

@ -285,6 +285,7 @@ pub use hue_shift::HueSaturationNode;
#[cfg(not(target_arch = "spirv"))]
mod hue_shift {
use super::*;
#[derive(Debug)]
pub struct HueSaturationNode<Hue, Saturation, Lightness> {
hue_shift: Hue,
@ -461,21 +462,6 @@ fn vibrance_node(color: Color, vibrance: f64) -> Color {
altered_color.to_gamma_srgb()
}
#[derive(Debug, Clone, Copy)]
pub struct BrightnessContrastNode<Brightness, Contrast> {
brightness: Brightness,
contrast: Contrast,
}
// From https://stackoverflow.com/questions/2976274/adjust-bitmap-image-brightness-contrast-using-c
#[node_macro::node_fn(BrightnessContrastNode)]
fn adjust_image_brightness_and_contrast(color: Color, brightness: f64, contrast: f64) -> Color {
let (brightness, contrast) = (brightness as f32, contrast as f32);
let factor = (259. * (contrast + 255.)) / (255. * (259. - contrast));
let channel = |channel: f32| ((factor * (channel * 255. + brightness - 128.) + 128.) / 255.).clamp(0., 1.);
color.map_rgb(channel)
}
#[derive(Debug, Clone, Copy)]
pub struct OpacityNode<O> {
opacity_multiplier: O,
@ -524,5 +510,6 @@ fn exposure(color: Color, exposure: f64, offset: f64, gamma_correction: f64) ->
.gamma(gamma_correction as f32)
.map_rgb(|c: f32| c.clamp(0., 1.));
// TODO: Remove conversion to linear when the whole node graph uses linear color
result.to_gamma_srgb()
}

View file

@ -0,0 +1,355 @@
use crate::{Color, Node};
// LEGACY BRIGHTNESS/CONTRAST
pub struct BrightnessContrastLegacyMapperNode {
contrast: f32,
combined: f32,
}
impl<'i> Node<'i, Color> for BrightnessContrastLegacyMapperNode {
type Output = Color;
fn eval<'s: 'i>(&'s self, color: Color) -> Color {
color.map_rgb(|c| (c + c * self.contrast + self.combined).clamp(0., 1.))
}
}
#[derive(Debug, Clone, Copy)]
pub struct GenerateBrightnessContrastLegacyMapperNode<Brightness, Contrast> {
brightness: Brightness,
contrast: Contrast,
}
#[node_macro::node_fn(GenerateBrightnessContrastLegacyMapperNode)]
fn brightness_contrast_legacy_node(_primary: (), brightness: f32, contrast: f32) -> BrightnessContrastLegacyMapperNode {
let brightness = brightness / 255.;
let contrast = contrast / 100.;
let contrast = if contrast > 0. { (contrast * std::f32::consts::FRAC_PI_2 - 0.01).tan() } else { contrast };
let combined = brightness * contrast + brightness - contrast / 2.;
BrightnessContrastLegacyMapperNode { contrast, combined }
}
// NORMAL BRIGHTNESS/CONTRAST
pub struct BrightnessContrastMapperNode {
combined_lut: [f32; WINDOW_SIZE],
}
impl<'i> Node<'i, Color> for BrightnessContrastMapperNode {
type Output = Color;
fn eval<'s: 'i>(&'s self, color: Color) -> Color {
color.map_rgb(|c| {
let index_in_combined_lut = (c * (self.combined_lut.len() - 1) as f32).round() as usize;
self.combined_lut[index_in_combined_lut]
})
}
}
#[derive(Debug, Clone, Copy)]
pub struct GenerateBrightnessContrastMapperNode<Brightness, Contrast> {
brightness: Brightness,
contrast: Contrast,
}
#[node_macro::node_fn(GenerateBrightnessContrastMapperNode)]
fn brightness_contrast_node(_primary: (), brightness: f32, contrast: f32) -> BrightnessContrastMapperNode {
// Brightness LUT
let brightness_is_negative = brightness < 0.;
let brightness = brightness.abs() / 100.;
let brightness_curve_points = CubicSplines {
x: [0., 130. - brightness * 26., 233. - brightness * 48., 255.].map(|x| x / 255.),
y: [0., 130. + brightness * 51., 233. + brightness * 10., 255.].map(|x| x / 255.),
};
let brightness_curve_solutions = solve_cubic_splines(&brightness_curve_points);
let mut brightness_lut: [f32; WINDOW_SIZE] = core::array::from_fn(|i| {
let x = i as f32 / (WINDOW_SIZE as f32 - 1.);
interpolate_cubic_splines(x, &brightness_curve_points, &brightness_curve_solutions)
});
// Special handling for when brightness is negative
if brightness_is_negative {
brightness_lut = core::array::from_fn(|i| {
let mut x = i;
while x > 1 && brightness_lut[x] > i as f32 / WINDOW_SIZE as f32 {
x -= 1;
}
x as f32 / WINDOW_SIZE as f32
});
}
// Contrast LUT
let contrast = contrast / 100.;
let contrast_curve_points = CubicSplines {
x: [0., 64., 192., 255.].map(|x| x / 255.),
y: [0., 64. - contrast * 30., 192. + contrast * 30., 255.].map(|x| x / 255.),
};
let contrast_curve_solutions = solve_cubic_splines(&contrast_curve_points);
let contrast_lut: [f32; WINDOW_SIZE] = core::array::from_fn(|i| {
let x = i as f32 / (WINDOW_SIZE as f32 - 1.);
interpolate_cubic_splines(x, &contrast_curve_points, &contrast_curve_solutions)
});
// Composed brightness and contrast LUTs
let combined_lut = brightness_lut.map(|brightness| {
let index_in_contrast_lut = (brightness * (contrast_lut.len() - 1) as f32).round() as usize;
contrast_lut[index_in_contrast_lut]
});
BrightnessContrastMapperNode { combined_lut }
}
const WINDOW_SIZE: usize = 1024;
struct CubicSplines {
x: [f32; 4],
y: [f32; 4],
}
fn solve_cubic_splines(cubic_spline_values: &CubicSplines) -> [f32; 4] {
let (x, y) = (&cubic_spline_values.x, &cubic_spline_values.y);
// Build an augmented matrix to solve the system of equations using Gaussian elimination
let mut augmented_matrix = [
[
2. / (x[1] - x[0]),
1. / (x[1] - x[0]),
0.,
0.,
// |
3. * (y[1] - y[0]) / ((x[1] - x[0]) * (x[1] - x[0])),
],
[
1. / (x[1] - x[1 - 1]),
2. * (1. / (x[1] - x[1 - 1]) + 1. / (x[1 + 1] - x[1])),
1. / (x[1 + 1] - x[1]),
0.,
// |
3. * ((y[1] - y[1 - 1]) / ((x[1] - x[1 - 1]) * (x[1] - x[1 - 1])) + (y[1 + 1] - y[1]) / ((x[1 + 1] - x[1]) * (x[1 + 1] - x[1]))),
],
[
0.,
1. / (x[2] - x[2 - 1]),
2. * (1. / (x[2] - x[2 - 1]) + 1. / (x[2 + 1] - x[2])),
1. / (x[2 + 1] - x[2]),
// |
3. * ((y[2] - y[2 - 1]) / ((x[2] - x[2 - 1]) * (x[2] - x[2 - 1])) + (y[2 + 1] - y[2]) / ((x[2 + 1] - x[2]) * (x[2 + 1] - x[2]))),
],
[
0.,
0.,
1. / (x[3] - x[2]),
2. / (x[3] - x[2]),
// |
3. * (y[3] - y[2]) / ((x[3] - x[2]) * (x[3] - x[2])),
],
];
// Gaussian elimination: forward elimination
for row in 0..4 {
let pivot_row_index = (row..4)
.max_by(|&a_row, &b_row| {
augmented_matrix[a_row][row]
.abs()
.partial_cmp(&augmented_matrix[b_row][row].abs())
.unwrap_or(core::cmp::Ordering::Equal)
})
.unwrap();
// Swap the current row with the row that has the largest pivot element
augmented_matrix.swap(row, pivot_row_index);
// Eliminate the current column in all rows below the current one
for row_below_current in row + 1..4 {
assert!(augmented_matrix[row][row].abs() > std::f32::EPSILON);
let scale_factor = augmented_matrix[row_below_current][row] / augmented_matrix[row][row];
for col in row..5 {
augmented_matrix[row_below_current][col] -= augmented_matrix[row][col] * scale_factor
}
}
}
// Gaussian elimination: back substitution
let mut solutions = [0.; 4];
for col in (0..4).rev() {
assert!(augmented_matrix[col][col].abs() > std::f32::EPSILON);
solutions[col] = augmented_matrix[col][4] / augmented_matrix[col][col];
for row in (0..col).rev() {
augmented_matrix[row][4] -= augmented_matrix[row][col] * solutions[col];
augmented_matrix[row][col] = 0.;
}
}
solutions
}
fn interpolate_cubic_splines(input: f32, points: &CubicSplines, solutions: &[f32]) -> f32 {
if input <= points.x[0] {
return points.y[0];
}
if input >= points.x[points.x.len() - 1] {
return points.y[points.x.len() - 1];
}
// Find the segment that the input falls between
let mut segment = 1;
while points.x[segment] < input {
segment += 1;
}
let segment_start = segment - 1;
let segment_end = segment;
// Calculate the output value using quadratic interpolation
let input_value = points.x[segment_start];
let input_value_prev = points.x[segment_end];
let output_value = points.y[segment_start];
let output_value_prev = points.y[segment_end];
let solutions_value = solutions[segment_start];
let solutions_value_prev = solutions[segment_end];
let output_delta = solutions_value_prev * (input_value - input_value_prev) - (output_value - output_value_prev);
let solution_delta = (output_value - output_value_prev) - solutions_value * (input_value - input_value_prev);
let input_ratio = (input - input_value_prev) / (input_value - input_value_prev);
let prev_output_ratio = (1. - input_ratio) * output_value_prev;
let output_ratio = input_ratio * output_value;
let quadratic_ratio = input_ratio * (1. - input_ratio) * (output_delta * (1. - input_ratio) + solution_delta * input_ratio);
let result = prev_output_ratio + output_ratio + quadratic_ratio;
result.clamp(0., 1.)
}
mod tests {
use crate::value::ClonedNode;
#[allow(unused_imports)]
use super::*;
#[test]
fn brightness_contrast_legacy_tests() {
let brightness_contrast_legacy_map = |brightness, contrast| -> [u8; 256] {
let brightness = ClonedNode::new(brightness);
let contrast = ClonedNode::new(contrast);
let generate_brightness_contrast_legacy_node = GenerateBrightnessContrastLegacyMapperNode::new(brightness, contrast);
let mapper = generate_brightness_contrast_legacy_node.eval(());
let color = |r| Color::from_rgbaf32_unchecked(r, 0., 0., 1.);
core::array::from_fn(|x| (mapper.eval(color(x as f32 / 255.)).r() * 255.).round() as u8)
};
assert_eq!(brightness_contrast_legacy_map(-150., 100.), [0; 256]);
assert_eq!(brightness_contrast_legacy_map(-77., 100.), {
let mut x = [0; 204].into_iter().chain([77, 178].into_iter()).chain([255; 50].into_iter());
core::array::from_fn(|_| x.next().unwrap())
});
assert_eq!(brightness_contrast_legacy_map(0., 100.), {
let mut x = [0; 127].into_iter().chain([77, 178].into_iter()).chain([255; 127].into_iter());
core::array::from_fn(|_| x.next().unwrap())
});
assert_eq!(brightness_contrast_legacy_map(53., 100.), {
let mut x = [0; 74].into_iter().chain([77, 178].into_iter()).chain([255; 180].into_iter());
core::array::from_fn(|_| x.next().unwrap())
});
assert_eq!(brightness_contrast_legacy_map(150., 100.), [255; 256]);
assert_eq!(brightness_contrast_legacy_map(-150., 0.), {
let mut x = [0; 151].into_iter().chain(1..);
core::array::from_fn(|_| x.next().unwrap())
});
assert_eq!(brightness_contrast_legacy_map(-77., 0.), {
let mut x = [0; 78].into_iter().chain(1..);
core::array::from_fn(|_| x.next().unwrap())
});
assert_eq!(brightness_contrast_legacy_map(0., 0.), core::array::from_fn(|i| i as u8));
assert_eq!(brightness_contrast_legacy_map(53., 0.), core::array::from_fn(|i| (i + 53).min(255) as u8));
assert_eq!(brightness_contrast_legacy_map(150., 0.), core::array::from_fn(|i| (i + 150).min(255) as u8));
assert_eq!(brightness_contrast_legacy_map(-150., -100.), [128; 256]);
assert_eq!(brightness_contrast_legacy_map(-77., -100.), [128; 256]);
assert_eq!(brightness_contrast_legacy_map(0., -100.), [128; 256]);
assert_eq!(brightness_contrast_legacy_map(53., -100.), [128; 256]);
assert_eq!(brightness_contrast_legacy_map(150., -100.), [128; 256]);
}
#[test]
fn brightness_contrast_tests() {
let brightness_contrast_map = |brightness, contrast| -> [u8; 1024] {
let brightness = ClonedNode::new(brightness);
let contrast = ClonedNode::new(contrast);
let generate_brightness_contrast_node = GenerateBrightnessContrastMapperNode::new(brightness, contrast);
let mapper = generate_brightness_contrast_node.eval(());
let color = |r| Color::from_rgbaf32_unchecked(r, 0., 0., 1.);
core::array::from_fn(|x| (mapper.eval(color(x as f32 / 1023.)).r() * 255.).round() as u8)
};
let string_data = |string: &str| string.split(',').map(|s| s.parse().unwrap()).collect::<Vec<u8>>();
assert_eq!(
&brightness_contrast_map(-150., 100.),
string_data("0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,38,38,38,38,38,39,39,39,39,39,39,39,39,40,40,40,40,40,40,40,40,41,41,41,41,41,41,42,42,42,42,42,42,42,43,43,43,43,43,43,44,44,44,44,44,45,45,45,45,45,45,45,46,46,46,46,46,46,47,47,47,47,47,48,48,48,48,48,48,48,49,49,49,49,49,50,50,50,50,50,51,51,51,51,51,52,52,52,52,52,53,53,53,53,53,54,54,54,54,54,55,55,55,55,55,56,56,56,56,56,57,57,57,57,57,58,58,58,58,59,59,59,59,59,60,60,60,60,61,61,61,61,61,62,62,62,63,63,63,63,64,64,64,64,65,65,65,65,66,66,66,66,66,67,67,68,68,68,68,69,69,69,69,70,70,70,71,71,71,71,72,72,72,73,73,73,74,74,74,74,75,75,75,76,76,76,77,77,77,78,78,78,79,79,79,80,80,80,81,81,82,82,82,83,83,83,84,84,84,85,85,86,86,86,87,87,88,88,88,89,89,90,90,91,91,92,92,92,93,93,94,94,95,95,96,96,96,97,98,98,99,99,99,100,101,101,101,102,103,103,104,104,105,106,106,107,107,108,108,109,110,110,111,111,112,113,114,114,115,116,116,117,118,119,119,120,121,122,122,123,124,125,125,126,127,128,129,130,131,131,132,133,134,135,136,137,139,140,141,142,143,144,146,147,148,150,151,152,154,155,157,159,160,162,164,166,167,169,171,173,175,177,180,182,184,186,189,191,194,196,199,201,204,206,209,212,214,217,220,223,225,228,231,234,236,239,242,244,247,250,252").as_slice()
);
assert_eq!(
brightness_contrast_map(-77., 100.),
string_data("0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,29,29,29,29,29,29,30,30,30,30,30,30,30,30,31,31,31,31,31,31,32,32,32,32,32,32,33,33,33,33,33,33,33,34,34,34,34,34,34,35,35,35,35,35,35,36,36,36,36,36,36,37,37,37,37,37,37,38,38,38,38,38,39,39,39,39,39,39,40,40,40,40,40,40,41,41,41,41,42,42,42,42,42,42,43,43,43,43,43,44,44,44,44,45,45,45,45,45,45,46,46,46,46,46,47,47,47,47,48,48,48,48,48,48,49,49,49,49,50,50,50,50,50,51,51,51,51,52,52,52,52,53,53,53,53,53,54,54,54,54,55,55,55,55,56,56,56,56,56,57,57,57,57,58,58,58,58,59,59,59,59,60,60,60,60,60,61,61,61,61,62,62,62,63,63,63,63,64,64,64,64,65,65,65,65,66,66,66,66,67,67,67,68,68,68,68,69,69,69,69,70,70,70,71,71,71,71,72,72,72,72,73,73,73,74,74,74,74,75,75,75,75,76,76,77,77,77,77,78,78,78,78,79,79,79,80,80,80,80,81,81,82,82,82,82,83,83,83,84,84,84,84,85,85,86,86,86,86,87,87,87,88,88,88,88,89,89,90,90,90,90,91,91,92,92,92,92,93,93,93,94,94,94,95,95,95,96,96,96,96,97,97,98,98,99,99,99,99,100,100,101,101,101,101,102,102,103,103,103,103,104,104,105,105,105,106,106,106,107,107,107,108,108,108,109,109,110,110,110,111,111,111,112,112,113,113,113,114,114,114,115,115,116,116,116,117,117,117,118,118,119,119,119,119,120,120,121,121,122,122,122,123,123,124,124,124,125,125,125,126,126,127,127,128,128,128,128,129,129,130,130,131,131,131,131,132,132,133,133,133,134,134,135,135,136,136,136,137,137,138,138,139,139,139,140,140,141,141,142,142,142,143,143,144,144,144,145,145,146,146,147,147,148,148,149,149,150,150,150,151,151,152,152,152,153,153,154,155,155,155,156,156,157,157,157,158,159,159,159,160,160,161,161,161,162,163,163,164,164,164,165,166,166,166,167,167,168,168,169,169,170,170,171,171,172,172,173,173,174,174,175,175,175,176,177,177,177,178,179,179,179,180,180,181,181,182,182,183,183,184,184,185,185,186,186,187,188,188,188,189,189,190,190,191,192,192,193,193,194,194,195,195,195,196,196,197,198,198,199,199,200,200,201,201,202,202,203,204,204,204,205,205,206,207,207,208,208,209,209,210,210,211,211,212,212,213,214,214,214,215,216,216,217,217,218,218,219,219,220,220,221,221,222,222,223,224,224,225,225,226,226,227,227,228,228,229,229,230,230,231,232,232,233,233,234,234,235,235,236,236,237,237,238,238,239,239,240,240,241,241,242,242,243,243,244,244,245,246,246,246,247,247,248,248,249,249,250,250,251,252,252,252,253,253,254,254").as_slice()
);
assert_eq!(
brightness_contrast_map(0., 100.),
string_data("0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,16,16,16,16,16,16,16,17,17,17,17,17,17,18,18,18,18,18,18,18,19,19,19,19,19,19,20,20,20,20,20,20,21,21,21,21,21,22,22,22,22,22,22,23,23,23,23,23,24,24,24,24,24,25,25,25,25,25,26,26,26,26,26,27,27,27,27,27,28,28,28,28,28,29,29,29,29,30,30,30,30,30,31,31,31,31,32,32,32,32,33,33,33,33,34,34,34,34,35,35,35,35,36,36,36,36,37,37,37,37,38,38,38,39,39,39,39,40,40,40,40,41,41,41,42,42,42,42,43,43,43,44,44,44,45,45,45,45,46,46,46,47,47,47,48,48,48,48,49,49,49,50,50,50,51,51,51,52,52,52,53,53,53,54,54,54,55,55,55,56,56,56,57,57,57,58,58,58,59,59,59,60,60,60,61,61,61,62,62,63,63,63,64,64,64,65,65,65,66,66,66,67,67,68,68,68,69,69,69,70,70,71,71,71,72,72,72,73,73,74,74,74,75,75,75,76,76,77,77,77,78,78,78,79,79,80,80,80,81,81,82,82,82,83,83,84,84,84,85,85,86,86,86,87,87,88,88,88,89,89,90,90,90,91,91,92,92,92,93,93,94,94,94,95,95,96,96,96,97,97,98,98,99,99,99,100,100,101,101,101,102,102,103,103,103,104,104,105,105,106,106,106,107,107,108,108,108,109,109,110,110,111,111,111,112,112,113,113,114,114,114,115,115,116,116,117,117,117,118,118,119,119,119,120,120,121,121,122,122,122,123,123,124,124,125,125,125,126,126,127,127,128,128,128,129,129,130,130,131,131,131,132,132,133,133,133,134,134,135,135,136,136,136,137,137,138,138,139,139,139,140,140,141,141,142,142,142,143,143,144,144,144,145,145,146,146,147,147,147,148,148,149,149,150,150,150,151,151,152,152,152,153,153,154,154,155,155,155,156,156,157,157,157,158,158,159,159,159,160,160,161,161,161,162,162,163,163,164,164,164,165,165,166,166,166,167,167,168,168,168,169,169,170,170,170,171,171,172,172,172,173,173,174,174,174,175,175,175,176,176,177,177,177,178,178,179,179,179,180,180,180,181,181,182,182,182,183,183,183,184,184,185,185,185,186,186,186,187,187,188,188,188,189,189,189,190,190,190,191,191,192,192,192,193,193,193,194,194,194,195,195,195,196,196,196,197,197,198,198,198,199,199,199,200,200,200,201,201,201,202,202,202,203,203,203,204,204,204,204,205,205,205,206,206,206,207,207,207,208,208,208,209,209,209,209,210,210,210,211,211,211,212,212,212,212,213,213,213,214,214,214,214,215,215,215,216,216,216,216,217,217,217,218,218,218,218,219,219,219,219,220,220,220,220,221,221,221,221,222,222,222,222,223,223,223,223,224,224,224,224,225,225,225,225,225,226,226,226,226,227,227,227,227,227,228,228,228,228,229,229,229,229,229,230,230,230,230,230,231,231,231,231,231,232,232,232,232,232,233,233,233,233,233,233,234,234,234,234,234,234,235,235,235,235,235,236,236,236,236,236,236,236,237,237,237,237,237,237,238,238,238,238,238,238,239,239,239,239,239,239,239,240,240,240,240,240,240,240,241,241,241,241,241,241,241,241,242,242,242,242,242,242,242,242,243,243,243,243,243,243,243,243,244,244,244,244,244,244,244,244,245,245,245,245,245,245,245,245,245,246,246,246,246,246,246,246,246,246,246,247,247,247,247,247,247,247,247,247,247,248,248,248,248,248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,249,249,249,250,250,250,250,250,250,250,250,250,250,250,250,251,251,251,251,251,251,251,251,251,251,251,251,252,252,252,252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,253,254,254,254,254,254,254,254,254,254,254,254,254,254,254,255,255,255,255,255,255,255").as_slice()
);
assert_eq!(
brightness_contrast_map(53., 100.),
string_data("0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,9,9,9,9,9,9,10,10,10,10,10,10,10,11,11,11,11,11,11,12,12,12,12,12,13,13,13,13,13,13,14,14,14,14,14,14,15,15,15,15,15,16,16,16,16,16,17,17,17,17,18,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,22,22,22,22,23,23,23,24,24,24,24,25,25,25,25,26,26,26,27,27,27,27,28,28,28,29,29,29,30,30,30,30,31,31,32,32,32,33,33,33,34,34,34,35,35,35,36,36,36,37,37,37,38,38,39,39,39,40,40,40,41,41,42,42,42,43,43,44,44,45,45,45,46,46,47,47,48,48,48,49,49,50,50,51,51,51,52,52,53,53,54,54,55,55,56,56,57,57,57,58,58,59,59,60,60,61,61,62,62,63,63,64,64,65,65,66,66,66,67,68,68,69,69,69,70,71,71,72,72,73,73,74,74,75,75,76,76,77,77,78,78,79,79,80,80,81,81,82,82,83,84,84,84,85,86,86,87,87,88,88,89,89,90,90,91,92,92,92,93,94,94,95,95,96,96,97,97,98,99,99,100,100,101,101,102,102,103,103,104,104,105,106,106,107,107,108,108,109,109,110,111,111,111,112,113,113,114,114,115,115,116,117,117,118,118,119,119,120,120,121,122,122,122,123,124,124,125,125,126,126,127,128,128,128,129,130,130,131,131,132,132,133,133,134,134,135,136,136,136,137,138,138,139,139,140,140,141,142,142,142,143,144,144,144,145,146,146,147,147,147,148,149,149,150,150,151,151,152,152,153,153,154,155,155,155,156,156,157,157,158,158,159,159,160,160,161,161,162,162,163,163,164,164,165,165,166,166,167,167,168,168,169,169,170,170,170,171,172,172,172,173,174,174,174,175,175,175,176,177,177,177,178,179,179,179,180,180,180,181,182,182,182,183,183,184,184,185,185,185,186,186,187,187,188,188,188,189,189,190,190,190,191,191,192,192,193,193,193,194,194,194,195,195,196,196,196,197,197,198,198,199,199,199,200,200,200,201,201,201,202,202,203,203,203,204,204,204,204,205,205,206,206,206,207,207,207,208,208,208,209,209,209,210,210,210,211,211,211,212,212,212,212,213,213,213,214,214,214,215,215,215,216,216,216,216,217,217,217,218,218,218,218,219,219,219,219,220,220,220,220,221,221,221,221,222,222,222,222,223,223,223,223,224,224,224,224,225,225,225,225,225,226,226,226,226,227,227,227,227,227,228,228,228,228,229,229,229,229,229,230,230,230,230,230,230,231,231,231,231,231,232,232,232,232,232,233,233,233,233,233,233,233,234,234,234,234,234,234,234,235,235,235,235,235,236,236,236,236,236,236,236,236,237,237,237,237,237,237,237,238,238,238,238,238,238,238,239,239,239,239,239,239,239,239,239,240,240,240,240,240,240,240,240,241,241,241,241,241,241,241,241,241,241,242,242,242,242,242,242,242,242,242,242,243,243,243,243,243,243,243,243,243,243,243,244,244,244,244,244,244,244,244,244,244,244,245,245,245,245,245,245,245,245,245,245,245,245,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255").as_slice()
);
assert_eq!(
brightness_contrast_map(150., 100.),
string_data("0,0,0,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,10,10,10,10,11,11,11,12,12,12,13,13,13,14,14,14,15,15,16,16,16,17,17,18,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,30,30,31,31,32,33,33,34,35,35,36,37,37,38,39,40,40,41,42,42,43,44,45,46,46,47,48,49,50,50,51,52,53,54,55,56,56,57,58,59,60,61,62,63,64,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,78,80,80,82,82,84,84,86,86,88,88,90,90,92,92,93,94,95,96,97,99,99,101,101,102,103,104,106,106,107,108,109,111,111,112,114,114,116,117,117,119,119,120,122,122,123,125,125,127,128,128,129,131,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,150,152,152,153,154,155,156,157,158,159,159,161,161,162,163,164,165,166,167,168,168,169,170,171,172,173,174,174,175,176,177,177,178,179,180,180,181,182,183,183,184,185,186,187,188,188,189,189,190,191,192,192,193,194,194,195,196,196,197,198,199,199,200,200,201,202,202,203,204,204,205,205,206,206,207,208,208,209,209,210,210,211,211,212,212,213,213,214,214,215,215,216,216,217,217,218,218,219,219,220,220,220,221,221,222,222,222,223,223,224,224,224,225,225,225,226,226,226,227,227,227,228,228,229,229,229,229,230,230,230,231,231,231,231,232,232,232,233,233,233,233,233,234,234,234,234,235,235,235,235,236,236,236,236,236,237,237,237,237,237,238,238,238,238,238,239,239,239,239,239,239,240,240,240,240,240,240,241,241,241,241,241,241,241,241,242,242,242,242,242,242,242,242,243,243,243,243,243,243,243,243,244,244,244,244,244,244,244,244,245,245,245,245,245,245,245,245,245,245,245,246,246,246,246,246,246,246,246,246,246,246,246,247,247,247,247,247,247,247,247,247,247,247,247,247,247,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255").as_slice()
);
assert_eq!(
brightness_contrast_map(-150., 0.),
string_data("0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,32,32,32,32,32,32,32,32,32,32,33,33,33,33,33,33,33,33,33,33,34,34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35,35,35,35,36,36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,37,37,37,38,38,38,38,38,38,38,38,38,38,39,39,39,39,39,39,39,39,39,39,40,40,40,40,40,40,40,40,40,41,41,41,41,41,41,41,41,41,41,42,42,42,42,42,42,42,42,42,42,43,43,43,43,43,43,43,43,43,43,44,44,44,44,44,44,44,44,44,45,45,45,45,45,45,45,45,45,45,46,46,46,46,46,46,46,46,46,47,47,47,47,47,47,47,47,47,47,48,48,48,48,48,48,48,48,48,49,49,49,49,49,49,49,49,49,50,50,50,50,50,50,50,50,50,50,51,51,51,51,51,51,51,51,51,52,52,52,52,52,52,52,52,52,53,53,53,53,53,53,53,53,53,54,54,54,54,54,54,54,54,54,55,55,55,55,55,55,55,55,55,56,56,56,56,56,56,56,56,56,57,57,57,57,57,57,57,57,57,58,58,58,58,58,58,58,58,59,59,59,59,59,59,59,59,59,60,60,60,60,60,60,60,60,61,61,61,61,61,61,61,61,61,62,62,62,62,62,62,62,62,63,63,63,63,63,63,63,63,64,64,64,64,64,64,64,64,64,65,65,65,65,65,65,65,65,66,66,66,66,66,66,66,66,67,67,67,67,67,67,67,67,68,68,68,68,68,68,68,69,69,69,69,69,69,69,69,70,70,70,70,70,70,70,70,71,71,71,71,71,71,71,72,72,72,72,72,72,72,72,73,73,73,73,73,73,73,74,74,74,74,74,74,74,75,75,75,75,75,75,75,75,76,76,76,76,76,76,76,77,77,77,77,77,77,77,78,78,78,78,78,78,79,79,79,79,79,79,79,80,80,80,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,82,83,83,83,83,83,83,84,84,84,84,84,84,85,85,85,85,85,85,85,85,86,86,86,86,86,86,87,87,87,87,87,87,88,88,88,88,88,89,89,89,89,89,89,90,90,90,90,90,91,91,91,91,91,91,92,92,92,92,92,93,93,93,93,93,94,94,94,94,94,95,95,95,95,95,96,96,96,96,96,97,97,97,97,98,98,98,98,98,99,99,99,99,100,100,100,100,101,101,101,101,101,102,102,102,102,103,103,103,103,104,104,104,104,105,105,105,106,106,106,106,107,107,107,107,108,108,108,109,109,109,109,110,110,110,111,111,111,112,112,112,113,113,113,114,114,114,115,115,115,116,116,116,117,117,117,118,118,119,119,119,120,120,121,121,121,122,122,123,123,124,124,125,125,125,126,126,127,127,128,128,129,129,130,130,131,132,132,133,133,134,135,135,136,137,138,138,139,140,141,142,142,143,144,145,146,147,148,149,150,151,153,154,155,157,158,159,161,162,164,166,167,169,170,172,174,176,178,180,183,185,187,190,193,196,199,202,206,210,214,219,224,231,238,246").as_slice()
);
assert_eq!(
brightness_contrast_map(-77., 0.),
string_data("0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,7,8,8,8,8,8,8,8,9,9,9,9,9,9,9,10,10,10,10,10,10,10,11,11,11,11,11,11,12,12,12,12,12,12,12,13,13,13,13,13,13,13,14,14,14,14,14,14,14,15,15,15,15,15,15,16,16,16,16,16,16,16,17,17,17,17,17,17,17,18,18,18,18,18,18,18,19,19,19,19,19,19,20,20,20,20,20,20,20,21,21,21,21,21,21,21,22,22,22,22,22,22,22,23,23,23,23,23,23,24,24,24,24,24,24,24,25,25,25,25,25,25,25,26,26,26,26,26,26,26,27,27,27,27,27,27,28,28,28,28,28,28,28,29,29,29,29,29,29,29,30,30,30,30,30,30,31,31,31,31,31,31,31,32,32,32,32,32,32,32,33,33,33,33,33,33,34,34,34,34,34,34,34,35,35,35,35,35,35,36,36,36,36,36,36,36,37,37,37,37,37,37,37,38,38,38,38,38,38,39,39,39,39,39,39,39,40,40,40,40,40,40,41,41,41,41,41,41,41,42,42,42,42,42,42,43,43,43,43,43,43,43,44,44,44,44,44,44,45,45,45,45,45,45,45,46,46,46,46,46,46,47,47,47,47,47,47,47,48,48,48,48,48,48,49,49,49,49,49,49,49,50,50,50,50,50,50,51,51,51,51,51,51,52,52,52,52,52,52,52,53,53,53,53,53,53,54,54,54,54,54,54,55,55,55,55,55,55,55,56,56,56,56,56,56,57,57,57,57,57,57,58,58,58,58,58,58,58,59,59,59,59,59,59,60,60,60,60,60,60,61,61,61,61,61,61,62,62,62,62,62,62,63,63,63,63,63,63,63,64,64,64,64,64,64,65,65,65,65,65,65,66,66,66,66,66,66,67,67,67,67,67,67,68,68,68,68,68,68,69,69,69,69,69,69,70,70,70,70,70,70,71,71,71,71,71,71,72,72,72,72,72,72,73,73,73,73,73,73,74,74,74,74,74,74,75,75,75,75,75,75,76,76,76,76,76,76,77,77,77,77,77,77,78,78,78,78,78,78,79,79,79,79,79,80,80,80,80,80,80,81,81,81,81,81,81,82,82,82,82,82,82,83,83,83,83,83,84,84,84,84,84,84,85,85,85,85,85,85,85,86,86,86,86,86,86,87,87,87,87,87,88,88,88,88,88,88,89,89,89,89,89,90,90,90,90,90,90,91,91,91,91,91,92,92,92,92,92,92,93,93,93,93,93,94,94,94,94,94,94,95,95,95,95,95,96,96,96,96,96,97,97,97,97,97,97,98,98,98,98,98,99,99,99,99,99,100,100,100,100,100,101,101,101,101,101,101,102,102,102,102,102,103,103,103,103,103,104,104,104,104,104,105,105,105,105,105,106,106,106,106,106,107,107,107,107,107,108,108,108,108,108,109,109,109,109,109,110,110,110,110,110,111,111,111,111,112,112,112,112,112,113,113,113,113,113,114,114,114,114,114,115,115,115,115,116,116,116,116,116,117,117,117,117,117,118,118,118,118,119,119,119,119,119,120,120,120,120,121,121,121,121,121,122,122,122,122,123,123,123,123,123,124,124,124,124,125,125,125,125,126,126,126,126,126,127,127,127,127,128,128,128,128,128,129,129,129,129,129,130,130,130,130,131,131,131,131,132,132,132,132,133,133,133,133,134,134,134,134,135,135,135,135,136,136,136,136,137,137,137,137,138,138,138,138,139,139,139,140,140,140,140,141,141,141,141,142,142,142,142,143,143,143,144,144,144,144,145,145,145,145,146,146,146,147,147,147,147,148,148,148,149,149,149,149,150,150,150,151,151,151,151,152,152,152,153,153,153,154,154,154,154,155,155,155,156,156,156,157,157,157,158,158,158,159,159,159,160,160,160,160,161,161,161,162,162,162,163,163,163,164,164,165,165,165,166,166,166,167,167,167,168,168,168,169,169,170,170,170,170,171,171,171,172,172,173,173,173,174,174,175,175,175,176,176,177,177,177,178,178,179,179,180,180,180,181,181,182,182,183,183,184,184,184,185,185,186,186,187,187,188,188,189,189,190,190,191,191,192,192,193,194,194,195,195,196,196,197,198,198,199,200,200,201,201,202,203,203,204,205,206,206,207,208,209,209,210,211,212,213,214,214,215,216,217,218,219,220,221,222,223,224,226,227,228,229,230,232,233,234,236,237,239,240,242,243,245,246,248,250,251,253").as_slice()
);
assert_eq!(
brightness_contrast_map(0., 0.),
string_data("0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,22,22,22,22,23,23,23,23,24,24,24,24,25,25,25,25,26,26,26,26,27,27,27,27,28,28,28,28,29,29,29,29,30,30,30,30,31,31,31,31,32,32,32,32,33,33,33,33,34,34,34,34,35,35,35,35,36,36,36,36,37,37,37,37,38,38,38,38,39,39,39,39,40,40,40,40,41,41,41,41,42,42,42,42,43,43,43,43,44,44,44,44,45,45,45,45,46,46,46,46,47,47,47,47,48,48,48,48,49,49,49,49,50,50,50,50,51,51,51,51,52,52,52,52,53,53,53,53,54,54,54,54,55,55,55,55,56,56,56,56,57,57,57,57,58,58,58,58,59,59,59,59,60,60,60,60,61,61,61,61,62,62,62,62,63,63,63,63,64,64,64,64,65,65,65,65,66,66,66,66,67,67,67,67,68,68,68,68,69,69,69,69,70,70,70,70,71,71,71,71,72,72,72,72,73,73,73,73,74,74,74,74,75,75,75,75,76,76,76,76,77,77,77,77,78,78,78,78,79,79,79,79,80,80,80,80,81,81,81,81,82,82,82,82,83,83,83,83,84,84,84,84,85,85,85,85,85,86,86,86,86,87,87,87,87,88,88,88,88,89,89,89,89,90,90,90,90,91,91,91,91,92,92,92,92,93,93,93,93,94,94,94,94,95,95,95,95,96,96,96,96,97,97,97,97,98,98,98,98,99,99,99,99,100,100,100,100,101,101,101,101,102,102,102,102,103,103,103,103,104,104,104,104,105,105,105,105,106,106,106,106,107,107,107,107,108,108,108,108,109,109,109,109,110,110,110,110,111,111,111,111,112,112,112,112,113,113,113,113,114,114,114,114,115,115,115,115,116,116,116,116,117,117,117,117,118,118,118,118,119,119,119,119,120,120,120,120,121,121,121,121,122,122,122,122,123,123,123,123,124,124,124,124,125,125,125,125,126,126,126,126,127,127,127,127,128,128,128,128,129,129,129,129,130,130,130,130,131,131,131,131,132,132,132,132,133,133,133,133,134,134,134,134,135,135,135,135,136,136,136,136,137,137,137,137,138,138,138,138,139,139,139,139,140,140,140,140,141,141,141,141,142,142,142,142,143,143,143,143,144,144,144,144,145,145,145,145,146,146,146,146,147,147,147,147,148,148,148,148,149,149,149,149,150,150,150,150,151,151,151,151,152,152,152,152,153,153,153,153,154,154,154,154,155,155,155,155,156,156,156,156,157,157,157,157,158,158,158,158,159,159,159,159,160,160,160,160,161,161,161,161,162,162,162,162,163,163,163,163,164,164,164,164,165,165,165,165,166,166,166,166,167,167,167,167,168,168,168,168,169,169,169,169,170,170,170,170,170,171,171,171,171,172,172,172,172,173,173,173,173,174,174,174,174,175,175,175,175,176,176,176,176,177,177,177,177,178,178,178,178,179,179,179,179,180,180,180,180,181,181,181,181,182,182,182,182,183,183,183,183,184,184,184,184,185,185,185,185,186,186,186,186,187,187,187,187,188,188,188,188,189,189,189,189,190,190,190,190,191,191,191,191,192,192,192,192,193,193,193,193,194,194,194,194,195,195,195,195,196,196,196,196,197,197,197,197,198,198,198,198,199,199,199,199,200,200,200,200,201,201,201,201,202,202,202,202,203,203,203,203,204,204,204,204,205,205,205,205,206,206,206,206,207,207,207,207,208,208,208,208,209,209,209,209,210,210,210,210,211,211,211,211,212,212,212,212,213,213,213,213,214,214,214,214,215,215,215,215,216,216,216,216,217,217,217,217,218,218,218,218,219,219,219,219,220,220,220,220,221,221,221,221,222,222,222,222,223,223,223,223,224,224,224,224,225,225,225,225,226,226,226,226,227,227,227,227,228,228,228,228,229,229,229,229,230,230,230,230,231,231,231,231,232,232,232,232,233,233,233,233,234,234,234,234,235,235,235,235,236,236,236,236,237,237,237,237,238,238,238,238,239,239,239,239,240,240,240,240,241,241,241,241,242,242,242,242,243,243,243,243,244,244,244,244,245,245,245,245,246,246,246,246,247,247,247,247,248,248,248,248,249,249,249,249,250,250,250,250,251,251,251,251,252,252,252,252,253,253,253,253,254,254,254,254,255,255,255").as_slice()
);
assert_eq!(
brightness_contrast_map(53., 0.),
string_data("0,0,1,1,1,2,2,2,3,3,3,4,4,5,5,5,6,6,6,7,7,7,8,8,8,9,9,10,10,10,11,11,11,12,12,12,13,13,14,14,14,15,15,15,16,16,16,17,17,17,18,18,19,19,19,20,20,20,21,21,21,22,22,22,23,23,24,24,24,25,25,25,26,26,26,27,27,27,28,28,29,29,29,30,30,30,31,31,31,32,32,32,33,33,34,34,34,35,35,35,36,36,36,37,37,37,38,38,39,39,39,40,40,40,41,41,41,42,42,42,43,43,44,44,44,45,45,45,46,46,46,47,47,47,48,48,48,49,49,50,50,50,51,51,51,52,52,52,53,53,53,54,54,54,55,55,56,56,56,57,57,57,58,58,58,59,59,59,60,60,60,61,61,62,62,62,63,63,63,64,64,64,65,65,65,66,66,66,67,67,67,68,68,69,69,69,70,70,70,71,71,71,72,72,72,73,73,73,74,74,74,75,75,75,76,76,76,77,77,78,78,78,79,79,79,80,80,80,81,81,81,82,82,82,83,83,83,84,84,84,85,85,85,86,86,86,87,87,87,88,88,88,89,89,89,90,90,90,91,91,91,92,92,92,93,93,93,94,94,94,95,95,95,96,96,96,97,97,97,98,98,98,99,99,99,100,100,100,101,101,101,102,102,102,103,103,103,104,104,104,105,105,105,106,106,106,107,107,107,108,108,108,109,109,109,110,110,110,111,111,111,112,112,112,113,113,113,114,114,114,115,115,115,116,116,116,117,117,117,118,118,118,119,119,119,120,120,120,120,121,121,121,122,122,122,123,123,123,124,124,124,125,125,125,126,126,126,127,127,127,128,128,128,129,129,129,129,130,130,130,131,131,131,132,132,132,133,133,133,134,134,134,135,135,135,135,136,136,136,137,137,137,138,138,138,139,139,139,139,140,140,140,141,141,141,142,142,142,143,143,143,144,144,144,144,145,145,145,146,146,146,147,147,147,147,148,148,148,149,149,149,150,150,150,150,151,151,151,152,152,152,153,153,153,153,154,154,154,155,155,155,156,156,156,156,157,157,157,158,158,158,159,159,159,159,160,160,160,161,161,161,161,162,162,162,163,163,163,163,164,164,164,165,165,165,165,166,166,166,167,167,167,167,168,168,168,169,169,169,169,170,170,170,170,171,171,171,171,172,172,172,173,173,173,173,174,174,174,175,175,175,175,176,176,176,176,177,177,177,178,178,178,178,179,179,179,179,180,180,180,180,181,181,181,182,182,182,182,183,183,183,183,184,184,184,184,185,185,185,186,186,186,186,187,187,187,187,188,188,188,188,189,189,189,189,190,190,190,190,191,191,191,191,192,192,192,192,193,193,193,193,194,194,194,194,195,195,195,195,196,196,196,196,197,197,197,197,198,198,198,198,199,199,199,199,200,200,200,200,200,201,201,201,201,202,202,202,202,203,203,203,203,204,204,204,204,204,205,205,205,205,206,206,206,206,207,207,207,207,207,208,208,208,208,209,209,209,209,209,210,210,210,210,210,211,211,211,211,212,212,212,212,212,213,213,213,213,213,214,214,214,214,215,215,215,215,215,216,216,216,216,216,217,217,217,217,217,218,218,218,218,218,219,219,219,219,219,220,220,220,220,220,221,221,221,221,221,221,222,222,222,222,222,223,223,223,223,223,224,224,224,224,224,224,225,225,225,225,225,226,226,226,226,226,226,227,227,227,227,227,227,228,228,228,228,228,228,229,229,229,229,229,229,230,230,230,230,230,230,231,231,231,231,231,231,232,232,232,232,232,232,232,233,233,233,233,233,233,234,234,234,234,234,234,234,235,235,235,235,235,235,235,236,236,236,236,236,236,236,237,237,237,237,237,237,237,238,238,238,238,238,238,238,238,239,239,239,239,239,239,239,239,240,240,240,240,240,240,240,240,241,241,241,241,241,241,241,241,241,242,242,242,242,242,242,242,242,242,243,243,243,243,243,243,243,243,243,243,244,244,244,244,244,244,244,244,244,244,245,245,245,245,245,245,245,245,245,245,246,246,246,246,246,246,246,246,246,246,246,247,247,247,247,247,247,247,247,247,247,247,248,248,248,248,248,248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,249,249,249,249,249,250,250,250,250,250,250,250,250,250,250,250,250,250,251,251,251,251,251,251,251,251,251,251,251,251,251,252,252,252,252,252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,254,254,254,254,254,254,254,254,254,254,254,254,254,254,255,255,255,255,255,255,255,255,255,255").as_slice()
);
assert_eq!(
brightness_contrast_map(150., 0.),
string_data("0,1,1,2,3,3,4,5,5,6,7,7,8,9,9,10,11,11,12,13,14,14,15,16,16,17,18,18,19,20,20,21,22,22,23,24,24,25,26,26,27,28,29,29,30,31,31,32,33,33,34,35,35,36,37,37,38,39,39,40,41,41,42,43,43,44,45,45,46,47,47,48,49,49,50,51,51,52,53,53,54,55,55,56,57,57,58,59,59,60,61,61,62,63,63,64,65,65,66,67,67,68,69,69,70,71,71,72,73,73,74,75,75,76,76,77,78,78,79,80,80,81,82,82,83,84,84,85,85,86,87,87,88,88,89,90,90,91,92,92,93,94,94,95,95,96,97,97,98,99,99,100,100,101,102,102,103,104,104,105,105,106,107,107,108,108,109,110,110,111,112,112,113,113,114,115,115,116,116,117,118,118,119,119,120,121,121,122,122,123,123,124,125,125,126,126,127,128,128,129,129,130,130,131,132,132,133,133,134,134,135,136,136,137,137,138,138,139,140,140,141,141,142,142,143,143,144,145,145,146,146,147,147,148,148,149,149,150,151,151,152,152,153,153,154,154,155,155,156,156,157,157,158,158,159,159,160,160,161,161,162,162,163,164,164,165,165,166,166,166,167,167,168,168,169,169,170,170,171,171,172,172,173,173,173,174,174,175,175,176,176,177,177,178,178,179,179,180,180,180,181,181,182,182,183,183,184,184,184,185,185,186,186,187,187,187,188,188,189,189,190,190,190,191,191,192,192,192,193,193,194,194,194,195,195,196,196,196,197,197,197,198,198,199,199,199,200,200,200,201,201,202,202,202,203,203,203,204,204,204,205,205,205,206,206,206,207,207,207,208,208,208,209,209,209,210,210,210,211,211,211,212,212,212,212,213,213,213,214,214,214,215,215,215,215,216,216,216,217,217,217,217,218,218,218,218,219,219,219,219,220,220,220,220,221,221,221,221,222,222,222,222,223,223,223,223,224,224,224,224,225,225,225,225,225,226,226,226,226,226,227,227,227,227,228,228,228,228,228,229,229,229,229,229,229,230,230,230,230,230,231,231,231,231,231,231,232,232,232,232,232,233,233,233,233,233,233,234,234,234,234,234,234,234,235,235,235,235,235,235,235,236,236,236,236,236,236,236,237,237,237,237,237,237,237,238,238,238,238,238,238,238,238,239,239,239,239,239,239,239,239,239,240,240,240,240,240,240,240,240,240,241,241,241,241,241,241,241,241,241,241,242,242,242,242,242,242,242,242,242,242,242,243,243,243,243,243,243,243,243,243,243,243,243,244,244,244,244,244,244,244,244,244,244,244,244,244,244,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255").as_slice()
);
assert_eq!(
brightness_contrast_map(-150., -100.),
string_data("0,0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,10,10,10,10,10,10,11,11,11,11,11,11,11,11,12,12,12,12,12,13,13,13,13,13,13,14,14,14,14,14,14,14,14,15,15,15,15,15,15,16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,19,19,19,19,19,19,19,19,20,20,20,20,20,21,21,21,21,21,21,22,22,22,22,22,22,22,22,23,23,23,23,23,24,24,24,24,24,24,24,24,25,25,25,25,25,25,26,26,26,26,26,27,27,27,27,27,27,27,27,28,28,28,28,28,29,29,29,29,29,29,29,29,29,30,30,30,30,30,31,31,31,31,31,31,31,31,32,32,32,32,32,33,33,33,33,33,33,34,34,34,34,34,34,34,34,35,35,35,35,35,36,36,36,36,36,36,36,36,37,37,37,37,37,38,38,38,38,38,38,38,38,39,39,39,39,39,40,40,40,40,40,40,40,40,41,41,41,41,41,41,42,42,42,42,42,42,42,43,43,43,43,43,43,44,44,44,44,44,44,44,44,45,45,45,45,45,46,46,46,46,46,46,46,46,47,47,47,47,47,47,47,48,48,48,48,48,48,49,49,49,49,49,49,49,50,50,50,50,50,50,51,51,51,51,51,51,51,52,52,52,52,52,53,53,53,53,53,53,53,53,54,54,54,54,54,54,54,54,55,55,55,55,55,56,56,56,56,56,56,56,57,57,57,57,57,57,57,57,58,58,58,58,58,59,59,59,59,59,59,59,59,60,60,60,60,60,60,60,61,61,61,61,61,61,61,61,62,62,62,62,62,63,63,63,63,63,63,63,64,64,64,64,64,64,64,65,65,65,65,65,65,65,65,66,66,66,66,66,66,66,67,67,67,67,67,67,67,68,68,68,68,68,69,69,69,69,69,69,69,69,70,70,70,70,70,70,70,71,71,71,71,71,71,71,72,72,72,72,72,72,72,73,73,73,73,73,73,73,74,74,74,74,74,74,74,75,75,75,75,75,75,75,76,76,76,76,76,76,76,76,77,77,77,77,77,77,78,78,78,78,78,78,78,78,78,78,79,79,79,79,79,79,79,80,80,80,80,80,80,81,81,81,81,81,81,81,82,82,82,82,82,82,82,82,82,83,83,83,83,83,83,83,84,84,84,84,84,84,84,85,85,85,85,85,85,85,85,85,86,86,86,86,86,86,87,87,87,87,87,87,87,87,87,88,88,88,88,88,88,89,89,89,89,89,89,89,89,89,90,90,90,90,90,90,90,90,91,91,91,91,91,91,91,92,92,92,92,92,92,92,92,93,93,93,93,93,93,93,93,94,94,94,94,94,94,94,94,94,95,95,95,95,95,95,95,95,96,96,96,96,96,96,96,96,96,96,97,97,97,97,97,97,97,97,98,98,98,98,98,98,98,99,99,99,99,99,99,99,99,99,99,100,100,100,100,100,100,100,100,101,101,101,101,101,101,101,101,101,102,102,102,102,102,102,102,102,102,103,103,103,103,103,103,103,103,103,104,104,104,104,104,104,104,104,104,105,105,105,105,105,105,105,105,105,105,105,106,106,106,106,106,106,106,106,107,107,107,107,107,107,107,107,107,107,108,108,108,108,108,108,108,108,108,108,109,109,109,109,109,109,109,109,109,110,110,110,110,110,110,110,110,110,110,110,111,111,111,111,111,111,111,111,111,112,112,112,112,112,112,112,112,112,112,113,113,113,113,113,113,113,113,113,113,114,114,114,114,114,114,114,114,114,114,114,115,115,115,115,115,115,115,115,115,115,116,116,116,116,116,116,116,116,116,116,117,117,117,117,117,117,117,117,117,117,118,118,118,118,118,118,118,118,118,118,119,119,119,119,119,119,119,119,119,119,119,120,120,120,120,120,120,120,120,120,121,121,121,121,121,121,121,121,121,121,122,122,122,122,122,122,122,122,122,122,123,123,123,123,123,123,123,123,123,124,124,124,124,124,124,124,124,124,125,125,125,125,125,125,125,125,125,126,126,126,126,126,126,126,127,127,127,127,127,127,127,127,128,128,128,128,128,128,129,129,129,129,129,129,130,130,130,130,130,131,131,131,131,132,132,132,132,133,133,134,134,134,135,135,135,136,136,137,138,138,139,140,140,141,142,143,144,145,146,147,149,150,152,154,155,158,160,163,166,169,173,178,183,189,196,204,214,226,240").as_slice()
);
assert_eq!(
brightness_contrast_map(-77., -100.),
string_data("0,0,0,0,1,1,1,2,2,2,2,3,3,3,3,3,4,4,4,5,5,5,5,6,6,6,6,6,7,7,7,8,8,8,8,8,9,9,9,9,10,10,10,11,11,11,11,11,12,12,12,12,13,13,13,14,14,14,14,14,15,15,15,16,16,16,16,17,17,17,17,17,18,18,18,19,19,19,19,19,20,20,20,20,21,21,21,22,22,22,22,22,23,23,23,23,24,24,24,24,24,25,25,25,26,26,26,27,27,27,27,27,27,28,28,28,29,29,29,29,29,30,30,30,31,31,31,31,31,32,32,32,32,33,33,33,34,34,34,34,34,35,35,35,35,36,36,36,36,36,37,37,37,38,38,38,38,38,39,39,39,40,40,40,40,40,41,41,41,41,42,42,42,42,42,43,43,43,44,44,44,44,44,45,45,45,45,46,46,46,46,46,47,47,47,47,47,48,48,48,49,49,49,49,49,50,50,50,51,51,51,51,51,52,52,52,52,53,53,53,53,53,54,54,54,54,55,55,55,55,56,56,56,56,56,57,57,57,57,57,58,58,58,59,59,59,59,59,60,60,60,60,60,61,61,61,61,61,62,62,62,63,63,63,63,63,64,64,64,64,64,65,65,65,65,65,66,66,66,66,66,67,67,67,67,67,68,68,68,69,69,69,69,69,70,70,70,70,70,71,71,71,71,71,72,72,72,72,73,73,73,73,73,74,74,74,74,74,75,75,75,75,75,76,76,76,76,76,77,77,77,77,77,78,78,78,78,78,78,79,79,79,79,79,80,80,80,80,80,81,81,81,81,82,82,82,82,82,82,82,83,83,83,83,84,84,84,84,84,85,85,85,85,85,85,86,86,86,86,86,87,87,87,87,87,87,88,88,88,88,88,89,89,89,89,89,89,90,90,90,90,90,90,90,91,91,91,91,92,92,92,92,92,92,93,93,93,93,93,93,93,94,94,94,94,94,94,95,95,95,95,95,95,96,96,96,96,96,96,96,96,97,97,97,97,97,97,98,98,98,98,98,98,99,99,99,99,99,99,99,100,100,100,100,100,100,101,101,101,101,101,101,101,101,102,102,102,102,102,102,102,103,103,103,103,103,103,103,103,104,104,104,104,104,104,104,105,105,105,105,105,105,105,105,105,106,106,106,106,106,106,106,107,107,107,107,107,107,107,107,107,108,108,108,108,108,108,108,108,109,109,109,109,109,109,109,109,109,110,110,110,110,110,110,110,110,110,110,111,111,111,111,111,111,111,111,112,112,112,112,112,112,112,112,112,112,113,113,113,113,113,113,113,113,113,113,114,114,114,114,114,114,114,114,114,114,114,115,115,115,115,115,115,115,115,115,115,115,116,116,116,116,116,116,116,116,116,116,117,117,117,117,117,117,117,117,117,117,117,117,118,118,118,118,118,118,118,118,118,118,118,118,119,119,119,119,119,119,119,119,119,119,119,119,119,120,120,120,120,120,120,120,120,120,120,120,120,120,121,121,121,121,121,121,121,121,121,121,121,121,121,122,122,122,122,122,122,122,122,122,122,122,122,122,122,123,123,123,123,123,123,123,123,123,123,123,123,123,123,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,129,129,129,129,129,129,129,129,129,129,129,129,129,129,130,130,130,130,130,130,130,130,130,130,130,130,130,131,131,131,131,131,131,131,131,131,131,131,131,132,132,132,132,132,132,132,132,132,132,132,132,133,133,133,133,133,133,133,133,133,134,134,134,134,134,134,134,134,134,134,135,135,135,135,135,135,135,135,135,135,136,136,136,136,136,136,136,136,137,137,137,137,137,137,137,138,138,138,138,138,138,138,139,139,139,139,139,139,139,140,140,140,140,140,140,141,141,141,141,141,141,142,142,142,142,142,143,143,143,143,143,144,144,144,144,144,145,145,145,145,145,146,146,146,147,147,147,147,148,148,148,148,149,149,149,150,150,150,150,151,151,151,152,152,153,153,153,154,154,154,155,155,155,156,156,157,157,158,158,159,159,159,160,160,161,161,162,162,163,164,164,165,166,166,167,168,168,169,169,170,171,172,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,191,192,193,195,196,198,199,201,203,204,206,208,210,212,214,216,218,220,223,225,227,230,232,235,238,240,243,246,249,252").as_slice()
);
assert_eq!(
brightness_contrast_map(0., -100.),
string_data("0,0,1,1,2,2,3,3,3,4,4,5,5,6,6,6,7,7,8,8,8,9,9,10,10,11,11,11,12,12,13,13,14,14,14,15,15,16,16,17,17,17,18,18,19,19,19,20,20,21,21,22,22,22,23,23,24,24,24,25,25,26,26,27,27,27,28,28,29,29,29,30,30,31,31,31,32,32,33,33,34,34,34,35,35,36,36,36,37,37,38,38,38,39,39,40,40,40,41,41,42,42,42,43,43,44,44,44,45,45,46,46,46,47,47,47,48,48,49,49,49,50,50,51,51,51,52,52,53,53,53,54,54,54,55,55,56,56,56,57,57,57,58,58,59,59,59,60,60,60,61,61,61,62,62,63,63,63,64,64,64,65,65,65,66,66,66,67,67,67,68,68,69,69,69,70,70,70,71,71,71,72,72,72,73,73,73,74,74,74,75,75,75,76,76,76,77,77,77,78,78,78,78,79,79,79,80,80,80,81,81,81,82,82,82,82,83,83,83,84,84,84,85,85,85,85,86,86,86,87,87,87,87,88,88,88,89,89,89,89,90,90,90,90,91,91,91,92,92,92,92,93,93,93,93,94,94,94,94,95,95,95,95,96,96,96,96,96,97,97,97,97,98,98,98,98,99,99,99,99,99,100,100,100,100,101,101,101,101,101,102,102,102,102,102,103,103,103,103,103,104,104,104,104,104,105,105,105,105,105,105,106,106,106,106,106,107,107,107,107,107,107,108,108,108,108,108,108,109,109,109,109,109,109,110,110,110,110,110,110,110,111,111,111,111,111,111,112,112,112,112,112,112,112,113,113,113,113,113,113,113,114,114,114,114,114,114,114,114,115,115,115,115,115,115,115,115,116,116,116,116,116,116,116,116,117,117,117,117,117,117,117,117,117,118,118,118,118,118,118,118,118,118,119,119,119,119,119,119,119,119,119,119,120,120,120,120,120,120,120,120,120,120,121,121,121,121,121,121,121,121,121,121,121,122,122,122,122,122,122,122,122,122,122,122,123,123,123,123,123,123,123,123,123,123,123,123,124,124,124,124,124,124,124,124,124,124,124,124,124,125,125,125,125,125,125,125,125,125,125,125,125,125,126,126,126,126,126,126,126,126,126,126,126,126,126,127,127,127,127,127,127,127,127,127,127,127,127,127,127,128,128,128,128,128,128,128,128,128,128,128,128,128,129,129,129,129,129,129,129,129,129,129,129,129,129,129,130,130,130,130,130,130,130,130,130,130,130,130,130,131,131,131,131,131,131,131,131,131,131,131,131,131,132,132,132,132,132,132,132,132,132,132,132,132,133,133,133,133,133,133,133,133,133,133,133,134,134,134,134,134,134,134,134,134,134,134,135,135,135,135,135,135,135,135,135,135,135,136,136,136,136,136,136,136,136,136,136,137,137,137,137,137,137,137,137,137,138,138,138,138,138,138,138,138,138,139,139,139,139,139,139,139,139,139,140,140,140,140,140,140,140,140,141,141,141,141,141,141,141,141,142,142,142,142,142,142,142,143,143,143,143,143,143,143,144,144,144,144,144,144,144,145,145,145,145,145,145,145,146,146,146,146,146,146,147,147,147,147,147,147,148,148,148,148,148,148,149,149,149,149,149,150,150,150,150,150,150,151,151,151,151,151,152,152,152,152,152,153,153,153,153,153,154,154,154,154,154,155,155,155,155,155,156,156,156,156,157,157,157,157,157,158,158,158,158,159,159,159,159,159,160,160,160,160,161,161,161,161,162,162,162,162,163,163,163,163,164,164,164,165,165,165,165,166,166,166,166,167,167,167,168,168,168,168,169,169,169,169,170,170,170,171,171,171,172,172,172,172,173,173,173,174,174,174,175,175,175,175,176,176,176,177,177,177,178,178,178,179,179,179,180,180,180,181,181,181,182,182,182,183,183,183,184,184,184,185,185,185,186,186,186,187,187,187,188,188,188,189,189,189,190,190,191,191,191,192,192,192,193,193,193,194,194,195,195,195,196,196,196,197,197,197,198,198,199,199,199,200,200,200,201,201,202,202,202,203,203,204,204,204,205,205,205,206,206,207,207,207,208,208,209,209,209,210,210,211,211,211,212,212,212,213,213,214,214,214,215,215,216,216,217,217,217,218,218,219,219,219,220,220,221,221,221,222,222,223,223,223,224,224,225,225,225,226,226,227,227,228,228,228,229,229,230,230,230,231,231,232,232,233,233,233,234,234,235,235,235,236,236,237,237,238,238,238,239,239,240,240,241,241,241,242,242,243,243,244,244,244,245,245,246,246,246,247,247,248,248,249,249,249,250,250,251,251,252,252,252,253,253,254,254,255,255").as_slice()
);
assert_eq!(
brightness_contrast_map(53., -100.),
string_data("0,0,1,2,3,3,4,4,5,6,6,7,7,8,8,9,10,10,11,11,12,13,14,14,14,15,16,17,17,18,18,19,19,20,21,21,22,22,23,24,24,25,25,26,27,27,28,28,29,29,30,31,31,32,33,33,34,34,35,36,36,37,37,38,38,39,40,40,41,41,42,42,43,44,44,45,45,46,46,47,47,48,49,49,49,50,51,51,52,53,53,53,54,54,55,56,56,57,57,58,58,59,59,60,60,61,61,62,63,63,64,64,64,65,65,66,66,67,67,68,69,69,70,70,70,71,71,72,72,73,73,74,74,75,75,76,76,77,77,78,78,78,79,79,80,80,81,81,81,82,82,83,83,83,84,84,85,85,85,86,86,87,87,88,88,88,89,89,90,90,90,91,91,92,92,92,93,93,93,94,94,94,95,95,95,96,96,96,97,97,97,98,98,98,99,99,99,99,100,100,100,101,101,101,102,102,102,102,103,103,103,103,104,104,104,105,105,105,105,106,106,106,106,107,107,107,107,108,108,108,108,108,109,109,109,109,110,110,110,110,110,111,111,111,111,111,112,112,112,112,112,113,113,113,113,113,114,114,114,114,114,114,115,115,115,115,115,115,116,116,116,116,116,116,117,117,117,117,117,117,118,118,118,118,118,118,118,119,119,119,119,119,119,119,119,120,120,120,120,120,120,120,121,121,121,121,121,121,121,121,122,122,122,122,122,122,122,122,122,123,123,123,123,123,123,123,123,123,124,124,124,124,124,124,124,124,124,124,125,125,125,125,125,125,125,125,125,125,126,126,126,126,126,126,126,126,126,126,127,127,127,127,127,127,127,127,127,127,127,128,128,128,128,128,128,128,128,128,128,129,129,129,129,129,129,129,129,129,129,129,130,130,130,130,130,130,130,130,130,130,131,131,131,131,131,131,131,131,131,131,131,132,132,132,132,132,132,132,132,132,132,133,133,133,133,133,133,133,133,133,134,134,134,134,134,134,134,134,134,135,135,135,135,135,135,135,135,135,136,136,136,136,136,136,136,136,137,137,137,137,137,137,137,137,138,138,138,138,138,138,138,139,139,139,139,139,139,139,139,140,140,140,140,140,140,140,141,141,141,141,141,141,141,142,142,142,142,142,142,143,143,143,143,143,143,144,144,144,144,144,144,145,145,145,145,145,145,145,146,146,146,146,146,147,147,147,147,147,148,148,148,148,148,148,149,149,149,149,150,150,150,150,150,150,151,151,151,151,151,152,152,152,152,153,153,153,153,153,154,154,154,154,154,155,155,155,155,156,156,156,156,157,157,157,157,157,158,158,158,158,159,159,159,159,159,160,160,160,160,161,161,161,161,162,162,162,162,163,163,163,163,164,164,164,165,165,165,165,166,166,166,166,167,167,167,168,168,168,168,169,169,169,169,170,170,170,171,171,171,171,172,172,172,172,173,173,173,174,174,174,175,175,175,175,176,176,176,176,177,177,177,178,178,178,179,179,179,179,180,180,180,181,181,181,182,182,182,182,183,183,183,184,184,184,184,185,185,185,186,186,186,186,187,187,187,188,188,188,188,189,189,189,190,190,190,191,191,191,192,192,192,192,193,193,193,193,194,194,195,195,195,195,196,196,196,196,197,197,197,197,198,198,199,199,199,199,200,200,200,200,201,201,201,202,202,202,202,203,203,203,204,204,204,204,205,205,205,205,206,206,206,207,207,207,207,208,208,208,209,209,209,209,210,210,210,211,211,211,211,211,212,212,212,212,213,213,213,214,214,214,214,214,215,215,215,216,216,216,217,217,217,217,217,218,218,218,219,219,219,219,219,220,220,220,220,221,221,221,221,221,222,222,222,222,223,223,223,223,223,224,224,224,224,225,225,225,225,225,226,226,226,226,227,227,227,227,228,228,228,228,228,228,229,229,229,229,230,230,230,230,230,230,230,231,231,231,231,232,232,232,232,233,233,233,233,233,233,233,234,234,234,234,234,235,235,235,235,235,235,235,236,236,236,236,236,237,237,237,237,237,238,238,238,238,238,238,238,238,239,239,239,239,239,240,240,240,240,240,240,241,241,241,241,241,241,241,241,242,242,242,242,242,242,243,243,243,243,243,243,244,244,244,244,244,244,244,244,244,245,245,245,245,245,245,245,246,246,246,246,246,246,246,246,246,247,247,247,247,247,247,247,248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,249,249,250,250,250,250,250,250,250,251,251,251,251,251,251,251,252,252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253,253,253,254,254,254,254,254,254,254,255,255,255,255,255,255").as_slice()
);
assert_eq!(
brightness_contrast_map(150., -100.),
string_data("0,1,2,3,5,6,7,8,9,11,11,13,14,15,16,17,19,19,21,22,23,24,25,27,28,29,30,31,32,33,34,36,36,38,39,40,41,42,43,44,45,46,47,48,49,51,51,53,54,55,56,57,58,59,60,61,61,63,64,65,65,66,67,68,69,70,71,72,73,74,75,76,76,77,78,79,80,81,82,82,83,84,85,85,86,87,88,89,89,90,90,91,92,93,93,94,95,95,96,96,97,98,98,99,99,100,101,101,102,102,103,103,104,104,105,105,106,106,107,107,108,108,108,109,109,110,110,110,111,111,112,112,112,113,113,113,114,114,114,115,115,115,116,116,116,117,117,117,117,118,118,118,119,119,119,119,120,120,120,120,121,121,121,121,121,122,122,122,122,123,123,123,123,123,124,124,124,124,124,124,125,125,125,125,125,126,126,126,126,126,126,127,127,127,127,127,128,128,128,128,128,128,129,129,129,129,129,129,130,130,130,130,130,130,131,131,131,131,131,131,132,132,132,132,132,133,133,133,133,133,134,134,134,134,134,135,135,135,135,135,136,136,136,136,136,137,137,137,137,138,138,138,138,138,139,139,139,139,140,140,140,140,141,141,141,141,142,142,142,142,143,143,143,144,144,144,144,145,145,145,146,146,146,147,147,147,147,148,148,148,149,149,149,150,150,150,151,151,151,152,152,153,153,153,154,154,154,155,155,155,156,156,157,157,157,158,158,159,159,159,160,160,160,161,161,162,162,162,163,163,164,164,165,165,165,166,166,167,167,168,168,168,169,169,170,170,170,171,171,172,172,173,173,174,174,175,175,175,176,176,177,177,177,178,178,179,179,180,180,181,181,181,182,182,183,183,184,184,184,185,185,186,186,186,187,187,188,188,188,189,189,190,190,191,191,191,192,192,193,193,193,194,194,195,195,195,196,196,196,197,197,197,198,198,199,199,199,200,200,200,201,201,202,202,202,203,203,204,204,204,205,205,205,205,206,206,207,207,207,207,208,208,209,209,209,209,210,210,211,211,211,211,212,212,212,212,213,213,213,214,214,214,214,215,215,215,216,216,217,217,217,217,217,218,218,218,219,219,219,219,219,220,220,220,221,221,221,221,221,222,222,222,223,223,223,223,223,223,224,224,224,225,225,225,225,225,225,226,226,226,226,227,227,227,227,228,228,228,228,228,228,228,229,229,229,229,230,230,230,230,230,230,230,230,231,231,231,231,231,232,232,232,232,232,233,233,233,233,233,233,233,233,234,234,234,234,234,234,235,235,235,235,235,235,235,235,235,235,236,236,236,236,236,236,236,237,237,237,237,237,237,237,238,238,238,238,238,238,238,238,238,238,238,238,239,239,239,239,239,239,239,239,240,240,240,240,240,240,240,240,240,240,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,242,242,242,242,242,242,242,242,242,242,242,243,243,243,243,243,243,243,243,243,243,243,243,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,245,245,245,245,245,245,245,245,245,245,245,245,245,245,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255").as_slice()
);
}
}