use std::io::{Seek, SeekFrom, Write}; use binrw::{BinRead, BinResult, BinWrite, BinWriterExt, Endian, FilePtr64}; use crate::{array_of::ArrayOf, layer::Layer, pen::PenHeader, types::Rgba}; const FILE_MAGIC: &[u8; 16] = b"E\0Z\0C\0A\0D\0X\06\04\0"; #[derive(BinRead, Debug)] #[br(magic = b"E\0Z\0C\0A\0D\0X\06\04\0")] pub struct EzCadHeader { _unknown_1: [u8; 0x150], pub thumbnail_offset: FilePtr64, pub pens_offset: FilePtr64, _unknown_offset: FilePtr64, pub layers_offset: FilePtr64>, _unknown_2: [u8; 0x1A8], } // Manually implement BinWrite as FilePtr does not support serialization // See: https://github.com/jam1garner/binrw/issues/4 impl BinWrite for EzCadHeader { type Args<'a> = (); fn write_options( &self, writer: &mut W, endian: Endian, args: Self::Args<'_>, ) -> BinResult<()> { FILE_MAGIC.write_options(writer, endian, args)?; self._unknown_1.write_options(writer, endian, args)?; // Save offset addresses and write placeholder (zeros) for now let thumbnail_save_offset: u64 = writer.stream_position().unwrap(); 0u64.write_options(writer, endian, args)?; let pens_save_offset: u64 = writer.stream_position().unwrap(); 0u64.write_options(writer, endian, args)?; let unknown_save_offset: u64 = writer.stream_position().unwrap(); 0u64.write_options(writer, endian, args)?; let layers_save_offset: u64 = writer.stream_position().unwrap(); 0u64.write_options(writer, endian, args)?; self._unknown_2.write_options(writer, endian, args)?; // Helper fn to write current address to given offset without modifying cursor position let write_offset = |writer: &mut W, offset: u64| -> BinResult<()> { let current_offset: u64 = writer.stream_position().unwrap(); writer.seek(SeekFrom::Start(offset)).unwrap(); writer.write_type(¤t_offset, endian)?; writer.seek(SeekFrom::Start(current_offset)).unwrap(); Ok(()) }; // Write thumbnail contents write_offset(writer, thumbnail_save_offset)?; self.thumbnail_offset.write_options(writer, endian, args)?; // Write unknown contents write_offset(writer, unknown_save_offset)?; self._unknown_offset.write_options(writer, endian, args)?; // Write pens write_offset(writer, pens_save_offset)?; self.pens_offset.write_options(writer, endian, args)?; // Write layers write_offset(writer, layers_save_offset)?; self.layers_offset.write_options(writer, endian, args) } } #[derive(BinRead, BinWrite, Debug)] pub struct Thumbnail { _zeros_1: u32, pub dimension_x: u32, pub dimension_y: u32, _unknown_1: u32, // 0x320? _unknown_2: u32, // 0x200001? _zeros_2: [u32; 3], #[br(count = dimension_x * dimension_y)] pub pixels: Vec, // Takes a few ms longer than Vec } #[derive(BinRead, BinWrite, Debug)] pub struct Unknown { _zeros: u32, }