125 lines
4.6 KiB
Rust
125 lines
4.6 KiB
Rust
use hcie_protocol::Layer;
|
|
use hcie_protocol::effects::LayerEffect;
|
|
use std::path::Path;
|
|
|
|
fn main() {
|
|
let output_dir = Path::new("_tmp/psd_test_output");
|
|
std::fs::create_dir_all(output_dir).ok();
|
|
|
|
println!("=== Generate Test PSDs ===");
|
|
|
|
// Test 1: Simple layer, no effects
|
|
{
|
|
let layers = vec![
|
|
Layer::new_blank("Background", 256, 256),
|
|
];
|
|
let composited = vec![255u8; 256 * 256 * 4];
|
|
let path = output_dir.join("test_simple.psd");
|
|
hcie_psd::save_psd(&layers, 256, 256, &composited, &path).unwrap();
|
|
verify_psd(&path, "Simple (no effects)");
|
|
}
|
|
|
|
// Test 2: Layer with InnerShadow effect
|
|
{
|
|
let mut layer = Layer::new_blank("Effect Layer", 256, 256);
|
|
layer.effects.push(LayerEffect::InnerShadow {
|
|
enabled: true,
|
|
blend_mode: "normal".to_string(),
|
|
color: [0, 0, 0, 255],
|
|
opacity: 0.75,
|
|
angle: 120.0,
|
|
distance: 10.0,
|
|
choke: 5.0,
|
|
size: 15.0,
|
|
noise: 0.0,
|
|
contour: None,
|
|
});
|
|
let layers = vec![layer];
|
|
let composited = vec![255u8; 256 * 256 * 4];
|
|
let path = output_dir.join("test_inner_shadow.psd");
|
|
hcie_psd::save_psd(&layers, 256, 256, &composited, &path).unwrap();
|
|
verify_psd(&path, "InnerShadow");
|
|
}
|
|
|
|
// Test 3: Two layers, one with effects
|
|
{
|
|
let bg = Layer::new_blank("Background", 256, 256);
|
|
let mut fg = Layer::new_blank("Foreground", 256, 256);
|
|
fg.effects.push(LayerEffect::DropShadow {
|
|
enabled: true,
|
|
blend_mode: "normal".to_string(),
|
|
color: [0, 0, 0, 255],
|
|
opacity: 0.5,
|
|
angle: 120.0,
|
|
distance: 5.0,
|
|
spread: 0.0,
|
|
size: 10.0,
|
|
noise: 0.0,
|
|
contour: None,
|
|
});
|
|
let layers = vec![bg, fg];
|
|
let composited = vec![255u8; 256 * 256 * 4];
|
|
let path = output_dir.join("test_two_layers.psd");
|
|
hcie_psd::save_psd(&layers, 256, 256, &composited, &path).unwrap();
|
|
verify_psd(&path, "Two layers + DropShadow");
|
|
}
|
|
|
|
// Test 4: Roundtrip the reference PSD
|
|
{
|
|
let ref_path = Path::new("_images/_psd_stil_test/inner_shadow/black_triangle_green_inner_shadow_normal_blend.psd");
|
|
if ref_path.exists() {
|
|
let layers = hcie_psd::import_psd(ref_path).unwrap();
|
|
let orig_bytes = std::fs::read(ref_path).unwrap();
|
|
let psd = hcie_psd::Psd::from_bytes(&orig_bytes).unwrap();
|
|
let composited = psd.rgba();
|
|
let path = output_dir.join("test_roundtrip.psd");
|
|
hcie_psd::save_psd(&layers, psd.width(), psd.height(), &composited, &path).unwrap();
|
|
verify_psd(&path, "Roundtrip from reference PSD");
|
|
}
|
|
}
|
|
|
|
// Test 5: Verify pixel data round-trip
|
|
{
|
|
println!("\n=== Pixel Data Verification ===");
|
|
let ref_path = Path::new("_images/_psd_stil_test/inner_shadow/black_triangle_green_inner_shadow_normal_blend.psd");
|
|
if ref_path.exists() {
|
|
let orig_bytes = std::fs::read(ref_path).unwrap();
|
|
let orig_psd = hcie_psd::Psd::from_bytes(&orig_bytes).unwrap();
|
|
let orig_rgba = orig_psd.rgba();
|
|
|
|
let saved_path = output_dir.join("test_roundtrip.psd");
|
|
let saved_bytes = std::fs::read(&saved_path).unwrap();
|
|
let saved_psd = hcie_psd::Psd::from_bytes(&saved_bytes).unwrap();
|
|
let saved_rgba = saved_psd.rgba();
|
|
|
|
let mut diff_count = 0;
|
|
let mut max_diff: u8 = 0;
|
|
for i in 0..orig_rgba.len().min(saved_rgba.len()) {
|
|
let d = (orig_rgba[i] as i16 - saved_rgba[i] as i16).unsigned_abs() as u8;
|
|
if d > 0 {
|
|
diff_count += 1;
|
|
max_diff = max_diff.max(d);
|
|
}
|
|
}
|
|
println!("Original RGBA: {} bytes", orig_rgba.len());
|
|
println!("Saved RGBA: {} bytes", saved_rgba.len());
|
|
println!("Differing bytes: {} / {}", diff_count, orig_rgba.len());
|
|
println!("Max per-byte diff: {}", max_diff);
|
|
println!("MAE: {:.2}", diff_count as f64 / orig_rgba.len() as f64);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn verify_psd(path: &Path, label: &str) {
|
|
let bytes = std::fs::read(path).unwrap();
|
|
match hcie_psd::Psd::from_bytes(&bytes) {
|
|
Ok(psd) => {
|
|
println!("[OK] {}: {} bytes, {}x{}, {} layers",
|
|
label, bytes.len(), psd.width(), psd.height(), psd.layers().len());
|
|
}
|
|
Err(e) => {
|
|
println!("[FAIL] {}: {} bytes, error: {:?}", label, bytes.len(), e);
|
|
}
|
|
}
|
|
}
|