0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "decompress_common.h"
0012 #include "lib.h"
0013
0014
0015 #define LZX_NUM_CHARS 256
0016
0017
0018 #define LZX_MIN_MATCH_LEN 2
0019 #define LZX_MAX_MATCH_LEN 257
0020
0021
0022 #define LZX_NUM_LENS (LZX_MAX_MATCH_LEN - LZX_MIN_MATCH_LEN + 1)
0023
0024
0025 #define LZX_NUM_PRIMARY_LENS 7
0026 #define LZX_NUM_LEN_HEADERS (LZX_NUM_PRIMARY_LENS + 1)
0027
0028
0029 #define LZX_BLOCKTYPE_VERBATIM 1
0030 #define LZX_BLOCKTYPE_ALIGNED 2
0031 #define LZX_BLOCKTYPE_UNCOMPRESSED 3
0032
0033
0034 #define LZX_NUM_OFFSET_SLOTS 30
0035
0036
0037 #define LZX_MAINCODE_NUM_SYMBOLS \
0038 (LZX_NUM_CHARS + (LZX_NUM_OFFSET_SLOTS * LZX_NUM_LEN_HEADERS))
0039
0040
0041 #define LZX_LENCODE_NUM_SYMBOLS (LZX_NUM_LENS - LZX_NUM_PRIMARY_LENS)
0042
0043
0044 #define LZX_PRECODE_NUM_SYMBOLS 20
0045
0046
0047 #define LZX_PRECODE_ELEMENT_SIZE 4
0048
0049
0050
0051
0052 #define LZX_NUM_ALIGNED_OFFSET_BITS 3
0053
0054
0055 #define LZX_ALIGNEDCODE_NUM_SYMBOLS (1 << LZX_NUM_ALIGNED_OFFSET_BITS)
0056
0057
0058
0059
0060 #define LZX_ALIGNED_OFFSET_BITMASK ((1 << LZX_NUM_ALIGNED_OFFSET_BITS) - 1)
0061
0062
0063 #define LZX_ALIGNEDCODE_ELEMENT_SIZE 3
0064
0065
0066 #define LZX_MAX_MAIN_CODEWORD_LEN 16
0067 #define LZX_MAX_LEN_CODEWORD_LEN 16
0068 #define LZX_MAX_PRE_CODEWORD_LEN ((1 << LZX_PRECODE_ELEMENT_SIZE) - 1)
0069 #define LZX_MAX_ALIGNED_CODEWORD_LEN ((1 << LZX_ALIGNEDCODE_ELEMENT_SIZE) - 1)
0070
0071
0072
0073
0074
0075
0076 #define LZX_DEFAULT_FILESIZE 12000000
0077
0078
0079 #define LZX_DEFAULT_BLOCK_SIZE 32768
0080
0081
0082 #define LZX_NUM_RECENT_OFFSETS 3
0083
0084
0085 #define LZX_MAINCODE_TABLEBITS 11
0086 #define LZX_LENCODE_TABLEBITS 10
0087 #define LZX_PRECODE_TABLEBITS 6
0088 #define LZX_ALIGNEDCODE_TABLEBITS 7
0089
0090 #define LZX_READ_LENS_MAX_OVERRUN 50
0091
0092
0093
0094 static const u32 lzx_offset_slot_base[LZX_NUM_OFFSET_SLOTS + 1] = {
0095 0, 1, 2, 3, 4,
0096 6, 8, 12, 16, 24,
0097 32, 48, 64, 96, 128,
0098 192, 256, 384, 512, 768,
0099 1024, 1536, 2048, 3072, 4096,
0100 6144, 8192, 12288, 16384, 24576,
0101 32768,
0102 };
0103
0104
0105
0106
0107 static const u8 lzx_extra_offset_bits[LZX_NUM_OFFSET_SLOTS] = {
0108 0, 0, 0, 0, 1,
0109 1, 2, 2, 3, 3,
0110 4, 4, 5, 5, 6,
0111 6, 7, 7, 8, 8,
0112 9, 9, 10, 10, 11,
0113 11, 12, 12, 13, 13,
0114 };
0115
0116
0117 struct lzx_decompressor {
0118
0119
0120
0121
0122
0123 u16 maincode_decode_table[(1 << LZX_MAINCODE_TABLEBITS) +
0124 (LZX_MAINCODE_NUM_SYMBOLS * 2)];
0125 u8 maincode_lens[LZX_MAINCODE_NUM_SYMBOLS + LZX_READ_LENS_MAX_OVERRUN];
0126
0127
0128 u16 lencode_decode_table[(1 << LZX_LENCODE_TABLEBITS) +
0129 (LZX_LENCODE_NUM_SYMBOLS * 2)];
0130 u8 lencode_lens[LZX_LENCODE_NUM_SYMBOLS + LZX_READ_LENS_MAX_OVERRUN];
0131
0132
0133 u16 alignedcode_decode_table[(1 << LZX_ALIGNEDCODE_TABLEBITS) +
0134 (LZX_ALIGNEDCODE_NUM_SYMBOLS * 2)];
0135 u8 alignedcode_lens[LZX_ALIGNEDCODE_NUM_SYMBOLS];
0136
0137 u16 precode_decode_table[(1 << LZX_PRECODE_TABLEBITS) +
0138 (LZX_PRECODE_NUM_SYMBOLS * 2)];
0139 u8 precode_lens[LZX_PRECODE_NUM_SYMBOLS];
0140
0141
0142 u16 working_space[2 * (1 + LZX_MAX_MAIN_CODEWORD_LEN) +
0143 LZX_MAINCODE_NUM_SYMBOLS];
0144 };
0145
0146 static void undo_e8_translation(void *target, s32 input_pos)
0147 {
0148 s32 abs_offset, rel_offset;
0149
0150 abs_offset = get_unaligned_le32(target);
0151 if (abs_offset >= 0) {
0152 if (abs_offset < LZX_DEFAULT_FILESIZE) {
0153
0154 rel_offset = abs_offset - input_pos;
0155 put_unaligned_le32(rel_offset, target);
0156 }
0157 } else {
0158 if (abs_offset >= -input_pos) {
0159
0160 rel_offset = abs_offset + LZX_DEFAULT_FILESIZE;
0161 put_unaligned_le32(rel_offset, target);
0162 }
0163 }
0164 }
0165
0166
0167
0168
0169
0170
0171
0172 static void lzx_postprocess(u8 *data, u32 size)
0173 {
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184 u8 *tail;
0185 u8 saved_bytes[6];
0186 u8 *p;
0187
0188 if (size <= 10)
0189 return;
0190
0191 tail = &data[size - 6];
0192 memcpy(saved_bytes, tail, 6);
0193 memset(tail, 0xE8, 6);
0194 p = data;
0195 for (;;) {
0196 while (*p != 0xE8)
0197 p++;
0198 if (p >= tail)
0199 break;
0200 undo_e8_translation(p + 1, p - data);
0201 p += 5;
0202 }
0203 memcpy(tail, saved_bytes, 6);
0204 }
0205
0206
0207 static forceinline u32 read_presym(const struct lzx_decompressor *d,
0208 struct input_bitstream *is)
0209 {
0210 return read_huffsym(is, d->precode_decode_table,
0211 LZX_PRECODE_TABLEBITS, LZX_MAX_PRE_CODEWORD_LEN);
0212 }
0213
0214
0215 static forceinline u32 read_mainsym(const struct lzx_decompressor *d,
0216 struct input_bitstream *is)
0217 {
0218 return read_huffsym(is, d->maincode_decode_table,
0219 LZX_MAINCODE_TABLEBITS, LZX_MAX_MAIN_CODEWORD_LEN);
0220 }
0221
0222
0223 static forceinline u32 read_lensym(const struct lzx_decompressor *d,
0224 struct input_bitstream *is)
0225 {
0226 return read_huffsym(is, d->lencode_decode_table,
0227 LZX_LENCODE_TABLEBITS, LZX_MAX_LEN_CODEWORD_LEN);
0228 }
0229
0230
0231 static forceinline u32 read_alignedsym(const struct lzx_decompressor *d,
0232 struct input_bitstream *is)
0233 {
0234 return read_huffsym(is, d->alignedcode_decode_table,
0235 LZX_ALIGNEDCODE_TABLEBITS,
0236 LZX_MAX_ALIGNED_CODEWORD_LEN);
0237 }
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254 static int lzx_read_codeword_lens(struct lzx_decompressor *d,
0255 struct input_bitstream *is,
0256 u8 *lens, u32 num_lens)
0257 {
0258 u8 *len_ptr = lens;
0259 u8 *lens_end = lens + num_lens;
0260 int i;
0261
0262
0263
0264
0265 for (i = 0; i < LZX_PRECODE_NUM_SYMBOLS; i++) {
0266 d->precode_lens[i] =
0267 bitstream_read_bits(is, LZX_PRECODE_ELEMENT_SIZE);
0268 }
0269
0270
0271 if (make_huffman_decode_table(d->precode_decode_table,
0272 LZX_PRECODE_NUM_SYMBOLS,
0273 LZX_PRECODE_TABLEBITS,
0274 d->precode_lens,
0275 LZX_MAX_PRE_CODEWORD_LEN,
0276 d->working_space))
0277 return -1;
0278
0279
0280 do {
0281 u32 presym;
0282 u8 len;
0283
0284
0285 presym = read_presym(d, is);
0286 if (presym < 17) {
0287
0288 len = *len_ptr - presym;
0289 if ((s8)len < 0)
0290 len += 17;
0291 *len_ptr++ = len;
0292 } else {
0293
0294
0295 u32 run_len;
0296
0297 if (presym == 17) {
0298
0299 run_len = 4 + bitstream_read_bits(is, 4);
0300 len = 0;
0301 } else if (presym == 18) {
0302
0303 run_len = 20 + bitstream_read_bits(is, 5);
0304 len = 0;
0305 } else {
0306
0307 run_len = 4 + bitstream_read_bits(is, 1);
0308 presym = read_presym(d, is);
0309 if (presym > 17)
0310 return -1;
0311 len = *len_ptr - presym;
0312 if ((s8)len < 0)
0313 len += 17;
0314 }
0315
0316 do {
0317 *len_ptr++ = len;
0318 } while (--run_len);
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329 }
0330 } while (len_ptr < lens_end);
0331
0332 return 0;
0333 }
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345 static int lzx_read_block_header(struct lzx_decompressor *d,
0346 struct input_bitstream *is,
0347 int *block_type_ret,
0348 u32 *block_size_ret,
0349 u32 recent_offsets[])
0350 {
0351 int block_type;
0352 u32 block_size;
0353 int i;
0354
0355 bitstream_ensure_bits(is, 4);
0356
0357
0358
0359
0360 block_type = bitstream_pop_bits(is, 3);
0361
0362
0363 if (bitstream_pop_bits(is, 1)) {
0364 block_size = LZX_DEFAULT_BLOCK_SIZE;
0365 } else {
0366 block_size = 0;
0367 block_size |= bitstream_read_bits(is, 8);
0368 block_size <<= 8;
0369 block_size |= bitstream_read_bits(is, 8);
0370 }
0371
0372 switch (block_type) {
0373
0374 case LZX_BLOCKTYPE_ALIGNED:
0375
0376
0377
0378
0379 for (i = 0; i < LZX_ALIGNEDCODE_NUM_SYMBOLS; i++) {
0380 d->alignedcode_lens[i] =
0381 bitstream_read_bits(is,
0382 LZX_ALIGNEDCODE_ELEMENT_SIZE);
0383 }
0384
0385 if (make_huffman_decode_table(d->alignedcode_decode_table,
0386 LZX_ALIGNEDCODE_NUM_SYMBOLS,
0387 LZX_ALIGNEDCODE_TABLEBITS,
0388 d->alignedcode_lens,
0389 LZX_MAX_ALIGNED_CODEWORD_LEN,
0390 d->working_space))
0391 return -1;
0392
0393
0394
0395
0396 fallthrough;
0397
0398 case LZX_BLOCKTYPE_VERBATIM:
0399
0400
0401
0402
0403
0404
0405
0406
0407 if (lzx_read_codeword_lens(d, is, d->maincode_lens,
0408 LZX_NUM_CHARS))
0409 return -1;
0410
0411 if (lzx_read_codeword_lens(d, is,
0412 d->maincode_lens + LZX_NUM_CHARS,
0413 LZX_MAINCODE_NUM_SYMBOLS - LZX_NUM_CHARS))
0414 return -1;
0415
0416 if (make_huffman_decode_table(d->maincode_decode_table,
0417 LZX_MAINCODE_NUM_SYMBOLS,
0418 LZX_MAINCODE_TABLEBITS,
0419 d->maincode_lens,
0420 LZX_MAX_MAIN_CODEWORD_LEN,
0421 d->working_space))
0422 return -1;
0423
0424
0425
0426 if (lzx_read_codeword_lens(d, is, d->lencode_lens,
0427 LZX_LENCODE_NUM_SYMBOLS))
0428 return -1;
0429
0430 if (make_huffman_decode_table(d->lencode_decode_table,
0431 LZX_LENCODE_NUM_SYMBOLS,
0432 LZX_LENCODE_TABLEBITS,
0433 d->lencode_lens,
0434 LZX_MAX_LEN_CODEWORD_LEN,
0435 d->working_space))
0436 return -1;
0437
0438 break;
0439
0440 case LZX_BLOCKTYPE_UNCOMPRESSED:
0441
0442
0443
0444
0445
0446
0447 bitstream_ensure_bits(is, 1);
0448 bitstream_align(is);
0449
0450 recent_offsets[0] = bitstream_read_u32(is);
0451 recent_offsets[1] = bitstream_read_u32(is);
0452 recent_offsets[2] = bitstream_read_u32(is);
0453
0454
0455 if (recent_offsets[0] == 0 || recent_offsets[1] == 0 ||
0456 recent_offsets[2] == 0)
0457 return -1;
0458 break;
0459
0460 default:
0461
0462 return -1;
0463 }
0464
0465 *block_type_ret = block_type;
0466 *block_size_ret = block_size;
0467 return 0;
0468 }
0469
0470
0471 static int lzx_decompress_block(const struct lzx_decompressor *d,
0472 struct input_bitstream *is,
0473 int block_type, u32 block_size,
0474 u8 * const out_begin, u8 *out_next,
0475 u32 recent_offsets[])
0476 {
0477 u8 * const block_end = out_next + block_size;
0478 u32 ones_if_aligned = 0U - (block_type == LZX_BLOCKTYPE_ALIGNED);
0479
0480 do {
0481 u32 mainsym;
0482 u32 match_len;
0483 u32 match_offset;
0484 u32 offset_slot;
0485 u32 num_extra_bits;
0486
0487 mainsym = read_mainsym(d, is);
0488 if (mainsym < LZX_NUM_CHARS) {
0489
0490 *out_next++ = mainsym;
0491 continue;
0492 }
0493
0494
0495
0496
0497 mainsym -= LZX_NUM_CHARS;
0498 match_len = mainsym % LZX_NUM_LEN_HEADERS;
0499 offset_slot = mainsym / LZX_NUM_LEN_HEADERS;
0500
0501
0502 if (match_len == LZX_NUM_PRIMARY_LENS)
0503 match_len += read_lensym(d, is);
0504 match_len += LZX_MIN_MATCH_LEN;
0505
0506 if (offset_slot < LZX_NUM_RECENT_OFFSETS) {
0507
0508
0509
0510
0511
0512
0513
0514 match_offset = recent_offsets[offset_slot];
0515 recent_offsets[offset_slot] = recent_offsets[0];
0516 recent_offsets[0] = match_offset;
0517 } else {
0518
0519
0520
0521
0522
0523 num_extra_bits = lzx_extra_offset_bits[offset_slot];
0524
0525
0526 match_offset = lzx_offset_slot_base[offset_slot];
0527
0528
0529
0530
0531
0532
0533 if ((num_extra_bits & ones_if_aligned) >= LZX_NUM_ALIGNED_OFFSET_BITS) {
0534 match_offset +=
0535 bitstream_read_bits(is, num_extra_bits -
0536 LZX_NUM_ALIGNED_OFFSET_BITS)
0537 << LZX_NUM_ALIGNED_OFFSET_BITS;
0538 match_offset += read_alignedsym(d, is);
0539 } else {
0540 match_offset += bitstream_read_bits(is, num_extra_bits);
0541 }
0542
0543
0544 match_offset -= (LZX_NUM_RECENT_OFFSETS - 1);
0545
0546
0547 recent_offsets[2] = recent_offsets[1];
0548 recent_offsets[1] = recent_offsets[0];
0549 recent_offsets[0] = match_offset;
0550 }
0551
0552
0553
0554 if (match_len > (size_t)(block_end - out_next))
0555 return -1;
0556
0557 if (match_offset > (size_t)(out_next - out_begin))
0558 return -1;
0559
0560 out_next = lz_copy(out_next, match_len, match_offset,
0561 block_end, LZX_MIN_MATCH_LEN);
0562
0563 } while (out_next != block_end);
0564
0565 return 0;
0566 }
0567
0568
0569
0570
0571
0572
0573
0574 struct lzx_decompressor *lzx_allocate_decompressor(void)
0575 {
0576 return kmalloc(sizeof(struct lzx_decompressor), GFP_NOFS);
0577 }
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590 int lzx_decompress(struct lzx_decompressor *decompressor,
0591 const void *compressed_data, size_t compressed_size,
0592 void *uncompressed_data, size_t uncompressed_size)
0593 {
0594 struct lzx_decompressor *d = decompressor;
0595 u8 * const out_begin = uncompressed_data;
0596 u8 *out_next = out_begin;
0597 u8 * const out_end = out_begin + uncompressed_size;
0598 struct input_bitstream is;
0599 u32 recent_offsets[LZX_NUM_RECENT_OFFSETS] = {1, 1, 1};
0600 int e8_status = 0;
0601
0602 init_input_bitstream(&is, compressed_data, compressed_size);
0603
0604
0605 memset(d->maincode_lens, 0, LZX_MAINCODE_NUM_SYMBOLS);
0606 memset(d->lencode_lens, 0, LZX_LENCODE_NUM_SYMBOLS);
0607
0608
0609
0610 while (out_next != out_end) {
0611 int block_type;
0612 u32 block_size;
0613
0614 if (lzx_read_block_header(d, &is, &block_type, &block_size,
0615 recent_offsets))
0616 goto invalid;
0617
0618 if (block_size < 1 || block_size > (size_t)(out_end - out_next))
0619 goto invalid;
0620
0621 if (block_type != LZX_BLOCKTYPE_UNCOMPRESSED) {
0622
0623
0624
0625 if (lzx_decompress_block(d,
0626 &is,
0627 block_type,
0628 block_size,
0629 out_begin,
0630 out_next,
0631 recent_offsets))
0632 goto invalid;
0633
0634 e8_status |= d->maincode_lens[0xe8];
0635 out_next += block_size;
0636 } else {
0637
0638
0639 out_next = bitstream_read_bytes(&is, out_next,
0640 block_size);
0641 if (!out_next)
0642 goto invalid;
0643
0644 if (block_size & 1)
0645 bitstream_read_byte(&is);
0646
0647 e8_status = 1;
0648 }
0649 }
0650
0651
0652 if (e8_status)
0653 lzx_postprocess(uncompressed_data, uncompressed_size);
0654
0655 return 0;
0656
0657 invalid:
0658 return -1;
0659 }
0660
0661
0662
0663
0664
0665
0666
0667 void lzx_free_decompressor(struct lzx_decompressor *decompressor)
0668 {
0669 kfree(decompressor);
0670 }