Skip to content

Commit

Permalink
Ported mediancut.
Browse files Browse the repository at this point in the history
  • Loading branch information
mkrueger committed Sep 9, 2023
1 parent 5612bf2 commit fc9dbe4
Show file tree
Hide file tree
Showing 5 changed files with 1,237 additions and 1,346 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "icy_sixel"
version = "0.1.0"
version = "0.1.1"
edition = "2021"
authors = ["Mike Krüger <[email protected]>"]
description = "A 100% rust sixel library."
Expand Down
85 changes: 44 additions & 41 deletions src/dither.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use std::vec;

use crate::{
pixelformat::sixel_helper_normalize_pixelformat, BuiltinDither, ColorChoosingMethod,
DiffusionMethod, FindLargestDim, PixelFormat, Quality, SixelError, SixelResult,
SIXEL_PALETTE_MAX, quant::{sixel_quant_make_palette, sixel_quant_apply_palette},
pixelformat::sixel_helper_normalize_pixelformat,
quant::{sixel_quant_apply_palette, sixel_quant_make_palette},
BuiltinDither, DiffusionMethod, MethodForLargest, MethodForRep, PixelFormat, Quality,
SixelError, SixelResult, SIXEL_PALETTE_MAX,
};

pub struct sixel_dither {
Expand All @@ -16,13 +17,13 @@ pub struct sixel_dither {
pub optimize_palette: bool, /* minimize palette size */
pub complexion: i32, /* for complexion correction */
pub bodyonly: bool, /* do not output palette section if true */
pub method_for_largest: FindLargestDim, /* method for finding the largest dimention
pub method_for_largest: MethodForLargest, /* method for finding the largest dimention
for splitting */
pub method_for_rep: ColorChoosingMethod, /* method for choosing a color from the box */
pub method_for_rep: MethodForRep, /* method for choosing a color from the box */
pub method_for_diffuse: DiffusionMethod, /* method for diffusing */
pub quality_mode: Quality, /* quality of histogram */
pub keycolor: i32, /* background color */
pub pixelformat: PixelFormat, /* pixelformat for internal processing */
pub quality_mode: Quality, /* quality of histogram */
pub keycolor: i32, /* background color */
pub pixelformat: PixelFormat, /* pixelformat for internal processing */
}

const pal_mono_dark: [u8; 6] = [0x00, 0x00, 0x00, 0xff, 0xff, 0xff];
Expand Down Expand Up @@ -205,7 +206,6 @@ impl sixel_dither {
}
Quality::LOW
};

