Skip to content

Commit c9677fb

Browse files
committed
wasm
1 parent 4a714d7 commit c9677fb

File tree

7 files changed

+200
-112
lines changed

7 files changed

+200
-112
lines changed

Cargo.toml

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,9 @@ name = "chaotic-enc"
33
version = "0.1.0"
44
edition = "2024"
55

6+
[lib]
7+
crate-type = ["cdylib"]
8+
69
[dependencies]
7-
clap = { version = "4.5.39", features = ["derive"] }
810
image = "0.25.6"
9-
10-
[[bin]]
11-
name="cenc"
12-
path="src/encode.rs"
13-
14-
[[bin]]
15-
name="cdec"
16-
path="src/decode.rs"
11+
wasm-bindgen = "0.2.100"

index.html

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Image encoder</title>
7+
8+
<div id="secret-container">
9+
<input type="file" id="fileInput" accept="image/*">
10+
<label id="hint">Select an image file to encode</label>
11+
<br>
12+
<label for="secretInput">Secret:</label>
13+
<input id="secretInput" placeholder="Enter your secret here">
14+
</script>
15+
16+
<hr>
17+
<div id="button-container">
18+
<button id="encodeButton">Encode</button>
19+
<button id="decodeButton">Decode</button>
20+
</div>
21+
22+
<div id="output"></div>
23+
</head>
24+
25+
<style>
26+
body {
27+
font-family: Arial, sans-serif;
28+
margin: 20px;
29+
}
30+
#fileInput {
31+
display: block;
32+
margin-bottom: 10px;
33+
}
34+
#output img {
35+
max-width: 100%;
36+
height: auto;
37+
}
38+
</style>
39+
40+
<body>
41+
<script type="module">
42+
import init, { encode, decode } from './pkg/chaotic_enc.js';
43+
44+
await init(); // Initialize the WASM module
45+
const secretInput = document.getElementById('secretInput');
46+
const fileInput = document.getElementById('fileInput');
47+
const outputDiv = document.getElementById('output');
48+
const hintLabel = document.getElementById('hint');
49+
const encodeButton = document.getElementById('encodeButton');
50+
const decodeButton = document.getElementById('decodeButton');
51+
52+
async function getInputBlob() {
53+
if (fileInput.files.length === 0) {
54+
throw new Error("No file selected");
55+
}
56+
const file = fileInput.files[0];
57+
const arrayBuffer = await file.arrayBuffer();
58+
return new Uint8Array(arrayBuffer);
59+
}
60+
61+
async function showImage(imBlob) {
62+
const blob = new Blob([imBlob], { type: 'image/png' });
63+
const url = URL.createObjectURL(blob);
64+
65+
const imgElem = document.createElement('img');
66+
imgElem.src = url;
67+
imgElem.alt = 'Encoded Image';
68+
outputDiv.innerHTML = ''; // Clear previous output
69+
outputDiv.appendChild(imgElem);
70+
}
71+
72+
async function encode_image() {
73+
const inputBlob = await getInputBlob();
74+
75+
hintLabel.textContent = `Encoding...`;
76+
await new Promise(resolve => setTimeout(resolve, 0)); // Simulate processing delay
77+
78+
let outputBlob;
79+
try {
80+
outputBlob = encode(inputBlob, secretInput.value);
81+
hintLabel.textContent = `Encode successfully!`;
82+
}
83+
catch (error) {
84+
hintLabel.textContent = `Error encoding: ${error.message}`;
85+
console.error(error);
86+
return;
87+
}
88+
await showImage(outputBlob);
89+
}
90+
91+
async function decode_image() {
92+
const inputBlob = await getInputBlob();
93+
94+
hintLabel.textContent = `Decoding...`;
95+
await new Promise(resolve => setTimeout(resolve, 0)); // Simulate processing delay
96+
97+
let outputBlob;
98+
try {
99+
outputBlob = decode(inputBlob, secretInput.value);
100+
hintLabel.textContent = `Decode successfully!`;
101+
}
102+
catch (error) {
103+
hintLabel.textContent = `Error decoding: ${error.message}`;
104+
console.error(error);
105+
return;
106+
}
107+
await showImage(outputBlob);
108+
}
109+
110+
encodeButton.addEventListener('click', encode_image);
111+
decodeButton.addEventListener('click', decode_image);
112+
113+
</script>
114+
</body>
115+
</html>

src/decode.rs

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/encode.rs

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/imlib.rs

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/lib.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
mod logistic_map;
2+
3+
use std::collections::hash_map::DefaultHasher;
4+
use std::hash::{Hash, Hasher};
5+
use std::u8;
6+
use wasm_bindgen::prelude::*;
7+
use image::{self, ImageEncoder};
8+
9+
pub struct ImageOptions {
10+
pub width: u32,
11+
pub height: u32,
12+
}
13+
14+
fn str2f(s: &str) -> f32 {
15+
let mut hasher = DefaultHasher::new();
16+
s.hash(&mut hasher);
17+
let hash = hasher.finish();
18+
let x = (hash as f32) / (u64::MAX as f32);
19+
x
20+
}
21+
22+
fn img2vec(im: &[u8]) -> (Vec<[u8; 3]>, ImageOptions) {
23+
let img = image::load_from_memory(im).expect("Failed to load image");
24+
let rgb = img.to_rgb8();
25+
let mut pixels = Vec::with_capacity(rgb.width() as usize * rgb.height() as usize);
26+
for pixel in rgb.pixels() {
27+
pixels.push([pixel[0], pixel[1], pixel[2]]);
28+
};
29+
30+
(pixels, ImageOptions {
31+
width: rgb.width(),
32+
height: rgb.height(),
33+
})
34+
}
35+
36+
fn vec2pngblob(pixels: &Vec<[u8; 3]>, im_opt: ImageOptions) -> Box<[u8]> {
37+
let ImageOptions { width, height } = im_opt;
38+
39+
let mut img = image::RgbImage::new(width, height);
40+
for (i, pixel) in pixels.iter().enumerate() {
41+
let x = (i % width as usize) as u32;
42+
let y = (i / width as usize) as u32;
43+
img.put_pixel(x, y, image::Rgb(*pixel));
44+
};
45+
46+
// Encode the image to PNG format
47+
let mut buf = Vec::new();
48+
let encoder = image::codecs::png::PngEncoder::new(&mut buf);
49+
encoder.write_image(
50+
&img,
51+
width,
52+
height,
53+
image::ExtendedColorType::Rgb8,
54+
).expect("Failed to encode image");
55+
56+
buf.into_boxed_slice()
57+
}
58+
59+
#[wasm_bindgen]
60+
pub fn encode(im: &[u8], secret: &str) -> Box<[u8]> {
61+
let (mut im_v, im_opt) = img2vec(im);
62+
63+
let pixels = logistic_map::encode(
64+
&mut im_v,
65+
str2f(&secret)
66+
);
67+
68+
vec2pngblob(&pixels, im_opt)
69+
}
70+
71+
#[wasm_bindgen]
72+
pub fn decode(im: &[u8], secret: &str) -> Box<[u8]> {
73+
let (im_v, im_opt) = img2vec(im);
74+
75+
let pixels = logistic_map::decode(
76+
&im_v,
77+
str2f(&secret)
78+
);
79+
80+
vec2pngblob(&pixels, im_opt)
81+
}

src/parser.rs

Lines changed: 0 additions & 42 deletions
This file was deleted.

0 commit comments

Comments
 (0)