diff options
-rw-r--r-- | archival/libunarchive/decompress_unlzma.c | 170 |
1 files changed, 90 insertions, 80 deletions
diff --git a/archival/libunarchive/decompress_unlzma.c b/archival/libunarchive/decompress_unlzma.c index a690280..c1b0a31 100644 --- a/archival/libunarchive/decompress_unlzma.c +++ b/archival/libunarchive/decompress_unlzma.c @@ -22,7 +22,7 @@ typedef struct { int fd; uint8_t *ptr; - uint8_t *buffer; +// uint8_t *buffer; uint8_t *buffer_end; int buffer_size; uint32_t code; @@ -30,6 +30,8 @@ typedef struct { uint32_t bound; } rc_t; +//#define RC_BUFFER ((uint8_t*)(void*)(rc+1)) +#define RC_BUFFER ((uint8_t*)(rc+1)) #define RC_TOP_BITS 24 #define RC_MOVE_BITS 5 @@ -39,22 +41,24 @@ typedef struct { /* Called twice: once at startup and once in rc_normalize() */ static void rc_read(rc_t * rc) { - rc->buffer_size = read(rc->fd, rc->buffer, rc->buffer_size); + rc->buffer_size = read(rc->fd, RC_BUFFER, rc->buffer_size); if (rc->buffer_size <= 0) bb_error_msg_and_die("unexpected EOF"); - rc->ptr = rc->buffer; - rc->buffer_end = rc->buffer + rc->buffer_size; + rc->ptr = RC_BUFFER; + rc->buffer_end = RC_BUFFER + rc->buffer_size; } /* Called once */ -static void rc_init(rc_t * rc, int fd, int buffer_size) +static rc_t* rc_init(int fd, int buffer_size) { int i; + rc_t* rc; + + rc = xmalloc(sizeof(rc_t) + buffer_size); rc->fd = fd; - rc->buffer = xmalloc(buffer_size); rc->buffer_size = buffer_size; - rc->buffer_end = rc->buffer + rc->buffer_size; + rc->buffer_end = RC_BUFFER + rc->buffer_size; rc->ptr = rc->buffer_end; rc->code = 0; @@ -64,13 +68,14 @@ static void rc_init(rc_t * rc, int fd, int buffer_size) rc_read(rc); rc->code = (rc->code << 8) | *rc->ptr++; } + return rc; } -/* Called once. TODO: bb_maybe_free() */ +/* Called once */ static ATTRIBUTE_ALWAYS_INLINE void rc_free(rc_t * rc) { if (ENABLE_FEATURE_CLEAN_UP) - free(rc->buffer); + free(rc); } /* Called twice, but one callsite is in speed_inline'd rc_is_bit_0_helper() */ @@ -163,53 +168,58 @@ typedef struct { } __attribute__ ((packed)) lzma_header_t; -#define LZMA_BASE_SIZE 1846 -#define LZMA_LIT_SIZE 768 +/* #defines will make compiler to compute/optimize each one with each usage. + * Have heart and use enum instead. */ +enum { + LZMA_BASE_SIZE = 1846, + LZMA_LIT_SIZE = 768, + + LZMA_NUM_POS_BITS_MAX = 4, -#define LZMA_NUM_POS_BITS_MAX 4 + LZMA_LEN_NUM_LOW_BITS = 3, + LZMA_LEN_NUM_MID_BITS = 3, + LZMA_LEN_NUM_HIGH_BITS = 8, -#define LZMA_LEN_NUM_LOW_BITS 3 -#define LZMA_LEN_NUM_MID_BITS 3 -#define LZMA_LEN_NUM_HIGH_BITS 8 + LZMA_LEN_CHOICE = 0, + LZMA_LEN_CHOICE_2 = (LZMA_LEN_CHOICE + 1), + LZMA_LEN_LOW = (LZMA_LEN_CHOICE_2 + 1), + LZMA_LEN_MID = (LZMA_LEN_LOW \ + + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS))), + LZMA_LEN_HIGH = (LZMA_LEN_MID \ + + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS))), + LZMA_NUM_LEN_PROBS = (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS)), -#define LZMA_LEN_CHOICE 0 -#define LZMA_LEN_CHOICE_2 (LZMA_LEN_CHOICE + 1) -#define LZMA_LEN_LOW (LZMA_LEN_CHOICE_2 + 1) -#define LZMA_LEN_MID (LZMA_LEN_LOW \ - + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS))) -#define LZMA_LEN_HIGH (LZMA_LEN_MID \ - +(1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS))) -#define LZMA_NUM_LEN_PROBS (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS)) + LZMA_NUM_STATES = 12, + LZMA_NUM_LIT_STATES = 7, -#define LZMA_NUM_STATES 12 -#define LZMA_NUM_LIT_STATES 7 + LZMA_START_POS_MODEL_INDEX = 4, + LZMA_END_POS_MODEL_INDEX = 14, + LZMA_NUM_FULL_DISTANCES = (1 << (LZMA_END_POS_MODEL_INDEX >> 1)), -#define LZMA_START_POS_MODEL_INDEX 4 -#define LZMA_END_POS_MODEL_INDEX 14 -#define LZMA_NUM_FULL_DISTANCES (1 << (LZMA_END_POS_MODEL_INDEX >> 1)) + LZMA_NUM_POS_SLOT_BITS = 6, + LZMA_NUM_LEN_TO_POS_STATES = 4, -#define LZMA_NUM_POS_SLOT_BITS 6 -#define LZMA_NUM_LEN_TO_POS_STATES 4 + LZMA_NUM_ALIGN_BITS = 4, -#define LZMA_NUM_ALIGN_BITS 4 + LZMA_MATCH_MIN_LEN = 2, -#define LZMA_MATCH_MIN_LEN 2 + LZMA_IS_MATCH = 0, + LZMA_IS_REP = (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)), + LZMA_IS_REP_G0 = (LZMA_IS_REP + LZMA_NUM_STATES), + LZMA_IS_REP_G1 = (LZMA_IS_REP_G0 + LZMA_NUM_STATES), + LZMA_IS_REP_G2 = (LZMA_IS_REP_G1 + LZMA_NUM_STATES), + LZMA_IS_REP_0_LONG = (LZMA_IS_REP_G2 + LZMA_NUM_STATES), + LZMA_POS_SLOT = (LZMA_IS_REP_0_LONG \ + + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)), + LZMA_SPEC_POS = (LZMA_POS_SLOT \ + + (LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS)), + LZMA_ALIGN = (LZMA_SPEC_POS \ + + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX), + LZMA_LEN_CODER = (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS)), + LZMA_REP_LEN_CODER = (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS), + LZMA_LITERAL = (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS), +}; -#define LZMA_IS_MATCH 0 -#define LZMA_IS_REP (LZMA_IS_MATCH + (LZMA_NUM_STATES <<LZMA_NUM_POS_BITS_MAX)) -#define LZMA_IS_REP_G0 (LZMA_IS_REP + LZMA_NUM_STATES) -#define LZMA_IS_REP_G1 (LZMA_IS_REP_G0 + LZMA_NUM_STATES) -#define LZMA_IS_REP_G2 (LZMA_IS_REP_G1 + LZMA_NUM_STATES) -#define LZMA_IS_REP_0_LONG (LZMA_IS_REP_G2 + LZMA_NUM_STATES) -#define LZMA_POS_SLOT (LZMA_IS_REP_0_LONG \ - + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)) -#define LZMA_SPEC_POS (LZMA_POS_SLOT \ - +(LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS)) -#define LZMA_ALIGN (LZMA_SPEC_POS \ - + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX) -#define LZMA_LEN_CODER (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS)) -#define LZMA_REP_LEN_CODER (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS) -#define LZMA_LITERAL (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS) USE_DESKTOP(long long) int unlzma(int src_fd, int dst_fd) @@ -225,7 +235,7 @@ unlzma(int src_fd, int dst_fd) uint16_t *prob_lit; int num_bits; int num_probs; - rc_t rc; + rc_t *rc; int i, mi; uint8_t *buffer; uint8_t previous_byte = 0; @@ -260,16 +270,16 @@ unlzma(int src_fd, int dst_fd) for (i = 0; i < num_probs; i++) p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; - rc_init(&rc, src_fd, 0x10000); + rc = rc_init(src_fd, 0x10000); 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; - if (rc_is_bit_0(&rc, prob)) { + if (rc_is_bit_0(rc, prob)) { mi = 1; - rc_update_bit_0(&rc, prob); + 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))))); @@ -287,7 +297,7 @@ unlzma(int src_fd, int dst_fd) match_byte <<= 1; bit = match_byte & 0x100; prob_lit = prob + 0x100 + bit + mi; - if (rc_get_bit(&rc, prob_lit, &mi)) { + if (rc_get_bit(rc, prob_lit, &mi)) { if (!bit) break; } else { @@ -298,7 +308,7 @@ unlzma(int src_fd, int dst_fd) } while (mi < 0x100) { prob_lit = prob + mi; - rc_get_bit(&rc, prob_lit, &mi); + rc_get_bit(rc, prob_lit, &mi); } previous_byte = (uint8_t) mi; @@ -320,24 +330,24 @@ unlzma(int src_fd, int dst_fd) int offset; uint16_t *prob_len; - rc_update_bit_1(&rc, prob); + rc_update_bit_1(rc, prob); prob = p + LZMA_IS_REP + state; - if (rc_is_bit_0(&rc, prob)) { - rc_update_bit_0(&rc, prob); + if (rc_is_bit_0(rc, prob)) { + rc_update_bit_0(rc, prob); rep3 = rep2; rep2 = rep1; rep1 = rep0; state = state < LZMA_NUM_LIT_STATES ? 0 : 3; prob = p + LZMA_LEN_CODER; } else { - rc_update_bit_1(&rc, prob); + rc_update_bit_1(rc, prob); prob = p + LZMA_IS_REP_G0 + state; - if (rc_is_bit_0(&rc, prob)) { - rc_update_bit_0(&rc, prob); + 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); - if (rc_is_bit_0(&rc, prob)) { - rc_update_bit_0(&rc, prob); + if (rc_is_bit_0(rc, prob)) { + rc_update_bit_0(rc, prob); state = state < LZMA_NUM_LIT_STATES ? 9 : 11; pos = buffer_pos - rep0; @@ -354,24 +364,24 @@ unlzma(int src_fd, int dst_fd) } continue; } else { - rc_update_bit_1(&rc, prob); + rc_update_bit_1(rc, prob); } } else { uint32_t distance; - rc_update_bit_1(&rc, prob); + rc_update_bit_1(rc, prob); prob = p + LZMA_IS_REP_G1 + state; - if (rc_is_bit_0(&rc, prob)) { - rc_update_bit_0(&rc, prob); + if (rc_is_bit_0(rc, prob)) { + rc_update_bit_0(rc, prob); distance = rep1; } else { - rc_update_bit_1(&rc, prob); + rc_update_bit_1(rc, prob); prob = p + LZMA_IS_REP_G2 + state; - if (rc_is_bit_0(&rc, prob)) { - rc_update_bit_0(&rc, prob); + if (rc_is_bit_0(rc, prob)) { + rc_update_bit_0(rc, prob); distance = rep2; } else { - rc_update_bit_1(&rc, prob); + rc_update_bit_1(rc, prob); distance = rep3; rep3 = rep2; } @@ -385,30 +395,30 @@ unlzma(int src_fd, int dst_fd) } prob_len = prob + LZMA_LEN_CHOICE; - if (rc_is_bit_0(&rc, prob_len)) { - rc_update_bit_0(&rc, prob_len); + 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)); offset = 0; num_bits = LZMA_LEN_NUM_LOW_BITS; } else { - rc_update_bit_1(&rc, prob_len); + rc_update_bit_1(rc, prob_len); prob_len = prob + LZMA_LEN_CHOICE_2; - if (rc_is_bit_0(&rc, prob_len)) { - rc_update_bit_0(&rc, prob_len); + 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)); offset = 1 << LZMA_LEN_NUM_LOW_BITS; num_bits = LZMA_LEN_NUM_MID_BITS; } else { - rc_update_bit_1(&rc, prob_len); + 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)); num_bits = LZMA_LEN_NUM_HIGH_BITS; } } - rc_bit_tree_decode(&rc, prob_len, num_bits, &len); + rc_bit_tree_decode(rc, prob_len, num_bits, &len); len += offset; if (state < 4) { @@ -421,7 +431,7 @@ unlzma(int src_fd, int dst_fd) 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, + rc_bit_tree_decode(rc, prob, LZMA_NUM_POS_SLOT_BITS, &pos_slot); if (pos_slot >= LZMA_START_POS_MODEL_INDEX) { num_bits = (pos_slot >> 1) - 1; @@ -432,7 +442,7 @@ unlzma(int src_fd, int dst_fd) } else { num_bits -= LZMA_NUM_ALIGN_BITS; while (num_bits--) - rep0 = (rep0 << 1) | rc_direct_bit(&rc); + rep0 = (rep0 << 1) | rc_direct_bit(rc); prob = p + LZMA_ALIGN; rep0 <<= LZMA_NUM_ALIGN_BITS; num_bits = LZMA_NUM_ALIGN_BITS; @@ -440,7 +450,7 @@ unlzma(int src_fd, int dst_fd) i = 1; mi = 1; while (num_bits--) { - if (rc_get_bit(&rc, prob + mi, &mi)) + if (rc_get_bit(rc, prob + mi, &mi)) rep0 |= i; i <<= 1; } @@ -473,6 +483,6 @@ unlzma(int src_fd, int dst_fd) // FIXME: error check write(dst_fd, buffer, buffer_pos); USE_DESKTOP(total_written += buffer_pos;) - rc_free(&rc); + rc_free(rc); return USE_DESKTOP(total_written) + 0; } |