Skip to content

Commit a96930c

Browse files
committed
code format and ui minor improvement
worker return file format for downloading; show error msg while keep image
1 parent 1caf2e9 commit a96930c

File tree

4 files changed

+35
-20
lines changed

4 files changed

+35
-20
lines changed

app/script.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ async function getInputBlob() {
3333
return new Uint8Array(arrayBuffer);
3434
}
3535

36-
function checkInput() {
36+
function checkInputRaise() {
3737
if (fileInput.files.length === 0) {
3838
showError("No image file selected");
3939
throw new Error("No image file selected");
@@ -67,7 +67,7 @@ function resetOutput() {
6767
footer.style.top = '-3rem';
6868
}
6969

70-
async function showImage(imBlob) {
70+
async function showImage(imBlob, format) {
7171
resetOutput();
7272
ensureOutput();
7373

@@ -85,16 +85,16 @@ async function showImage(imBlob) {
8585
const a = document.createElement('a');
8686
a.href = url;
8787
const timeName = new Date().toISOString().replace(/[:.]/g, '-');
88-
a.download = `img-${timeName}.${imTypeSelect.value}`;
88+
a.download = `img-${timeName}.${format}`;
8989
document.body.appendChild(a);
9090
a.click();
9191
document.body.removeChild(a);
9292
};
9393
}
9494

9595
async function encode_image() {
96+
checkInputRaise();
9697
resetOutput();
97-
checkInput();
9898

9999
const inputBlob = await getInputBlob();
100100
hintLabel.textContent = `Encoding...`;
@@ -110,8 +110,8 @@ async function encode_image() {
110110
}
111111

112112
async function decode_image() {
113+
checkInputRaise();
113114
resetOutput();
114-
checkInput();
115115

116116
const inputBlob = await getInputBlob();
117117
hintLabel.textContent = `Decoding...`;
@@ -132,7 +132,10 @@ worker.onmessage = async (event) => {
132132
console.error(event.data.error);
133133
return;
134134
}
135-
await showImage(event.data.buffer);
135+
await showImage(
136+
event.data.buffer,
137+
event.data.format
138+
);
136139
};
137140

138141
// Event listeners for inputs

app/worker.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ self.onmessage = async function(event) {
1111

1212
if (type === 'encode') {
1313
const encoded = encode(buffer, secret, maxSide, outputAs);
14-
self.postMessage({ type: 'encoded', buffer: encoded });
14+
self.postMessage({ type: 'encoded', buffer: encoded, format: outputAs });
1515
}
1616

1717
if (type === 'decode') {
1818
const decoded = decode(buffer, secret, maxSide, outputAs);
19-
self.postMessage({ type: 'decoded', buffer: decoded });
19+
self.postMessage({ type: 'decoded', buffer: decoded, format: outputAs });
2020
}
2121
}

src/lib.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ fn str2f(s: &str) -> f64 {
3131

3232
fn maybe_resize(img: image::RgbImage, max_side: u32) -> (image::RgbImage, u32, u32) {
3333
let (width, height) = img.dimensions();
34+
3435
if width > max_side || height > max_side {
3536
let scale = max_side as f64 / width.max(height) as f64;
3637
let new_width = (width as f64 * scale).round() as u32;
@@ -48,15 +49,18 @@ fn maybe_resize(img: image::RgbImage, max_side: u32) -> (image::RgbImage, u32, u
4849
fn img2vec(im: &[u8], limit_max_side: Option<u32>) -> (Vec<u8>, ImageOptions) {
4950
let img = image::load_from_memory(im).expect("Failed to load image");
5051
let mut rgb = img.to_rgb8();
52+
5153
if let Some(max_side) = limit_max_side {
5254
(rgb, _, _) = maybe_resize(rgb, max_side);
5355
}
56+
5457
let mut pixels = Vec::with_capacity(rgb.width() as usize * rgb.height() as usize * 3);
5558
for pixel in rgb.pixels() {
5659
pixels.push(pixel[0]);
5760
pixels.push(pixel[1]);
5861
pixels.push(pixel[2]);
5962
};
63+
6064
(pixels, ImageOptions {
6165
width: rgb.width(),
6266
height: rgb.height(),
@@ -72,6 +76,7 @@ enum ImageType {
7276
fn vec2imblob(pixels: &Vec<u8>, im_opt: ImageOptions, limit_max_side: Option<u32>, im_type: ImageType) -> Box<[u8]> {
7377
let ImageOptions { mut width, mut height , channels} = im_opt;
7478
let mut img = image::RgbImage::new(width, height);
79+
7580
for (i, pixel) in pixels.chunks(channels as usize).enumerate() {
7681
let x = (i % width as usize) as u32;
7782
let y = (i / width as usize) as u32;
@@ -81,9 +86,11 @@ fn vec2imblob(pixels: &Vec<u8>, im_opt: ImageOptions, limit_max_side: Option<u32
8186
pixel[2],
8287
]));
8388
};
89+
8490
if let Some(max_side) = limit_max_side {
8591
(img, width, height) = maybe_resize(img, max_side);
8692
}
93+
8794
let mut buf = Vec::new();
8895
match im_type {
8996
ImageType::Png => {
@@ -98,6 +105,7 @@ fn vec2imblob(pixels: &Vec<u8>, im_opt: ImageOptions, limit_max_side: Option<u32
98105
},
99106
}
100107
console_log!("Export image, dimensions: {}x{}", width, height);
108+
101109
buf.into_boxed_slice()
102110
}
103111

@@ -106,9 +114,10 @@ pub fn encode(im: &[u8], secret: &str, max_side: i32, as_type: &str) -> Box<[u8]
106114
console_log!("Encoding image with secret: {}, max_side: {}", secret, max_side);
107115
let max_side = if max_side < 1 { None } else { Some(max_side as u32) };
108116

109-
let (im_v, im_opt) = img2vec(im, max_side);
110117
let seed = str2f(&secret);
111118
console_log!("Seed: {}", seed);
119+
120+
let (im_v, im_opt) = img2vec(im, max_side);
112121
let pixels = logistic_map::encode::<3>(&im_v, seed);
113122
vec2imblob(&pixels, im_opt, None, match as_type {
114123
"png" => ImageType::Png,
@@ -122,9 +131,10 @@ pub fn decode(im: &[u8], secret: &str, max_side: i32, as_type: &str) -> Box<[u8]
122131
console_log!("Decoding image with secret: {}, max_side: {}", secret, max_side);
123132
let max_side = if max_side < 1 { None } else { Some(max_side as u32) };
124133

125-
let (im_v, im_opt) = img2vec(im, None);
126134
let seed = str2f(&secret);
127135
console_log!("Seed: {}", seed);
136+
137+
let (im_v, im_opt) = img2vec(im, None);
128138
let pixels = logistic_map::decode::<3>(&im_v, seed);
129139
vec2imblob(&pixels, im_opt, max_side, match as_type {
130140
"png" => ImageType::Png,

src/logistic_map.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ enum DiffuseDirection {
3838
Forward,
3939
Backward,
4040
}
41-
fn diffuse<T: Copy>(im: &Vec<T>, enc_map: &Vec<f64>, direction: DiffuseDirection, chunk_size: usize) -> Vec<T>
41+
fn diffuse<const C: usize>(im: &Vec<u8>, enc_map: &Vec<f64>, direction: DiffuseDirection) -> Vec<u8>
4242
{
43-
let enc_map = enc_map[..im.len()/chunk_size]
43+
let enc_map = enc_map[..im.len()/C]
4444
.iter()
4545
.map(|&x| x.to_bits())
4646
.collect();
@@ -50,20 +50,20 @@ fn diffuse<T: Copy>(im: &Vec<T>, enc_map: &Vec<f64>, direction: DiffuseDirection
5050
match direction {
5151
DiffuseDirection::Forward => {
5252
for &index in &indices {
53-
for i in 0..chunk_size {
54-
let index = index * chunk_size + i;
53+
for i in 0..C {
54+
let index = index * C + i;
5555
diffuse_pixels.push(im[index]);
5656
}
5757
}
5858
},
5959
DiffuseDirection::Backward => {
60-
let mut lookup: Vec<usize> = vec![0; im.len() / chunk_size];
60+
let mut lookup: Vec<usize> = vec![0; im.len() / C];
6161
for (i, &index) in indices.iter().enumerate() {
6262
lookup[index] = i;
6363
}
6464
for &index in &lookup {
65-
for i in 0..chunk_size {
66-
let index = index * chunk_size + i;
65+
for i in 0..C {
66+
let index = index * C + i;
6767
diffuse_pixels.push(im[index]);
6868
}
6969
}
@@ -72,14 +72,15 @@ fn diffuse<T: Copy>(im: &Vec<T>, enc_map: &Vec<f64>, direction: DiffuseDirection
7272
diffuse_pixels
7373
}
7474

75-
// C: channel size, e.g. 3 for RGB
75+
// C: channel size for diffusion process, reduce computation with higher C
7676
pub fn encode<const C: usize>(im: &Vec<u8>, x0: f64) -> Vec<u8> {
7777
let enc_map = generate_map(LogisticMapOptions {
7878
x: x0,
7979
r: R,
8080
size: im.len(),
8181
});
82-
let im = diffuse(&im, &enc_map, DiffuseDirection::Forward, C);
82+
83+
let im = diffuse::<C>(&im, &enc_map, DiffuseDirection::Forward);
8384
confuse_xor(&im, &enc_map)
8485
}
8586

@@ -89,6 +90,7 @@ pub fn decode<const C:usize>(im: &Vec<u8>, x0: f64) -> Vec<u8> {
8990
r: R,
9091
size: im.len(),
9192
});
93+
9294
let im = confuse_xor(&im, &enc_map);
93-
diffuse(&im, &enc_map, DiffuseDirection::Backward, C)
95+
diffuse::<C>(&im, &enc_map, DiffuseDirection::Backward)
9496
}

0 commit comments

Comments
 (0)