87 lines
3.3 KiB
Rust
87 lines
3.3 KiB
Rust
use hcie_protocol::Layer;
|
|
use hcie_protocol::effects::LayerEffect;
|
|
use std::path::Path;
|
|
|
|
fn main() {
|
|
println!("=== Verify PSD with baked-in effects opens correctly ===\n");
|
|
|
|
// Simulate the app's behavior: create a layer where pixel data already has
|
|
// the inner shadow effect rendered in, but don't include effects in the save.
|
|
let mut layer = Layer::new_blank("Effect Layer", 256, 256);
|
|
|
|
// Simulate green inner shadow baked into pixels
|
|
// (just add some green to the edges for testing)
|
|
for y in 0..256u32 {
|
|
for x in 0..256u32 {
|
|
let idx = (y * 256 + x) as usize * 4;
|
|
let is_edge = x < 30 || x > 226 || y < 30 || y > 226;
|
|
if is_edge {
|
|
layer.pixels[idx + 1] = 128; // green channel
|
|
}
|
|
}
|
|
}
|
|
|
|
// Save with effects list (save_psd will strip them)
|
|
layer.effects.push(LayerEffect::InnerShadow {
|
|
enabled: true,
|
|
blend_mode: "normal".to_string(),
|
|
color: [0, 255, 0, 255],
|
|
opacity: 0.75,
|
|
angle: 120.0,
|
|
distance: 10.0,
|
|
choke: 5.0,
|
|
size: 15.0,
|
|
noise: 0.0,
|
|
contour: None,
|
|
});
|
|
|
|
let composited = layer.pixels.clone();
|
|
let path = Path::new("_tmp/psd_test_output/test_baked_effects.psd");
|
|
hcie_psd::save_psd(&[layer], 256, 256, &composited, path).unwrap();
|
|
|
|
// Verify
|
|
let bytes = std::fs::read(path).unwrap();
|
|
match hcie_psd::Psd::from_bytes(&bytes) {
|
|
Ok(psd) => {
|
|
println!("[OK] {} bytes, {}x{}, {} layers", bytes.len(), psd.width(), psd.height(), psd.layers().len());
|
|
let rgba = psd.rgba();
|
|
let non_zero_g = rgba.chunks_exact(4).filter(|c| c[1] > 0).count();
|
|
println!("Green non-zero pixels: {} (should have baked-in green)", non_zero_g);
|
|
}
|
|
Err(e) => println!("[FAIL] {:?}", e),
|
|
}
|
|
|
|
// Check that no lfx2 block exists
|
|
let import_result = hcie_psd::import_psd(path);
|
|
match import_result {
|
|
Ok(layers) => {
|
|
for l in &layers {
|
|
println!("Layer '{}': effects={} (should be 0)", l.name, l.effects.len());
|
|
}
|
|
}
|
|
Err(e) => println!("import_psd: {}", e),
|
|
}
|
|
|
|
// Also verify the original reference roundtrip still works
|
|
println!("\n=== Reference PSD roundtrip ===");
|
|
let ref_path = Path::new("_images/_psd_stil_test/inner_shadow/black_triangle_green_inner_shadow_normal_blend.psd");
|
|
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 out_path = Path::new("_tmp/psd_test_output/test_ref_roundtrip_clean.psd");
|
|
hcie_psd::save_psd(&layers, psd.width(), psd.height(), &composited, out_path).unwrap();
|
|
|
|
let saved_bytes = std::fs::read(out_path).unwrap();
|
|
match hcie_psd::Psd::from_bytes(&saved_bytes) {
|
|
Ok(psd) => {
|
|
println!("[OK] {} bytes, {}x{}, {} layers", saved_bytes.len(), psd.width(), psd.height(), psd.layers().len());
|
|
let saved_rgba = psd.rgba();
|
|
let orig_rgba = composited;
|
|
let diff_count = orig_rgba.iter().zip(saved_rgba.iter()).filter(|(a, b)| a != b).count();
|
|
println!("Pixel diff: {} / {} (should be 0)", diff_count, orig_rgba.len());
|
|
}
|
|
Err(e) => println!("[FAIL] {:?}", e),
|
|
}
|
|
}
|