123 lines
4.6 KiB
Rust
123 lines
4.6 KiB
Rust
#![deny(warnings)]
|
|
// [TSM.ID].[11031972] — All Rights Reserved. Proprietary & Confidential.
|
|
use tracing::debug;
|
|
|
|
/// Struktur 1 Titik Perubahan Neuromorphic (Spike/Event)
|
|
/// Sangat padat memori: X (u16), Y (u16), R (i16), G (i16), B (i16) -> Hanya 10 bytes per piksel yang berubah.
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
pub struct PulsarEvent {
|
|
pub x: u16,
|
|
pub y: u16,
|
|
pub dr: i16,
|
|
pub dg: i16,
|
|
pub db: i16,
|
|
}
|
|
|
|
/// THE PULSAR CODEC (Phase 43)
|
|
/// Neuromorphic Frameless Compression
|
|
pub struct PulsarCodec;
|
|
|
|
impl PulsarCodec {
|
|
/// ENCODER: Menelan dua frame (Frame Lama & Frame Baru)
|
|
/// Membandingkannya secara spatiotemporal dan hanya memuntahkan Koordinat Piksel yang bergerak/berubah.
|
|
pub fn encode_frameless_stream(old_frame: &[u8], new_frame: &[u8], width: u16, height: u16) -> Vec<PulsarEvent> {
|
|
let mut events = Vec::new();
|
|
// Asumsi RGB format (3 bytes per pixel)
|
|
let total_pixels = (width as usize) * (height as usize);
|
|
|
|
for i in 0..total_pixels {
|
|
let offset = i * 3;
|
|
|
|
// Cegah out-of-bounds untuk simulasi
|
|
if offset + 2 >= old_frame.len() || offset + 2 >= new_frame.len() {
|
|
break;
|
|
}
|
|
|
|
let r_old = old_frame[offset] as i16;
|
|
let g_old = old_frame[offset + 1] as i16;
|
|
let b_old = old_frame[offset + 2] as i16;
|
|
|
|
let r_new = new_frame[offset] as i16;
|
|
let g_new = new_frame[offset + 1] as i16;
|
|
let b_new = new_frame[offset + 2] as i16;
|
|
|
|
let dr = r_new - r_old;
|
|
let dg = g_new - g_old;
|
|
let db = b_new - b_old;
|
|
|
|
// Threshold Sensitivitas (Mengabaikan *noise* kecil dari kamera)
|
|
if dr.abs() > 5 || dg.abs() > 5 || db.abs() > 5 {
|
|
let x = (i % width as usize) as u16;
|
|
let y = (i / width as usize) as u16;
|
|
|
|
events.push(PulsarEvent { x, y, dr, dg, db });
|
|
}
|
|
}
|
|
|
|
if events.is_empty() {
|
|
debug!("PULSAR: Tidak ada gerakan. Emitting 0 Bytes.");
|
|
} else {
|
|
debug!("PULSAR: Mengirim {} events piksel perubahan.", events.len());
|
|
}
|
|
|
|
events
|
|
}
|
|
|
|
/// DECODER: Menerima "Pulsar Events" (Delta pergerakan) dari internet dan langsung
|
|
/// memodifikasi frame yang sudah ada di RAM pengguna tanpa perhitungan matriks DCT.
|
|
pub fn apply_events_to_canvas(canvas: &mut [u8], events: &[PulsarEvent], width: u16) {
|
|
for event in events {
|
|
let offset = ((event.y as usize * width as usize) + event.x as usize) * 3;
|
|
|
|
if offset + 2 < canvas.len() {
|
|
// Terapkan selisih warna
|
|
let current_r = canvas[offset] as i16;
|
|
let current_g = canvas[offset + 1] as i16;
|
|
let current_b = canvas[offset + 2] as i16;
|
|
|
|
// Saturasi clamp agar tidak tembus 255/0
|
|
canvas[offset] = (current_r + event.dr).clamp(0, 255) as u8;
|
|
canvas[offset + 1] = (current_g + event.dg).clamp(0, 255) as u8;
|
|
canvas[offset + 2] = (current_b + event.db).clamp(0, 255) as u8;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_pulsar_frameless_efficiency() {
|
|
let width = 2;
|
|
let height = 2;
|
|
// Total piksel = 4 (RGB = 12 bytes total per frame)
|
|
// Layar awal: Semua Hitam
|
|
let old_frame: Vec<u8> = vec![0,0,0, 0,0,0, 0,0,0, 0,0,0];
|
|
|
|
// Layar baru: Hanya 1 piksel di sudut kiri atas (x:0, y:0) yang menyala jadi merah
|
|
let new_frame: Vec<u8> = vec![255,0,0, 0,0,0, 0,0,0, 0,0,0];
|
|
|
|
// EKSEKUSI PULSAR ENCODER (Pemusnahan AV1)
|
|
let events = PulsarCodec::encode_frameless_stream(&old_frame, &new_frame, width, height);
|
|
|
|
// PEMBUKTIAN EFISIENSI MUTLAK
|
|
// Alih-alih mengirim frame utuh, mesin HANYA mengirim 1 event (1 piksel)!
|
|
assert_eq!(events.len(), 1);
|
|
assert_eq!(events[0].dr, 255);
|
|
assert_eq!(events[0].x, 0);
|
|
assert_eq!(events[0].y, 0);
|
|
|
|
println!("PULSAR ENCODE BERHASIL: Efisiensi memori hancur! Frame tidak dikirim. Hanya 10 bytes koordinat perubahan yang dikirim.");
|
|
|
|
// EKSEKUSI PULSAR DECODER
|
|
let mut client_canvas = old_frame.clone();
|
|
PulsarCodec::apply_events_to_canvas(&mut client_canvas, &events, width);
|
|
|
|
// Pastikan kanvas diubah sempurna sesuai new_frame tanpa memproses 3 piksel lainnya
|
|
assert_eq!(client_canvas, new_frame);
|
|
println!("PULSAR DECODE BERHASIL: Kanvas direkonstruksi seketika (Zero-Latency) tanpa perhitungan blok (DCT) CPU!");
|
|
}
|
|
}
|