1#![forbid(unsafe_code)]
2
3use core::ffi::c_int;
4
5use crate::allocator::Allocator;
6use crate::bzlib::{
7 index_into_f, BzStream, DSlice, DState, DecompressMode, ReturnCode, SaveArea, BZ_MAX_SELECTORS,
8 BZ_RAND_UPD_MASK, BZ_RUNA, BZ_RUNB,
9};
10use crate::{debug_log, huffman};
11
12const MTFA_SIZE: u16 = 4096;
15const MTFL_SIZE: usize = 16;
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
18#[allow(non_camel_case_types)]
19pub(crate) enum State {
20 BZ_X_IDLE = 1,
21 BZ_X_OUTPUT = 2,
22 BZ_X_MAGIC_1 = 10,
23 BZ_X_MAGIC_2 = 11,
24 BZ_X_MAGIC_3 = 12,
25 BZ_X_MAGIC_4 = 13,
26 BZ_X_BLKHDR_1 = 14,
27 BZ_X_BLKHDR_2 = 15,
28 BZ_X_BLKHDR_3 = 16,
29 BZ_X_BLKHDR_4 = 17,
30 BZ_X_BLKHDR_5 = 18,
31 BZ_X_BLKHDR_6 = 19,
32 BZ_X_BCRC_1 = 20,
33 BZ_X_BCRC_2 = 21,
34 BZ_X_BCRC_3 = 22,
35 BZ_X_BCRC_4 = 23,
36 BZ_X_RANDBIT = 24,
37 BZ_X_ORIGPTR_1 = 25,
38 BZ_X_ORIGPTR_2 = 26,
39 BZ_X_ORIGPTR_3 = 27,
40 BZ_X_MAPPING_1 = 28,
41 BZ_X_MAPPING_2 = 29,
42 BZ_X_SELECTOR_1 = 30,
43 BZ_X_SELECTOR_2 = 31,
44 BZ_X_SELECTOR_3 = 32,
45 BZ_X_CODING_1 = 33,
46 BZ_X_CODING_2 = 34,
47 BZ_X_CODING_3 = 35,
48 BZ_X_MTF_1 = 36,
49 BZ_X_MTF_2 = 37,
50 BZ_X_MTF_3 = 38,
51 BZ_X_MTF_4 = 39,
52 BZ_X_MTF_5 = 40,
53 BZ_X_MTF_6 = 41,
54 BZ_X_ENDHDR_2 = 42,
55 BZ_X_ENDHDR_3 = 43,
56 BZ_X_ENDHDR_4 = 44,
57 BZ_X_ENDHDR_5 = 45,
58 BZ_X_ENDHDR_6 = 46,
59 BZ_X_CCRC_1 = 47,
60 BZ_X_CCRC_2 = 48,
61 BZ_X_CCRC_3 = 49,
62 BZ_X_CCRC_4 = 50,
63}
64
65#[allow(non_camel_case_types)]
66#[derive(Eq, PartialEq)]
67enum Block {
68 BZ_X_MAGIC_2,
69 BZ_X_MAGIC_3,
70 BZ_X_MAGIC_4,
71 BZ_X_BLKHDR_1,
72 BZ_X_BLKHDR_2,
73 BZ_X_BLKHDR_3,
74 BZ_X_BLKHDR_4,
75 BZ_X_BLKHDR_5,
76 BZ_X_BLKHDR_6,
77 BZ_X_BCRC_1,
78 BZ_X_BCRC_2,
79 BZ_X_BCRC_3,
80 BZ_X_BCRC_4,
81 BZ_X_RANDBIT,
82 BZ_X_ORIGPTR_1,
83 BZ_X_ORIGPTR_2,
84 BZ_X_ORIGPTR_3,
85 BZ_X_MAPPING_1,
86 BZ_X_MAPPING_2,
87 BZ_X_SELECTOR_1,
88 BZ_X_SELECTOR_2,
89 BZ_X_SELECTOR_3,
90 BZ_X_CODING_1,
91 BZ_X_CODING_2,
92 BZ_X_CODING_3,
93 BZ_X_MTF_1,
94 BZ_X_MTF_2,
95 BZ_X_MTF_3,
96 BZ_X_MTF_4,
97 BZ_X_MTF_5,
98 BZ_X_MTF_6,
99 BZ_X_ENDHDR_2,
100 BZ_X_ENDHDR_3,
101 BZ_X_ENDHDR_4,
102 BZ_X_ENDHDR_5,
103 BZ_X_ENDHDR_6,
104 BZ_X_CCRC_1,
105 BZ_X_CCRC_2,
106 BZ_X_CCRC_3,
107 BZ_X_CCRC_4,
108 Block1,
109 Block11,
110 Block18,
111 Block24,
112 Block25,
113 Block26,
114 Block28,
115 Block35,
116 Block39,
117 Block40,
118 Block41,
119 Block43,
120 Block45,
121 Block46,
122 Block51,
123 Block52,
124 Block56,
125 Block58,
126}
127use Block::*;
128
129pub(crate) fn decompress(
130 strm: &mut BzStream<DState>,
131 s: &mut DState,
132 allocator: &Allocator,
133) -> ReturnCode {
134 let mut current_block: Block;
135 let mut uc: u8;
136
137 let old_avail_in = strm.avail_in;
138
139 if let State::BZ_X_MAGIC_1 = s.state {
140 s.save = SaveArea::default();
142 }
143
144 let SaveArea {
146 mut i,
147 mut j,
148 mut t,
149 mut alphaSize,
150 mut nGroups,
151 mut nSelectors,
152 mut EOB,
153 mut groupNo,
154 mut groupPos,
155 mut nextSym,
156 mut nblockMAX100k,
157 mut nblock,
158 mut es,
159 mut logN,
160 mut curr,
161 mut zn,
162 mut zvec,
163 mut zj,
164 mut gSel,
165 mut gMinlen,
166 } = s.save;
167
168 let ret_val: ReturnCode = 'save_state_and_return: {
169 macro_rules! GET_BYTE {
170 ($strm:expr, $s:expr) => {
171 (GET_BITS!($strm, $s, 8) & 0xFF) as u8
172 };
173 }
174
175 macro_rules! GET_BIT {
176 ($strm:expr, $s:expr) => {
177 GET_BITS!($strm, $s, 1) != 0
178 };
179 }
180
181 macro_rules! GET_BITS {
182 ($strm:expr, $s:expr, $nnn:expr) => {
183 loop {
184 if $s.bsLive >= $nnn {
185 let v: u64 = ($s.bsBuff >> ($s.bsLive - $nnn)) & ((1 << $nnn) - 1);
186 $s.bsLive -= $nnn;
187 break v;
188 }
189
190 if $s.state < State::BZ_X_ENDHDR_2 {
197 if let Some((bit_buffer, bits_used)) = strm.pull_u64($s.bsBuff, $s.bsLive) {
198 $s.bsBuff = bit_buffer;
199 $s.bsLive = bits_used;
200 continue;
201 }
202 }
203
204 if let Some((bit_buffer, bits_used)) = strm.pull_u8($s.bsBuff, $s.bsLive) {
205 $s.bsBuff = bit_buffer;
206 $s.bsLive = bits_used;
207 } else {
208 break 'save_state_and_return ReturnCode::BZ_OK;
209 }
210 }
211 };
212 }
213
214 macro_rules! update_group_pos {
215 ($s:expr) => {
216 if groupPos == 0 {
217 groupNo += 1;
218 gSel = match $s.selector[..usize::from(nSelectors)].get(groupNo as usize) {
219 Some(&gSel) => gSel,
220 None => error!(BZ_DATA_ERROR),
221 };
222 gMinlen = $s.minLens[usize::from(gSel)];
223 groupPos = 50;
224 }
225 groupPos -= 1;
226 };
227 }
228
229 macro_rules! error {
230 ($code:ident) => {{
231 break 'save_state_and_return ReturnCode::$code;
232 }};
233 }
234
235 match s.state {
236 State::BZ_X_MAGIC_1 => {
237 s.state = State::BZ_X_MAGIC_1;
238
239 uc = GET_BYTE!(strm, s);
240
241 if uc != b'B' {
242 error!(BZ_DATA_ERROR_MAGIC);
243 }
244
245 current_block = BZ_X_MAGIC_2;
246 }
247 State::BZ_X_MAGIC_2 => current_block = BZ_X_MAGIC_2,
248 State::BZ_X_MAGIC_3 => current_block = BZ_X_MAGIC_3,
249 State::BZ_X_MAGIC_4 => current_block = BZ_X_MAGIC_4,
250 State::BZ_X_BLKHDR_1 => current_block = BZ_X_BLKHDR_1,
251 State::BZ_X_BLKHDR_2 => current_block = BZ_X_BLKHDR_2,
252 State::BZ_X_BLKHDR_3 => current_block = BZ_X_BLKHDR_3,
253 State::BZ_X_BLKHDR_4 => current_block = BZ_X_BLKHDR_4,
254 State::BZ_X_BLKHDR_5 => current_block = BZ_X_BLKHDR_5,
255 State::BZ_X_BLKHDR_6 => current_block = BZ_X_BLKHDR_6,
256 State::BZ_X_BCRC_1 => current_block = BZ_X_BCRC_1,
257 State::BZ_X_BCRC_2 => current_block = BZ_X_BCRC_2,
258 State::BZ_X_BCRC_3 => current_block = BZ_X_BCRC_3,
259 State::BZ_X_BCRC_4 => current_block = BZ_X_BCRC_4,
260 State::BZ_X_RANDBIT => current_block = BZ_X_RANDBIT,
261 State::BZ_X_ORIGPTR_1 => current_block = BZ_X_ORIGPTR_1,
262 State::BZ_X_ORIGPTR_2 => current_block = BZ_X_ORIGPTR_2,
263 State::BZ_X_ORIGPTR_3 => current_block = BZ_X_ORIGPTR_3,
264 State::BZ_X_MAPPING_1 => current_block = BZ_X_MAPPING_1,
265 State::BZ_X_MAPPING_2 => current_block = BZ_X_MAPPING_2,
266 State::BZ_X_SELECTOR_1 => current_block = BZ_X_SELECTOR_1,
267 State::BZ_X_SELECTOR_2 => current_block = BZ_X_SELECTOR_2,
268 State::BZ_X_SELECTOR_3 => current_block = BZ_X_SELECTOR_3,
269 State::BZ_X_CODING_1 => current_block = BZ_X_CODING_1,
270 State::BZ_X_CODING_2 => current_block = BZ_X_CODING_2,
271 State::BZ_X_CODING_3 => current_block = BZ_X_CODING_3,
272 State::BZ_X_MTF_1 => current_block = BZ_X_MTF_1,
273 State::BZ_X_MTF_2 => current_block = BZ_X_MTF_2,
274 State::BZ_X_MTF_3 => current_block = BZ_X_MTF_3,
275 State::BZ_X_MTF_4 => current_block = BZ_X_MTF_4,
276 State::BZ_X_MTF_5 => current_block = BZ_X_MTF_5,
277 State::BZ_X_MTF_6 => current_block = BZ_X_MTF_6,
278 State::BZ_X_ENDHDR_2 => current_block = BZ_X_ENDHDR_2,
279 State::BZ_X_ENDHDR_3 => current_block = BZ_X_ENDHDR_3,
280 State::BZ_X_ENDHDR_4 => current_block = BZ_X_ENDHDR_4,
281 State::BZ_X_ENDHDR_5 => current_block = BZ_X_ENDHDR_5,
282 State::BZ_X_ENDHDR_6 => current_block = BZ_X_ENDHDR_6,
283 State::BZ_X_CCRC_1 => current_block = BZ_X_CCRC_1,
284 State::BZ_X_CCRC_2 => current_block = BZ_X_CCRC_2,
285 State::BZ_X_CCRC_3 => current_block = BZ_X_CCRC_3,
286 State::BZ_X_CCRC_4 => current_block = BZ_X_CCRC_4,
287 State::BZ_X_IDLE | State::BZ_X_OUTPUT => unreachable!(),
288 }
289 if current_block == BZ_X_MAGIC_2 {
290 s.state = State::BZ_X_MAGIC_2;
291
292 uc = GET_BYTE!(strm, s);
293
294 if uc != b'Z' {
295 error!(BZ_DATA_ERROR_MAGIC);
296 }
297
298 current_block = BZ_X_MAGIC_3;
299 }
300 if current_block == BZ_X_MAGIC_3 {
301 s.state = State::BZ_X_MAGIC_3;
302
303 uc = GET_BYTE!(strm, s);
304
305 if uc != b'h' {
306 error!(BZ_DATA_ERROR_MAGIC);
307 }
308
309 current_block = BZ_X_MAGIC_4;
310 }
311 if current_block == BZ_X_MAGIC_4 {
312 s.state = State::BZ_X_MAGIC_4;
313
314 s.blockSize100k = GET_BYTE!(strm, s);
315
316 if !(b'1'..=b'9').contains(&s.blockSize100k) {
317 error!(BZ_DATA_ERROR_MAGIC);
318 }
319
320 s.blockSize100k -= b'0';
321
322 match s.smallDecompress {
323 DecompressMode::Small => {
324 let ll16_len = usize::from(s.blockSize100k) * 100000;
326 let Some(ll16) = DSlice::alloc(allocator, ll16_len) else {
327 error!(BZ_MEM_ERROR);
328 };
329
330 let ll4_len = (1 + usize::from(s.blockSize100k) * 100000) >> 1;
332 let Some(ll4) = DSlice::alloc(allocator, ll4_len) else {
333 error!(BZ_MEM_ERROR);
334 };
335
336 s.ll16 = ll16;
337 s.ll4 = ll4;
338 }
339 DecompressMode::Fast => {
340 let tt_len = usize::from(s.blockSize100k) * 100000;
342 let Some(tt) = DSlice::alloc(allocator, tt_len) else {
343 error!(BZ_MEM_ERROR);
344 };
345
346 s.tt = tt;
347 }
348 }
349
350 current_block = BZ_X_BLKHDR_1;
351 }
352 if current_block == BZ_X_BLKHDR_1 {
353 s.state = State::BZ_X_BLKHDR_1;
354
355 uc = GET_BYTE!(strm, s);
356
357 match uc {
358 0x17 => current_block = BZ_X_ENDHDR_2,
359 0x31 => current_block = BZ_X_BLKHDR_2,
360 _ => error!(BZ_DATA_ERROR),
361 };
362 }
363 match current_block {
364 BZ_X_ENDHDR_2 => {
365 s.state = State::BZ_X_ENDHDR_2;
366
367 uc = GET_BYTE!(strm, s);
368
369 if uc != 0x72 {
370 error!(BZ_DATA_ERROR);
371 }
372
373 current_block = BZ_X_ENDHDR_3;
374 }
375 BZ_X_BLKHDR_2 => {
376 s.state = State::BZ_X_BLKHDR_2;
377
378 uc = GET_BYTE!(strm, s);
379
380 if uc != 0x41 {
381 error!(BZ_DATA_ERROR);
382 }
383 current_block = BZ_X_BLKHDR_3;
384 }
385 _ => {}
386 }
387 match current_block {
388 BZ_X_ENDHDR_3 => {
389 s.state = State::BZ_X_ENDHDR_3;
390
391 uc = GET_BYTE!(strm, s);
392
393 if uc != 0x45 {
394 error!(BZ_DATA_ERROR);
395 }
396
397 current_block = BZ_X_ENDHDR_4;
398 }
399 BZ_X_BLKHDR_3 => {
400 s.state = State::BZ_X_BLKHDR_3;
401
402 uc = GET_BYTE!(strm, s);
403
404 if uc != 0x59 {
405 error!(BZ_DATA_ERROR);
406 }
407
408 current_block = BZ_X_BLKHDR_4;
409 }
410 _ => {}
411 }
412 match current_block {
413 BZ_X_ENDHDR_4 => {
414 s.state = State::BZ_X_ENDHDR_4;
415
416 uc = GET_BYTE!(strm, s);
417
418 if uc != 0x38 {
419 error!(BZ_DATA_ERROR);
420 }
421
422 current_block = BZ_X_ENDHDR_5;
423 }
424 BZ_X_BLKHDR_4 => {
425 s.state = State::BZ_X_BLKHDR_4;
426
427 uc = GET_BYTE!(strm, s);
428
429 if uc != 0x26 {
430 error!(BZ_DATA_ERROR);
431 }
432
433 current_block = BZ_X_BLKHDR_5;
434 }
435 _ => {}
436 }
437 match current_block {
438 BZ_X_ENDHDR_5 => {
439 s.state = State::BZ_X_ENDHDR_5;
440
441 uc = GET_BYTE!(strm, s);
442
443 if uc != 0x50 {
444 error!(BZ_DATA_ERROR);
445 }
446
447 current_block = BZ_X_ENDHDR_6;
448 }
449 BZ_X_BLKHDR_5 => {
450 s.state = State::BZ_X_BLKHDR_5;
451
452 uc = GET_BYTE!(strm, s);
453
454 if uc != 0x53 {
455 error!(BZ_DATA_ERROR);
456 }
457
458 current_block = BZ_X_BLKHDR_6;
459 }
460 _ => {}
461 }
462 match current_block {
463 BZ_X_ENDHDR_6 => {
464 s.state = State::BZ_X_ENDHDR_6;
465
466 uc = GET_BYTE!(strm, s);
467
468 if uc != 0x90 {
469 error!(BZ_DATA_ERROR);
470 }
471
472 s.storedCombinedCRC = 0_u32;
473 current_block = BZ_X_CCRC_1;
474 }
475 BZ_X_BLKHDR_6 => {
476 s.state = State::BZ_X_BLKHDR_6;
477
478 uc = GET_BYTE!(strm, s);
479
480 if uc != 0x59 {
481 error!(BZ_DATA_ERROR);
482 }
483
484 s.currBlockNo += 1;
485 if s.verbosity >= 2 {
486 debug_log!("\n [{}: huff+mtf ", s.currBlockNo);
487 }
488 s.storedBlockCRC = 0_u32;
489 current_block = BZ_X_BCRC_1;
490 }
491 _ => {}
492 }
493 match current_block {
494 BZ_X_CCRC_1 => {
495 s.state = State::BZ_X_CCRC_1;
496
497 uc = GET_BYTE!(strm, s);
498
499 s.storedCombinedCRC = (s.storedCombinedCRC << 8) | uc as u32;
500 current_block = BZ_X_CCRC_2;
501 }
502 BZ_X_BCRC_1 => {
503 s.state = State::BZ_X_BCRC_1;
504
505 uc = GET_BYTE!(strm, s);
506
507 s.storedBlockCRC = (s.storedBlockCRC << 8) | uc as u32;
508 current_block = BZ_X_BCRC_2;
509 }
510 _ => {}
511 }
512 match current_block {
513 BZ_X_CCRC_2 => {
514 s.state = State::BZ_X_CCRC_2;
515
516 uc = GET_BYTE!(strm, s);
517
518 s.storedCombinedCRC = (s.storedCombinedCRC << 8) | uc as u32;
519 current_block = BZ_X_CCRC_3;
520 }
521 BZ_X_BCRC_2 => {
522 s.state = State::BZ_X_BCRC_2;
523
524 uc = GET_BYTE!(strm, s);
525
526 s.storedBlockCRC = (s.storedBlockCRC << 8) | uc as u32;
527 current_block = BZ_X_BCRC_3;
528 }
529 _ => {}
530 }
531 match current_block {
532 BZ_X_CCRC_3 => {
533 s.state = State::BZ_X_CCRC_3;
534
535 uc = GET_BYTE!(strm, s);
536
537 s.storedCombinedCRC = (s.storedCombinedCRC << 8) | uc as u32;
538 current_block = BZ_X_CCRC_4;
539 }
540 BZ_X_BCRC_3 => {
541 s.state = State::BZ_X_BCRC_3;
542
543 uc = GET_BYTE!(strm, s);
544
545 s.storedBlockCRC = (s.storedBlockCRC << 8) | uc as u32;
546 current_block = BZ_X_BCRC_4;
547 }
548 _ => {}
549 }
550 match current_block {
551 BZ_X_BCRC_4 => {
552 s.state = State::BZ_X_BCRC_4;
553
554 uc = GET_BYTE!(strm, s);
555
556 s.storedBlockCRC = (s.storedBlockCRC << 8) | uc as u32;
557 current_block = BZ_X_RANDBIT;
558 }
559 BZ_X_CCRC_4 => {
560 s.state = State::BZ_X_CCRC_4;
561
562 uc = GET_BYTE!(strm, s);
563
564 s.storedCombinedCRC = (s.storedCombinedCRC << 8) | uc as u32;
565 s.state = State::BZ_X_IDLE;
566 error!(BZ_STREAM_END);
567 }
568 _ => {}
569 }
570 if current_block == BZ_X_RANDBIT {
571 s.state = State::BZ_X_RANDBIT;
572
573 s.blockRandomised = GET_BITS!(strm, s, 1) != 0;
574
575 s.origPtr = 0;
576 current_block = BZ_X_ORIGPTR_1;
577 }
578 if current_block == BZ_X_ORIGPTR_1 {
579 s.state = State::BZ_X_ORIGPTR_1;
580
581 uc = GET_BYTE!(strm, s);
582
583 s.origPtr = (s.origPtr << 8) | i32::from(uc);
584 current_block = BZ_X_ORIGPTR_2;
585 }
586 if current_block == BZ_X_ORIGPTR_2 {
587 s.state = State::BZ_X_ORIGPTR_2;
588
589 uc = GET_BYTE!(strm, s);
590
591 s.origPtr = (s.origPtr << 8) | i32::from(uc);
592 current_block = BZ_X_ORIGPTR_3;
593 }
594 if current_block == BZ_X_ORIGPTR_3 {
595 s.state = State::BZ_X_ORIGPTR_3;
596
597 uc = GET_BYTE!(strm, s);
598
599 s.origPtr = (s.origPtr << 8) | i32::from(uc);
600 if !(0..=10 + 100000 * i32::from(s.blockSize100k)).contains(&s.origPtr) {
601 error!(BZ_DATA_ERROR);
602 }
603
604 i = 0;
605 current_block = Block43;
606 }
607
608 let tt = s.tt.as_mut_slice();
610 let ll16 = s.ll16.as_mut_slice();
611 let ll4 = s.ll4.as_mut_slice();
612
613 'state_machine: loop {
614 match current_block {
615 BZ_X_MAPPING_1 => {
616 s.state = State::BZ_X_MAPPING_1;
617
618 uc = GET_BIT!(strm, s) as u8;
619
620 s.inUse16[i as usize] = uc == 1;
621 i += 1;
622 current_block = Block43;
623 continue;
624 }
625 Block43 => {
626 if i < 16 {
627 current_block = BZ_X_MAPPING_1;
628 continue;
629 }
630 s.inUse.fill(false);
631 i = 0;
632 current_block = Block18;
633 }
634 BZ_X_MAPPING_2 => {
635 s.state = State::BZ_X_MAPPING_2;
636
637 uc = GET_BIT!(strm, s) as u8;
638
639 if uc == 1 {
640 s.inUse[(i * 16 + j) as usize] = true;
641 }
642 j += 1;
643 current_block = Block28;
644 }
645 BZ_X_SELECTOR_1 => {
646 s.state = State::BZ_X_SELECTOR_1;
647
648 nGroups = GET_BITS!(strm, s, 3) as u8;
649
650 if (2..=6).contains(&nGroups) {
651 current_block = BZ_X_SELECTOR_2;
652 continue;
653 }
654 error!(BZ_DATA_ERROR);
655 }
656 BZ_X_SELECTOR_2 => {
657 s.state = State::BZ_X_SELECTOR_2;
658
659 nSelectors = GET_BITS!(strm, s, 15) as u16;
660
661 if nSelectors < 1 {
662 error!(BZ_DATA_ERROR);
663 } else {
664 i = 0;
665 }
666 current_block = Block39;
667 }
668 BZ_X_SELECTOR_3 => {
669 s.state = State::BZ_X_SELECTOR_3;
670
671 uc = GET_BIT!(strm, s) as u8;
672
673 if uc == 0 {
674 current_block = Block1;
675 } else {
676 j += 1;
677 if j >= i32::from(nGroups) {
678 error!(BZ_DATA_ERROR);
679 } else {
680 current_block = Block25;
681 }
682 }
683 }
684 BZ_X_CODING_1 => {
685 s.state = State::BZ_X_CODING_1;
686
687 curr = GET_BITS!(strm, s, 5) as u8;
688
689 i = 0;
690 current_block = Block26;
691 }
692 BZ_X_CODING_2 => {
693 s.state = State::BZ_X_CODING_2;
694
695 uc = GET_BIT!(strm, s) as u8;
696
697 if uc != 0 {
698 current_block = BZ_X_CODING_3;
699 continue;
700 }
701 current_block = Block51;
702 }
703 BZ_X_CODING_3 => {
704 s.state = State::BZ_X_CODING_3;
705
706 uc = GET_BIT!(strm, s) as u8;
707
708 match uc {
709 0 => curr += 1,
710 _ => curr -= 1,
711 }
712
713 current_block = Block45;
714 }
715 BZ_X_MTF_1 => {
716 s.state = State::BZ_X_MTF_1;
717
718 zvec = GET_BITS!(strm, s, zn as i32) as i32;
719
720 current_block = Block56;
721 }
722 BZ_X_MTF_2 => {
723 s.state = State::BZ_X_MTF_2;
724
725 zj = GET_BIT!(strm, s);
726
727 zvec = (zvec << 1) | zj as i32;
728 current_block = Block56;
729 }
730 BZ_X_MTF_3 => {
731 s.state = State::BZ_X_MTF_3;
732
733 zvec = GET_BITS!(strm, s, zn as i32) as i32;
734
735 current_block = Block52;
736 }
737 BZ_X_MTF_4 => {
738 s.state = State::BZ_X_MTF_4;
739
740 zj = GET_BIT!(strm, s);
741
742 zvec = (zvec << 1) | zj as i32;
743 current_block = Block52;
744 }
745 BZ_X_MTF_5 => {
746 s.state = State::BZ_X_MTF_5;
747
748 zvec = GET_BITS!(strm, s, zn as i32) as i32;
749
750 current_block = Block24;
751 }
752 _ => {
753 s.state = State::BZ_X_MTF_6;
754
755 zj = GET_BIT!(strm, s);
756
757 zvec = (zvec << 1) | zj as i32;
758 current_block = Block24;
759 }
760 }
761
762 macro_rules! get_next_sym {
763 ($next_block:ident) => {
764 if zn > 20 {
765 error!(BZ_DATA_ERROR);
767 } else if zvec <= s.limit[usize::from(gSel)][zn as usize] {
768 let index = zvec - s.base[usize::from(gSel)][zn as usize];
769 match s.perm[usize::from(gSel)].get(index as usize) {
770 Some(&nextSym) => nextSym,
771 None => error!(BZ_DATA_ERROR),
772 }
773 } else {
774 zn += 1;
775 current_block = $next_block;
776 continue 'state_machine;
777 }
778 };
779 }
780
781 match current_block {
782 Block24 => {
783 nextSym = get_next_sym!(BZ_X_MTF_6);
784 current_block = Block40;
785 }
786 Block52 => {
787 nextSym = get_next_sym!(BZ_X_MTF_4);
788
789 if nextSym == BZ_RUNA || nextSym == BZ_RUNB {
790 current_block = Block46;
791 } else {
792 let uc = s.seqToUnseq[usize::from(s.mtfa[usize::from(s.mtfbase[0])])];
793 s.unzftab[usize::from(uc)] += es;
794 match s.smallDecompress {
795 DecompressMode::Small => {
796 match ll16.get_mut(nblock as usize..(nblock + es) as usize) {
797 Some(slice) => slice.fill(u16::from(uc)),
798 None => error!(BZ_DATA_ERROR),
799 };
800 nblock += es;
801 }
802 DecompressMode::Fast => {
803 match tt.get_mut(nblock as usize..(nblock + es) as usize) {
804 Some(slice) => slice.fill(u32::from(uc)),
805 None => error!(BZ_DATA_ERROR),
806 };
807 nblock += es;
808 }
809 }
810 current_block = Block40;
811 }
812 }
813 Block56 => {
814 nextSym = get_next_sym!(BZ_X_MTF_2);
815 current_block = Block40;
816 }
817 _ => {}
818 }
819 if current_block == Block40 {
820 if nextSym == EOB {
821 current_block = Block41;
822 } else if nextSym == BZ_RUNA || nextSym == BZ_RUNB {
823 es = 0;
824 logN = 0;
825 current_block = Block46;
826 } else if nblock >= 100000 * u32::from(nblockMAX100k) {
827 error!(BZ_DATA_ERROR);
828 } else {
829 let uc = usize::from(initialize_mtfa(&mut s.mtfa, &mut s.mtfbase, nextSym));
830 let index = s.seqToUnseq[uc];
831 s.unzftab[usize::from(index)] += 1;
832 match s.smallDecompress {
833 DecompressMode::Small => ll16[nblock as usize] = u16::from(index),
834 DecompressMode::Fast => tt[nblock as usize] = u32::from(index),
835 }
836 nblock += 1;
837 update_group_pos!(s);
838 zn = gMinlen;
839 current_block = BZ_X_MTF_5;
840 continue;
841 }
842 match current_block {
843 Block46 => {}
844 _ => {
845 if s.origPtr < 0 || s.origPtr >= nblock as i32 {
846 error!(BZ_DATA_ERROR);
847 } else {
848 if s.unzftab.iter().any(|e| !(0..=nblock).contains(e)) {
849 error!(BZ_DATA_ERROR);
850 }
851 s.cftab[0] = 0;
852 s.cftab[1..].copy_from_slice(&s.unzftab);
853 for i in 1..s.cftab.len() {
854 s.cftab[i] += s.cftab[i - 1];
855 }
856 if s.cftab.iter().any(|e| !(0..=nblock).contains(e)) {
857 error!(BZ_DATA_ERROR);
858 }
859 if s.cftab.windows(2).any(|w| w[0] > w[1]) {
862 error!(BZ_DATA_ERROR);
863 }
864 s.state_out_len = 0;
865 s.state_out_ch = 0;
866 s.calculatedBlockCRC = u32::MAX;
867 s.state = State::BZ_X_OUTPUT;
868 if s.verbosity >= 2 {
869 debug_log!("rt+rld");
870 }
871 match s.smallDecompress {
872 DecompressMode::Small => {
873 s.cftabCopy = s.cftab;
875
876 for i in 0..nblock as usize {
878 let uc = usize::from(ll16[i]);
879 ll16[i] = (s.cftabCopy[uc] & 0xffff) as u16;
880
881 let (mask, shift) = match i & 0x1 {
883 0 => (0xF0, 0),
884 _ => (0x0F, 4),
885 };
886 ll4[i / 2] &= mask;
887 ll4[i / 2] |= ((s.cftabCopy[uc] >> 16) << shift) as u8;
888
889 s.cftabCopy[uc] += 1;
890 }
891
892 i = s.origPtr;
894 j = (ll16[i as usize] as u32
895 | (((ll4[(i >> 1) as usize] as u32 >> ((i << 2) & 0b100))
896 & 0xf)
897 << 16)) as i32;
898 loop {
899 let tmp_0: i32 = (ll16[j as usize] as u32
900 | (((ll4[(j >> 1) as usize] as u32
901 >> ((j << 2) & 0b100))
902 & 0xf)
903 << 16))
904 as i32;
905 ll16[j as usize] = (i & 0xffff) as u16;
906 if j & 0x1 == 0 {
907 ll4[(j >> 1) as usize] = (ll4[(j >> 1) as usize]
908 as c_int
909 & 0xf0
910 | (i >> 16))
911 as u8;
912 } else {
913 ll4[(j >> 1) as usize] =
914 (ll4[(j >> 1) as usize] as c_int & 0xf
915 | ((i >> 16) << 4))
916 as u8
917 }
918 i = j;
919 j = tmp_0;
920 if i == s.origPtr {
921 break;
922 }
923 }
924
925 s.tPos = s.origPtr as u32;
926 s.nblock_used = 0;
927
928 s.k0 = index_into_f(s.tPos, &s.cftab);
929 s.tPos = match ll16.get(s.tPos as usize) {
930 None => error!(BZ_DATA_ERROR),
931 Some(&low_bits) => {
932 let high_bits = (ll4[(s.tPos >> 1) as usize]
933 >> ((s.tPos << 2) & 0b100))
934 & 0xf;
935 u32::from(low_bits) | (u32::from(high_bits) << 16)
936 }
937 };
938 s.nblock_used += 1;
939
940 if s.blockRandomised {
941 s.rNToGo = 0;
942 s.rTPos = 0;
943 BZ_RAND_UPD_MASK!(s);
944 s.k0 ^= u8::from(s.rNToGo == 1)
945 }
946 }
947 DecompressMode::Fast => {
948 for i in 0..nblock as usize {
949 let uc = (tt[i] & 0xff) as usize;
950 tt[s.cftab[uc] as usize] |= (i << 8) as u32;
951 s.cftab[uc] += 1;
952 }
953 s.tPos = tt[s.origPtr as usize] >> 8;
954 s.nblock_used = 0;
955
956 s.tPos = match tt.get(s.tPos as usize) {
957 Some(&tPos) => tPos,
958 None => error!(BZ_DATA_ERROR),
959 };
960 s.k0 = (s.tPos & 0xff) as u8;
961 s.tPos >>= 8;
962 s.nblock_used += 1;
963
964 if s.blockRandomised {
965 s.rNToGo = 0;
966 s.rTPos = 0;
967 BZ_RAND_UPD_MASK!(s);
968 s.k0 ^= u8::from(s.rNToGo == 1)
969 }
970 }
971 }
972
973 break 'save_state_and_return ReturnCode::BZ_OK;
974 }
975 }
976 }
977 }
978 if current_block == Block46 {
979 const LOG_2MB: u8 = 21; if logN >= LOG_2MB {
988 error!(BZ_DATA_ERROR);
989 } else {
990 let mul = match nextSym {
991 BZ_RUNA => 1,
992 BZ_RUNB => 2,
993 _ => 0,
994 };
995 es += mul * (1 << logN);
996 logN += 1;
997 update_group_pos!(s);
998 zn = gMinlen;
999 current_block = BZ_X_MTF_3;
1000 continue;
1001 }
1002 }
1003 loop {
1004 match current_block {
1005 Block28 => {
1006 if j < 16 {
1007 current_block = BZ_X_MAPPING_2;
1008 continue 'state_machine;
1009 }
1010 }
1011 Block39 => {
1012 if i < i32::from(nSelectors) {
1013 j = 0;
1014 current_block = Block25;
1015 continue;
1016 } else {
1017 nSelectors = Ord::min(nSelectors, BZ_MAX_SELECTORS);
1019
1020 let mut pos: [u8; 6] = [0, 1, 2, 3, 4, 5];
1021 for i in 0..usize::from(nSelectors) {
1022 rotate_right_1(&mut pos[..=usize::from(s.selectorMtf[i])]);
1023 s.selector[i] = pos[0];
1024 }
1025
1026 let bits_needed =
1028 usize::from(nGroups) * (5 + (usize::from(alphaSize) * 2 * 20));
1029 let bytes_needed = bits_needed.div_ceil(8);
1030
1031 if strm.avail_in as usize >= bytes_needed {
1032 for t in 0..usize::from(nGroups) {
1033 let mut curr = GET_BITS!(strm, s, 5);
1034 for i in 0..usize::from(alphaSize) {
1035 loop {
1036 if !(1..=20).contains(&curr) {
1037 error!(BZ_DATA_ERROR);
1038 }
1039 if !GET_BIT!(strm, s) {
1040 break;
1041 };
1042 match GET_BIT!(strm, s) {
1043 false => curr += 1,
1044 true => curr -= 1,
1045 }
1046 }
1047
1048 s.len[t][i] = curr as u8;
1049 }
1050 }
1051
1052 t = nGroups;
1053 current_block = Block35;
1054 break;
1055 } else {
1056 t = 0;
1057 current_block = Block35;
1058 break;
1059 }
1060 }
1061 }
1062 Block18 => {
1063 if let Some(&in_use) = s.inUse16.get(i as usize) {
1064 if in_use {
1065 j = 0;
1066 current_block = Block28;
1067 continue;
1068 }
1069 } else {
1070 s.nInUse = 0;
1072 for (i, in_use) in s.inUse.iter().enumerate() {
1073 if *in_use {
1074 s.seqToUnseq[usize::from(s.nInUse)] = i as u8;
1075 s.nInUse += 1;
1076 }
1077 }
1078
1079 if s.nInUse == 0 {
1080 current_block = Block11;
1081 break;
1082 } else {
1083 current_block = Block58;
1084 break;
1085 }
1086 }
1087 }
1088 Block51 => {
1089 s.len[t as usize][i as usize] = curr;
1090 i += 1;
1091 current_block = Block26;
1092 continue;
1093 }
1094 Block26 => {
1095 if i < i32::from(alphaSize) {
1096 current_block = Block45;
1097 continue;
1098 }
1099 t += 1;
1100 current_block = Block35;
1101 break;
1102 }
1103 Block1 => {
1104 if i < i32::from(BZ_MAX_SELECTORS) {
1105 s.selectorMtf[i as usize] = j as u8;
1106 }
1107 i += 1;
1108 current_block = Block39;
1109 continue;
1110 }
1111 Block25 => {
1112 current_block = BZ_X_SELECTOR_3;
1113 continue 'state_machine;
1114 }
1115 _ => {
1116 if false {
1117 current_block = Block51;
1118 continue;
1119 }
1120 if (1..=20).contains(&curr) {
1121 current_block = BZ_X_CODING_2;
1122 continue 'state_machine;
1123 }
1124 error!(BZ_DATA_ERROR);
1125 }
1126 }
1127 i += 1;
1128 current_block = Block18;
1129 }
1130 match current_block {
1131 Block58 => {
1132 alphaSize = s.nInUse + 2;
1133 current_block = BZ_X_SELECTOR_1;
1134 }
1135 Block11 => {
1136 error!(BZ_DATA_ERROR);
1137 }
1138 _ => {
1139 if t < nGroups {
1140 current_block = BZ_X_CODING_1;
1141 continue;
1142 }
1143
1144 for t in 0..usize::from(nGroups) {
1146 let len = &s.len[t][..usize::from(alphaSize)];
1148
1149 let mut minLen = 32u8;
1150 let mut maxLen = 0u8;
1151 for ¤t in len {
1152 maxLen = Ord::max(maxLen, current);
1153 minLen = Ord::min(minLen, current);
1154 }
1155 s.minLens[t] = minLen;
1156
1157 huffman::create_decode_tables(
1158 &mut s.limit[t],
1159 &mut s.base[t],
1160 &mut s.perm[t],
1161 len,
1162 minLen,
1163 maxLen,
1164 );
1165 }
1166
1167 EOB = s.nInUse + 1;
1170 nblockMAX100k = s.blockSize100k;
1171 s.unzftab.fill(0);
1172
1173 let mut kk: u16 = MTFA_SIZE - 1;
1175 for ii in (0..256 / MTFL_SIZE).rev() {
1176 for jj in (0..MTFL_SIZE).rev() {
1177 s.mtfa[usize::from(kk)] = (ii * MTFL_SIZE + jj) as u8;
1178 kk -= 1;
1179 }
1180 s.mtfbase[ii] = kk + 1;
1181 }
1182 nblock = 0;
1185 groupNo = -1;
1186 groupPos = 0;
1187 update_group_pos!(s);
1188
1189 zn = gMinlen;
1190 current_block = BZ_X_MTF_1;
1191 }
1192 }
1193 }
1194 };
1195
1196 s.save = SaveArea {
1197 i,
1198 j,
1199 t,
1200 alphaSize,
1201 nGroups,
1202 nSelectors,
1203 EOB,
1204 groupNo,
1205 groupPos,
1206 nextSym,
1207 nblockMAX100k,
1208 nblock,
1209 es,
1210 logN,
1211 curr,
1212 zn,
1213 zvec,
1214 zj,
1215 gSel,
1216 gMinlen,
1217 };
1218
1219 let bytes_read = old_avail_in - strm.avail_in;
1221 let old_total_in_lo32 = strm.total_in_lo32;
1222 strm.total_in_lo32 = strm.total_in_lo32.wrapping_add(bytes_read);
1223 strm.total_in_hi32 += (strm.total_in_lo32 < old_total_in_lo32) as u32;
1224
1225 ret_val
1226}
1227
1228fn initialize_mtfa(mtfa: &mut [u8; 4096], mtfbase: &mut [u16; 16], nextSym: u16) -> u8 {
1229 let nn = usize::from(nextSym - 1);
1230
1231 if nn < MTFL_SIZE {
1232 let pp = usize::from(mtfbase[0]);
1234 let uc = mtfa[pp + nn];
1235 rotate_right_1(&mut mtfa[pp..][..=nn]);
1236
1237 uc
1238 } else {
1239 let mut lno = nn.wrapping_div(MTFL_SIZE);
1241 let off = nn.wrapping_rem(MTFL_SIZE);
1242 let base = usize::from(mtfbase[lno]);
1243 let uc = mtfa[base + off];
1244
1245 mtfa.copy_within(base..base + off, base + 1);
1247
1248 mtfbase[lno] += 1;
1249 while lno > 0 {
1250 mtfbase[lno] -= 1;
1251 mtfa[usize::from(mtfbase[lno])] = mtfa[usize::from(mtfbase[lno - 1] + 16 - 1)];
1252 lno -= 1;
1253 }
1254 mtfbase[0] -= 1;
1255 mtfa[usize::from(mtfbase[0])] = uc;
1256
1257 if mtfbase[0] == 0 {
1258 let mut kk = MTFA_SIZE - 1;
1259 for ii in (0..256 / MTFL_SIZE).rev() {
1260 for jj in (0..MTFL_SIZE).rev() {
1261 mtfa[usize::from(kk)] = mtfa[usize::from(mtfbase[ii]) + jj];
1262 kk -= 1;
1263 }
1264 mtfbase[ii] = kk + 1;
1265 }
1266 }
1267
1268 uc
1269 }
1270}
1271
1272fn rotate_right_1(slice: &mut [u8]) {
1273 match slice {
1274 [] | [_] => { }
1275 [a, b] => {
1276 core::mem::swap(a, b)
1282 }
1283 [.., last] => {
1284 let last = *last;
1285 slice.copy_within(0..slice.len() - 1, 1);
1286 slice[0] = last;
1287 }
1288 }
1289}