Ok(Self {
palette: vec![0; ncolors as usize * 3],
cachetable: None,
Expand All @@ -217,8 +217,8 @@ impl sixel_dither {
optimize_palette: false,
complexion: 1,
bodyonly: false,
method_for_largest: FindLargestDim::Norm,
method_for_rep: ColorChoosingMethod::CenterBox,
method_for_largest: MethodForLargest::Norm,
method_for_rep: MethodForRep::CenterBox,
method_for_diffuse: DiffusionMethod::FS,
quality_mode,
pixelformat: PixelFormat::RGB888,
Expand Down Expand Up @@ -247,17 +247,17 @@ impl sixel_dither {
Ok(result)
}

pub fn set_method_for_largest(&mut self, method_for_largest: FindLargestDim) {
self.method_for_largest = if matches!(method_for_largest, FindLargestDim::Auto) {
FindLargestDim::Norm
pub fn set_method_for_largest(&mut self, method_for_largest: MethodForLargest) {
self.method_for_largest = if matches!(method_for_largest, MethodForLargest::Auto) {
MethodForLargest::Norm
} else {
method_for_largest
};
}

pub fn set_method_for_rep(&mut self, method_for_rep: ColorChoosingMethod) {
self.method_for_rep = if matches!(method_for_rep, ColorChoosingMethod::Auto) {
ColorChoosingMethod::CenterBox
pub fn set_method_for_rep(&mut self, method_for_rep: MethodForRep) {
self.method_for_rep = if matches!(method_for_rep, MethodForRep::Auto) {
MethodForRep::CenterBox
} else {
method_for_rep
};
Expand All @@ -281,8 +281,8 @@ impl sixel_dither {
width: i32,
height: i32,
mut pixelformat: PixelFormat,
method_for_largest: FindLargestDim,
method_for_rep: ColorChoosingMethod,
method_for_largest: MethodForLargest,
method_for_rep: MethodForRep,
quality_mode: Quality,
) -> SixelResult<()> {
self.set_pixelformat(pixelformat);
Expand All @@ -307,17 +307,17 @@ impl sixel_dither {
self.set_quality_mode(quality_mode);

let buf = sixel_quant_make_palette(
&input_pixels,
width * height * 3,
PixelFormat::RGB888,
self.reqcolors,
&mut self.ncolors,
&mut self.origcolors,
self.method_for_largest,
self.method_for_rep,
self.quality_mode)?;

println!("set colors:{}", self.ncolors);
&input_pixels,
width * height * 3,
PixelFormat::RGB888,
self.reqcolors,
&mut self.ncolors,
&mut self.origcolors,
self.method_for_largest,
self.method_for_rep,
self.quality_mode,
)?;

self.palette = buf;
self.optimized = true;
if self.origcolors <= self.ncolors {
Expand Down Expand Up @@ -430,17 +430,20 @@ impl sixel_dither {
} else {
pixels.to_vec()
};

let ncolors = sixel_quant_apply_palette(&mut dest,
&mut input_pixels,
width, height, 3,
&mut self.palette,
self.ncolors,
self.method_for_diffuse,
self.optimized,
self.optimize_palette,
self.complexion,
Some(self.cachetable.as_mut().unwrap()))?;
let ncolors = sixel_quant_apply_palette(
&mut dest,
&mut input_pixels,
width,
height,
3,
&mut self.palette,
self.ncolors,
self.method_for_diffuse,
self.optimized,
self.optimize_palette,
self.complexion,
Some(self.cachetable.as_mut().unwrap()),
)?;
self.ncolors = ncolors;

Ok(dest)
Expand Down
28 changes: 18 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use output::sixel_output;
pub mod dither;
pub mod output;
pub mod pixelformat;
pub mod tosixel;
pub mod quant;
pub mod tosixel;

/* limitations */
const SIXEL_OUTPUT_PACKET_SIZE: usize = 16384;
Expand Down Expand Up @@ -95,7 +95,7 @@ const SIXEL_FAILED(status) (((status) & 0x1000) != 0)
/// method for finding the largest dimension for splitting,
/// and sorting by that component
#[derive(Clone, Copy)]
pub enum FindLargestDim {
pub enum MethodForLargest {
/// choose automatically the method for finding the largest dimension
Auto,
/// simply comparing the range in RGB space
Expand All @@ -106,7 +106,7 @@ pub enum FindLargestDim {

/// method for choosing a color from the box
#[derive(Clone, Copy)]
pub enum ColorChoosingMethod {
pub enum MethodForRep {
/// choose automatically the method for selecting
/// representative color from each box
Auto,
Expand Down Expand Up @@ -592,6 +592,9 @@ pub fn sixel_string(
height: i32,
pixelformat: PixelFormat,
method_for_diffuse: DiffusionMethod,
method_for_largest: MethodForLargest,
method_for_rep: MethodForRep,
quality_mode: Quality,
) -> SixelResult<String> {
let mut sixel_data: Vec<u8> = Vec::new();

Expand All @@ -604,16 +607,21 @@ pub fn sixel_string(
width,
height,
pixelformat,
FindLargestDim::Norm,
ColorChoosingMethod::Auto,
Quality::AUTO,
method_for_largest,
method_for_rep,
quality_mode,
)?;
sixel_dither.set_pixelformat(pixelformat);
sixel_dither.set_diffusion_type(DiffusionMethod::Stucki);
// sixel_dither.set_diffusion_type(method_for_diffuse);

sixel_dither.set_diffusion_type(method_for_diffuse);

let mut bytes = bytes.to_vec();
sixel_output.encode(&mut bytes, width, height, 0, &mut sixel_dither)?;

Ok(String::from_utf8_lossy(&sixel_data).to_string())
}
} /*
pub fn main() {
let bytes = vec![
];
println!("{}", sixel_string(&bytes, 128, 128, PixelFormat::RGB888, DiffusionMethod::Stucki, MethodForLargest::Auto, MethodForRep::Auto, Quality::AUTO).unwrap());
}*/
Loading

0 comments on commit fc9dbe4

Please sign in to comment.