///|
/// 演示图生成器:输出三张 PNG(hex 编码,每行一个标签)。
/// 1) clean — 渐变底图(模拟直播画面)
/// 2) lsb — 嵌入不可见水印(观众 ID,视觉无差别)
/// 3) visible — 叠加点阵 + 文本水印(可见防去重)
fn main {
let base = make_gradient(512, 288)
print_line("clean", png_hex(base))
let _ = base.embed_invisible(
Bytes::from_array([
b'V', b'I', b'E', b'W', b'E', b'R', b'-', b'0', b'4', b'2', b'1',
]),
key=99L,
)
print_line("lsb", png_hex(base))
let _ = base.embed_dots(@lib.DotConfig::default())
let _ = base.embed_text(
@lib.TextConfig::new("LIVE", 16, 16, 3, 0.6, 0xFFFF_FFFF),
)
print_line("visible", png_hex(base))
trace_demo()
}
///|
fn make_gradient(w : Int32, h : Int32) -> @lib.RgbaImage {
let img = @lib.RgbaImage::new(w, h, 0)
for y in 0.. String {
match img.encode_png() {
Ok(bytes) => to_hex(bytes)
Err(e) => "ERR:\{e}"
}
}
///|
fn print_line(tag : String, hex : String) -> Unit {
println("\{tag}:\{hex}")
}
///|
fn to_hex(bytes : Bytes) -> String {
let mut s = ""
for i in 0..> 4) + digit(b & 0xF)
}
s
}
///|
fn digit(n : Int32) -> String {
if n < 10 {
(n + 48).unsafe_to_char().to_string()
} else {
(n + 87).unsafe_to_char().to_string()
}
}
///|
/// 溯源演示数据:三位接收者持不同 seed,泄漏帧命中 seed=42(接收者 C)。
/// 点阵判定用成对对照 contrast(目标命中率 − 对照命中率),正确候选应显著更高。
fn trace_demo() -> Unit {
let leak = make_gradient(512, 288)
let _ = leak.embed_dots(@lib.DotConfig::default()) // 接收者 C 的配置
let c_a = @lib.DotConfig::new(0.05, 1, 1L, 1.0, 0, 0)
let c_b = @lib.DotConfig::new(0.05, 1, 2L, 1.0, 0, 0)
let c_c = @lib.DotConfig::default()
print_line("contrast_a", @lib.dot_contrast(leak, c_a).to_string())
print_line("contrast_b", @lib.dot_contrast(leak, c_b).to_string())
print_line("contrast_c", @lib.dot_contrast(leak, c_c).to_string())
print_line("trace_idx", @lib.trace_dots(leak, [c_a, c_b, c_c]).to_string())
}