#![allow(dead_code)]
#[allow(dead_code)]
#[derive(Debug, Clone, PartialEq)]
pub struct DatamoshEffectConfig {
pub iframe_interval: u32,
pub block_size_px: u32,
pub error_blur: f32,
pub intensity: f32,
pub feedback: f32,
pub enabled: bool,
}
impl Default for DatamoshEffectConfig {
fn default() -> Self {
Self {
iframe_interval: 30,
block_size_px: 16,
error_blur: 0.3,
intensity: 0.6,
feedback: 0.85,
enabled: true,
}
}
}
#[allow(dead_code)]
pub fn new_datamosh_effect_config() -> DatamoshEffectConfig {
DatamoshEffectConfig::default()
}
#[allow(dead_code)]
pub fn dm_set_intensity(cfg: &mut DatamoshEffectConfig, v: f32) {
cfg.intensity = v.clamp(0.0, 1.0);
}
#[allow(dead_code)]
pub fn dm_set_feedback(cfg: &mut DatamoshEffectConfig, v: f32) {
cfg.feedback = v.clamp(0.0, 1.0);
}
#[allow(dead_code)]
pub fn dm_set_block_size(cfg: &mut DatamoshEffectConfig, px: u32) {
cfg.block_size_px = px.clamp(2, 64);
}
#[allow(dead_code)]
pub fn dm_set_iframe_interval(cfg: &mut DatamoshEffectConfig, frames: u32) {
cfg.iframe_interval = frames.max(1);
}
#[allow(dead_code)]
pub fn dm_is_iframe(frame: u32, cfg: &DatamoshEffectConfig) -> bool {
cfg.iframe_interval > 0 && frame.is_multiple_of(cfg.iframe_interval)
}
#[allow(dead_code)]
pub fn dm_accumulate(current: f32, accumulated: f32, cfg: &DatamoshEffectConfig) -> f32 {
if !cfg.enabled {
return current;
}
let feedback = cfg.feedback;
(accumulated * feedback + current * (1.0 - feedback)).clamp(0.0, 1.0)
}
#[allow(dead_code)]
pub fn dm_artifact_strength(frame: u32, cfg: &DatamoshEffectConfig) -> f32 {
if !cfg.enabled || dm_is_iframe(frame, cfg) {
0.0
} else {
cfg.intensity
}
}
#[allow(dead_code)]
pub fn dm_block_count(width_px: u32, height_px: u32, cfg: &DatamoshEffectConfig) -> u32 {
let bx = width_px.div_ceil(cfg.block_size_px);
let by = height_px.div_ceil(cfg.block_size_px);
bx * by
}
#[allow(dead_code)]
pub fn dm_to_json(cfg: &DatamoshEffectConfig) -> String {
format!(
"{{\"iframe_interval\":{},\"intensity\":{:.3},\"feedback\":{:.3},\"enabled\":{}}}",
cfg.iframe_interval, cfg.intensity, cfg.feedback, cfg.enabled
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn iframe_on_interval() {
let cfg = new_datamosh_effect_config();
assert!(dm_is_iframe(0, &cfg));
assert!(dm_is_iframe(30, &cfg));
}
#[test]
fn not_iframe_between() {
let cfg = new_datamosh_effect_config();
assert!(!dm_is_iframe(15, &cfg));
}
#[test]
fn artifact_zero_on_iframe() {
let cfg = new_datamosh_effect_config();
assert!(dm_artifact_strength(0, &cfg) < 1e-6);
}
#[test]
fn artifact_nonzero_between_iframes() {
let cfg = new_datamosh_effect_config();
assert!(dm_artifact_strength(5, &cfg) > 0.0);
}
#[test]
fn artifact_zero_when_disabled() {
let mut cfg = new_datamosh_effect_config();
cfg.enabled = false;
assert!(dm_artifact_strength(5, &cfg) < 1e-6);
}
#[test]
fn accumulate_moves_toward_current() {
let cfg = new_datamosh_effect_config();
let acc = dm_accumulate(0.0, 1.0, &cfg);
assert!(acc < 1.0); }
#[test]
fn block_count_correct() {
let cfg = new_datamosh_effect_config(); let count = dm_block_count(64, 32, &cfg);
assert_eq!(count, 4 * 2);
}
#[test]
fn block_size_clamps() {
let mut cfg = new_datamosh_effect_config();
dm_set_block_size(&mut cfg, 1);
assert_eq!(cfg.block_size_px, 2);
}
#[test]
fn intensity_clamps() {
let mut cfg = new_datamosh_effect_config();
dm_set_intensity(&mut cfg, 5.0);
assert!((cfg.intensity - 1.0).abs() < 1e-6);
}
#[test]
fn json_has_keys() {
let j = dm_to_json(&new_datamosh_effect_config());
assert!(j.contains("iframe_interval") && j.contains("enabled"));
}
}