Skip to content

Commit

Permalink
refactor remapper code
Browse files Browse the repository at this point in the history
  • Loading branch information
exoticorn committed Jul 24, 2016
1 parent 6dbf34b commit fa1fcd9
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 58 deletions.
5 changes: 3 additions & 2 deletions examples/demo.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
extern crate exoquant;
extern crate lodepng;

use exoquant::{Color, Remapper, RemapperOrdered, SimpleColorSpace};
use exoquant::{Color, SimpleColorSpace};
use exoquant::remapper::*;

fn main() {
println!("Loading PNG");
Expand Down Expand Up @@ -49,7 +50,7 @@ fn main() {
state.info_raw().colortype = lodepng::ColorType::LCT_PALETTE;

println!("Remapping image to palette");
let remapper = RemapperOrdered::new(&palette, &colorspace);
let remapper = Remapper::new(&palette, &colorspace, DithererOrdered);
let image: Vec<_> = remapper.remap8(&input_image, input.width);

println!("Saving PNG");
Expand Down
2 changes: 1 addition & 1 deletion src/colorspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub struct SimpleColorSpace {
impl SimpleColorSpace {
pub fn default() -> SimpleColorSpace {
SimpleColorSpace {
gamma: 2.2,
gamma: 1.145,
scale: FloatColor {
r: 1.0,
g: 1.2,
Expand Down
3 changes: 1 addition & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ mod color;
mod histogram;
mod quantizer;
pub mod colormap;
mod remapper;
pub mod remapper;
mod kmeans;
pub mod colorspace;

pub use color::Color;
pub use histogram::Histogram;
pub use quantizer::Quantizer;
pub use remapper::{Remapper, RemapperNoDither, RemapperOrdered, RemapperOrdered2};
pub use kmeans::{optimize_palette, optimize_palette_weighted};
pub use colorspace::{ColorSpace, SimpleColorSpace};
106 changes: 53 additions & 53 deletions src/remapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,101 +3,101 @@ use ::color::FloatColor;
use ::colormap::ColorMap;
use ::colorspace::ColorSpace;

pub trait Remapper {
fn remap(&self, image: &[Color], width: usize) -> Vec<usize>;
fn remap8(&self, image: &[Color], width: usize) -> Vec<u8> {
self.remap(image, width).iter().map(|i| *i as u8).collect()
}
}

pub struct RemapperNoDither<'a, T: 'a + ColorSpace> {
pub struct Remapper<'a, T: 'a + ColorSpace, D: Ditherer> {
map: ColorMap,
colorspace: &'a T,
ditherer: D,
}

impl<'a, T: ColorSpace> RemapperNoDither<'a, T> {
pub fn new(palette: &[Color], colorspace: &'a T) -> RemapperNoDither<'a, T> {
RemapperNoDither {
impl<'a, T: ColorSpace, D: Ditherer> Remapper<'a, T, D> {
pub fn new(palette: &[Color], colorspace: &'a T, ditherer: D) -> Remapper<'a, T, D> {
Remapper {
map: ColorMap::new(palette, colorspace),
colorspace: colorspace,
ditherer: ditherer,
}
}
}

impl<'a, T: ColorSpace> Remapper for RemapperNoDither<'a, T> {
fn remap(&self, image: &[Color], _: usize) -> Vec<usize> {
image.iter().map(|c| self.map.find_nearest(self.colorspace.to_float(*c))).collect()
pub fn remap(&self, image: &[Color], width: usize) -> Vec<usize> {
self.ditherer.remap(&self.map, self.colorspace, image, width)
}

pub fn remap8(&self, image: &[Color], width: usize) -> Vec<u8> {
self.remap(image, width).iter().map(|i| *i as u8).collect()
}
}

pub struct RemapperOrdered<'a, T: 'a + ColorSpace> {
map: ColorMap,
colorspace: &'a T,
pub trait Ditherer {
fn remap<T: ColorSpace>(&self,
map: &ColorMap,
colorspace: &T,
image: &[Color],
width: usize)
-> Vec<usize>;
}

impl<'a, T: ColorSpace> RemapperOrdered<'a, T> {
pub fn new(palette: &[Color], colorspace: &'a T) -> RemapperOrdered<'a, T> {
RemapperOrdered {
map: ColorMap::new(palette, colorspace),
colorspace: colorspace,
}
pub struct DithererNone;
impl Ditherer for DithererNone {
fn remap<T: ColorSpace>(&self,
map: &ColorMap,
colorspace: &T,
image: &[Color],
_: usize)
-> Vec<usize> {
image.iter().map(|c| map.find_nearest(colorspace.to_float(*c))).collect()
}
}

pub struct DithererOrdered;
const DITHER_MATRIX: [f64; 4] = [-0.375, 0.125, 0.375, -0.125];

impl<'a, T: ColorSpace> Remapper for RemapperOrdered<'a, T> {
fn remap(&self, image: &[Color], width: usize) -> Vec<usize> {
impl Ditherer for DithererOrdered {
fn remap<T: ColorSpace>(&self,
map: &ColorMap,
colorspace: &T,
image: &[Color],
width: usize)
-> Vec<usize> {
image.iter()
.enumerate()
.map(|(i, c)| {
let x = i % width;
let y = i / width;
let dither = DITHER_MATRIX[(x & 1) + (y & 1) * 2];
let color: FloatColor = self.colorspace.to_float(*c);
let i = self.map.find_nearest(color);
let d = self.map.neighbor_distance(i);
let color: FloatColor = colorspace.to_float(*c);
let i = map.find_nearest(color);
let d = map.neighbor_distance(i);
let color = color + (d * dither * 0.75);
self.map.find_nearest(color)
map.find_nearest(color)
})
.collect()
}
}

pub struct RemapperOrdered2<'a, T: 'a + ColorSpace> {
map: ColorMap,
colorspace: &'a T,
}

impl<'a, T: ColorSpace> RemapperOrdered2<'a, T> {
pub fn new(palette: &[Color], colorspace: &'a T) -> RemapperOrdered2<'a, T> {
RemapperOrdered2 {
map: ColorMap::new(palette, colorspace),
colorspace: colorspace,
}
}
}

pub struct DithererExperimentalOrdered;
const DITHER_MATRIX2: [u32; 4] = [0, 2, 3, 1];

impl<'a, T: ColorSpace> Remapper for RemapperOrdered2<'a, T> {
fn remap(&self, image: &[Color], width: usize) -> Vec<usize> {
impl Ditherer for DithererExperimentalOrdered {
fn remap<T: ColorSpace>(&self,
map: &ColorMap,
colorspace: &T,
image: &[Color],
width: usize)
-> Vec<usize> {
image.iter()
.enumerate()
.map(|(i, c)| {
let x = i % width;
let y = i / width;
let color: FloatColor = self.colorspace.to_float(*c);
let i = self.map.find_nearest(color);
let c = self.map.float_color(i);
let color: FloatColor = colorspace.to_float(*c);
let i = map.find_nearest(color);
let c = map.float_color(i);
let diff = color - c;
let d = diff.abs();
if d < 0.00001 {
return i;
}
let dir = diff * (1.0 / d);
let j = self.map.neighbor_in_dir(i, dir);
let c2 = self.map.float_color(j);
let j = map.neighbor_in_dir(i, dir);
let c2 = map.float_color(j);
let span = c2 - c;
let f = (color - c).dot(&span) / span.dot(&span);
let offset = if f > 0.375 {
Expand Down

0 comments on commit fa1fcd9

Please sign in to comment.