1use crate::error::{McRawError, Result, read_le_bytes};
2use crate::simd_portable::*;
3use wide::u16x8;
4
5const ENCODING_BLOCK: usize = 64;
6const HEADER_LENGTH: usize = 2;
7const METADATA_OFFSET: usize = 16;
8const ENCODING_BLOCK_LENGTH: [usize; 17] = [
9 0, 8, 16, 24, 32, 40, 48, 64, 64, 80, 80, 128, 128, 128, 128, 128, 128,
10];
11
12#[inline(always)]
13fn decode1(out: &mut [u16], inp: &[u8]) -> Result<usize> {
14 let n = u16x8::splat(0x01);
15 let p = load_u8_to_u16x8(inp)?;
16 store_u16x8(&mut out[0..], p & n)?;
17 store_u16x8(&mut out[8..], (p & (n << 1u32)) >> 1u32)?;
18 store_u16x8(&mut out[16..], (p & (n << 2u32)) >> 2u32)?;
19 store_u16x8(&mut out[24..], (p & (n << 3u32)) >> 3u32)?;
20 store_u16x8(&mut out[32..], (p & (n << 4u32)) >> 4u32)?;
21 store_u16x8(&mut out[40..], (p & (n << 5u32)) >> 5u32)?;
22 store_u16x8(&mut out[48..], (p & (n << 6u32)) >> 6u32)?;
23 store_u16x8(&mut out[56..], (p & (n << 7u32)) >> 7u32)?;
24 Ok(ENCODING_BLOCK_LENGTH[1])
25}
26
27#[inline(always)]
28fn decode2_one(out: &mut [u16], inp: &[u8]) -> Result<usize> {
29 let n = u16x8::splat(0x03);
30 let p = load_u8_to_u16x8(inp)?;
31 store_u16x8(&mut out[0..], p & n)?;
32 store_u16x8(&mut out[8..], (p & (n << 2u32)) >> 2u32)?;
33 store_u16x8(&mut out[16..], (p & (n << 4u32)) >> 4u32)?;
34 store_u16x8(&mut out[24..], (p & (n << 6u32)) >> 6u32)?;
35 Ok(8)
36}
37
38#[inline(always)]
39fn decode2(out: &mut [u16], inp: &[u8]) -> Result<usize> {
40 let mut o = decode2_one(&mut out[0..], inp)?;
41 o += decode2_one(&mut out[32..], &inp[o..])?;
42 Ok(o)
43}
44
45#[inline(always)]
46fn decode3(out: &mut [u16], inp: &[u8]) -> Result<usize> {
47 let n = u16x8::splat(0x07);
48 let t = u16x8::splat(0x03);
49 let r = u16x8::splat(0x01);
50
51 let p0 = load_u8_to_u16x8(inp)?;
52 let p1 = load_u8_to_u16x8(&inp[8..])?;
53 let p2 = load_u8_to_u16x8(&inp[16..])?;
54
55 let r0 = p0 & n;
56 let r1 = (p0 & (n << 3u32)) >> 3u32;
57 let _r2 = (p0 & (t << 6u32)) >> 6u32;
58 let r3 = p1 & n;
59 let r4 = (p1 & (n << 3u32)) >> 3u32;
60 let _r5 = (p1 & (t << 6u32)) >> 6u32;
61 let r6 = p2 & n;
62 let r7 = (p2 & (n << 3u32)) >> 3u32;
63
64 let r2 = _r2 | (((p2 >> 6u32) & r) << 2u32);
65 let r5 = _r5 | (((p2 >> 7u32) & r) << 2u32);
66
67 store_u16x8(&mut out[0..], r0)?;
68 store_u16x8(&mut out[8..], r1)?;
69 store_u16x8(&mut out[16..], r2)?;
70 store_u16x8(&mut out[24..], r3)?;
71 store_u16x8(&mut out[32..], r4)?;
72 store_u16x8(&mut out[40..], r5)?;
73 store_u16x8(&mut out[48..], r6)?;
74 store_u16x8(&mut out[56..], r7)?;
75
76 Ok(ENCODING_BLOCK_LENGTH[3])
77}
78
79#[inline(always)]
80fn decode4_one(out: &mut [u16], inp: &[u8]) -> Result<usize> {
81 let n = u16x8::splat(0x0F);
82 let p = load_u8_to_u16x8(inp)?;
83 store_u16x8(&mut out[0..], p & n)?;
84 store_u16x8(&mut out[8..], (p & (n << 4u32)) >> 4u32)?;
85 Ok(8)
86}
87
88#[inline(always)]
89fn decode4(out: &mut [u16], inp: &[u8]) -> Result<usize> {
90 let mut o = decode4_one(&mut out[0..], inp)?;
91 o += decode4_one(&mut out[16..], &inp[o..])?;
92 o += decode4_one(&mut out[32..], &inp[o..])?;
93 o += decode4_one(&mut out[48..], &inp[o..])?;
94 Ok(o)
95}
96
97#[inline(always)]
98fn decode5(out: &mut [u16], inp: &[u8]) -> Result<usize> {
99 let n = u16x8::splat(0x1F);
100 let l = u16x8::splat(0x07);
101 let u = u16x8::splat(0x03);
102 let f = u16x8::splat(0x01);
103
104 let p0 = load_u8_to_u16x8(inp)?;
105 let p1 = load_u8_to_u16x8(&inp[8..])?;
106 let p2 = load_u8_to_u16x8(&inp[16..])?;
107 let p3 = load_u8_to_u16x8(&inp[24..])?;
108 let p4 = load_u8_to_u16x8(&inp[32..])?;
109
110 store_u16x8(&mut out[0..], p0 & n)?;
111 store_u16x8(&mut out[8..], p1 & n)?;
112 store_u16x8(&mut out[16..], p2 & n)?;
113 store_u16x8(&mut out[24..], p3 & n)?;
114 store_u16x8(&mut out[32..], p4 & n)?;
115 store_u16x8(&mut out[40..], (p0 >> 5u32) & l | (((p3 >> 5u32) & u) << 3u32))?;
116 store_u16x8(&mut out[48..], (p1 >> 5u32) & l | (((p4 >> 5u32) & u) << 3u32))?;
117
118 let tmp0 = (p2 >> 5u32) & l;
119 let tmp1 = tmp0 | ((p3 >> 7u32) & f) << 3u32;
120 store_u16x8(&mut out[56..], tmp1 | (((p4 >> 7u32) & f) << 4u32))?;
121
122 Ok(ENCODING_BLOCK_LENGTH[5])
123}
124
125#[inline(always)]
126fn decode6(out: &mut [u16], inp: &[u8]) -> Result<usize> {
127 let n = u16x8::splat(0x3F);
128 let l = u16x8::splat(0x03);
129
130 let p0 = load_u8_to_u16x8(inp)?;
131 let p1 = load_u8_to_u16x8(&inp[8..])?;
132 let p2 = load_u8_to_u16x8(&inp[16..])?;
133 let p3 = load_u8_to_u16x8(&inp[24..])?;
134 let p4 = load_u8_to_u16x8(&inp[32..])?;
135 let p5 = load_u8_to_u16x8(&inp[40..])?;
136
137 store_u16x8(&mut out[0..], p0 & n)?;
138 store_u16x8(&mut out[8..], p1 & n)?;
139 store_u16x8(&mut out[16..], p2 & n)?;
140 store_u16x8(&mut out[24..], p3 & n)?;
141 store_u16x8(&mut out[32..], p4 & n)?;
142 store_u16x8(&mut out[40..], p5 & n)?;
143
144 store_u16x8(
145 &mut out[48..],
146 ((p0 >> 6u32) & l) | (((p1 >> 6u32) & l) << 2u32) | (((p2 >> 6u32) & l) << 4u32),
147 )?;
148 store_u16x8(
149 &mut out[56..],
150 ((p3 >> 6u32) & l) | (((p4 >> 6u32) & l) << 2u32) | (((p5 >> 6u32) & l) << 4u32),
151 )?;
152
153 Ok(ENCODING_BLOCK_LENGTH[6])
154}
155
156#[inline(always)]
157fn decode8_one(out: &mut [u16], inp: &[u8]) -> Result<usize> {
158 store_u16x8(out, load_u8_to_u16x8(inp)?)?;
159 Ok(8)
160}
161
162#[inline(always)]
163fn decode8(out: &mut [u16], inp: &[u8]) -> Result<usize> {
164 let mut o = 0;
165 for i in (0..64).step_by(8) {
166 o += decode8_one(&mut out[i..], &inp[o..])?;
167 }
168 Ok(o)
169}
170
171#[inline(always)]
172fn decode10(out: &mut [u16], inp: &[u8]) -> Result<usize> {
173 let n = u16x8::splat(0xFF);
174 let l = u16x8::splat(0x03);
175
176 let p0 = load_u8_to_u16x8(inp)?;
177 let p1 = load_u8_to_u16x8(&inp[8..])?;
178 let p2 = load_u8_to_u16x8(&inp[16..])?;
179 let p3 = load_u8_to_u16x8(&inp[24..])?;
180 let p4 = load_u8_to_u16x8(&inp[32..])?;
181 let p5 = load_u8_to_u16x8(&inp[40..])?;
182 let p6 = load_u8_to_u16x8(&inp[48..])?;
183 let p7 = load_u8_to_u16x8(&inp[56..])?;
184 let p8 = load_u8_to_u16x8(&inp[64..])?;
185 let p9 = load_u8_to_u16x8(&inp[72..])?;
186
187 let _r0 = p0 & n;
188 let _r1 = p1 & n;
189 let _r2 = p2 & n;
190 let _r3 = p3 & n;
191
192 store_u16x8(&mut out[0..], _r0 | ((p4 & l) << 8u32))?;
193 store_u16x8(&mut out[8..], _r1 | ((p4 & (l << 2u32)) << 6u32))?;
194 store_u16x8(&mut out[16..], _r2 | ((p4 & (l << 4u32)) << 4u32))?;
195 store_u16x8(&mut out[24..], _r3 | ((p4 & (l << 6u32)) << 2u32))?;
196
197 let _r4 = p5 & n;
198 let _r5 = p6 & n;
199 let _r6 = p7 & n;
200 let _r7 = p8 & n;
201
202 store_u16x8(&mut out[32..], _r4 | ((p9 & l) << 8u32))?;
203 store_u16x8(&mut out[40..], _r5 | ((p9 & (l << 2u32)) << 6u32))?;
204 store_u16x8(&mut out[48..], _r6 | ((p9 & (l << 4u32)) << 4u32))?;
205 store_u16x8(&mut out[56..], _r7 | ((p9 & (l << 6u32)) << 2u32))?;
206
207 Ok(ENCODING_BLOCK_LENGTH[10])
208}
209
210#[inline(always)]
211fn decode16_one(out: &mut [u16], inp: &[u8]) -> Result<usize> {
212 let chunk: &[u8; 16] = inp
213 .get(..16)
214 .ok_or(McRawError::TruncatedData)?
215 .try_into()
216 .map_err(|_| McRawError::TruncatedData)?;
217 let arr = [
218 u16::from_le_bytes([chunk[0], chunk[1]]),
219 u16::from_le_bytes([chunk[2], chunk[3]]),
220 u16::from_le_bytes([chunk[4], chunk[5]]),
221 u16::from_le_bytes([chunk[6], chunk[7]]),
222 u16::from_le_bytes([chunk[8], chunk[9]]),
223 u16::from_le_bytes([chunk[10], chunk[11]]),
224 u16::from_le_bytes([chunk[12], chunk[13]]),
225 u16::from_le_bytes([chunk[14], chunk[15]]),
226 ];
227 store_u16x8(out, u16x8::from(arr))?;
228 Ok(16)
229}
230
231#[inline(always)]
232fn decode16(out: &mut [u16], inp: &[u8]) -> Result<usize> {
233 let mut o = 0;
234 for i in (0..64).step_by(8) {
235 o += decode16_one(&mut out[i..], &inp[o..])?;
236 }
237 Ok(o)
238}
239
240#[inline(always)]
241fn decode_block(out: &mut [u16], bits: u16, inp: &[u8], offset: usize, len: usize) -> Result<usize> {
242 let block_len = ENCODING_BLOCK_LENGTH
243 .get(bits as usize)
244 .copied()
245 .ok_or(McRawError::InvalidCompressionType(bits as i32))?;
246
247 if offset + block_len > len {
248 return Ok(len - offset);
249 }
250
251 let slice = &inp[offset..];
252 match bits {
253 0 => {
254 out[..ENCODING_BLOCK].fill(0);
255 Ok(0)
256 }
257 1 => decode1(out, slice),
258 2 => decode2(out, slice),
259 3 => decode3(out, slice),
260 4 => decode4(out, slice),
261 5 => decode5(out, slice),
262 6 => decode6(out, slice),
263 7 | 8 => decode8(out, slice),
264 9 | 10 => decode10(out, slice),
265 _ => decode16(out, slice),
266 }
267}
268
269fn decode_metadata(inp: &[u8], mut offset: usize, len: usize, out: &mut Vec<u16>) -> Result<usize> {
270 if offset + 4 > len {
271 return Err(McRawError::TruncatedData);
272 }
273
274 let num_blocks = u32::from_le_bytes(read_le_bytes(inp, offset)?) as usize;
275 offset += 4;
276 out.resize(num_blocks, 0);
277
278 let mut ptr = 0;
279 let mut i = 0;
280 while i < num_blocks {
281 let (bits, reference) = decode_header(&inp[offset..])?;
282 offset += HEADER_LENGTH;
283 offset += decode_block(&mut out[ptr..], bits as u16, inp, offset, len)?;
284 for x in 0..ENCODING_BLOCK.min(num_blocks - i) {
285 out[ptr + x] += reference;
286 }
287 ptr += ENCODING_BLOCK;
288 i += ENCODING_BLOCK;
289 }
290 Ok(offset)
291}
292
293pub fn decode(output: &mut [u16], width: usize, _height: usize, input: &[u8]) -> Result<usize> {
298 if input.len() < METADATA_OFFSET {
299 return Err(McRawError::TruncatedData);
300 }
301
302 let enc_w = u32::from_le_bytes(read_le_bytes(input, 0)?) as usize;
303 let enc_h = u32::from_le_bytes(read_le_bytes(input, 4)?) as usize;
304 let bits_off = u32::from_le_bytes(read_le_bytes(input, 8)?) as usize;
305 let refs_off = u32::from_le_bytes(read_le_bytes(input, 12)?) as usize;
306
307 if bits_off > input.len() || refs_off > input.len() || !enc_w.is_multiple_of(ENCODING_BLOCK) || enc_w < width
308 {
309 return Err(McRawError::DecompressionFailed("invalid raw header".into()));
310 }
311
312 let mut bits = Vec::new();
313 let mut refs = Vec::new();
314 decode_metadata(input, bits_off, input.len(), &mut bits)?;
315 decode_metadata(input, refs_off, input.len(), &mut refs)?;
316
317 let mut offset = METADATA_OFFSET;
318 let mut meta_idx = 0;
319 let mut out_idx = 0;
320
321 let mut row0 = vec![0u16; enc_w];
322 let mut row1 = vec![0u16; enc_w];
323 let mut row2 = vec![0u16; enc_w];
324 let mut row3 = vec![0u16; enc_w];
325
326 for _ in (0..enc_h).step_by(4) {
327 for x in (0..enc_w).step_by(ENCODING_BLOCK) {
328 let b = [bits[meta_idx], bits[meta_idx + 1], bits[meta_idx + 2], bits[meta_idx + 3]];
329 let r = [refs[meta_idx], refs[meta_idx + 1], refs[meta_idx + 2], refs[meta_idx + 3]];
330
331 let mut p0 = [0u16; ENCODING_BLOCK];
332 let mut p1 = [0u16; ENCODING_BLOCK];
333 let mut p2 = [0u16; ENCODING_BLOCK];
334 let mut p3 = [0u16; ENCODING_BLOCK];
335
336 offset += decode_block(&mut p0, b[0], input, offset, input.len())?;
337 offset += decode_block(&mut p1, b[1], input, offset, input.len())?;
338 offset += decode_block(&mut p2, b[2], input, offset, input.len())?;
339 offset += decode_block(&mut p3, b[3], input, offset, input.len())?;
340
341 for i in (0..ENCODING_BLOCK).step_by(2) {
342 row0[x + i] = p0[i / 2] + r[0];
343 row0[x + i + 1] = p1[i / 2] + r[1];
344 row1[x + i] = p2[i / 2] + r[2];
345 row1[x + i + 1] = p3[i / 2] + r[3];
346 row2[x + i] = p0[ENCODING_BLOCK / 2 + i / 2] + r[0];
347 row2[x + i + 1] = p1[ENCODING_BLOCK / 2 + i / 2] + r[1];
348 row3[x + i] = p2[ENCODING_BLOCK / 2 + i / 2] + r[2];
349 row3[x + i + 1] = p3[ENCODING_BLOCK / 2 + i / 2] + r[3];
350 }
351 meta_idx += 4;
352 }
353
354 let c = width.min(enc_w);
355 output[out_idx..out_idx + c].copy_from_slice(&row0[..c]);
356 out_idx += width;
357 output[out_idx..out_idx + c].copy_from_slice(&row1[..c]);
358 out_idx += width;
359 output[out_idx..out_idx + c].copy_from_slice(&row2[..c]);
360 out_idx += width;
361 output[out_idx..out_idx + c].copy_from_slice(&row3[..c]);
362 out_idx += width;
363 }
364 Ok(out_idx)
365}