1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- 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<Thumbnail>,
- pub pens_offset: FilePtr64<PenHeader>,
- _unknown_offset: FilePtr64<Unknown>,
- pub layers_offset: FilePtr64<ArrayOf<Layer>>,
- _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<W: Write + Seek>(
- &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<Rgba>, // Takes a few ms longer than Vec<u32>
- }
- #[derive(BinRead, BinWrite, Debug)]
- pub struct Unknown {
- _zeros: u32,
- }
|