dither.rs - icy_draw - [fork] icy_draw is the successor to mystic draw.
HTML git clone https://git.drkhsh.at/icy_draw.git
DIR Log
DIR Files
DIR Refs
DIR README
---
dither.rs (21140B)
---
1 use std::vec;
2
3 use crate::{
4 pixelformat::sixel_helper_normalize_pixelformat,
5 quant::{sixel_quant_apply_palette, sixel_quant_make_palette},
6 BuiltinDither, DiffusionMethod, MethodForLargest, MethodForRep, PixelFormat, Quality, SixelError, SixelResult, SIXEL_PALETTE_MAX,
7 };
8
9 pub struct sixel_dither {
10 pub palette: Vec<u8>, /* palette definition */
11 pub cachetable: Option<Vec<u16>>, /* cache table */
12 pub reqcolors: i32, /* requested colors */
13 pub ncolors: i32, /* active colors */
14 pub origcolors: i32, /* original colors */
15 pub optimized: bool, /* pixel is 15bpp compressable */
16 pub optimize_palette: bool, /* minimize palette size */
17 pub complexion: i32, /* for complexion correction */
18 pub bodyonly: bool, /* do not output palette section if true */
19 pub method_for_largest: MethodForLargest, /* method for finding the largest dimention
20 for splitting */
21 pub method_for_rep: MethodForRep, /* method for choosing a color from the box */
22 pub method_for_diffuse: DiffusionMethod, /* method for diffusing */
23 pub quality_mode: Quality, /* quality of histogram */
24 pub keycolor: i32, /* background color */
25 pub pixelformat: PixelFormat, /* pixelformat for internal processing */
26 }
27
28 const pal_mono_dark: [u8; 6] = [0x00, 0x00, 0x00, 0xff, 0xff, 0xff];
29
30 const pal_mono_light: [u8; 6] = [0xff, 0xff, 0xff, 0x00, 0x00, 0x00];
31
32 const pal_gray_1bit: [u8; 6] = [0x00, 0x00, 0x00, 0xff, 0xff, 0xff];
33
34 const pal_gray_2bit: [u8; 12] = [0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff];
35
36 const pal_gray_4bit: [u8; 48] = [
37 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x33, 0x33, 0x33, 0x44, 0x44, 0x44, 0x55, 0x55, 0x55, 0x66, 0x66, 0x66, 0x77, 0x77, 0x77, 0x88, 0x88,
38 0x88, 0x99, 0x99, 0x99, 0xaa, 0xaa, 0xaa, 0xbb, 0xbb, 0xbb, 0xcc, 0xcc, 0xcc, 0xdd, 0xdd, 0xdd, 0xee, 0xee, 0xee, 0xff, 0xff, 0xff,
39 ];
40
41 const pal_gray_8bit: [u8; 768] = [
42 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x08, 0x08,
43 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x10, 0x10, 0x10, 0x11,
44 0x11, 0x11, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19,
45 0x1a, 0x1a, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22,
46 0x22, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x2a, 0x2a, 0x2a, 0x2b,
47 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x32, 0x32, 0x32, 0x33, 0x33, 0x33,
48 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0x36, 0x36, 0x36, 0x37, 0x37, 0x37, 0x38, 0x38, 0x38, 0x39, 0x39, 0x39, 0x3a, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3c, 0x3c,
49 0x3c, 0x3d, 0x3d, 0x3d, 0x3e, 0x3e, 0x3e, 0x3f, 0x3f, 0x3f, 0x40, 0x40, 0x40, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x43, 0x43, 0x43, 0x44, 0x44, 0x44, 0x45,
50 0x45, 0x45, 0x46, 0x46, 0x46, 0x47, 0x47, 0x47, 0x48, 0x48, 0x48, 0x49, 0x49, 0x49, 0x4a, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4c, 0x4c, 0x4d, 0x4d, 0x4d,
51 0x4e, 0x4e, 0x4e, 0x4f, 0x4f, 0x4f, 0x50, 0x50, 0x50, 0x51, 0x51, 0x51, 0x52, 0x52, 0x52, 0x53, 0x53, 0x53, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x56, 0x56,
52 0x56, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5c, 0x5c, 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x5e, 0x5f,
53 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, 0x63, 0x63, 0x64, 0x64, 0x64, 0x65, 0x65, 0x65, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67,
54 0x68, 0x68, 0x68, 0x69, 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x70,
55 0x70, 0x71, 0x71, 0x71, 0x72, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79,
56 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81,
57 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x86, 0x86, 0x86, 0x87, 0x87, 0x87, 0x88, 0x88, 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a,
58 0x8a, 0x8b, 0x8b, 0x8b, 0x8c, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x91, 0x91, 0x91, 0x92, 0x92, 0x92, 0x93,
59 0x93, 0x93, 0x94, 0x94, 0x94, 0x95, 0x95, 0x95, 0x96, 0x96, 0x96, 0x97, 0x97, 0x97, 0x98, 0x98, 0x98, 0x99, 0x99, 0x99, 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, 0x9b,
60 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0x9f, 0x9f, 0x9f, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4,
61 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa6, 0xa6, 0xa7, 0xa7, 0xa7, 0xa8, 0xa8, 0xa8, 0xa9, 0xa9, 0xa9, 0xaa, 0xaa, 0xaa, 0xab, 0xab, 0xab, 0xac, 0xac, 0xac, 0xad,
62 0xad, 0xad, 0xae, 0xae, 0xae, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5,
63 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe,
64 0xbe, 0xbf, 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc1, 0xc1, 0xc1, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc7,
65 0xc7, 0xc7, 0xc8, 0xc8, 0xc8, 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf,
66 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd2, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4, 0xd5, 0xd5, 0xd5, 0xd6, 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8,
67 0xd8, 0xd9, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe1,
68 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe9, 0xe9, 0xe9,
69 0xea, 0xea, 0xea, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf2, 0xf2,
70 0xf2, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfb,
71 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff,
72 ];
73
74 const pal_xterm256: [u8; 768] = [
75 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0x80, 0x80,
76 0x80, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
77 0x00, 0x5f, 0x00, 0x00, 0x87, 0x00, 0x00, 0xaf, 0x00, 0x00, 0xd7, 0x00, 0x00, 0xff, 0x00, 0x5f, 0x00, 0x00, 0x5f, 0x5f, 0x00, 0x5f, 0x87, 0x00, 0x5f, 0xaf,
78 0x00, 0x5f, 0xd7, 0x00, 0x5f, 0xff, 0x00, 0x87, 0x00, 0x00, 0x87, 0x5f, 0x00, 0x87, 0x87, 0x00, 0x87, 0xaf, 0x00, 0x87, 0xd7, 0x00, 0x87, 0xff, 0x00, 0xaf,
79 0x00, 0x00, 0xaf, 0x5f, 0x00, 0xaf, 0x87, 0x00, 0xaf, 0xaf, 0x00, 0xaf, 0xd7, 0x00, 0xaf, 0xff, 0x00, 0xd7, 0x00, 0x00, 0xd7, 0x5f, 0x00, 0xd7, 0x87, 0x00,
80 0xd7, 0xaf, 0x00, 0xd7, 0xd7, 0x00, 0xd7, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x5f, 0x00, 0xff, 0x87, 0x00, 0xff, 0xaf, 0x00, 0xff, 0xd7, 0x00, 0xff, 0xff,
81 0x5f, 0x00, 0x00, 0x5f, 0x00, 0x5f, 0x5f, 0x00, 0x87, 0x5f, 0x00, 0xaf, 0x5f, 0x00, 0xd7, 0x5f, 0x00, 0xff, 0x5f, 0x5f, 0x00, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
82 0x87, 0x5f, 0x5f, 0xaf, 0x5f, 0x5f, 0xd7, 0x5f, 0x5f, 0xff, 0x5f, 0x87, 0x00, 0x5f, 0x87, 0x5f, 0x5f, 0x87, 0x87, 0x5f, 0x87, 0xaf, 0x5f, 0x87, 0xd7, 0x5f,
83 0x87, 0xff, 0x5f, 0xaf, 0x00, 0x5f, 0xaf, 0x5f, 0x5f, 0xaf, 0x87, 0x5f, 0xaf, 0xaf, 0x5f, 0xaf, 0xd7, 0x5f, 0xaf, 0xff, 0x5f, 0xd7, 0x00, 0x5f, 0xd7, 0x5f,
84 0x5f, 0xd7, 0x87, 0x5f, 0xd7, 0xaf, 0x5f, 0xd7, 0xd7, 0x5f, 0xd7, 0xff, 0x5f, 0xff, 0x00, 0x5f, 0xff, 0x5f, 0x5f, 0xff, 0x87, 0x5f, 0xff, 0xaf, 0x5f, 0xff,
85 0xd7, 0x5f, 0xff, 0xff, 0x87, 0x00, 0x00, 0x87, 0x00, 0x5f, 0x87, 0x00, 0x87, 0x87, 0x00, 0xaf, 0x87, 0x00, 0xd7, 0x87, 0x00, 0xff, 0x87, 0x5f, 0x00, 0x87,
86 0x5f, 0x5f, 0x87, 0x5f, 0x87, 0x87, 0x5f, 0xaf, 0x87, 0x5f, 0xd7, 0x87, 0x5f, 0xff, 0x87, 0x87, 0x00, 0x87, 0x87, 0x5f, 0x87, 0x87, 0x87, 0x87, 0x87, 0xaf,
87 0x87, 0x87, 0xd7, 0x87, 0x87, 0xff, 0x87, 0xaf, 0x00, 0x87, 0xaf, 0x5f, 0x87, 0xaf, 0x87, 0x87, 0xaf, 0xaf, 0x87, 0xaf, 0xd7, 0x87, 0xaf, 0xff, 0x87, 0xd7,
88 0x00, 0x87, 0xd7, 0x5f, 0x87, 0xd7, 0x87, 0x87, 0xd7, 0xaf, 0x87, 0xd7, 0xd7, 0x87, 0xd7, 0xff, 0x87, 0xff, 0x00, 0x87, 0xff, 0x5f, 0x87, 0xff, 0x87, 0x87,
89 0xff, 0xaf, 0x87, 0xff, 0xd7, 0x87, 0xff, 0xff, 0xaf, 0x00, 0x00, 0xaf, 0x00, 0x5f, 0xaf, 0x00, 0x87, 0xaf, 0x00, 0xaf, 0xaf, 0x00, 0xd7, 0xaf, 0x00, 0xff,
90 0xaf, 0x5f, 0x00, 0xaf, 0x5f, 0x5f, 0xaf, 0x5f, 0x87, 0xaf, 0x5f, 0xaf, 0xaf, 0x5f, 0xd7, 0xaf, 0x5f, 0xff, 0xaf, 0x87, 0x00, 0xaf, 0x87, 0x5f, 0xaf, 0x87,
91 0x87, 0xaf, 0x87, 0xaf, 0xaf, 0x87, 0xd7, 0xaf, 0x87, 0xff, 0xaf, 0xaf, 0x00, 0xaf, 0xaf, 0x5f, 0xaf, 0xaf, 0x87, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xd7, 0xaf,
92 0xaf, 0xff, 0xaf, 0xd7, 0x00, 0xaf, 0xd7, 0x5f, 0xaf, 0xd7, 0x87, 0xaf, 0xd7, 0xaf, 0xaf, 0xd7, 0xd7, 0xaf, 0xd7, 0xff, 0xaf, 0xff, 0x00, 0xaf, 0xff, 0x5f,
93 0xaf, 0xff, 0x87, 0xaf, 0xff, 0xaf, 0xaf, 0xff, 0xd7, 0xaf, 0xff, 0xff, 0xd7, 0x00, 0x00, 0xd7, 0x00, 0x5f, 0xd7, 0x00, 0x87, 0xd7, 0x00, 0xaf, 0xd7, 0x00,
94 0xd7, 0xd7, 0x00, 0xff, 0xd7, 0x5f, 0x00, 0xd7, 0x5f, 0x5f, 0xd7, 0x5f, 0x87, 0xd7, 0x5f, 0xaf, 0xd7, 0x5f, 0xd7, 0xd7, 0x5f, 0xff, 0xd7, 0x87, 0x00, 0xd7,
95 0x87, 0x5f, 0xd7, 0x87, 0x87, 0xd7, 0x87, 0xaf, 0xd7, 0x87, 0xd7, 0xd7, 0x87, 0xff, 0xd7, 0xaf, 0x00, 0xd7, 0xaf, 0x5f, 0xd7, 0xaf, 0x87, 0xd7, 0xaf, 0xaf,
96 0xd7, 0xaf, 0xd7, 0xd7, 0xaf, 0xff, 0xd7, 0xd7, 0x00, 0xd7, 0xd7, 0x5f, 0xd7, 0xd7, 0x87, 0xd7, 0xd7, 0xaf, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xff, 0xd7, 0xff,
97 0x00, 0xd7, 0xff, 0x5f, 0xd7, 0xff, 0x87, 0xd7, 0xff, 0xaf, 0xd7, 0xff, 0xd7, 0xd7, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x5f, 0xff, 0x00, 0x87, 0xff,
98 0x00, 0xaf, 0xff, 0x00, 0xd7, 0xff, 0x00, 0xff, 0xff, 0x5f, 0x00, 0xff, 0x5f, 0x5f, 0xff, 0x5f, 0x87, 0xff, 0x5f, 0xaf, 0xff, 0x5f, 0xd7, 0xff, 0x5f, 0xff,
99 0xff, 0x87, 0x00, 0xff, 0x87, 0x5f, 0xff, 0x87, 0x87, 0xff, 0x87, 0xaf, 0xff, 0x87, 0xd7, 0xff, 0x87, 0xff, 0xff, 0xaf, 0x00, 0xff, 0xaf, 0x5f, 0xff, 0xaf,
100 0x87, 0xff, 0xaf, 0xaf, 0xff, 0xaf, 0xd7, 0xff, 0xaf, 0xff, 0xff, 0xd7, 0x00, 0xff, 0xd7, 0x5f, 0xff, 0xd7, 0x87, 0xff, 0xd7, 0xaf, 0xff, 0xd7, 0xd7, 0xff,
101 0xd7, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x5f, 0xff, 0xff, 0x87, 0xff, 0xff, 0xaf, 0xff, 0xff, 0xd7, 0xff, 0xff, 0xff, 0x08, 0x08, 0x08, 0x12, 0x12, 0x12,
102 0x1c, 0x1c, 0x1c, 0x26, 0x26, 0x26, 0x30, 0x30, 0x30, 0x3a, 0x3a, 0x3a, 0x44, 0x44, 0x44, 0x4e, 0x4e, 0x4e, 0x58, 0x58, 0x58, 0x62, 0x62, 0x62, 0x6c, 0x6c,
103 0x6c, 0x76, 0x76, 0x76, 0x80, 0x80, 0x80, 0x8a, 0x8a, 0x8a, 0x94, 0x94, 0x94, 0x9e, 0x9e, 0x9e, 0xa8, 0xa8, 0xa8, 0xb2, 0xb2, 0xb2, 0xbc, 0xbc, 0xbc, 0xc6,
104 0xc6, 0xc6, 0xd0, 0xd0, 0xd0, 0xda, 0xda, 0xda, 0xe4, 0xe4, 0xe4, 0xee, 0xee, 0xee,
105 ];
106
107 /*
108 * VT340 undocumented behavior regarding the color palette reported
109 * by Vertis Sidus(@vrtsds):
110 * it loads the first fifteen colors as 1 through 15, and loads the
111 * sixteenth color as 0.
112 */
113 const pal_vt340_mono: [u8; 48] = [
114 0x21, 0x21, 0x21, // 1 Gray-2
115 0x42, 0x42, 0x42, // 2 Gray-4
116 0x66, 0x66, 0x66, // 3 Gray-6
117 0x0F, 0x0F, 0x0F, // 4 Gray-1
118 0x33, 0x33, 0x33, // 5 Gray-3
119 0x54, 0x54, 0x54, // 6 Gray-5
120 0x75, 0x75, 0x75, // 7 White 7
121 0x00, 0x00, 0x00, // 8 Black 0
122 0x21, 0x21, 0x21, // 9 Gray-2
123 0x42, 0x42, 0x42, // 10 Gray-4
124 0x66, 0x66, 0x66, // 11 Gray-6
125 0x0F, 0x0F, 0x0F, // 12 Gray-1
126 0x33, 0x33, 0x33, // 13 Gray-3
127 0x54, 0x54, 0x54, // 14 Gray-5
128 0x75, 0x75, 0x75, // 15 White 7
129 0x00, 0x00, 0x00, // 0 Black
130 ];
131
132 const pal_vt340_color: [u8; 48] = [
133 0x21, 0x21, 0x21, // 1 Gray-2
134 0x42, 0x42, 0x42, // 2 Gray-4
135 0x66, 0x66, 0x66, // 3 Gray-6
136 0x0F, 0x0F, 0x0F, // 4 Gray-1
137 0x33, 0x33, 0x33, // 5 Gray-3
138 0x54, 0x54, 0x54, // 6 Gray-5
139 0x75, 0x75, 0x75, // 7 White 7
140 0x00, 0x00, 0x00, // 8 Black 0
141 0x21, 0x21, 0x21, // 9 Gray-2
142 0x42, 0x42, 0x42, // 10 Gray-4
143 0x66, 0x66, 0x66, // 11 Gray-6
144 0x0F, 0x0F, 0x0F, // 12 Gray-1
145 0x33, 0x33, 0x33, // 13 Gray-3
146 0x54, 0x54, 0x54, // 14 Gray-5
147 0x75, 0x75, 0x75, // 15 White 7
148 0x00, 0x00, 0x00, // 0 Black
149 ];
150
151 impl sixel_dither {
152 /// create dither context object
153 /// /* required colors */
154 pub fn new(mut ncolors: i32) -> SixelResult<Self> {
155 let quality_mode = if ncolors < 0 {
156 ncolors = SIXEL_PALETTE_MAX as i32;
157 Quality::HIGHCOLOR
158 } else {
159 if ncolors > SIXEL_PALETTE_MAX as i32 {
160 return Err(Box::new(SixelError::BadInput));
161 }
162 if ncolors < 1 {
163 return Err(Box::new(SixelError::BadInput));
164 // sixel_helper_set_additional_message(
165 // "sixel_dither_new: palette colors must be more than 0");
166 }
167 Quality::LOW
168 };
169 Ok(Self {
170 palette: vec![0; ncolors as usize * 3],
171 cachetable: None,
172 reqcolors: ncolors,
173 ncolors,
174 origcolors: (-1),
175 keycolor: (-1),
176 optimized: false,
177 optimize_palette: false,
178 complexion: 1,
179 bodyonly: false,
180 method_for_largest: MethodForLargest::Norm,
181 method_for_rep: MethodForRep::CenterBox,
182 method_for_diffuse: DiffusionMethod::FS,
183 quality_mode,
184 pixelformat: PixelFormat::RGB888,
185 })
186 }
187
188 pub fn sixel_dither_get(builtin_dither: BuiltinDither) -> SixelResult<Self> {
189 let (ncolors, palette, keycolor) = match builtin_dither {
190 BuiltinDither::MonoDark => (2, pal_mono_dark.to_vec(), 0),
191 BuiltinDither::MonoLight => (2, pal_mono_light.to_vec(), 0),
192 BuiltinDither::XTerm16 => (16, pal_xterm256.to_vec(), -1),
193 BuiltinDither::XTerm256 => (256, pal_xterm256.to_vec(), -1),
194 BuiltinDither::VT340Mono => (16, pal_vt340_mono.to_vec(), -1),
195 BuiltinDither::VT340Color => (16, pal_vt340_color.to_vec(), -1),
196 BuiltinDither::G1 => (2, pal_gray_1bit.to_vec(), -1),
197 BuiltinDither::G2 => (4, pal_gray_2bit.to_vec(), -1),
198 BuiltinDither::G4 => (16, pal_gray_4bit.to_vec(), -1),
199 BuiltinDither::G8 => (256, pal_gray_8bit.to_vec(), -1),
200 };
201
202 let mut result = sixel_dither::new(ncolors)?;
203 result.palette = palette;
204 result.keycolor = keycolor;
205 result.optimized = true;
206 result.optimize_palette = false;
207 Ok(result)
208 }
209
210 pub fn set_method_for_largest(&mut self, method_for_largest: MethodForLargest) {
211 self.method_for_largest = if matches!(method_for_largest, MethodForLargest::Auto) {
212 MethodForLargest::Norm
213 } else {
214 method_for_largest
215 };
216 }
217
218 pub fn set_method_for_rep(&mut self, method_for_rep: MethodForRep) {
219 self.method_for_rep = if matches!(method_for_rep, MethodForRep::Auto) {
220 MethodForRep::CenterBox
221 } else {
222 method_for_rep
223 };
224 }
225
226 pub fn set_quality_mode(&mut self, quality_mode: Quality) {
227 self.quality_mode = if matches!(quality_mode, Quality::AUTO) {
228 if self.ncolors <= 8 {
229 Quality::HIGH
230 } else {
231 Quality::LOW
232 }
233 } else {
234 quality_mode
235 };
236 }
237
238 #[allow(clippy::too_many_arguments)]
239 pub fn initialize(
240 &mut self,
241 data: &[u8],
242 width: i32,
243 height: i32,
244 pixelformat: PixelFormat,
245 method_for_largest: MethodForLargest,
246 method_for_rep: MethodForRep,
247 quality_mode: Quality,
248 ) -> SixelResult<()> {
249 self.set_pixelformat(pixelformat);
250 let input_pixels = match pixelformat {
251 PixelFormat::RGB888 => data.to_vec(),
252 _ => {
253 /* normalize pixelformat */
254 let mut normalized_pixels = vec![0; (width * height * 3) as usize];
255 self.set_pixelformat(sixel_helper_normalize_pixelformat(&mut normalized_pixels, data, pixelformat, width, height)?);
256 normalized_pixels
257 }
258 };
259
260 self.set_method_for_largest(method_for_largest);
261 self.set_method_for_rep(method_for_rep);
262 self.set_quality_mode(quality_mode);
263
264 let buf = sixel_quant_make_palette(
265 &input_pixels,
266 width * height * 3,
267 PixelFormat::RGB888,
268 self.reqcolors,
269 &mut self.ncolors,
270 &mut self.origcolors,
271 self.method_for_largest,
272 self.method_for_rep,
273 self.quality_mode,
274 )?;
275
276 self.palette = buf;
277 self.optimized = true;
278 if self.origcolors <= self.reqcolors {
279 self.method_for_diffuse = DiffusionMethod::None;
280 }
281 Ok(())
282 }
283
284 /// set diffusion type, choose from enum methodForDiffuse
285 pub fn set_diffusion_type(&mut self, method_for_diffuse: DiffusionMethod) {
286 self.method_for_diffuse = if matches!(method_for_diffuse, DiffusionMethod::Auto) {
287 if self.ncolors > 16 {
288 DiffusionMethod::FS
289 } else {
290 DiffusionMethod::Atkinson
291 }
292 } else {
293 method_for_diffuse
294 };
295 }
296
297 /// get number of palette colors
298 pub fn get_num_of_palette_colors(&self) -> i32 {
299 self.ncolors
300 }
301
302 /// get number of histogram colors
303 pub fn get_num_of_histogram_colors(&self) -> i32 {
304 self.origcolors
305 }
306
307 /// get palette
308 pub fn get_palette(&self) -> &[u8] {
309 &self.palette
310 }
311
312 /// set palette
313 pub fn set_palette(&mut self, palette: Vec<u8>) {
314 self.palette = palette;
315 }
316
317 /// set the factor of complexion color correcting
318 // /* complexion score (>= 1) */
319 pub fn set_complexion_score(&mut self, score: i32) {
320 self.complexion = score;
321 }
322
323 /* set whether omitting palette difinition */
324 pub fn set_body_only(&mut self, bodyonly: bool)
325 /* 0: output palette section
326 1: do not output palette section */
327 {
328 self.bodyonly = bodyonly;
329 }
330
331 /* set whether optimize palette size */
332 pub fn set_optimize_palette(&mut self, do_op: bool)
333 /* 0: optimize palette size
334 1: don't optimize palette size */
335 {
336 self.optimize_palette = do_op;
337 }
338
339 /* set pixelformat */
340 pub fn set_pixelformat(&mut self, pixelformat: PixelFormat) /* one of enum pixelFormat */
341 {
342 self.pixelformat = pixelformat;
343 }
344
345 /* set transparent */
346 pub fn set_transparent(&mut self, transparent: i32) /* transparent color index */
347 {
348 self.keycolor = transparent;
349 }
350
351 /* set transparent */
352 pub fn apply_palette(&mut self, pixels: &[u8], width: i32, height: i32) -> SixelResult<Vec<u8>> {
353 let bufsize = width * height;
354 let mut dest = vec![0; bufsize as usize];
355
356 /* if quality_mode is full, do not use palette caching */
357 if matches!(self.quality_mode, Quality::FULL) {
358 self.optimized = false;
359 }
360
361 if self.cachetable.is_none() && self.optimized && self.palette != pal_mono_dark && self.palette != pal_mono_light {
362 self.cachetable = Some(vec![0; 1 << (3 * 5 * 2)]);
363 }
364
365 let mut input_pixels = if !matches!(self.pixelformat, PixelFormat::RGB888) {
366 /* normalize pixelformat */
367 let mut normalized_pixels = vec![0; (width * height * 3) as usize];
368 self.pixelformat = sixel_helper_normalize_pixelformat(&mut normalized_pixels, pixels, self.pixelformat, width, height)?;
369 normalized_pixels
370 } else {
371 pixels.to_vec()
372 };
373 let ncolors = sixel_quant_apply_palette(
374 &mut dest,
375 &mut input_pixels,
376 width,
377 height,
378 3,
379 &mut self.palette,
380 self.ncolors,
381 self.method_for_diffuse,
382 self.optimized,
383 self.optimize_palette,
384 self.complexion,
385 Some(self.cachetable.as_mut().unwrap()),
386 )?;
387 self.ncolors = ncolors;
388
389 Ok(dest)
390 }
391 }