Files
hcie-rust-v3.05/hcie-io/examples/dump_lfx2.rs
T

111 lines
5.2 KiB
Rust
Raw Normal View History

2026-07-09 02:59:53 +03:00
fn main() {
for path_str in [
"_images/_psd_stil_test/hc_drop_shadow.psd",
"_images/_psd_stil_test/fx_drop_shadow.psd",
2026-07-09 02:59:53 +03:00
] {
println!("\n========================================\nFILE: {}", path_str);
let path = std::path::Path::new(path_str);
let bytes = std::fs::read(path).unwrap();
let mut r = hcie_psd::psd_reader::PsdReader::new(&bytes);
r.read(26).unwrap();
let color_mode_len = r.read_u32().unwrap() as usize;
r.read(color_mode_len).unwrap();
let img_res_len = r.read_u32().unwrap() as usize;
r.read(img_res_len).unwrap();
let _layer_mask_len_val = r.read_u32().unwrap() as usize;
let _layer_info_len = r.read_u32().unwrap() as usize;
let layer_count_raw = r.read_i16().unwrap();
let layer_count = layer_count_raw.abs() as usize;
for _idx in 0..layer_count {
let _top = r.read_i32().unwrap();
let _left = r.read_i32().unwrap();
let _bottom = r.read_i32().unwrap();
let _right = r.read_i32().unwrap();
let channel_count = r.read_u16().unwrap() as usize;
for _ in 0..channel_count {
let _id = r.read_i16().unwrap();
let _len = r.read_u32().unwrap();
}
r.read(4).unwrap(); r.read(4).unwrap(); r.read_u8().unwrap(); r.read_u8().unwrap(); r.read_u8().unwrap(); r.read(1).unwrap();
let extra_data_len = r.read_u32().unwrap() as usize;
let extra_start = r.pos();
let layer_mask_len = r.read_u32().unwrap() as usize;
r.read(layer_mask_len).unwrap();
let blending_ranges_len = r.read_u32().unwrap() as usize;
r.read(blending_ranges_len).unwrap();
let name_len = r.read_u8().unwrap() as usize;
let name_bytes = r.read(name_len).unwrap();
let name = String::from_utf8_lossy(name_bytes).to_string();
let bytes_mod_4 = (name_len + 1) % 4;
let padding = (4 - bytes_mod_4) % 4;
r.read(padding).unwrap();
while r.pos() < extra_start + extra_data_len {
let sig = r.read(4).unwrap();
if sig != b"8BIM" && sig != b"8B64" { break; }
let key_bytes = r.read(4).unwrap();
let key = String::from_utf8_lossy(key_bytes).to_string();
let block_len = r.read_u32().unwrap() as usize;
let block_start = r.pos();
if key == "lfx2" {
let data = r.read(block_len).unwrap().to_vec();
println!("Layer '{}' lfx2 block: {} bytes", name, data.len());
// Try different offsets to parse top-level descriptor
for offset in [0, 4, 8, 10, 14, 16] {
if let Some((entries, _)) = hcie_fx::parser::parse_descriptor_body(&data, offset) {
if !entries.is_empty() {
println!(" Parsed at offset {} with {} entries", offset, entries.len());
dump_entries(&entries, 2);
}
}
}
} else {
r.read(block_len).unwrap();
}
r.seek(block_start + block_len).unwrap();
if block_len % 2 != 0 { r.read(1).unwrap(); }
}
r.seek(extra_start + extra_data_len).unwrap();
}
}
}
fn dump_entries(entries: &[( [u8; 4], hcie_fx::parser::DescValue)], depth: usize) {
let indent = " ".repeat(depth);
for (k, v) in entries {
let key_str = String::from_utf8_lossy(k).to_string();
match v {
hcie_fx::parser::DescValue::Bool(b) => println!("{}{}: bool = {}", indent, key_str, b),
hcie_fx::parser::DescValue::Long(l) => println!("{}{}: long = {}", indent, key_str, l),
hcie_fx::parser::DescValue::Double(d) => println!("{}{}: double = {:.4}", indent, key_str, d),
hcie_fx::parser::DescValue::UnitFloat { unit, value } => {
println!("{}{}: unit_float({:?}) = {:.4}", indent, key_str, String::from_utf8_lossy(unit), value);
}
hcie_fx::parser::DescValue::Enum { class_id, value } => {
println!("{}{}: enum({:?}) = {:?}", indent, key_str, String::from_utf8_lossy(class_id), String::from_utf8_lossy(value));
}
hcie_fx::parser::DescValue::Object(sub) => {
println!("{}{}: Objc({})", indent, key_str, sub.len());
dump_entries(sub, depth + 1);
}
hcie_fx::parser::DescValue::List(items) => {
println!("{}{}: List({})", indent, key_str, items.len());
for (i, item) in items.iter().enumerate() {
println!("{} [{}]: {:?}", indent, i, std::mem::discriminant(item));
if let hcie_fx::parser::DescValue::Object(sub) = item {
dump_entries(sub, depth + 2);
}
}
}
_ => println!("{}{}: Unknown", indent, key_str),
}
}
}