msg_tool\utils\psd/
compression.rs1use super::NormalLayer;
2use super::types::*;
3use crate::ext::io::*;
4use anyhow::Result;
5use std::io::Read;
6
7pub fn rle_compress(data: &[u8]) -> Vec<u8> {
8 let start = 0;
9 let line_end = data.len();
10 let mut idx = start;
11 let mut literal: Vec<u8> = Vec::new();
12 let mut out_line: Vec<u8> = Vec::new();
13 while idx < line_end {
14 let mut run_len = 1;
16 while idx + run_len < line_end && data[idx + run_len] == data[idx] && run_len < 128 {
17 run_len += 1;
18 }
19
20 if run_len >= 3 {
21 if !literal.is_empty() {
23 let header = (literal.len() - 1) as i8;
25 out_line.push(header as u8);
26 out_line.extend_from_slice(&literal);
27 literal.clear();
28 }
29 let header = -(((run_len as u8) - 1) as i8);
31 out_line.push(header as u8);
32 out_line.push(data[idx]);
33 idx += run_len;
34 } else {
35 literal.push(data[idx]);
37 idx += 1;
38 if literal.len() == 128 {
40 let header = (literal.len() - 1) as i8;
41 out_line.push(header as u8);
42 out_line.extend_from_slice(&literal);
43 literal.clear();
44 } else {
45 if idx < line_end {
47 let mut look_run = 1;
48 while idx + look_run < line_end
49 && data[idx + look_run] == data[idx]
50 && look_run < 128
51 {
52 look_run += 1;
53 }
54 if look_run >= 3 {
55 if !literal.is_empty() {
56 let header = (literal.len() - 1) as i8;
57 out_line.push(header as u8);
58 out_line.extend_from_slice(&literal);
59 literal.clear();
60 }
61 }
62 }
63 }
64 }
65 }
66 if !literal.is_empty() {
68 let header = (literal.len() - 1) as i8;
69 out_line.push(header as u8);
70 out_line.extend_from_slice(&literal);
71 literal.clear();
72 }
73 out_line
74}
75
76pub fn rle_decompress(data: &[u8]) -> Result<Vec<u8>> {
77 let mut reader = MemReaderRef::new(data);
78 let len = data.len();
79 let mut out = Vec::new();
80 while reader.pos < len {
81 let c = reader.read_i8()?;
82 if c >= 0 {
83 let rlen = (c as usize) + 1;
84 let old_len = out.len();
85 out.resize(old_len + rlen, 0);
86 reader.read_exact(&mut out[old_len..old_len + rlen])?;
87 } else {
88 let rlen = (-(c as isize) as usize) + 1;
89 let val = reader.read_u8()?;
90 let old_len = out.len();
91 out.resize(old_len + rlen, val);
92 }
93 }
94 Ok(out)
95}
96
97pub fn decompress_channel_image_data(
98 data: &mut ChannelImageData,
99 layer: &NormalLayer,
100) -> Result<()> {
101 match data.compression {
102 0 => Ok(()), 1 => {
104 let mut reader = MemReaderRef::new(&data.image_data);
105 let base = &layer.layer.base;
106 let height = (base.bottom - base.top) as u32;
107 let length_len = height as usize * 2;
108 let mut start = length_len;
109 let mut image = Vec::new();
110 for _ in 0..height {
111 let len = reader.read_u16_be()? as usize;
112 let decompressed = rle_decompress(&data.image_data[start..start + len])?;
113 start += len;
114 image.extend(decompressed);
115 }
116 data.image_data = image;
117 data.compression = 0;
118 Ok(())
119 }
120 2 => {
121 let mut decoder = flate2::read::ZlibDecoder::new(&data.image_data[..]);
122 let mut decompressed = Vec::new();
123 decoder.read_to_end(&mut decompressed)?;
124 data.image_data = decompressed;
125 data.compression = 0;
126 Ok(())
127 }
128 3 => {
129 let mut decoder = flate2::read::ZlibDecoder::new(&data.image_data[..]);
130 let mut decompressed = Vec::new();
131 decoder.read_to_end(&mut decompressed)?;
132 let base = &layer.layer.base;
133 let height = (base.bottom - base.top) as u32;
134 let width = (base.right - base.left) as u32;
135 let bit_depth = layer.psd.bit_depth();
136 if bit_depth == 1 {
137 anyhow::bail!("Decompression for 1-bit images is not implemented yet");
138 }
139 let mut writer = MemWriterRef::new(&mut decompressed);
140 for _ in 0..height {
141 if bit_depth == 8 {
142 let mut pre = writer.read_u8()?;
143 for _ in 1..width {
144 let cur = writer.peek_u8()?;
145 let val = cur.wrapping_add(pre);
146 writer.write_u8(val)?;
147 pre = val;
148 }
149 } else if bit_depth == 16 {
150 let mut pre = writer.read_u16_be()?;
151 for _ in 1..width {
152 let cur = writer.peek_u16_be()?;
153 let val = cur.wrapping_add(pre);
154 writer.write_u16_be(val)?;
155 pre = val;
156 }
157 } else if bit_depth == 32 {
158 let mut pre = writer.read_u32_be()?;
159 for _ in 1..width {
160 let cur = writer.peek_u32_be()?;
161 let val = cur.wrapping_add(pre);
162 writer.write_u32_be(val)?;
163 pre = val;
164 }
165 } else {
166 anyhow::bail!("Unsupported bit depth for decompression: {}", bit_depth);
167 }
168 }
169 data.image_data = decompressed;
170 data.compression = 0;
171 Ok(())
172 }
173 _ => anyhow::bail!("Unsupported compression type: {}", data.compression),
174 }
175}