rbzip2 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,66 +1,82 @@
1
- # This code is free software; you can redistribute it and/or modify it under
2
- # the terms of the new BSD License.
3
- #
4
- # Copyright (c) 2011, Sebastian Staudt
5
-
6
- module RBzip2
7
-
8
- BASEBLOCKSIZE = 100000
9
- MAX_ALPHA_SIZE = 258
10
- MAX_CODE_LEN = 23
11
- RUNA = 0
12
- RUNB = 1
13
- N_GROUPS = 6
14
- G_SIZE = 50
15
- N_ITERS = 4
16
- MAX_SELECTORS = (2 + (900000 / G_SIZE))
17
- NUM_OVERSHOOT_BYTES = 20
18
-
19
- EOF = 0
20
- START_BLOCK_STATE = 1
21
- RAND_PART_A_STATE = 2
22
- RAND_PART_B_STATE = 3
23
- RAND_PART_C_STATE = 4
24
- NO_RAND_PART_A_STATE = 5
25
- NO_RAND_PART_B_STATE = 6
26
- NO_RAND_PART_C_STATE = 7
27
-
28
- RNUMS = [
29
- 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 985, 724, 205, 454, 863,
30
- 491, 741, 242, 949, 214, 733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
31
- 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 878, 465, 811, 169, 869,
32
- 675, 611, 697, 867, 561, 862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
33
- 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 170, 607, 520, 932, 727,
34
- 476, 693, 425, 174, 647, 73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
35
- 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 641, 801, 220, 162, 819,
36
- 984, 589, 513, 495, 799, 161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
37
- 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 98, 553, 163, 354, 666,
38
- 933, 424, 341, 533, 870, 227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
39
- 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 184, 943, 795, 384, 383,
40
- 461, 404, 758, 839, 887, 715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
41
- 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 652, 934, 970, 447, 318,
42
- 353, 859, 672, 112, 785, 645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
43
- 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 653, 282, 762, 623, 680,
44
- 81, 927, 626, 789, 125, 411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
45
- 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 857, 956, 358, 619, 580,
46
- 124, 737, 594, 701, 612, 669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
47
- 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 344, 805, 988, 739, 511,
48
- 655, 814, 334, 249, 515, 897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
49
- 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 686, 754, 806, 760, 493,
50
- 403, 415, 394, 687, 700, 946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
51
- 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 680, 879, 194, 572, 640,
52
- 724, 926, 56, 204, 700, 707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
53
- 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 134, 108, 571, 364, 631,
54
- 212, 174, 643, 304, 329, 343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
55
- 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 170, 514, 364, 692, 829,
56
- 82, 855, 953, 676, 246, 369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
57
- 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 896, 831, 547, 261, 524,
58
- 462, 293, 465, 502, 56, 661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
59
- 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 61, 688, 793, 644, 986,
60
- 403, 106, 366, 905, 644, 372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
61
- 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 920, 176, 193, 713, 857,
62
- 265, 203, 50, 668, 108, 645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
63
- 936, 638
64
- ]
65
-
66
- end
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2011, Sebastian Staudt
5
+
6
+ module RBzip2::Constants
7
+
8
+ BASEBLOCKSIZE = 100000
9
+ MAX_ALPHA_SIZE = 258
10
+ MAX_CODE_LEN = 23
11
+ RUNA = 0
12
+ RUNB = 1
13
+ N_GROUPS = 6
14
+ G_SIZE = 50
15
+ N_ITERS = 4
16
+ MAX_SELECTORS = (2 + (900000 / G_SIZE))
17
+ NUM_OVERSHOOT_BYTES = 20
18
+
19
+ EOF = 0
20
+ START_BLOCK_STATE = 1
21
+ RAND_PART_A_STATE = 2
22
+ RAND_PART_B_STATE = 3
23
+ RAND_PART_C_STATE = 4
24
+ NO_RAND_PART_A_STATE = 5
25
+ NO_RAND_PART_B_STATE = 6
26
+ NO_RAND_PART_C_STATE = 7
27
+
28
+ RNUMS = [
29
+ 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 985, 724, 205, 454, 863,
30
+ 491, 741, 242, 949, 214, 733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
31
+ 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 878, 465, 811, 169, 869,
32
+ 675, 611, 697, 867, 561, 862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
33
+ 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 170, 607, 520, 932, 727,
34
+ 476, 693, 425, 174, 647, 73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
35
+ 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 641, 801, 220, 162, 819,
36
+ 984, 589, 513, 495, 799, 161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
37
+ 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 98, 553, 163, 354, 666,
38
+ 933, 424, 341, 533, 870, 227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
39
+ 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 184, 943, 795, 384, 383,
40
+ 461, 404, 758, 839, 887, 715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
41
+ 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 652, 934, 970, 447, 318,
42
+ 353, 859, 672, 112, 785, 645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
43
+ 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 653, 282, 762, 623, 680,
44
+ 81, 927, 626, 789, 125, 411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
45
+ 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 857, 956, 358, 619, 580,
46
+ 124, 737, 594, 701, 612, 669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
47
+ 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 344, 805, 988, 739, 511,
48
+ 655, 814, 334, 249, 515, 897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
49
+ 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 686, 754, 806, 760, 493,
50
+ 403, 415, 394, 687, 700, 946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
51
+ 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 680, 879, 194, 572, 640,
52
+ 724, 926, 56, 204, 700, 707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
53
+ 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 134, 108, 571, 364, 631,
54
+ 212, 174, 643, 304, 329, 343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
55
+ 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 170, 514, 364, 692, 829,
56
+ 82, 855, 953, 676, 246, 369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
57
+ 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 896, 831, 547, 261, 524,
58
+ 462, 293, 465, 502, 56, 661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
59
+ 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 61, 688, 793, 644, 986,
60
+ 403, 106, 366, 905, 644, 372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
61
+ 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 920, 176, 193, 713, 857,
62
+ 265, 203, 50, 668, 108, 645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
63
+ 936, 638
64
+ ]
65
+
66
+ MIN_BLOCK_SIZE = 1
67
+ MAX_BLOCK_SIZE = 9
68
+ SETMASK = (1 << 21)
69
+ CLEARMASK = (~SETMASK)
70
+ GREATER_ICOST = 15
71
+ LESSER_ICOST = 0
72
+ SMALL_THRESH = 20
73
+ DEPTH_THRESH = 10
74
+ WORK_FACTOR = 30
75
+ QSORT_STACK_SIZE = 1000
76
+
77
+ INCS = [
78
+ 1, 4, 13, 40, 121, 364, 1093, 3280, 9841, 29524, 88573, 265720, 797161,
79
+ 2391484
80
+ ]
81
+
82
+ end
@@ -1,105 +1,105 @@
1
- # This code is free software; you can redistribute it and/or modify it under
2
- # the terms of the new BSD License.
3
- #
4
- # Copyright (c) 2011, Sebastian Staudt
5
-
6
- class RBzip2::CRC
7
-
8
- CRC32_TABLE = [
9
- 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
10
- 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
11
- 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
12
- 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
13
- 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
14
- 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
15
- 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
16
- 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
17
- 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
18
- 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
19
- 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
20
- 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
21
- 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
22
- 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
23
- 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
24
- 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
25
- 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
26
- 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
27
- 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
28
- 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
29
- 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
30
- 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
31
- 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
32
- 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
33
- 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
34
- 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
35
- 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
36
- 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
37
- 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
38
- 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
39
- 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
40
- 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
41
- 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
42
- 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
43
- 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
44
- 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
45
- 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
46
- 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
47
- 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
48
- 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
49
- 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
50
- 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
51
- 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
52
- 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
53
- 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
54
- 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
55
- 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
56
- 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
57
- 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
58
- 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
59
- 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
60
- 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
61
- 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
62
- 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
63
- 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
64
- 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
65
- 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
66
- 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
67
- 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
68
- 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
69
- 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
70
- 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
71
- 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
72
- 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
73
- ]
74
-
75
- attr_accessor :global_crc
76
-
77
- def initialize
78
- initialize_crc
79
- end
80
-
81
- def initialize_crc
82
- @global_crc = 0xffffffff
83
- end
84
-
85
- def final_crc
86
- @global_crc ^ 0xffffffff
87
- end
88
-
89
- def update_crc(in_ch, repeat = -1)
90
- if repeat == -1
91
- temp = ((@global_crc >> 24) ^ in_ch) % 256
92
- temp = 256 + temp if temp < 0
93
- @global_crc = ((@global_crc << 8) ^ CRC32_TABLE[temp]) % 2**32
94
- else
95
- global_crc_shadow = @global_crc
96
- repeat.downto(0) do
97
- temp = ((global_crc_shadow >> 24) ^ in_ch) % 256
98
- temp = 256 + temp if temp < 0
99
- global_crc_shadow = (global_crc_shadow << 8) ^ CRC32_TABLE[temp]
100
- end
101
- @global_crc = global_crc_shadow % 2**32
102
- end
103
- end
104
-
105
- end
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2011, Sebastian Staudt
5
+
6
+ class RBzip2::CRC
7
+
8
+ CRC32_TABLE = [
9
+ 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
10
+ 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
11
+ 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
12
+ 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
13
+ 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
14
+ 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
15
+ 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
16
+ 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
17
+ 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
18
+ 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
19
+ 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
20
+ 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
21
+ 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
22
+ 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
23
+ 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
24
+ 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
25
+ 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
26
+ 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
27
+ 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
28
+ 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
29
+ 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
30
+ 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
31
+ 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
32
+ 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
33
+ 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
34
+ 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
35
+ 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
36
+ 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
37
+ 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
38
+ 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
39
+ 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
40
+ 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
41
+ 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
42
+ 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
43
+ 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
44
+ 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
45
+ 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
46
+ 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
47
+ 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
48
+ 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
49
+ 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
50
+ 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
51
+ 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
52
+ 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
53
+ 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
54
+ 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
55
+ 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
56
+ 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
57
+ 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
58
+ 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
59
+ 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
60
+ 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
61
+ 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
62
+ 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
63
+ 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
64
+ 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
65
+ 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
66
+ 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
67
+ 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
68
+ 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
69
+ 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
70
+ 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
71
+ 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
72
+ 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
73
+ ]
74
+
75
+ attr_accessor :global_crc
76
+
77
+ def initialize
78
+ initialize_crc
79
+ end
80
+
81
+ def initialize_crc
82
+ @global_crc = 0xffffffff
83
+ end
84
+
85
+ def final_crc
86
+ @global_crc ^ 0xffffffff
87
+ end
88
+
89
+ def update_crc(in_ch, repeat = -1)
90
+ if repeat == -1
91
+ temp = ((@global_crc >> 24) ^ in_ch) % 256
92
+ temp = 256 + temp if temp < 0
93
+ @global_crc = ((@global_crc << 8) ^ CRC32_TABLE[temp]) & 0xffffffff
94
+ else
95
+ global_crc_shadow = @global_crc
96
+ repeat.times do
97
+ temp = (global_crc_shadow >> 24) ^ in_ch
98
+ temp = 256 + temp if temp < 0
99
+ global_crc_shadow = ((global_crc_shadow << 8) ^ CRC32_TABLE[temp]) & 0xffffffff
100
+ end
101
+ @global_crc = global_crc_shadow
102
+ end
103
+ end
104
+
105
+ end
@@ -1,684 +1,703 @@
1
- # This code is free software; you can redistribute it and/or modify it under
2
- # the terms of the new BSD License.
3
- #
4
- # Copyright (c) 2011, Sebastian Staudt
5
-
6
- require 'stringio'
7
-
8
- require 'rbzip2/crc'
9
- require 'rbzip2/constants'
10
- require 'rbzip2/data'
11
-
12
- module RBzip2::Decompressor
13
-
14
- def count(read)
15
- @bytes_read += read if read != -1
16
- end
17
-
18
- def read(length = uncompressed)
19
- raise 'stream closed' if @io.nil?
20
-
21
- if length == 1
22
- r = read0
23
- count (r < 0 ? -1 : 1)
24
- r
25
- elsif length > 0
26
- r = StringIO.new
27
- length.times do
28
- b = read0
29
- break if b < 0
30
- r.write b.chr
31
- end
32
- count r.size
33
- r.string
34
- end
35
- end
36
-
37
- def read0
38
- ret_char = @current_char
39
-
40
- case @current_state
41
- when RBzip2::EOF
42
- return -1
43
-
44
- when RBzip2::RAND_PART_B_STATE
45
- setup_rand_part_b
46
-
47
- when RBzip2::RAND_PART_C_STATE
48
- setup_rand_part_c
49
-
50
- when RBzip2::NO_RAND_PART_B_STATE
51
- setup_no_rand_part_b
52
-
53
- when RBzip2::NO_RAND_PART_C_STATE
54
- setup_no_rand_part_c
55
-
56
- when RBzip2::START_BLOCK_STATE
57
- when RBzip2::RAND_PART_A_STATE
58
- when RBzip2::NO_RAND_PART_A_STATE
59
- else
60
- raise 'illegal state'
61
- end
62
-
63
- ret_char
64
- end
65
-
66
- def make_maps
67
- in_use = @data.in_use
68
- seq_to_unseq = @data.seq_to_unseq;
69
-
70
- n_in_use_shadow = 0;
71
-
72
- 256.times do |i|
73
- if in_use[i]
74
- seq_to_unseq[n_in_use_shadow] = i
75
- n_in_use_shadow += 1
76
- end
77
- end
78
-
79
- @n_in_use = n_in_use_shadow;
80
- end
81
-
82
- def init
83
- check_magic
84
-
85
- block_size = @io.read(1).to_i
86
- raise 'Illegal block size.' if block_size < 1 || block_size > 9
87
- @block_size = block_size
88
-
89
- init_block
90
- setup_block
91
- end
92
-
93
- def check_magic
94
- raise 'Magic number does not match "BZh".' unless @io.read(3) == 'BZh'
95
- end
96
-
97
- def init_block
98
- magic = [ubyte, ubyte, ubyte, ubyte, ubyte, ubyte]
99
-
100
- if magic == [0x17, 0x72, 0x45, 0x38, 0x50, 0x90]
101
- complete
102
- elsif magic != [0x31, 0x41, 0x59, 0x26, 0x53, 0x59]
103
- @current_state = RBzip2::EOF
104
-
105
- raise 'Bad block header.'
106
- else
107
- @stored_block_crc = int
108
- @block_randomised = bit
109
-
110
- @data = RBzip2::Data.new @block_size if @data.nil?
111
-
112
- get_and_move_to_front_decode
113
-
114
- @crc.initialize_crc
115
- @current_state = RBzip2::START_BLOCK_STATE
116
- end
117
- end
118
-
119
- def end_block
120
- @computed_block_crc = @crc.final_crc
121
-
122
- if @stored_block_crc != @computed_block_crc
123
- @computed_combined_crc = (@stored_combined_crc << 1) | (@stored_combined_crc >> 31)
124
- @computed_combined_crc ^= @stored_block_crc
125
-
126
- raise 'BZip2 CRC error'
127
- end
128
-
129
- @computed_combined_crc = (@computed_combined_crc << 1) | (@computed_combined_crc >> 31)
130
- @computed_combined_crc ^= @computed_block_crc
131
- end
132
-
133
- def complete
134
- @stored_combined_crc = int
135
- @current_state = RBzip2::EOF
136
- @data = nil
137
-
138
- raise 'BZip2 CRC error' if @stored_combined_crc != @computed_combined_crc
139
- end
140
-
141
- def close
142
- if @io != $stdin
143
- @io = nil
144
- @data = nil
145
- end
146
- end
147
-
148
- def r(n)
149
- live_shadow = @live
150
- buff_shadow = @buff
151
-
152
- if live_shadow < n
153
- begin
154
- thech = @io.read(1)[0].ord
155
-
156
- raise 'unexpected end of stream' if thech < 0
157
-
158
- buff_shadow = (buff_shadow << 8) | thech
159
- live_shadow += 8
160
- end while live_shadow < n
161
-
162
- @buff = buff_shadow
163
- end
164
-
165
- @live = live_shadow - n
166
-
167
- (buff_shadow >> (live_shadow - n)) & ((1 << n) - 1)
168
- end
169
-
170
- def bit
171
- r(1) != 0
172
- end
173
-
174
- def ubyte
175
- r 8
176
- end
177
-
178
- def int
179
- (((((r(8) << 8) | r(8)) << 8) | r(8)) << 8) | r(8)
180
- end
181
-
182
- def create_decode_tables(limit, base, perm, length, min_len, max_len, alpha_size)
183
- pp = 0
184
- (min_len..max_len).each do |i|
185
- alpha_size.times do |j|
186
- if length[j] == i
187
- perm[pp] = j
188
- pp += 1
189
- end
190
- end
191
- end
192
-
193
- RBzip2::MAX_CODE_LEN.downto 1 do |i|
194
- base[i] = 0
195
- limit[i] = 0
196
- end
197
-
198
- alpha_size.times do |i|
199
- base[length[i] + 1] += 1
200
- end
201
-
202
- b = 0
203
- 1.upto(RBzip2::MAX_CODE_LEN - 1) do |i|
204
- b += base[i]
205
- base[i] = b
206
- end
207
-
208
- vec = 0
209
- min_len.upto(max_len) do |i|
210
- b = base[i]
211
- nb = base[i + 1]
212
- vec += nb - b
213
- b = nb
214
- limit[i] = vec -1
215
- vec = vec << 1
216
- end
217
-
218
- (min_len + 1).upto(max_len) do |i|
219
- base[i] = ((limit[i - 1] + 1) << 1) - base[i]
220
- end
221
- end
222
-
223
- def receive_decoding_tables
224
- in_use = @data.in_use
225
- pos = @data.receive_decoding_tables_pos
226
- selector = @data.selector
227
- selector_mtf = @data.selector_mtf
228
-
229
- in_use16 = 0
230
-
231
- 16.times do |i|
232
- in_use16 |= 1 << i if bit
233
- end
234
-
235
- 255.downto(0) do |i|
236
- in_use[i] = false
237
- end
238
-
239
- 16.times do |i|
240
- if (in_use16 & (1 << i)) != 0
241
- i16 = i << 4
242
- 16.times do |j|
243
- in_use[i16 + j] = true if bit
244
- end
245
- end
246
- end
247
-
248
- make_maps
249
- alpha_size = @n_in_use + 2
250
-
251
- groups = r 3
252
- selectors = r 15
253
-
254
- selectors.times do |i|
255
- j = 0
256
- while bit
257
- j += 1
258
- end
259
- selector_mtf[i] = j
260
- end
261
-
262
- groups.downto(0) do |v|
263
- pos[v] = v
264
- end
265
-
266
- selectors.times do |i|
267
- v = selector_mtf[i] & 0xff
268
- tmp = pos[v]
269
-
270
- while v > 0 do
271
- pos[v] = pos[v -= 1]
272
- end
273
-
274
- pos[0] = tmp
275
- selector[i] = tmp
276
- end
277
-
278
- len = @data.temp_char_array_2d
279
-
280
- groups.times do |t|
281
- curr = r 5
282
- len_t = len[t]
283
- alpha_size.times do |i|
284
- while bit
285
- curr += bit ? -1 : 1
286
- end
287
- len_t[i] = curr
288
- end
289
- @data.temp_char_array_2d[t] = len_t
290
- end
291
-
292
- create_huffman_decoding_tables alpha_size, groups
293
- end
294
-
295
- def create_huffman_decoding_tables(alpha_size, groups)
296
- len = @data.temp_char_array_2d
297
- min_lens = @data.min_lens
298
- limit = @data.limit
299
- base = @data.base
300
- perm = @data.perm
301
-
302
- groups.times do |t|
303
- min_len = 32
304
- max_len = 0
305
- len_t = len[t]
306
-
307
- (alpha_size - 1).downto 0 do |i|
308
- lent = len_t[i]
309
- max_len = lent if lent > max_len
310
- min_len = lent if lent < min_len
311
- end
312
-
313
- create_decode_tables limit[t], base[t], perm[t], len[t], min_len, max_len, alpha_size
314
- min_lens[t] = min_len
315
- end
316
- end
317
-
318
- def get_and_move_to_front_decode
319
- @orig_ptr = r 24
320
- receive_decoding_tables
321
-
322
- ll8 = @data.ll8
323
- unzftab = @data.unzftab
324
- selector = @data.selector
325
- seq_to_unseq = @data.seq_to_unseq
326
- yy = @data.get_and_move_to_front_decode_yy
327
- min_lens = @data.min_lens
328
- limit = @data.limit
329
- base = @data.base
330
- perm = @data.perm
331
- limit_last = @block_size * RBzip2::BASEBLOCKSIZE
332
-
333
- 256.downto(0) do |i|
334
- yy[i] = i
335
- unzftab[i] = 0
336
- end
337
-
338
- group_no = 0
339
- group_pos = RBzip2::G_SIZE - 1
340
- eob = @n_in_use + 1
341
- next_sym = get_and_move_to_front_decode0 0
342
- buff_shadow = @buff
343
- live_shadow = @live
344
- last_shadow = -1
345
- zt = selector[group_no] & 0xff
346
- base_zt = base[zt]
347
- limit_zt = limit[zt]
348
- perm_zt = perm[zt]
349
- min_lens_zt = min_lens[zt]
350
-
351
- while next_sym != eob
352
- if (next_sym == RBzip2::RUNA) || (next_sym == RBzip2::RUNB)
353
- s = -1
354
-
355
- n = 1
356
- loop do
357
- if next_sym == RBzip2::RUNA
358
- s += n
359
- elsif next_sym == RBzip2::RUNB
360
- s += n << 1
361
- else
362
- break
363
- end
364
-
365
- if group_pos == 0
366
- group_pos = RBzip2::G_SIZE - 1
367
- group_no += 1
368
- zt = selector[group_no] & 0xff
369
- base_zt = base[zt]
370
- limit_zt = limit[zt]
371
- perm_zt = perm[zt]
372
- min_lens_zt = min_lens[zt]
373
- else
374
- group_pos -= 1
375
- end
376
-
377
- zn = min_lens_zt
378
-
379
- while live_shadow < zn
380
- thech = @io.read(1)[0].ord
381
-
382
- raise 'unexpected end of stream' if thech < 0
383
-
384
- buff_shadow = (buff_shadow << 8) | thech
385
- live_shadow += 8
386
- end
387
-
388
- zvec = (buff_shadow >> (live_shadow - zn)) & ((1 << zn) - 1)
389
- live_shadow -= zn
390
-
391
- while zvec > limit_zt[zn]
392
- zn += 1
393
-
394
- while live_shadow < 1
395
- thech = @io.read(1)[0].ord
396
-
397
- raise 'unexpected end of stream' if thech < 0
398
-
399
- buff_shadow = (buff_shadow << 8) | thech
400
- live_shadow += 8
401
- end
402
-
403
- live_shadow -= 1
404
- zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
405
- end
406
-
407
- next_sym = perm_zt[zvec - base_zt[zn]]
408
-
409
- n = n << 1
410
- end
411
-
412
- ch = seq_to_unseq[yy[0]]
413
- unzftab[ch & 0xff] += s + 1
414
-
415
- while s >= 0
416
- last_shadow += 1
417
- ll8[last_shadow] = ch
418
- s -= 1
419
- end
420
-
421
- raise 'block overrun' if last_shadow >= limit_last
422
- else
423
- last_shadow += 1
424
- raise 'block overrun' if last_shadow >= limit_last
425
-
426
- tmp = yy[next_sym - 1]
427
- unzftab[seq_to_unseq[tmp] & 0xff] += 1
428
- ll8[last_shadow] = seq_to_unseq[tmp]
429
-
430
- yy[1, next_sym - 1] = yy[0, next_sym - 1]
431
- yy[0] = tmp
432
-
433
- if group_pos == 0
434
- group_pos = RBzip2::G_SIZE - 1
435
- group_no += 1
436
- zt = selector[group_no] & 0xff
437
- base_zt = base[zt]
438
- limit_zt = limit[zt]
439
- perm_zt = perm[zt]
440
- min_lens_zt = min_lens[zt]
441
- else
442
- group_pos -= 1
443
- end
444
-
445
- zn = min_lens_zt
446
-
447
- while live_shadow < zn
448
- thech = @io.read(1)[0].ord
449
-
450
- raise 'unexpected end of stream' if thech < 0
451
-
452
- buff_shadow = (buff_shadow << 8) | thech
453
- live_shadow += 8
454
- end
455
- zvec = (buff_shadow >> (live_shadow - zn)) & ((1 << zn) - 1)
456
- live_shadow -= zn
457
-
458
- while zvec > limit_zt[zn]
459
- zn += 1
460
- while live_shadow < 1
461
- thech = @io.read(1)[0].ord
462
-
463
- raise 'unexpected end of stream' if thech < 0
464
-
465
- buff_shadow = (buff_shadow << 8) | thech
466
- live_shadow += 8
467
- end
468
- live_shadow -= 1
469
- zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
470
- end
471
-
472
- next_sym = perm_zt[zvec - base_zt[zn]]
473
- end
474
- end
475
-
476
- @last = last_shadow
477
- @live = live_shadow
478
- @buff = buff_shadow
479
- end
480
-
481
- def get_and_move_to_front_decode0(group_no)
482
- zt = @data.selector[group_no] & 0xff
483
- limit_zt = @data.limit[zt]
484
- zn = @data.min_lens[zt]
485
- zvec = r zn
486
- live_shadow = @live
487
- buff_shadow = @buff
488
-
489
- while zvec > limit_zt[zn]
490
- zn += 1
491
-
492
- while live_shadow < 1
493
- thech = @io.read(1)[0].ord
494
-
495
- raise 'unexpected end of stream' if thech < 0
496
-
497
- buff_shadow = (buff_shadow << 8) | thech
498
- live_shadow += 8
499
- end
500
-
501
- live_shadow -=1
502
- zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
503
- end
504
-
505
- @live = live_shadow
506
- @buff = buff_shadow
507
-
508
- @data.perm[zt][zvec - @data.base[zt][zn]]
509
- end
510
-
511
- def setup_block
512
- return if @data.nil?
513
-
514
- cftab = @data.cftab
515
- tt = @data.init_tt @last + 1
516
- ll8 = @data.ll8
517
- cftab[0] = 0
518
- cftab[1, 256] = @data.unzftab[0, 256]
519
-
520
- c = cftab[0]
521
- 1.upto(256) do |i|
522
- c += cftab[i]
523
- cftab[i] = c
524
- end
525
-
526
- last_shadow = @last
527
- (last_shadow + 1).times do |i|
528
- cftab_i = ll8[i] & 0xff
529
- tt[cftab[cftab_i]] = i
530
- cftab[cftab_i] += 1
531
- end
532
-
533
- raise 'stream corrupted' if @orig_ptr < 0 || @orig_ptr >= tt.size
534
-
535
- @su_t_pos = tt[@orig_ptr]
536
- @su_count = 0
537
- @su_i2 = 0
538
- @su_ch2 = 256
539
-
540
- if @block_randomised
541
- @su_r_n_to_go = 0
542
- @su_r_t_pos = 0
543
-
544
- setup_rand_part_a
545
- else
546
- setup_no_rand_part_a
547
- end
548
- end
549
-
550
- def setup_rand_part_a
551
- if @su_i2 <= @last
552
- @su_ch_prev = @su_ch2
553
- su_ch2_shadow = @data.ll8[@su_t_pos] & 0xff
554
- @su_t_pos = @data.tt[@su_t_pos]
555
-
556
- if @su_r_n_to_go == 0
557
- @su_r_n_to_go = RBzip2::RNUMS[@su_r_t_pos] - 1
558
- @su_r_t_pos += 1
559
- @su_r_t_pos = 0 if @su_r_t_pos == 512
560
- else
561
- @su_r_n_to_go -= 1
562
- end
563
-
564
- @su_ch2 = su_ch2_shadow ^= (@su_r_n_to_go == 1) ? 1 : 0
565
- @su_i2 += 1
566
- @current_char = su_ch2_shadow
567
- @current_state = RBzip2::RAND_PART_B_STATE
568
- @crc.update_crc su_ch2_shadow
569
- else
570
- end_block
571
- init_block
572
- setup_block
573
- end
574
- end
575
-
576
- def setup_no_rand_part_a
577
- if @su_i2 <= @last
578
- @su_ch_prev = @su_ch2
579
- su_ch2_shadow = @data.ll8[@su_t_pos] & 0xff
580
- @su_ch2 = su_ch2_shadow
581
- @su_t_pos = @data.tt[@su_t_pos]
582
- @su_i2 += 1
583
- @current_char = su_ch2_shadow
584
- @current_state = RBzip2::NO_RAND_PART_B_STATE
585
- @crc.update_crc su_ch2_shadow
586
- else
587
- @current_state = RBzip2::NO_RAND_PART_A_STATE
588
- end_block
589
- init_block
590
- setup_block
591
- end
592
- end
593
-
594
- def setup_rand_part_b
595
- if @su_ch2 != @su_ch_prev
596
- @current_state = RBzip2::RAND_PART_A_STATE
597
- @su_count = 1
598
- setup_rand_part_a
599
- else
600
- @su_count += 1
601
- if @su_count >= 4
602
- @su_z = @data.ll8[@su_t_pos] & 0xff
603
- @su_t_pos = @data.tt[@su_t_pos]
604
-
605
- if @su_r_n_to_go == 0
606
- @su_r_n_to_go = RBzip2::RNUMS[@su_r_t_pos] - 1
607
- @su_r_t_pos += 1
608
- @su_r_t_pos = 0 if @su_r_t_pos == 512
609
- else
610
- @su_r_n_to_go -= 1
611
- end
612
-
613
- @su_j2 = 0
614
- @current_state = RBzip2::RAND_PART_C_STATE
615
- @su_z ^= 1 if @su_r_n_to_go == 1
616
- setup_rand_part_c
617
- else
618
- @current_state = RBzip2::RAND_PART_A_STATE
619
- setup_rand_part_a
620
- end
621
- end
622
- end
623
-
624
- def setup_rand_part_c
625
- if @su_j2 < @su_z
626
- @current_char = @su_ch2
627
- @crc.update_crc @su_ch2
628
- @su_j2 += 1
629
- else
630
- @current_state = RBzip2::RAND_PART_A_STATE
631
- @su_i2 += 1
632
- @su_count = 0
633
- setup_rand_part_a
634
- end
635
- end
636
-
637
- def setup_no_rand_part_b
638
- if @su_ch2 != @su_ch_prev
639
- @su_count = 1
640
- setup_no_rand_part_a
641
- else
642
- @su_count += 1
643
- if @su_count >= 4
644
- @su_z = @data.ll8[@su_t_pos] & 0xff
645
- @su_t_pos = @data.tt[@su_t_pos]
646
- @su_j2 = 0
647
- setup_no_rand_part_c
648
- else
649
- setup_no_rand_part_a
650
- end
651
- end
652
- end
653
-
654
- def setup_no_rand_part_c
655
- if @su_j2 < @su_z
656
- su_ch2_shadow = @su_ch2
657
- @current_char = su_ch2_shadow
658
- @crc.update_crc su_ch2_shadow
659
- @su_j2 += 1
660
- @current_state = RBzip2::NO_RAND_PART_C_STATE
661
- else
662
- @su_i2 += 1
663
- @su_count = 0
664
- setup_no_rand_part_a
665
- end
666
- end
667
-
668
- def size
669
- if @io.is_a? StringIO
670
- @io.size
671
- elsif @io.is_a? File
672
- @io.stat.size
673
- end
674
- end
675
-
676
- def uncompressed
677
- @last + 1
678
- end
679
-
680
- def inspect
681
- "#<#{self.class}: @io=#{@io.inspect} size=#{size} uncompressed=#{uncompressed}>"
682
- end
683
-
684
- end
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2011, Sebastian Staudt
5
+
6
+ require 'stringio'
7
+
8
+ class RBzip2::Decompressor
9
+
10
+ include RBzip2::Constants
11
+
12
+ def initialize(io)
13
+ @buff = 0
14
+ @bytes_read = 0
15
+ @computed_combined_crc = 0
16
+ @crc = RBzip2::CRC.new
17
+ @current_char = -1
18
+ @io = io
19
+ @live = 0
20
+ @stored_combined_crc = 0
21
+ @su_t_pos = 0
22
+ init
23
+ end
24
+
25
+ def count(read)
26
+ @bytes_read += read if read != -1
27
+ end
28
+
29
+ def read(length = nil)
30
+ raise 'stream closed' if @io.nil?
31
+
32
+ if length == 1
33
+ r = read0
34
+ count (r < 0 ? -1 : 1)
35
+ r
36
+ else
37
+ r = StringIO.new
38
+ if length == nil
39
+ loop do
40
+ b = read0
41
+ break if b < 0
42
+ r.write b.chr
43
+ end
44
+ elsif length > 0
45
+ length.times do
46
+ b = read0
47
+ break if b < 0
48
+ r.write b.chr
49
+ end
50
+ count r.size
51
+ end
52
+ r.string
53
+ end
54
+ end
55
+
56
+ def read0
57
+ ret_char = @current_char
58
+
59
+ case @current_state
60
+ when EOF
61
+ return -1
62
+
63
+ when RAND_PART_B_STATE
64
+ setup_rand_part_b
65
+
66
+ when RAND_PART_C_STATE
67
+ setup_rand_part_c
68
+
69
+ when NO_RAND_PART_B_STATE
70
+ setup_no_rand_part_b
71
+
72
+ when NO_RAND_PART_C_STATE
73
+ setup_no_rand_part_c
74
+
75
+ when START_BLOCK_STATE
76
+ when RAND_PART_A_STATE
77
+ when NO_RAND_PART_A_STATE
78
+ else
79
+ raise 'illegal state'
80
+ end
81
+
82
+ ret_char
83
+ end
84
+
85
+ def make_maps
86
+ in_use = @data.in_use
87
+ seq_to_unseq = @data.seq_to_unseq;
88
+
89
+ n_in_use_shadow = 0;
90
+
91
+ 256.times do |i|
92
+ if in_use[i]
93
+ seq_to_unseq[n_in_use_shadow] = i
94
+ n_in_use_shadow += 1
95
+ end
96
+ end
97
+
98
+ @n_in_use = n_in_use_shadow;
99
+ end
100
+
101
+ def init
102
+ check_magic
103
+
104
+ block_size = @io.read(1).to_i
105
+ raise 'Illegal block size.' if block_size < 1 || block_size > 9
106
+ @block_size = block_size
107
+
108
+ init_block
109
+ setup_block
110
+ end
111
+
112
+ def check_magic
113
+ raise 'Magic number does not match "BZh".' unless @io.read(3) == 'BZh'
114
+ end
115
+
116
+ def init_block
117
+ magic = [ubyte, ubyte, ubyte, ubyte, ubyte, ubyte]
118
+
119
+ if magic == [0x17, 0x72, 0x45, 0x38, 0x50, 0x90]
120
+ complete
121
+ elsif magic != [0x31, 0x41, 0x59, 0x26, 0x53, 0x59]
122
+ @current_state = EOF
123
+
124
+ raise 'Bad block header.'
125
+ else
126
+ @stored_block_crc = int
127
+ @block_randomised = bit
128
+
129
+ @data = RBzip2::InputData.new @block_size if @data.nil?
130
+
131
+ get_and_move_to_front_decode
132
+
133
+ @crc.initialize_crc
134
+ @current_state = START_BLOCK_STATE
135
+ end
136
+ end
137
+
138
+ def end_block
139
+ @computed_block_crc = @crc.final_crc
140
+
141
+ if @stored_block_crc != @computed_block_crc
142
+ @computed_combined_crc = (@stored_combined_crc << 1) | (@stored_combined_crc >> 31)
143
+ @computed_combined_crc ^= @stored_block_crc
144
+
145
+ raise 'BZip2 CRC error'
146
+ end
147
+
148
+ @computed_combined_crc = (@computed_combined_crc << 1) | (@computed_combined_crc >> 31)
149
+ @computed_combined_crc ^= @computed_block_crc
150
+ end
151
+
152
+ def complete
153
+ @stored_combined_crc = int
154
+ @current_state = EOF
155
+ @data = nil
156
+
157
+ raise 'BZip2 CRC error' if @stored_combined_crc != @computed_combined_crc
158
+ end
159
+
160
+ def close
161
+ if @io != $stdin
162
+ @io = nil
163
+ @data = nil
164
+ end
165
+ end
166
+
167
+ def r(n)
168
+ live_shadow = @live
169
+ buff_shadow = @buff
170
+
171
+ if live_shadow < n
172
+ begin
173
+ thech = @io.read(1)[0].ord
174
+
175
+ raise 'unexpected end of stream' if thech < 0
176
+
177
+ buff_shadow = (buff_shadow << 8) | thech
178
+ live_shadow += 8
179
+ end while live_shadow < n
180
+
181
+ @buff = buff_shadow
182
+ end
183
+
184
+ @live = live_shadow - n
185
+
186
+ (buff_shadow >> (live_shadow - n)) & ((1 << n) - 1)
187
+ end
188
+
189
+ def bit
190
+ r(1) != 0
191
+ end
192
+
193
+ def ubyte
194
+ r 8
195
+ end
196
+
197
+ def int
198
+ (((((r(8) << 8) | r(8)) << 8) | r(8)) << 8) | r(8)
199
+ end
200
+
201
+ def create_decode_tables(limit, base, perm, length, min_len, max_len, alpha_size)
202
+ pp = 0
203
+ (min_len..max_len).each do |i|
204
+ alpha_size.times do |j|
205
+ if length[j] == i
206
+ perm[pp] = j
207
+ pp += 1
208
+ end
209
+ end
210
+ end
211
+
212
+ MAX_CODE_LEN.downto 1 do |i|
213
+ base[i] = 0
214
+ limit[i] = 0
215
+ end
216
+
217
+ alpha_size.times do |i|
218
+ base[length[i] + 1] += 1
219
+ end
220
+
221
+ b = 0
222
+ 1.upto(MAX_CODE_LEN - 1) do |i|
223
+ b += base[i]
224
+ base[i] = b
225
+ end
226
+
227
+ vec = 0
228
+ min_len.upto(max_len) do |i|
229
+ b = base[i]
230
+ nb = base[i + 1]
231
+ vec += nb - b
232
+ b = nb
233
+ limit[i] = vec -1
234
+ vec = vec << 1
235
+ end
236
+
237
+ (min_len + 1).upto(max_len) do |i|
238
+ base[i] = ((limit[i - 1] + 1) << 1) - base[i]
239
+ end
240
+ end
241
+
242
+ def receive_decoding_tables
243
+ in_use = @data.in_use
244
+ pos = @data.receive_decoding_tables_pos
245
+ selector = @data.selector
246
+ selector_mtf = @data.selector_mtf
247
+
248
+ in_use16 = 0
249
+
250
+ 16.times do |i|
251
+ in_use16 |= 1 << i if bit
252
+ end
253
+
254
+ 255.downto(0) do |i|
255
+ in_use[i] = false
256
+ end
257
+
258
+ 16.times do |i|
259
+ if (in_use16 & (1 << i)) != 0
260
+ i16 = i << 4
261
+ 16.times do |j|
262
+ in_use[i16 + j] = true if bit
263
+ end
264
+ end
265
+ end
266
+
267
+ make_maps
268
+ alpha_size = @n_in_use + 2
269
+
270
+ groups = r 3
271
+ selectors = r 15
272
+
273
+ selectors.times do |i|
274
+ j = 0
275
+ while bit
276
+ j += 1
277
+ end
278
+ selector_mtf[i] = j
279
+ end
280
+
281
+ groups.downto(0) do |v|
282
+ pos[v] = v
283
+ end
284
+
285
+ selectors.times do |i|
286
+ v = selector_mtf[i] & 0xff
287
+ tmp = pos[v]
288
+
289
+ while v > 0 do
290
+ pos[v] = pos[v -= 1]
291
+ end
292
+
293
+ pos[0] = tmp
294
+ selector[i] = tmp
295
+ end
296
+
297
+ len = @data.temp_char_array_2d
298
+
299
+ groups.times do |t|
300
+ curr = r 5
301
+ len_t = len[t]
302
+ alpha_size.times do |i|
303
+ while bit
304
+ curr += bit ? -1 : 1
305
+ end
306
+ len_t[i] = curr
307
+ end
308
+ @data.temp_char_array_2d[t] = len_t
309
+ end
310
+
311
+ create_huffman_decoding_tables alpha_size, groups
312
+ end
313
+
314
+ def create_huffman_decoding_tables(alpha_size, groups)
315
+ len = @data.temp_char_array_2d
316
+ min_lens = @data.min_lens
317
+ limit = @data.limit
318
+ base = @data.base
319
+ perm = @data.perm
320
+
321
+ groups.times do |t|
322
+ min_len = 32
323
+ max_len = 0
324
+ len_t = len[t]
325
+
326
+ (alpha_size - 1).downto 0 do |i|
327
+ lent = len_t[i]
328
+ max_len = lent if lent > max_len
329
+ min_len = lent if lent < min_len
330
+ end
331
+
332
+ create_decode_tables limit[t], base[t], perm[t], len[t], min_len, max_len, alpha_size
333
+ min_lens[t] = min_len
334
+ end
335
+ end
336
+
337
+ def get_and_move_to_front_decode
338
+ @orig_ptr = r 24
339
+ receive_decoding_tables
340
+
341
+ ll8 = @data.ll8
342
+ unzftab = @data.unzftab
343
+ selector = @data.selector
344
+ seq_to_unseq = @data.seq_to_unseq
345
+ yy = @data.get_and_move_to_front_decode_yy
346
+ min_lens = @data.min_lens
347
+ limit = @data.limit
348
+ base = @data.base
349
+ perm = @data.perm
350
+ limit_last = @block_size * BASEBLOCKSIZE
351
+
352
+ 256.downto(0) do |i|
353
+ yy[i] = i
354
+ unzftab[i] = 0
355
+ end
356
+
357
+ group_no = 0
358
+ group_pos = G_SIZE - 1
359
+ eob = @n_in_use + 1
360
+ next_sym = get_and_move_to_front_decode0 0
361
+ buff_shadow = @buff
362
+ live_shadow = @live
363
+ last_shadow = -1
364
+ zt = selector[group_no] & 0xff
365
+ base_zt = base[zt]
366
+ limit_zt = limit[zt]
367
+ perm_zt = perm[zt]
368
+ min_lens_zt = min_lens[zt]
369
+
370
+ while next_sym != eob
371
+ if (next_sym == RUNA) || (next_sym == RUNB)
372
+ s = -1
373
+
374
+ n = 1
375
+ loop do
376
+ if next_sym == RUNA
377
+ s += n
378
+ elsif next_sym == RUNB
379
+ s += n << 1
380
+ else
381
+ break
382
+ end
383
+
384
+ if group_pos == 0
385
+ group_pos = G_SIZE - 1
386
+ group_no += 1
387
+ zt = selector[group_no] & 0xff
388
+ base_zt = base[zt]
389
+ limit_zt = limit[zt]
390
+ perm_zt = perm[zt]
391
+ min_lens_zt = min_lens[zt]
392
+ else
393
+ group_pos -= 1
394
+ end
395
+
396
+ zn = min_lens_zt
397
+
398
+ while live_shadow < zn
399
+ thech = @io.read(1)[0].ord
400
+
401
+ raise 'unexpected end of stream' if thech < 0
402
+
403
+ buff_shadow = (buff_shadow << 8) | thech
404
+ live_shadow += 8
405
+ end
406
+
407
+ zvec = (buff_shadow >> (live_shadow - zn)) & ((1 << zn) - 1)
408
+ live_shadow -= zn
409
+
410
+ while zvec > limit_zt[zn]
411
+ zn += 1
412
+
413
+ while live_shadow < 1
414
+ thech = @io.read(1)[0].ord
415
+
416
+ raise 'unexpected end of stream' if thech < 0
417
+
418
+ buff_shadow = (buff_shadow << 8) | thech
419
+ live_shadow += 8
420
+ end
421
+
422
+ live_shadow -= 1
423
+ zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
424
+ end
425
+
426
+ next_sym = perm_zt[zvec - base_zt[zn]]
427
+
428
+ n = n << 1
429
+ end
430
+
431
+ ch = seq_to_unseq[yy[0]]
432
+ unzftab[ch & 0xff] += s + 1
433
+
434
+ while s >= 0
435
+ last_shadow += 1
436
+ ll8[last_shadow] = ch
437
+ s -= 1
438
+ end
439
+
440
+ raise 'block overrun' if last_shadow >= limit_last
441
+ else
442
+ last_shadow += 1
443
+ raise 'block overrun' if last_shadow >= limit_last
444
+
445
+ tmp = yy[next_sym - 1]
446
+ unzftab[seq_to_unseq[tmp] & 0xff] += 1
447
+ ll8[last_shadow] = seq_to_unseq[tmp]
448
+
449
+ yy[1, next_sym - 1] = yy[0, next_sym - 1]
450
+ yy[0] = tmp
451
+
452
+ if group_pos == 0
453
+ group_pos = G_SIZE - 1
454
+ group_no += 1
455
+ zt = selector[group_no] & 0xff
456
+ base_zt = base[zt]
457
+ limit_zt = limit[zt]
458
+ perm_zt = perm[zt]
459
+ min_lens_zt = min_lens[zt]
460
+ else
461
+ group_pos -= 1
462
+ end
463
+
464
+ zn = min_lens_zt
465
+
466
+ while live_shadow < zn
467
+ thech = @io.read(1)[0].ord
468
+
469
+ raise 'unexpected end of stream' if thech < 0
470
+
471
+ buff_shadow = (buff_shadow << 8) | thech
472
+ live_shadow += 8
473
+ end
474
+ zvec = (buff_shadow >> (live_shadow - zn)) & ((1 << zn) - 1)
475
+ live_shadow -= zn
476
+
477
+ while zvec > limit_zt[zn]
478
+ zn += 1
479
+ while live_shadow < 1
480
+ thech = @io.read(1)[0].ord
481
+
482
+ raise 'unexpected end of stream' if thech < 0
483
+
484
+ buff_shadow = (buff_shadow << 8) | thech
485
+ live_shadow += 8
486
+ end
487
+ live_shadow -= 1
488
+ zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
489
+ end
490
+
491
+ next_sym = perm_zt[zvec - base_zt[zn]]
492
+ end
493
+ end
494
+
495
+ @last = last_shadow
496
+ @live = live_shadow
497
+ @buff = buff_shadow
498
+ end
499
+
500
+ def get_and_move_to_front_decode0(group_no)
501
+ zt = @data.selector[group_no] & 0xff
502
+ limit_zt = @data.limit[zt]
503
+ zn = @data.min_lens[zt]
504
+ zvec = r zn
505
+ live_shadow = @live
506
+ buff_shadow = @buff
507
+
508
+ while zvec > limit_zt[zn]
509
+ zn += 1
510
+
511
+ while live_shadow < 1
512
+ thech = @io.read(1)[0].ord
513
+
514
+ raise 'unexpected end of stream' if thech < 0
515
+
516
+ buff_shadow = (buff_shadow << 8) | thech
517
+ live_shadow += 8
518
+ end
519
+
520
+ live_shadow -=1
521
+ zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
522
+ end
523
+
524
+ @live = live_shadow
525
+ @buff = buff_shadow
526
+
527
+ @data.perm[zt][zvec - @data.base[zt][zn]]
528
+ end
529
+
530
+ def setup_block
531
+ return if @data.nil?
532
+
533
+ cftab = @data.cftab
534
+ tt = @data.init_tt @last + 1
535
+ ll8 = @data.ll8
536
+ cftab[0] = 0
537
+ cftab[1, 256] = @data.unzftab[0, 256]
538
+
539
+ c = cftab[0]
540
+ 1.upto(256) do |i|
541
+ c += cftab[i]
542
+ cftab[i] = c
543
+ end
544
+
545
+ last_shadow = @last
546
+ (last_shadow + 1).times do |i|
547
+ cftab_i = ll8[i] & 0xff
548
+ tt[cftab[cftab_i]] = i
549
+ cftab[cftab_i] += 1
550
+ end
551
+
552
+ raise 'stream corrupted' if @orig_ptr < 0 || @orig_ptr >= tt.size
553
+
554
+ @su_t_pos = tt[@orig_ptr]
555
+ @su_count = 0
556
+ @su_i2 = 0
557
+ @su_ch2 = 256
558
+
559
+ if @block_randomised
560
+ @su_r_n_to_go = 0
561
+ @su_r_t_pos = 0
562
+
563
+ setup_rand_part_a
564
+ else
565
+ setup_no_rand_part_a
566
+ end
567
+ end
568
+
569
+ def setup_rand_part_a
570
+ if @su_i2 <= @last
571
+ @su_ch_prev = @su_ch2
572
+ su_ch2_shadow = @data.ll8[@su_t_pos] & 0xff
573
+ @su_t_pos = @data.tt[@su_t_pos]
574
+
575
+ if @su_r_n_to_go == 0
576
+ @su_r_n_to_go = RNUMS[@su_r_t_pos] - 1
577
+ @su_r_t_pos += 1
578
+ @su_r_t_pos = 0 if @su_r_t_pos == 512
579
+ else
580
+ @su_r_n_to_go -= 1
581
+ end
582
+
583
+ @su_ch2 = su_ch2_shadow ^= (@su_r_n_to_go == 1) ? 1 : 0
584
+ @su_i2 += 1
585
+ @current_char = su_ch2_shadow
586
+ @current_state = RAND_PART_B_STATE
587
+ @crc.update_crc su_ch2_shadow
588
+ else
589
+ end_block
590
+ init_block
591
+ setup_block
592
+ end
593
+ end
594
+
595
+ def setup_no_rand_part_a
596
+ if @su_i2 <= @last
597
+ @su_ch_prev = @su_ch2
598
+ su_ch2_shadow = @data.ll8[@su_t_pos] & 0xff
599
+ @su_ch2 = su_ch2_shadow
600
+ @su_t_pos = @data.tt[@su_t_pos]
601
+ @su_i2 += 1
602
+ @current_char = su_ch2_shadow
603
+ @current_state = NO_RAND_PART_B_STATE
604
+ @crc.update_crc su_ch2_shadow
605
+ else
606
+ @current_state = NO_RAND_PART_A_STATE
607
+ end_block
608
+ init_block
609
+ setup_block
610
+ end
611
+ end
612
+
613
+ def setup_rand_part_b
614
+ if @su_ch2 != @su_ch_prev
615
+ @current_state = RAND_PART_A_STATE
616
+ @su_count = 1
617
+ setup_rand_part_a
618
+ else
619
+ @su_count += 1
620
+ if @su_count >= 4
621
+ @su_z = @data.ll8[@su_t_pos] & 0xff
622
+ @su_t_pos = @data.tt[@su_t_pos]
623
+
624
+ if @su_r_n_to_go == 0
625
+ @su_r_n_to_go = RNUMS[@su_r_t_pos] - 1
626
+ @su_r_t_pos += 1
627
+ @su_r_t_pos = 0 if @su_r_t_pos == 512
628
+ else
629
+ @su_r_n_to_go -= 1
630
+ end
631
+
632
+ @su_j2 = 0
633
+ @current_state = RAND_PART_C_STATE
634
+ @su_z ^= 1 if @su_r_n_to_go == 1
635
+ setup_rand_part_c
636
+ else
637
+ @current_state = RAND_PART_A_STATE
638
+ setup_rand_part_a
639
+ end
640
+ end
641
+ end
642
+
643
+ def setup_rand_part_c
644
+ if @su_j2 < @su_z
645
+ @current_char = @su_ch2
646
+ @crc.update_crc @su_ch2
647
+ @su_j2 += 1
648
+ else
649
+ @current_state = RAND_PART_A_STATE
650
+ @su_i2 += 1
651
+ @su_count = 0
652
+ setup_rand_part_a
653
+ end
654
+ end
655
+
656
+ def setup_no_rand_part_b
657
+ if @su_ch2 != @su_ch_prev
658
+ @su_count = 1
659
+ setup_no_rand_part_a
660
+ else
661
+ @su_count += 1
662
+ if @su_count >= 4
663
+ @su_z = @data.ll8[@su_t_pos] & 0xff
664
+ @su_t_pos = @data.tt[@su_t_pos]
665
+ @su_j2 = 0
666
+ setup_no_rand_part_c
667
+ else
668
+ setup_no_rand_part_a
669
+ end
670
+ end
671
+ end
672
+
673
+ def setup_no_rand_part_c
674
+ if @su_j2 < @su_z
675
+ su_ch2_shadow = @su_ch2
676
+ @current_char = su_ch2_shadow
677
+ @crc.update_crc su_ch2_shadow
678
+ @su_j2 += 1
679
+ @current_state = NO_RAND_PART_C_STATE
680
+ else
681
+ @su_i2 += 1
682
+ @su_count = 0
683
+ setup_no_rand_part_a
684
+ end
685
+ end
686
+
687
+ def size
688
+ if @io.is_a? StringIO
689
+ @io.size
690
+ elsif @io.is_a? File
691
+ @io.stat.size
692
+ end
693
+ end
694
+
695
+ def uncompressed
696
+ @last + 1
697
+ end
698
+
699
+ def inspect
700
+ "#<#{self.class}: @io=#{@io.inspect} size=#{size} uncompressed=#{uncompressed}>"
701
+ end
702
+
703
+ end