msg_tool\utils\psd/
types.rs

1use crate::ext::io::*;
2use crate::types::*;
3use crate::utils::encoding::*;
4use crate::utils::struct_pack::*;
5use anyhow::Result;
6use msg_tool_macro::*;
7use std::any::Any;
8use std::io::{Read, Seek, Write};
9
10pub const PSD_SIGNATURE: &[u8; 4] = b"8BPS";
11pub const IMAGE_RESOURCE_SIGNATURE: &[u8; 4] = b"8BIM";
12pub const LAYER_NAME_SOURCE_SETTING_KEY: &[u8; 4] = b"lnsr";
13pub const LAYER_ID_KEY: &[u8; 4] = b"lyid";
14pub const SECTION_DIVIDER_SETTING_KEY: &[u8; 4] = b"lsct";
15pub const UNICODE_LAYER_KEY: &[u8; 4] = b"luni";
16
17#[derive(Debug, Clone)]
18pub struct UnicodeString(pub String);
19
20impl StructPack for UnicodeString {
21    fn pack<W: Write>(
22        &self,
23        writer: &mut W,
24        big: bool,
25        encoding: Encoding,
26        info: &Option<Box<dyn Any>>,
27    ) -> Result<()> {
28        let encoded: Vec<_> = self.0.encode_utf16().collect();
29        let len = encoded.len() as u32;
30        len.pack(writer, big, encoding, info)?;
31        for c in encoded {
32            c.pack(writer, big, encoding, info)?;
33        }
34        Ok(())
35    }
36}
37
38impl StructUnpack for UnicodeString {
39    fn unpack<R: Read + Seek>(
40        reader: &mut R,
41        big: bool,
42        encoding: Encoding,
43        info: &Option<Box<dyn Any>>,
44    ) -> Result<Self> {
45        let len = u32::unpack(reader, big, encoding, info)?;
46        if len == 0 {
47            return Ok(UnicodeString(String::new()));
48        }
49        let mut encoded: Vec<u16> = Vec::with_capacity(len as usize);
50        for _ in 0..len {
51            let c = u16::unpack(reader, big, encoding, info)?;
52            encoded.push(c);
53        }
54        let string = String::from_utf16(&encoded)
55            .map_err(|e| anyhow::anyhow!("Failed to decode UTF-16 string: {}", e))?;
56        Ok(UnicodeString(string))
57    }
58}
59
60#[derive(Debug, Clone)]
61pub struct PascalString(pub Vec<u8>);
62
63impl StructPack for PascalString {
64    fn pack<W: Write>(
65        &self,
66        writer: &mut W,
67        big: bool,
68        encoding: Encoding,
69        info: &Option<Box<dyn Any>>,
70    ) -> Result<()> {
71        let len = self.0.len() as u8;
72        len.pack(writer, big, encoding, info)?;
73        writer.write_all(&self.0)?;
74        if len % 2 == 0 {
75            writer.write_u8(0)?; // padding byte
76        }
77        Ok(())
78    }
79}
80
81impl StructUnpack for PascalString {
82    fn unpack<R: Read + Seek>(
83        reader: &mut R,
84        big: bool,
85        encoding: Encoding,
86        info: &Option<Box<dyn Any>>,
87    ) -> Result<Self> {
88        let len = u8::unpack(reader, big, encoding, info)?;
89        let encoded = reader.read_exact_vec(len as usize)?;
90        if len % 2 == 0 {
91            reader.read_u8()?; // padding byte
92        }
93        Ok(PascalString(encoded))
94    }
95}
96
97#[derive(Debug, Clone)]
98pub struct PascalString4(pub Vec<u8>);
99
100impl StructPack for PascalString4 {
101    fn pack<W: Write>(
102        &self,
103        writer: &mut W,
104        big: bool,
105        encoding: Encoding,
106        info: &Option<Box<dyn Any>>,
107    ) -> Result<()> {
108        let len = self.0.len() as u8;
109        len.pack(writer, big, encoding, info)?;
110        let padding = 4 - (len as usize + 1) % 4;
111        writer.write_all(&self.0)?;
112        if padding != 4 {
113            for _ in 0..padding {
114                writer.write_u8(0)?; // padding byte
115            }
116        }
117        Ok(())
118    }
119}
120
121impl StructUnpack for PascalString4 {
122    fn unpack<R: Read + Seek>(
123        reader: &mut R,
124        big: bool,
125        encoding: Encoding,
126        info: &Option<Box<dyn Any>>,
127    ) -> Result<Self> {
128        let len = u8::unpack(reader, big, encoding, info)?;
129        let encoded = reader.read_exact_vec(len as usize)?;
130        let padding = 4 - (len as usize + 1) % 4;
131        if padding != 4 {
132            for _ in 0..padding {
133                let pad_byte = reader.read_u8()?;
134                if pad_byte != 0 {
135                    return Err(anyhow::anyhow!(
136                        "Expected padding byte to be 0, got {}",
137                        pad_byte
138                    ));
139                }
140            }
141        }
142        Ok(PascalString4(encoded))
143    }
144}
145
146#[derive(Debug, Clone, StructPack, StructUnpack)]
147pub struct PsdHeader {
148    pub signature: [u8; 4],
149    pub version: u16,
150    pub reserved: [u8; 6],
151    pub channels: u16,
152    pub height: u32,
153    pub width: u32,
154    pub depth: u16,
155    pub color_mode: u16,
156}
157
158#[derive(Debug, Clone, StructPack, StructUnpack)]
159pub struct ColorModeData {
160    #[pvec(u32)]
161    pub data: Vec<u8>,
162}
163
164#[derive(Debug, Clone)]
165pub struct ImageResourceSection {
166    pub resources: Vec<ImageResourceBlock>,
167}
168
169impl StructUnpack for ImageResourceSection {
170    fn unpack<R: Read + Seek>(
171        reader: &mut R,
172        big: bool,
173        encoding: Encoding,
174        info: &Option<Box<dyn Any>>,
175    ) -> Result<Self> {
176        let length = u32::unpack(reader, big, encoding, info)?;
177        let mut stream_region = StreamRegion::with_size(reader, length as u64)?;
178        let mut resources = Vec::new();
179        while stream_region.cur_pos() < length as u64 {
180            let resource = ImageResourceBlock::unpack(&mut stream_region, big, encoding, info)?;
181            resources.push(resource);
182            if let Ok(d) = stream_region.peek_u8() {
183                if d == 0 {
184                    stream_region.read_u8()?; // padding byte
185                }
186            }
187        }
188        Ok(ImageResourceSection { resources })
189    }
190}
191
192impl StructPack for ImageResourceSection {
193    fn pack<W: Write>(
194        &self,
195        writer: &mut W,
196        big: bool,
197        encoding: Encoding,
198        info: &Option<Box<dyn Any>>,
199    ) -> Result<()> {
200        let mut mem = MemWriter::new();
201        for resource in &self.resources {
202            resource.pack(&mut mem, big, encoding, info)?;
203            // #TODO: check if padding byte is needed
204        }
205        let data = mem.into_inner();
206        let length = data.len() as u32;
207        length.pack(writer, big, encoding, info)?;
208        writer.write_all(&data)?;
209        Ok(())
210    }
211}
212
213#[derive(Debug, Clone, StructPack, StructUnpack)]
214pub struct ImageResourceBlock {
215    pub signature: [u8; 4],
216    pub resource_id: u16,
217    pub name: PascalString,
218    #[pvec(u32)]
219    pub data: Vec<u8>,
220}
221
222#[derive(Debug, Clone)]
223pub struct LayerAndMaskInfo {
224    pub layer_info: LayerInfo,
225    pub global_layer_mask_info: Option<GlobalLayerMaskInfo>,
226    pub tagged_blocks: Vec<u8>,
227}
228
229impl StructUnpack for LayerAndMaskInfo {
230    fn unpack<R: Read + Seek>(
231        reader: &mut R,
232        big: bool,
233        encoding: Encoding,
234        info: &Option<Box<dyn Any>>,
235    ) -> Result<Self> {
236        let length = u32::unpack(reader, big, encoding, info)?;
237        let mut stream_region = StreamRegion::with_size(reader, length as u64)?;
238        let layer_info = LayerInfo::unpack(&mut stream_region, big, encoding, info)?;
239        let length = u32::unpack(&mut stream_region, big, encoding, info)?;
240        let global_layer_mask_info = if length > 0 {
241            stream_region.seek_relative(-4)?;
242            Some(GlobalLayerMaskInfo::unpack(
243                &mut stream_region,
244                big,
245                encoding,
246                info,
247            )?)
248        } else {
249            None
250        };
251        let mut tagged_blocks = Vec::new();
252        stream_region.read_to_end(&mut tagged_blocks)?;
253        Ok(LayerAndMaskInfo {
254            layer_info,
255            global_layer_mask_info,
256            tagged_blocks,
257        })
258    }
259}
260
261impl StructPack for LayerAndMaskInfo {
262    fn pack<W: Write>(
263        &self,
264        writer: &mut W,
265        big: bool,
266        encoding: Encoding,
267        info: &Option<Box<dyn Any>>,
268    ) -> Result<()> {
269        let mut mem = MemWriter::new();
270        self.layer_info.pack(&mut mem, big, encoding, info)?;
271        if let Some(global_layer_mask_info) = &self.global_layer_mask_info {
272            global_layer_mask_info.pack(&mut mem, big, encoding, info)?;
273        } else {
274            0u32.pack(&mut mem, big, encoding, info)?; // no global layer mask info
275        }
276        mem.write_all(&self.tagged_blocks)?;
277        let data = mem.into_inner();
278        let length = data.len() as u32;
279        length.pack(writer, big, encoding, info)?;
280        writer.write_all(&data)?;
281        Ok(())
282    }
283}
284
285#[derive(Debug, Clone)]
286pub struct LayerInfo {
287    pub layer_count: i16,
288    pub layer_records: Vec<LayerRecord>,
289    pub channel_image_data: Vec<ChannelImageData>,
290}
291
292impl StructUnpack for LayerInfo {
293    fn unpack<R: Read + Seek>(
294        reader: &mut R,
295        big: bool,
296        encoding: Encoding,
297        info: &Option<Box<dyn Any>>,
298    ) -> Result<Self> {
299        let length = u32::unpack(reader, big, encoding, info)?;
300        let mut stream_region = StreamRegion::with_size(reader, length as u64)?;
301        let layer_count = i16::unpack(&mut stream_region, big, encoding, info)?;
302        let mut layer_records = Vec::new();
303        for _ in 0..layer_count.abs() {
304            let layer_record = LayerRecord::unpack(&mut stream_region, big, encoding, info)?;
305            layer_records.push(layer_record);
306        }
307        let mut channel_image_data = Vec::new();
308        for i in 0..layer_count.abs() {
309            let layer = &layer_records[i as usize];
310            for j in 0..layer.base.channels {
311                let info = Some(Box::new((layer.clone(), j as usize)) as Box<dyn Any>);
312                let data = ChannelImageData::unpack(&mut stream_region, big, encoding, &info)?;
313                channel_image_data.push(data);
314            }
315        }
316        stream_region.seek_to_end()?;
317        Ok(LayerInfo {
318            layer_count,
319            layer_records,
320            channel_image_data,
321        })
322    }
323}
324
325impl StructPack for LayerInfo {
326    fn pack<W: Write>(
327        &self,
328        writer: &mut W,
329        big: bool,
330        encoding: Encoding,
331        info: &Option<Box<dyn Any>>,
332    ) -> Result<()> {
333        let mut mem = MemWriter::new();
334        self.layer_count.pack(&mut mem, big, encoding, info)?;
335        for layer_record in &self.layer_records {
336            layer_record.pack(&mut mem, big, encoding, info)?;
337        }
338        let mut index = 0usize;
339        for i in 0..self.layer_count {
340            let layer = &self.layer_records[i as usize];
341            let info = Some(Box::new(layer.clone()) as Box<dyn Any>);
342            for _ in 0..layer.base.channels {
343                let data = &self.channel_image_data[index];
344                index += 1;
345                data.pack(&mut mem, big, encoding, &info)?;
346            }
347        }
348        let data = mem.into_inner();
349
350        // Pad to 2 bytes
351        let mut length = data.len() as u32;
352        let need_pad = length % 2 != 0;
353        if need_pad {
354            length += 1;
355        }
356        length.pack(writer, big, encoding, info)?;
357        writer.write_all(&data)?;
358        if need_pad {
359            writer.write_u8(0)?; // padding byte
360        }
361        Ok(())
362    }
363}
364
365#[derive(Debug, Clone, StructPack, StructUnpack)]
366pub struct LayerRecordBase {
367    pub top: i32,
368    pub left: i32,
369    pub bottom: i32,
370    pub right: i32,
371    pub channels: u16,
372    #[unpack_vec_len(channels)]
373    #[pack_vec_len(self.channels)]
374    pub channel_infos: Vec<ChannelInfo>,
375    pub blend_mode_signature: [u8; 4],
376    pub blend_mode_key: [u8; 4],
377    pub opacity: u8,
378    pub clipping: u8,
379    pub flags: u8,
380    pub filler: u8,
381}
382
383#[derive(Debug, Clone)]
384pub struct LayerRecord {
385    pub base: LayerRecordBase,
386    pub layer_mask: Option<LayerMask>,
387    pub layer_blending_ranges: LayerBlendingRanges,
388    pub layer_name: PascalString4,
389    pub infos: Vec<AdditionalLayerInfo>,
390}
391
392impl LayerRecord {
393    pub fn get_info<'a>(&'a self, key: &[u8; 4]) -> Option<&'a [u8]> {
394        for info in &self.infos {
395            if &info.key == key {
396                return Some(&info.data);
397            }
398        }
399        None
400    }
401
402    pub fn layer_name(&self, encoding: Encoding) -> Result<String> {
403        if let Some(uni) = self.get_info(UNICODE_LAYER_KEY) {
404            let data = UnicodeLayer::unpack(&mut MemReaderRef::new(uni), true, encoding, &None)?;
405            Ok(data.name.0)
406        } else {
407            let s = decode_to_string(encoding, &self.layer_name.0, true)?;
408            Ok(s)
409        }
410    }
411}
412
413impl StructPack for LayerRecord {
414    fn pack<W: Write>(
415        &self,
416        writer: &mut W,
417        big: bool,
418        encoding: Encoding,
419        info: &Option<Box<dyn Any>>,
420    ) -> Result<()> {
421        self.base.pack(writer, big, encoding, info)?;
422        let mut mem = MemWriter::new();
423        if let Some(layer_mask) = &self.layer_mask {
424            layer_mask.pack(&mut mem, big, encoding, info)?;
425        } else {
426            0u32.pack(&mut mem, big, encoding, info)?; // no layer mask
427        }
428        self.layer_blending_ranges
429            .pack(&mut mem, big, encoding, info)?;
430        self.layer_name.pack(&mut mem, big, encoding, info)?;
431        for additional_info in &self.infos {
432            additional_info.pack(&mut mem, big, encoding, info)?;
433        }
434        let data = mem.into_inner();
435        let extra_data_length = data.len() as u32;
436        extra_data_length.pack(writer, big, encoding, info)?;
437        writer.write_all(&data)?;
438        Ok(())
439    }
440}
441
442impl StructUnpack for LayerRecord {
443    fn unpack<R: Read + Seek>(
444        reader: &mut R,
445        big: bool,
446        encoding: Encoding,
447        info: &Option<Box<dyn Any>>,
448    ) -> Result<Self> {
449        let base = LayerRecordBase::unpack(reader, big, encoding, info)?;
450        let extra_data_length = u32::unpack(reader, big, encoding, info)?;
451        let mut stream_region = StreamRegion::with_size(reader, extra_data_length as u64)?;
452        let layer_mask_len = u32::unpack(&mut stream_region, big, encoding, info)?;
453        let layer_mask = if layer_mask_len > 0 {
454            stream_region.seek_relative(-4)?;
455            Some(LayerMask::unpack(&mut stream_region, big, encoding, info)?)
456        } else {
457            None
458        };
459        let layer_blending_ranges =
460            LayerBlendingRanges::unpack(&mut stream_region, big, encoding, info)?;
461        let layer_name = PascalString4::unpack(&mut stream_region, big, encoding, info)?;
462        let mut infos = Vec::new();
463        while stream_region.cur_pos() < extra_data_length as u64 {
464            let additional_info =
465                AdditionalLayerInfo::unpack(&mut stream_region, big, encoding, info)?;
466            infos.push(additional_info);
467        }
468        Ok(LayerRecord {
469            base,
470            layer_mask,
471            layer_blending_ranges,
472            layer_name,
473            infos,
474        })
475    }
476}
477
478#[derive(Debug, Clone)]
479pub struct LayerMask {
480    pub top: i32,
481    pub left: i32,
482    pub bottom: i32,
483    pub right: i32,
484    pub default_color: u8,
485    pub flags: u8,
486    pub mask_parameters: Option<u8>,
487    pub mask_data: Option<Vec<u8>>,
488    pub real_flags: Option<u8>,
489    pub real_user_mask_background: Option<u8>,
490    pub mask_top: Option<i32>,
491    pub mask_left: Option<i32>,
492    pub mask_bottom: Option<i32>,
493    pub mask_right: Option<i32>,
494}
495
496impl StructPack for LayerMask {
497    fn pack<W: Write>(
498        &self,
499        writer: &mut W,
500        big: bool,
501        encoding: Encoding,
502        info: &Option<Box<dyn Any>>,
503    ) -> Result<()> {
504        let mut mem = MemWriter::new();
505        self.top.pack(&mut mem, big, encoding, info)?;
506        self.left.pack(&mut mem, big, encoding, info)?;
507        self.bottom.pack(&mut mem, big, encoding, info)?;
508        self.right.pack(&mut mem, big, encoding, info)?;
509        self.default_color.pack(&mut mem, big, encoding, info)?;
510        self.flags.pack(&mut mem, big, encoding, info)?;
511        if self.flags == 4 {
512            if let Some(mask_parameters) = self.mask_parameters {
513                mask_parameters.pack(&mut mem, big, encoding, info)?;
514            } else {
515                return Err(anyhow::anyhow!(
516                    "mask_parameters is required when flags == 4"
517                ));
518            }
519        }
520        if let Some(mask_data) = &self.mask_data {
521            mem.write_all(mask_data)?;
522        }
523        if let Some(real_flags) = self.real_flags {
524            real_flags.pack(&mut mem, big, encoding, info)?;
525            let real_user_mask_background = self
526                .real_user_mask_background
527                .ok_or_else(|| anyhow::anyhow!("real_user_mask_background is required"))?;
528            real_user_mask_background.pack(&mut mem, big, encoding, info)?;
529            let mask_top = self
530                .mask_top
531                .ok_or_else(|| anyhow::anyhow!("mask_top is required"))?;
532            mask_top.pack(&mut mem, big, encoding, info)?;
533            let mask_left = self
534                .mask_left
535                .ok_or_else(|| anyhow::anyhow!("mask_left is required"))?;
536            mask_left.pack(&mut mem, big, encoding, info)?;
537            let mask_bottom = self
538                .mask_bottom
539                .ok_or_else(|| anyhow::anyhow!("mask_bottom is required"))?;
540            mask_bottom.pack(&mut mem, big, encoding, info)?;
541            let mask_right = self
542                .mask_right
543                .ok_or_else(|| anyhow::anyhow!("mask_right is required"))?;
544            mask_right.pack(&mut mem, big, encoding, info)?;
545        } else {
546            if mem.data.len() == 18 {
547                mem.write_u16(0)?; // padding to 20 bytes
548            }
549        }
550        let data = mem.into_inner();
551        let length = data.len() as u32;
552        length.pack(writer, big, encoding, info)?;
553        writer.write_all(&data)?;
554        Ok(())
555    }
556}
557
558impl StructUnpack for LayerMask {
559    fn unpack<R: Read + Seek>(
560        reader: &mut R,
561        big: bool,
562        encoding: Encoding,
563        info: &Option<Box<dyn Any>>,
564    ) -> Result<Self> {
565        let length = u32::unpack(reader, big, encoding, info)?;
566        let mut stream_region = StreamRegion::with_size(reader, length as u64)?;
567        let top = i32::unpack(&mut stream_region, big, encoding, info)?;
568        let left = i32::unpack(&mut stream_region, big, encoding, info)?;
569        let bottom = i32::unpack(&mut stream_region, big, encoding, info)?;
570        let right = i32::unpack(&mut stream_region, big, encoding, info)?;
571        let default_color = u8::unpack(&mut stream_region, big, encoding, info)?;
572        let flags = u8::unpack(&mut stream_region, big, encoding, info)?;
573        let mask_parameters = if flags == 4 {
574            Some(u8::unpack(&mut stream_region, big, encoding, info)?)
575        } else {
576            None
577        };
578        let mask_data = if flags == 0 || flags == 2 {
579            Some(stream_region.read_exact_vec(1)?)
580        } else if flags == 1 || flags == 3 {
581            Some(stream_region.read_exact_vec(8)?)
582        } else {
583            None
584        };
585        if length == 20 {
586            let _ = stream_region.read_u16()?; // padding
587        }
588        if stream_region.cur_pos() < length as u64 {
589            let real_flags = u8::unpack(&mut stream_region, big, encoding, info)?;
590            let real_user_mask_background = u8::unpack(&mut stream_region, big, encoding, info)?;
591            let mask_top = i32::unpack(&mut stream_region, big, encoding, info)?;
592            let mask_left = i32::unpack(&mut stream_region, big, encoding, info)?;
593            let mask_bottom = i32::unpack(&mut stream_region, big, encoding, info)?;
594            let mask_right = i32::unpack(&mut stream_region, big, encoding, info)?;
595            stream_region.seek_to_end()?;
596            Ok(LayerMask {
597                top,
598                left,
599                bottom,
600                right,
601                default_color,
602                flags,
603                mask_parameters,
604                mask_data,
605                real_flags: Some(real_flags),
606                real_user_mask_background: Some(real_user_mask_background),
607                mask_top: Some(mask_top),
608                mask_left: Some(mask_left),
609                mask_bottom: Some(mask_bottom),
610                mask_right: Some(mask_right),
611            })
612        } else {
613            stream_region.seek_to_end()?;
614            Ok(LayerMask {
615                top,
616                left,
617                bottom,
618                right,
619                default_color,
620                flags,
621                mask_parameters,
622                mask_data,
623                real_flags: None,
624                real_user_mask_background: None,
625                mask_top: None,
626                mask_left: None,
627                mask_bottom: None,
628                mask_right: None,
629            })
630        }
631    }
632}
633
634#[derive(Debug, Clone, StructPack, StructUnpack)]
635pub struct ChannelInfo {
636    pub channel_id: i16,
637    pub length: u32,
638}
639
640#[derive(Debug, Clone)]
641pub struct LayerBlendingRanges {
642    pub gray_blend_source: u32,
643    pub gray_blend_dest: u32,
644    pub channel_ranges: Vec<ChannelRange>,
645}
646
647impl StructUnpack for LayerBlendingRanges {
648    fn unpack<R: Read + Seek>(
649        reader: &mut R,
650        big: bool,
651        encoding: Encoding,
652        info: &Option<Box<dyn Any>>,
653    ) -> Result<Self> {
654        let total_length = u32::unpack(reader, big, encoding, info)?;
655        let mut stream_region = StreamRegion::with_size(reader, total_length as u64)?;
656        let gray_blend_source = u32::unpack(&mut stream_region, big, encoding, info)?;
657        let gray_blend_dest = u32::unpack(&mut stream_region, big, encoding, info)?;
658        let mut channel_ranges = Vec::new();
659        while stream_region.cur_pos() < total_length as u64 {
660            let channel_range = ChannelRange::unpack(&mut stream_region, big, encoding, info)?;
661            channel_ranges.push(channel_range);
662        }
663        Ok(LayerBlendingRanges {
664            gray_blend_source,
665            gray_blend_dest,
666            channel_ranges,
667        })
668    }
669}
670
671impl StructPack for LayerBlendingRanges {
672    fn pack<W: Write>(
673        &self,
674        writer: &mut W,
675        big: bool,
676        encoding: Encoding,
677        info: &Option<Box<dyn Any>>,
678    ) -> Result<()> {
679        let mut mem = MemWriter::new();
680        self.gray_blend_source.pack(&mut mem, big, encoding, info)?;
681        self.gray_blend_dest.pack(&mut mem, big, encoding, info)?;
682        for channel_range in &self.channel_ranges {
683            channel_range.pack(&mut mem, big, encoding, info)?;
684        }
685        let data = mem.into_inner();
686        let total_length = data.len() as u32;
687        total_length.pack(writer, big, encoding, info)?;
688        writer.write_all(&data)?;
689        Ok(())
690    }
691}
692
693#[derive(Debug, Clone, StructPack, StructUnpack)]
694pub struct ChannelRange {
695    pub source_range: u32,
696    pub dest_range: u32,
697}
698
699#[derive(Debug, Clone)]
700pub struct AdditionalLayerInfo {
701    pub signature: [u8; 4],
702    pub key: [u8; 4],
703    pub data: Vec<u8>,
704}
705
706impl StructUnpack for AdditionalLayerInfo {
707    fn unpack<R: Read + Seek>(
708        reader: &mut R,
709        big: bool,
710        encoding: Encoding,
711        info: &Option<Box<dyn Any>>,
712    ) -> Result<Self> {
713        let signature = <[u8; 4]>::unpack(reader, big, encoding, info)?;
714        let key = <[u8; 4]>::unpack(reader, big, encoding, info)?;
715        let length = u32::unpack(reader, big, encoding, info)?;
716        let data = reader.read_exact_vec(length as usize)?;
717        Ok(AdditionalLayerInfo {
718            signature,
719            key,
720            data,
721        })
722    }
723}
724
725impl StructPack for AdditionalLayerInfo {
726    fn pack<W: Write>(
727        &self,
728        writer: &mut W,
729        big: bool,
730        encoding: Encoding,
731        info: &Option<Box<dyn Any>>,
732    ) -> Result<()> {
733        self.signature.pack(writer, big, encoding, info)?;
734        self.key.pack(writer, big, encoding, info)?;
735        let mut length = self.data.len() as u32;
736        let need_pad = length % 2 != 0;
737        if need_pad {
738            length += 1;
739        }
740        length.pack(writer, big, encoding, info)?;
741        writer.write_all(&self.data)?;
742        if need_pad {
743            writer.write_u8(0)?; // padding byte
744        }
745        Ok(())
746    }
747}
748
749#[derive(Debug, Clone)]
750pub struct ChannelImageData {
751    pub compression: u16,
752    pub image_data: Vec<u8>,
753}
754
755fn get_layer_info(info: &Option<Box<dyn Any>>) -> Result<&LayerRecord> {
756    if let Some(boxed) = info {
757        if let Some(layer_record) = boxed.downcast_ref::<LayerRecord>() {
758            return Ok(layer_record);
759        }
760    }
761    Err(anyhow::anyhow!(
762        "LayerRecord info is required for ChannelImageData unpacking"
763    ))
764}
765
766fn get_layer_info_with_channel_index(info: &Option<Box<dyn Any>>) -> Result<&(LayerRecord, usize)> {
767    if let Some(boxed) = info {
768        if let Some(layer_info) = boxed.downcast_ref::<(LayerRecord, usize)>() {
769            return Ok(layer_info);
770        }
771    }
772    Err(anyhow::anyhow!(
773        "LayerRecord and channel index info is required for ChannelImageData unpacking"
774    ))
775}
776
777impl StructUnpack for ChannelImageData {
778    fn unpack<R: Read + Seek>(
779        reader: &mut R,
780        big: bool,
781        encoding: Encoding,
782        info: &Option<Box<dyn Any>>,
783    ) -> Result<Self> {
784        let (layer, idx) = get_layer_info_with_channel_index(info)?;
785        let layer_len = layer
786            .base
787            .channel_infos
788            .get(*idx)
789            .ok_or_else(|| anyhow::anyhow!("Channel index {} out of bounds for layer", idx))?
790            .length;
791        let mut stream_region = StreamRegion::with_size(reader, layer_len as u64)?;
792        let compression = u16::unpack(&mut stream_region, big, encoding, info)?;
793        let mut image_data = Vec::new();
794        stream_region.read_to_end(&mut image_data)?;
795        Ok(ChannelImageData {
796            compression,
797            image_data,
798        })
799    }
800}
801
802impl StructPack for ChannelImageData {
803    fn pack<W: Write>(
804        &self,
805        writer: &mut W,
806        big: bool,
807        encoding: Encoding,
808        info: &Option<Box<dyn Any>>,
809    ) -> Result<()> {
810        self.compression.pack(writer, big, encoding, info)?;
811        if self.compression == 0 {
812            let layer_info = get_layer_info(info)?;
813            let expected_len = (layer_info.base.bottom - layer_info.base.top) as usize
814                * (layer_info.base.right - layer_info.base.left) as usize;
815            if self.image_data.len() != expected_len {
816                return Err(anyhow::anyhow!(
817                    "Channel image data length does not match expected size"
818                ));
819            }
820        }
821        writer.write_all(&self.image_data)?;
822        Ok(())
823    }
824}
825
826#[derive(Debug, Clone)]
827pub struct GlobalLayerMaskInfo {
828    pub overlays_color_space: u16,
829    pub overlays_color_components: [u16; 4],
830    pub opacity: u16,
831    pub kind: u8,
832    pub filler: Vec<u8>,
833}
834
835impl StructUnpack for GlobalLayerMaskInfo {
836    fn unpack<R: Read + Seek>(
837        reader: &mut R,
838        big: bool,
839        encoding: Encoding,
840        info: &Option<Box<dyn Any>>,
841    ) -> Result<Self> {
842        let length = u32::unpack(reader, big, encoding, info)?;
843        let mut stream_region = StreamRegion::with_size(reader, length as u64)?;
844        let overlays_color_space = u16::unpack(&mut stream_region, big, encoding, info)?;
845        let mut overlays_color_components = [0u16; 4];
846        for i in 0..4 {
847            overlays_color_components[i] = u16::unpack(&mut stream_region, big, encoding, info)?;
848        }
849        let opacity = u16::unpack(&mut stream_region, big, encoding, info)?;
850        let kind = u8::unpack(&mut stream_region, big, encoding, info)?;
851        let filler_length = length as usize - 2 - (4 * 2) - 2 - 1;
852        let mut filler = vec![0u8; filler_length];
853        stream_region.read_exact(&mut filler)?;
854        stream_region.seek_to_end()?;
855        Ok(GlobalLayerMaskInfo {
856            overlays_color_space,
857            overlays_color_components,
858            opacity,
859            kind,
860            filler,
861        })
862    }
863}
864
865impl StructPack for GlobalLayerMaskInfo {
866    fn pack<W: Write>(
867        &self,
868        writer: &mut W,
869        big: bool,
870        encoding: Encoding,
871        info: &Option<Box<dyn Any>>,
872    ) -> Result<()> {
873        let mut mem = MemWriter::new();
874        self.overlays_color_space
875            .pack(&mut mem, big, encoding, info)?;
876        for component in &self.overlays_color_components {
877            component.pack(&mut mem, big, encoding, info)?;
878        }
879        self.opacity.pack(&mut mem, big, encoding, info)?;
880        self.kind.pack(&mut mem, big, encoding, info)?;
881        mem.write_all(&self.filler)?;
882        let data = mem.into_inner();
883        let length = data.len() as u32;
884        length.pack(writer, big, encoding, info)?;
885        writer.write_all(&data)?;
886        Ok(())
887    }
888}
889
890#[derive(Debug, Clone)]
891pub struct ImageDataSection {
892    pub compression: u16,
893    pub image_data: Vec<u8>,
894}
895
896fn get_psd_header(info: &Option<Box<dyn Any>>) -> Result<&PsdHeader> {
897    if let Some(boxed) = info {
898        if let Some(psd_header) = boxed.downcast_ref::<PsdHeader>() {
899            return Ok(psd_header);
900        }
901    }
902    Err(anyhow::anyhow!("PsdHeader info is required"))
903}
904
905impl StructUnpack for ImageDataSection {
906    fn unpack<R: Read + Seek>(
907        reader: &mut R,
908        big: bool,
909        encoding: Encoding,
910        info: &Option<Box<dyn Any>>,
911    ) -> Result<Self> {
912        let compression = u16::unpack(reader, big, encoding, info)?;
913        let mut image_data = Vec::new();
914        reader.read_to_end(&mut image_data)?;
915        Ok(ImageDataSection {
916            compression,
917            image_data,
918        })
919    }
920}
921
922impl StructPack for ImageDataSection {
923    fn pack<W: Write>(
924        &self,
925        writer: &mut W,
926        big: bool,
927        encoding: Encoding,
928        info: &Option<Box<dyn Any>>,
929    ) -> Result<()> {
930        self.compression.pack(writer, big, encoding, info)?;
931        if self.compression == 0 {
932            let psd_header = get_psd_header(info)?;
933            let expected_len = psd_header.channels as usize
934                * psd_header.height as usize
935                * psd_header.width as usize
936                * psd_header.depth as usize
937                / 8;
938            if self.image_data.len() != expected_len {
939                return Err(anyhow::anyhow!(
940                    "Image data length does not match expected size"
941                ));
942            }
943        }
944        writer.write_all(&self.image_data)?;
945        Ok(())
946    }
947}
948
949#[derive(Debug)]
950pub struct PsdFile {
951    pub header: PsdHeader,
952    pub color_mode_data: ColorModeData,
953    pub image_resource: ImageResourceSection,
954    pub layer_and_mask_info: LayerAndMaskInfo,
955    pub image_data: ImageDataSection,
956}
957
958impl StructPack for PsdFile {
959    fn pack<W: Write>(
960        &self,
961        writer: &mut W,
962        big: bool,
963        encoding: Encoding,
964        _info: &Option<Box<dyn Any>>,
965    ) -> Result<()> {
966        let psd_info = Some(Box::new(self.header.clone()) as Box<dyn Any>);
967        self.header.pack(writer, big, encoding, &psd_info)?;
968        self.color_mode_data
969            .pack(writer, big, encoding, &psd_info)?;
970        self.image_resource.pack(writer, big, encoding, &psd_info)?;
971        self.layer_and_mask_info
972            .pack(writer, big, encoding, &psd_info)?;
973        self.image_data.pack(writer, big, encoding, &psd_info)?;
974        Ok(())
975    }
976}
977
978impl StructUnpack for PsdFile {
979    fn unpack<R: Read + Seek>(
980        reader: &mut R,
981        big: bool,
982        encoding: Encoding,
983        info: &Option<Box<dyn Any>>,
984    ) -> Result<Self> {
985        let header = PsdHeader::unpack(reader, big, encoding, info)?;
986        let psd_info = Some(Box::new(header.clone()) as Box<dyn Any>);
987        let color_mode_data = ColorModeData::unpack(reader, big, encoding, &psd_info)?;
988        let image_resource = ImageResourceSection::unpack(reader, big, encoding, &psd_info)?;
989        let layer_and_mask_info = LayerAndMaskInfo::unpack(reader, big, encoding, &psd_info)?;
990        let image_data = ImageDataSection::unpack(reader, big, encoding, &psd_info)?;
991        Ok(PsdFile {
992            header,
993            color_mode_data,
994            image_resource,
995            layer_and_mask_info,
996            image_data,
997        })
998    }
999}
1000
1001impl PsdFile {
1002    pub fn layer_count(&self) -> usize {
1003        self.layer_and_mask_info.layer_info.layer_count.abs() as usize
1004    }
1005}
1006
1007#[derive(Debug, Clone, StructPack, StructUnpack)]
1008pub struct SectionDividerSetting {
1009    pub typ: u32,
1010    // TODO: implement the rest fields
1011}
1012
1013#[derive(Debug, Clone, StructPack, StructUnpack)]
1014pub struct UnicodeLayer {
1015    pub name: UnicodeString,
1016}
1017
1018#[derive(Debug, Clone, StructPack, StructUnpack)]
1019pub struct LayerID {
1020    /// ID for the layer
1021    pub id: u32,
1022}
1023
1024#[derive(Debug, Clone, StructPack, StructUnpack)]
1025pub struct LayerNameSourceSetting {
1026    /// ID for the layer name
1027    pub id: i32,
1028}