aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archival/libunarchive/decompress_unlzma.c60
1 files changed, 36 insertions, 24 deletions
diff --git a/archival/libunarchive/decompress_unlzma.c b/archival/libunarchive/decompress_unlzma.c
index 4f36c060f..5bf4de2bd 100644
--- a/archival/libunarchive/decompress_unlzma.c
+++ b/archival/libunarchive/decompress_unlzma.c
@@ -282,14 +282,16 @@ unpack_lzma_stream(int src_fd, int dst_fd)
while (global_pos + buffer_pos < header.dst_size) {
int pos_state = (buffer_pos + global_pos) & pos_state_mask;
- prob =
- p + LZMA_IS_MATCH + (state << LZMA_NUM_POS_BITS_MAX) + pos_state;
+ prob = p + LZMA_IS_MATCH + (state << LZMA_NUM_POS_BITS_MAX) + pos_state;
if (rc_is_bit_0(rc, prob)) {
mi = 1;
rc_update_bit_0(rc, prob);
- prob = (p + LZMA_LITERAL + (LZMA_LIT_SIZE
- * ((((buffer_pos + global_pos) & literal_pos_mask) << lc)
- + (previous_byte >> (8 - lc)))));
+ prob = (p + LZMA_LITERAL
+ + (LZMA_LIT_SIZE * ((((buffer_pos + global_pos) & literal_pos_mask) << lc)
+ + (previous_byte >> (8 - lc))
+ )
+ )
+ );
if (state >= LZMA_NUM_LIT_STATES) {
int match_byte;
@@ -317,8 +319,15 @@ unpack_lzma_stream(int src_fd, int dst_fd)
prob_lit = prob + mi;
rc_get_bit(rc, prob_lit, &mi);
}
- previous_byte = (uint8_t) mi;
+ state -= 3;
+ if (state < 4-3)
+ state = 0;
+ if (state >= 10-3)
+ state -= 6-3;
+
+ previous_byte = (uint8_t) mi;
+#if ENABLE_FEATURE_LZMA_FAST
buffer[buffer_pos++] = previous_byte;
if (buffer_pos == header.dict_size) {
buffer_pos = 0;
@@ -327,12 +336,10 @@ unpack_lzma_stream(int src_fd, int dst_fd)
goto bad;
USE_DESKTOP(total_written += header.dict_size;)
}
- if (state < 4)
- state = 0;
- else if (state < 10)
- state -= 3;
- else
- state -= 6;
+#else
+ len = 1;
+ goto one_byte;
+#endif
} else {
int offset;
uint16_t *prob_len;
@@ -352,11 +359,14 @@ unpack_lzma_stream(int src_fd, int dst_fd)
if (rc_is_bit_0(rc, prob)) {
rc_update_bit_0(rc, prob);
prob = (p + LZMA_IS_REP_0_LONG
- + (state << LZMA_NUM_POS_BITS_MAX) + pos_state);
+ + (state << LZMA_NUM_POS_BITS_MAX)
+ + pos_state
+ );
if (rc_is_bit_0(rc, prob)) {
rc_update_bit_0(rc, prob);
state = state < LZMA_NUM_LIT_STATES ? 9 : 11;
+#if ENABLE_FEATURE_LZMA_FAST
pos = buffer_pos - rep0;
while (pos >= header.dict_size)
pos += header.dict_size;
@@ -370,6 +380,10 @@ unpack_lzma_stream(int src_fd, int dst_fd)
USE_DESKTOP(total_written += header.dict_size;)
}
continue;
+#else
+ len = 1;
+ goto string;
+#endif
} else {
rc_update_bit_1(rc, prob);
}
@@ -405,7 +419,7 @@ unpack_lzma_stream(int src_fd, int dst_fd)
if (rc_is_bit_0(rc, prob_len)) {
rc_update_bit_0(rc, prob_len);
prob_len = (prob + LZMA_LEN_LOW
- + (pos_state << LZMA_LEN_NUM_LOW_BITS));
+ + (pos_state << LZMA_LEN_NUM_LOW_BITS));
offset = 0;
num_bits = LZMA_LEN_NUM_LOW_BITS;
} else {
@@ -414,14 +428,14 @@ unpack_lzma_stream(int src_fd, int dst_fd)
if (rc_is_bit_0(rc, prob_len)) {
rc_update_bit_0(rc, prob_len);
prob_len = (prob + LZMA_LEN_MID
- + (pos_state << LZMA_LEN_NUM_MID_BITS));
+ + (pos_state << LZMA_LEN_NUM_MID_BITS));
offset = 1 << LZMA_LEN_NUM_LOW_BITS;
num_bits = LZMA_LEN_NUM_MID_BITS;
} else {
rc_update_bit_1(rc, prob_len);
prob_len = prob + LZMA_LEN_HIGH;
offset = ((1 << LZMA_LEN_NUM_LOW_BITS)
- + (1 << LZMA_LEN_NUM_MID_BITS));
+ + (1 << LZMA_LEN_NUM_MID_BITS));
num_bits = LZMA_LEN_NUM_HIGH_BITS;
}
}
@@ -432,12 +446,10 @@ unpack_lzma_stream(int src_fd, int dst_fd)
int pos_slot;
state += LZMA_NUM_LIT_STATES;
- prob =
- p + LZMA_POS_SLOT +
- ((len <
- LZMA_NUM_LEN_TO_POS_STATES ? len :
- LZMA_NUM_LEN_TO_POS_STATES - 1)
- << LZMA_NUM_POS_SLOT_BITS);
+ prob = p + LZMA_POS_SLOT +
+ ((len < LZMA_NUM_LEN_TO_POS_STATES ? len :
+ LZMA_NUM_LEN_TO_POS_STATES - 1)
+ << LZMA_NUM_POS_SLOT_BITS);
rc_bit_tree_decode(rc, prob, LZMA_NUM_POS_SLOT_BITS,
&pos_slot);
if (pos_slot >= LZMA_START_POS_MODEL_INDEX) {
@@ -468,12 +480,13 @@ unpack_lzma_stream(int src_fd, int dst_fd)
}
len += LZMA_MATCH_MIN_LEN;
-
+ SKIP_FEATURE_LZMA_FAST(string:)
do {
pos = buffer_pos - rep0;
while (pos >= header.dict_size)
pos += header.dict_size;
previous_byte = buffer[pos];
+ SKIP_FEATURE_LZMA_FAST(one_byte:)
buffer[buffer_pos++] = previous_byte;
if (buffer_pos == header.dict_size) {
buffer_pos = 0;
@@ -487,7 +500,6 @@ unpack_lzma_stream(int src_fd, int dst_fd)
}
}
-
if (full_write(dst_fd, buffer, buffer_pos) != buffer_pos) {
bad:
rc_free(rc);