pub fn simple_h2v1(input: &[u8], in_width: usize, output: &mut [u8], _out_width: usize) {
for x in 0..in_width {
let val = input[x];
output[x * 2] = val;
output[x * 2 + 1] = val;
}
}
pub fn simple_h2v2(
input: &[u8],
in_width: usize,
in_height: usize,
output: &mut [u8],
out_width: usize,
_out_height: usize,
) {
for y in 0..in_height {
for x in 0..in_width {
let val = input[y * in_width + x];
let out_y = y * 2;
let out_x = x * 2;
output[out_y * out_width + out_x] = val;
output[out_y * out_width + out_x + 1] = val;
output[(out_y + 1) * out_width + out_x] = val;
output[(out_y + 1) * out_width + out_x + 1] = val;
}
}
}
pub fn fancy_h2v1(input: &[u8], in_width: usize, output: &mut [u8], _out_width: usize) {
if in_width == 0 {
return;
}
if in_width == 1 {
output[0] = input[0];
output[1] = input[0];
return;
}
if in_width == 2 {
output[0] = input[0];
output[1] = input[0];
output[2] = input[1];
output[3] = input[1];
return;
}
output[0] = input[0];
output[1] = ((3 * input[0] as u16 + input[1] as u16 + 2) >> 2) as u8;
for x in 1..in_width - 1 {
let left = input[x - 1] as u16;
let cur = input[x] as u16;
let right = input[x + 1] as u16;
output[x * 2] = ((3 * cur + left + 1) >> 2) as u8;
output[x * 2 + 1] = ((3 * cur + right + 2) >> 2) as u8;
}
let last = in_width - 1;
output[last * 2] = ((3 * input[last] as u16 + input[last - 1] as u16 + 1) >> 2) as u8;
output[last * 2 + 1] = input[last];
}
pub fn fancy_h2v2(
input: &[u8],
in_width: usize,
in_height: usize,
output: &mut [u8],
out_width: usize,
_out_height: usize,
) {
fancy_h2v2_strided(input, in_width, in_width, in_height, output, out_width);
}
pub fn fancy_h2v2_strided(
input: &[u8],
in_width: usize,
in_stride: usize,
in_height: usize,
output: &mut [u8],
out_width: usize,
) {
for y in 0..in_height {
let cur_row = &input[y * in_stride..y * in_stride + in_width];
let above = if y > 0 {
&input[(y - 1) * in_stride..(y - 1) * in_stride + in_width]
} else {
cur_row
};
let below = if y + 1 < in_height {
&input[(y + 1) * in_stride..(y + 1) * in_stride + in_width]
} else {
cur_row
};
for (v, neighbor) in [(0, above), (1, below)] {
let out_y = y * 2 + v;
let out_row = &mut output[out_y * out_width..];
fancy_h2v2_row(cur_row, neighbor, out_row, in_width);
}
}
}
pub fn fancy_h2v2_row(cur: &[u8], neighbor: &[u8], output: &mut [u8], in_width: usize) {
if in_width == 0 {
return;
}
if in_width == 1 {
let colsum = cur[0] as i32 * 3 + neighbor[0] as i32;
output[0] = ((colsum * 4 + 8) >> 4) as u8;
output[1] = ((colsum * 4 + 7) >> 4) as u8;
return;
}
if in_width == 2 {
let colsum0 = cur[0] as i32 * 3 + neighbor[0] as i32;
let colsum1 = cur[1] as i32 * 3 + neighbor[1] as i32;
output[0] = ((colsum0 * 4 + 8) >> 4) as u8;
output[1] = ((colsum0 * 4 + 7) >> 4) as u8;
output[2] = ((colsum1 * 4 + 8) >> 4) as u8;
output[3] = ((colsum1 * 4 + 7) >> 4) as u8;
return;
}
let colsum = |i: usize| -> i32 { cur[i] as i32 * 3 + neighbor[i] as i32 };
let mut this_cs = colsum(0);
let mut next_cs = colsum(1);
output[0] = ((this_cs * 4 + 8) >> 4) as u8;
output[1] = ((this_cs * 3 + next_cs + 7) >> 4) as u8;
let mut last_cs = this_cs;
this_cs = next_cs;
for x in 1..in_width - 1 {
next_cs = colsum(x + 1);
output[x * 2] = ((this_cs * 3 + last_cs + 8) >> 4) as u8;
output[x * 2 + 1] = ((this_cs * 3 + next_cs + 7) >> 4) as u8;
last_cs = this_cs;
this_cs = next_cs;
}
let last = in_width - 1;
output[last * 2] = ((this_cs * 3 + last_cs + 8) >> 4) as u8;
output[last * 2 + 1] = ((this_cs * 4 + 7) >> 4) as u8;
}