diff options
Diffstat (limited to 'libraries/xz-embedded/src/xz_dec_lzma2.c')
-rw-r--r-- | libraries/xz-embedded/src/xz_dec_lzma2.c | 1810 |
1 files changed, 905 insertions, 905 deletions
diff --git a/libraries/xz-embedded/src/xz_dec_lzma2.c b/libraries/xz-embedded/src/xz_dec_lzma2.c index 3d7b9a2e..365ace2b 100644 --- a/libraries/xz-embedded/src/xz_dec_lzma2.c +++ b/libraries/xz-embedded/src/xz_dec_lzma2.c @@ -43,244 +43,244 @@ */ struct dictionary { - /* Beginning of the history buffer */ - uint8_t *buf; - - /* Old position in buf (before decoding more data) */ - size_t start; - - /* Position in buf */ - size_t pos; - - /* - * How full dictionary is. This is used to detect corrupt input that - * would read beyond the beginning of the uncompressed stream. - */ - size_t full; - - /* Write limit; we don't write to buf[limit] or later bytes. */ - size_t limit; - - /* - * End of the dictionary buffer. In multi-call mode, this is - * the same as the dictionary size. In single-call mode, this - * indicates the size of the output buffer. - */ - size_t end; - - /* - * Size of the dictionary as specified in Block Header. This is used - * together with "full" to detect corrupt input that would make us - * read beyond the beginning of the uncompressed stream. - */ - uint32_t size; - - /* - * Maximum allowed dictionary size in multi-call mode. - * This is ignored in single-call mode. - */ - uint32_t size_max; - - /* - * Amount of memory currently allocated for the dictionary. - * This is used only with XZ_DYNALLOC. (With XZ_PREALLOC, - * size_max is always the same as the allocated size.) - */ - uint32_t allocated; - - /* Operation mode */ - enum xz_mode mode; + /* Beginning of the history buffer */ + uint8_t *buf; + + /* Old position in buf (before decoding more data) */ + size_t start; + + /* Position in buf */ + size_t pos; + + /* + * How full dictionary is. This is used to detect corrupt input that + * would read beyond the beginning of the uncompressed stream. + */ + size_t full; + + /* Write limit; we don't write to buf[limit] or later bytes. */ + size_t limit; + + /* + * End of the dictionary buffer. In multi-call mode, this is + * the same as the dictionary size. In single-call mode, this + * indicates the size of the output buffer. + */ + size_t end; + + /* + * Size of the dictionary as specified in Block Header. This is used + * together with "full" to detect corrupt input that would make us + * read beyond the beginning of the uncompressed stream. + */ + uint32_t size; + + /* + * Maximum allowed dictionary size in multi-call mode. + * This is ignored in single-call mode. + */ + uint32_t size_max; + + /* + * Amount of memory currently allocated for the dictionary. + * This is used only with XZ_DYNALLOC. (With XZ_PREALLOC, + * size_max is always the same as the allocated size.) + */ + uint32_t allocated; + + /* Operation mode */ + enum xz_mode mode; }; /* Range decoder */ struct rc_dec { - uint32_t range; - uint32_t code; - - /* - * Number of initializing bytes remaining to be read - * by rc_read_init(). - */ - uint32_t init_bytes_left; - - /* - * Buffer from which we read our input. It can be either - * temp.buf or the caller-provided input buffer. - */ - const uint8_t *in; - size_t in_pos; - size_t in_limit; + uint32_t range; + uint32_t code; + + /* + * Number of initializing bytes remaining to be read + * by rc_read_init(). + */ + uint32_t init_bytes_left; + + /* + * Buffer from which we read our input. It can be either + * temp.buf or the caller-provided input buffer. + */ + const uint8_t *in; + size_t in_pos; + size_t in_limit; }; /* Probabilities for a length decoder. */ struct lzma_len_dec { - /* Probability of match length being at least 10 */ - uint16_t choice; + /* Probability of match length being at least 10 */ + uint16_t choice; - /* Probability of match length being at least 18 */ - uint16_t choice2; + /* Probability of match length being at least 18 */ + uint16_t choice2; - /* Probabilities for match lengths 2-9 */ - uint16_t low[POS_STATES_MAX][LEN_LOW_SYMBOLS]; + /* Probabilities for match lengths 2-9 */ + uint16_t low[POS_STATES_MAX][LEN_LOW_SYMBOLS]; - /* Probabilities for match lengths 10-17 */ - uint16_t mid[POS_STATES_MAX][LEN_MID_SYMBOLS]; + /* Probabilities for match lengths 10-17 */ + uint16_t mid[POS_STATES_MAX][LEN_MID_SYMBOLS]; - /* Probabilities for match lengths 18-273 */ - uint16_t high[LEN_HIGH_SYMBOLS]; + /* Probabilities for match lengths 18-273 */ + uint16_t high[LEN_HIGH_SYMBOLS]; }; struct lzma_dec { - /* Distances of latest four matches */ - uint32_t rep0; - uint32_t rep1; - uint32_t rep2; - uint32_t rep3; - - /* Types of the most recently seen LZMA symbols */ - enum lzma_state state; - - /* - * Length of a match. This is updated so that dict_repeat can - * be called again to finish repeating the whole match. - */ - uint32_t len; - - /* - * LZMA properties or related bit masks (number of literal - * context bits, a mask dervied from the number of literal - * position bits, and a mask dervied from the number - * position bits) - */ - uint32_t lc; - uint32_t literal_pos_mask; /* (1 << lp) - 1 */ - uint32_t pos_mask; /* (1 << pb) - 1 */ - - /* If 1, it's a match. Otherwise it's a single 8-bit literal. */ - uint16_t is_match[STATES][POS_STATES_MAX]; - - /* If 1, it's a repeated match. The distance is one of rep0 .. rep3. */ - uint16_t is_rep[STATES]; - - /* - * If 0, distance of a repeated match is rep0. - * Otherwise check is_rep1. - */ - uint16_t is_rep0[STATES]; - - /* - * If 0, distance of a repeated match is rep1. - * Otherwise check is_rep2. - */ - uint16_t is_rep1[STATES]; - - /* If 0, distance of a repeated match is rep2. Otherwise it is rep3. */ - uint16_t is_rep2[STATES]; - - /* - * If 1, the repeated match has length of one byte. Otherwise - * the length is decoded from rep_len_decoder. - */ - uint16_t is_rep0_long[STATES][POS_STATES_MAX]; - - /* - * Probability tree for the highest two bits of the match - * distance. There is a separate probability tree for match - * lengths of 2 (i.e. MATCH_LEN_MIN), 3, 4, and [5, 273]. - */ - uint16_t dist_slot[DIST_STATES][DIST_SLOTS]; - - /* - * Probility trees for additional bits for match distance - * when the distance is in the range [4, 127]. - */ - uint16_t dist_special[FULL_DISTANCES - DIST_MODEL_END]; - - /* - * Probability tree for the lowest four bits of a match - * distance that is equal to or greater than 128. - */ - uint16_t dist_align[ALIGN_SIZE]; - - /* Length of a normal match */ - struct lzma_len_dec match_len_dec; - - /* Length of a repeated match */ - struct lzma_len_dec rep_len_dec; - - /* Probabilities of literals */ - uint16_t literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE]; + /* Distances of latest four matches */ + uint32_t rep0; + uint32_t rep1; + uint32_t rep2; + uint32_t rep3; + + /* Types of the most recently seen LZMA symbols */ + enum lzma_state state; + + /* + * Length of a match. This is updated so that dict_repeat can + * be called again to finish repeating the whole match. + */ + uint32_t len; + + /* + * LZMA properties or related bit masks (number of literal + * context bits, a mask dervied from the number of literal + * position bits, and a mask dervied from the number + * position bits) + */ + uint32_t lc; + uint32_t literal_pos_mask; /* (1 << lp) - 1 */ + uint32_t pos_mask; /* (1 << pb) - 1 */ + + /* If 1, it's a match. Otherwise it's a single 8-bit literal. */ + uint16_t is_match[STATES][POS_STATES_MAX]; + + /* If 1, it's a repeated match. The distance is one of rep0 .. rep3. */ + uint16_t is_rep[STATES]; + + /* + * If 0, distance of a repeated match is rep0. + * Otherwise check is_rep1. + */ + uint16_t is_rep0[STATES]; + + /* + * If 0, distance of a repeated match is rep1. + * Otherwise check is_rep2. + */ + uint16_t is_rep1[STATES]; + + /* If 0, distance of a repeated match is rep2. Otherwise it is rep3. */ + uint16_t is_rep2[STATES]; + + /* + * If 1, the repeated match has length of one byte. Otherwise + * the length is decoded from rep_len_decoder. + */ + uint16_t is_rep0_long[STATES][POS_STATES_MAX]; + + /* + * Probability tree for the highest two bits of the match + * distance. There is a separate probability tree for match + * lengths of 2 (i.e. MATCH_LEN_MIN), 3, 4, and [5, 273]. + */ + uint16_t dist_slot[DIST_STATES][DIST_SLOTS]; + + /* + * Probility trees for additional bits for match distance + * when the distance is in the range [4, 127]. + */ + uint16_t dist_special[FULL_DISTANCES - DIST_MODEL_END]; + + /* + * Probability tree for the lowest four bits of a match + * distance that is equal to or greater than 128. + */ + uint16_t dist_align[ALIGN_SIZE]; + + /* Length of a normal match */ + struct lzma_len_dec match_len_dec; + + /* Length of a repeated match */ + struct lzma_len_dec rep_len_dec; + + /* Probabilities of literals */ + uint16_t literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE]; }; struct lzma2_dec { - /* Position in xz_dec_lzma2_run(). */ - enum lzma2_seq - { - SEQ_CONTROL, - SEQ_UNCOMPRESSED_1, - SEQ_UNCOMPRESSED_2, - SEQ_COMPRESSED_0, - SEQ_COMPRESSED_1, - SEQ_PROPERTIES, - SEQ_LZMA_PREPARE, - SEQ_LZMA_RUN, - SEQ_COPY - } sequence; - - /* Next position after decoding the compressed size of the chunk. */ - enum lzma2_seq next_sequence; - - /* Uncompressed size of LZMA chunk (2 MiB at maximum) */ - uint32_t uncompressed; - - /* - * Compressed size of LZMA chunk or compressed/uncompressed - * size of uncompressed chunk (64 KiB at maximum) - */ - uint32_t compressed; - - /* - * True if dictionary reset is needed. This is false before - * the first chunk (LZMA or uncompressed). - */ - bool need_dict_reset; - - /* - * True if new LZMA properties are needed. This is false - * before the first LZMA chunk. - */ - bool need_props; + /* Position in xz_dec_lzma2_run(). */ + enum lzma2_seq + { + SEQ_CONTROL, + SEQ_UNCOMPRESSED_1, + SEQ_UNCOMPRESSED_2, + SEQ_COMPRESSED_0, + SEQ_COMPRESSED_1, + SEQ_PROPERTIES, + SEQ_LZMA_PREPARE, + SEQ_LZMA_RUN, + SEQ_COPY + } sequence; + + /* Next position after decoding the compressed size of the chunk. */ + enum lzma2_seq next_sequence; + + /* Uncompressed size of LZMA chunk (2 MiB at maximum) */ + uint32_t uncompressed; + + /* + * Compressed size of LZMA chunk or compressed/uncompressed + * size of uncompressed chunk (64 KiB at maximum) + */ + uint32_t compressed; + + /* + * True if dictionary reset is needed. This is false before + * the first chunk (LZMA or uncompressed). + */ + bool need_dict_reset; + + /* + * True if new LZMA properties are needed. This is false + * before the first LZMA chunk. + */ + bool need_props; }; struct xz_dec_lzma2 { - /* - * The order below is important on x86 to reduce code size and - * it shouldn't hurt on other platforms. Everything up to and - * including lzma.pos_mask are in the first 128 bytes on x86-32, - * which allows using smaller instructions to access those - * variables. On x86-64, fewer variables fit into the first 128 - * bytes, but this is still the best order without sacrificing - * the readability by splitting the structures. - */ - struct rc_dec rc; - struct dictionary dict; - struct lzma2_dec lzma2; - struct lzma_dec lzma; - - /* - * Temporary buffer which holds small number of input bytes between - * decoder calls. See lzma2_lzma() for details. - */ - struct - { - uint32_t size; - uint8_t buf[3 * LZMA_IN_REQUIRED]; - } temp; + /* + * The order below is important on x86 to reduce code size and + * it shouldn't hurt on other platforms. Everything up to and + * including lzma.pos_mask are in the first 128 bytes on x86-32, + * which allows using smaller instructions to access those + * variables. On x86-64, fewer variables fit into the first 128 + * bytes, but this is still the best order without sacrificing + * the readability by splitting the structures. + */ + struct rc_dec rc; + struct dictionary dict; + struct lzma2_dec lzma2; + struct lzma_dec lzma; + + /* + * Temporary buffer which holds small number of input bytes between + * decoder calls. See lzma2_lzma() for details. + */ + struct + { + uint32_t size; + uint8_t buf[3 * LZMA_IN_REQUIRED]; + } temp; }; /************** @@ -293,31 +293,31 @@ struct xz_dec_lzma2 */ static void dict_reset(struct dictionary *dict, struct xz_buf *b) { - if (DEC_IS_SINGLE(dict->mode)) - { - dict->buf = b->out + b->out_pos; - dict->end = b->out_size - b->out_pos; - } - - dict->start = 0; - dict->pos = 0; - dict->limit = 0; - dict->full = 0; + if (DEC_IS_SINGLE(dict->mode)) + { + dict->buf = b->out + b->out_pos; + dict->end = b->out_size - b->out_pos; + } + + dict->start = 0; + dict->pos = 0; + dict->limit = 0; + dict->full = 0; } /* Set dictionary write limit */ static void dict_limit(struct dictionary *dict, size_t out_max) { - if (dict->end - dict->pos <= out_max) - dict->limit = dict->end; - else - dict->limit = dict->pos + out_max; + if (dict->end - dict->pos <= out_max) + dict->limit = dict->end; + else + dict->limit = dict->pos + out_max; } /* Return true if at least one byte can be written into the dictionary. */ static inline bool dict_has_space(const struct dictionary *dict) { - return dict->pos < dict->limit; + return dict->pos < dict->limit; } /* @@ -328,12 +328,12 @@ static inline bool dict_has_space(const struct dictionary *dict) */ static inline uint32_t dict_get(const struct dictionary *dict, uint32_t dist) { - size_t offset = dict->pos - dist - 1; + size_t offset = dict->pos - dist - 1; - if (dist >= dict->pos) - offset += dict->end; + if (dist >= dict->pos) + offset += dict->end; - return dict->full > 0 ? dict->buf[offset] : 0; + return dict->full > 0 ? dict->buf[offset] : 0; } /* @@ -341,10 +341,10 @@ static inline uint32_t dict_get(const struct dictionary *dict, uint32_t dist) */ static inline void dict_put(struct dictionary *dict, uint8_t byte) { - dict->buf[dict->pos++] = byte; + dict->buf[dict->pos++] = byte; - if (dict->full < dict->pos) - dict->full = dict->pos; + if (dict->full < dict->pos) + dict->full = dict->pos; } /* @@ -354,66 +354,66 @@ static inline void dict_put(struct dictionary *dict, uint8_t byte) */ static bool dict_repeat(struct dictionary *dict, uint32_t *len, uint32_t dist) { - size_t back; - uint32_t left; + size_t back; + uint32_t left; - if (dist >= dict->full || dist >= dict->size) - return false; + if (dist >= dict->full || dist >= dict->size) + return false; - left = min_t(size_t, dict->limit - dict->pos, *len); - *len -= left; + left = min_t(size_t, dict->limit - dict->pos, *len); + *len -= left; - back = dict->pos - dist - 1; - if (dist >= dict->pos) - back += dict->end; + back = dict->pos - dist - 1; + if (dist >= dict->pos) + back += dict->end; - do - { - dict->buf[dict->pos++] = dict->buf[back++]; - if (back == dict->end) - back = 0; - } while (--left > 0); + do + { + dict->buf[dict->pos++] = dict->buf[back++]; + if (back == dict->end) + back = 0; + } while (--left > 0); - if (dict->full < dict->pos) - dict->full = dict->pos; + if (dict->full < dict->pos) + dict->full = dict->pos; - return true; + return true; } /* Copy uncompressed data as is from input to dictionary and output buffers. */ static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b, uint32_t *left) { - size_t copy_size; + size_t copy_size; - while (*left > 0 && b->in_pos < b->in_size && b->out_pos < b->out_size) - { - copy_size = min(b->in_size - b->in_pos, b->out_size - b->out_pos); - if (copy_size > dict->end - dict->pos) - copy_size = dict->end - dict->pos; - if (copy_size > *left) - copy_size = *left; + while (*left > 0 && b->in_pos < b->in_size && b->out_pos < b->out_size) + { + copy_size = min(b->in_size - b->in_pos, b->out_size - b->out_pos); + if (copy_size > dict->end - dict->pos) + copy_size = dict->end - dict->pos; + if (copy_size > *left) + copy_size = *left; - *left -= copy_size; + *left -= copy_size; - memcpy(dict->buf + dict->pos, b->in + b->in_pos, copy_size); - dict->pos += copy_size; + memcpy(dict->buf + dict->pos, b->in + b->in_pos, copy_size); + dict->pos += copy_size; - if (dict->full < dict->pos) - dict->full = dict->pos; + if (dict->full < dict->pos) + dict->full = dict->pos; - if (DEC_IS_MULTI(dict->mode)) - { - if (dict->pos == dict->end) - dict->pos = 0; + if (DEC_IS_MULTI(dict->mode)) + { + if (dict->pos == dict->end) + dict->pos = 0; - memcpy(b->out + b->out_pos, b->in + b->in_pos, copy_size); - } + memcpy(b->out + b->out_pos, b->in + b->in_pos, copy_size); + } - dict->start = dict->pos; + dict->start = dict->pos; - b->out_pos += copy_size; - b->in_pos += copy_size; - } + b->out_pos += copy_size; + b->in_pos += copy_size; + } } /* @@ -423,19 +423,19 @@ static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b, uint32_ */ static uint32_t dict_flush(struct dictionary *dict, struct xz_buf *b) { - size_t copy_size = dict->pos - dict->start; + size_t copy_size = dict->pos - dict->start; - if (DEC_IS_MULTI(dict->mode)) - { - if (dict->pos == dict->end) - dict->pos = 0; + if (DEC_IS_MULTI(dict->mode)) + { + if (dict->pos == dict->end) + dict->pos = 0; - memcpy(b->out + b->out_pos, dict->buf + dict->start, copy_size); - } + memcpy(b->out + b->out_pos, dict->buf + dict->start, copy_size); + } - dict->start = dict->pos; - b->out_pos += copy_size; - return copy_size; + dict->start = dict->pos; + b->out_pos += copy_size; + return copy_size; } /***************** @@ -445,9 +445,9 @@ static uint32_t dict_flush(struct dictionary *dict, struct xz_buf *b) /* Reset the range decoder. */ static void rc_reset(struct rc_dec *rc) { - rc->range = (uint32_t) - 1; - rc->code = 0; - rc->init_bytes_left = RC_INIT_BYTES; + rc->range = (uint32_t) - 1; + rc->code = 0; + rc->init_bytes_left = RC_INIT_BYTES; } /* @@ -456,22 +456,22 @@ static void rc_reset(struct rc_dec *rc) */ static bool rc_read_init(struct rc_dec *rc, struct xz_buf *b) { - while (rc->init_bytes_left > 0) - { - if (b->in_pos == b->in_size) - return false; + while (rc->init_bytes_left > 0) + { + if (b->in_pos == b->in_size) + return false; - rc->code = (rc->code << 8) + b->in[b->in_pos++]; - --rc->init_bytes_left; - } + rc->code = (rc->code << 8) + b->in[b->in_pos++]; + --rc->init_bytes_left; + } - return true; + return true; } /* Return true if there may not be enough input for the next decoding loop. */ static inline bool rc_limit_exceeded(const struct rc_dec *rc) { - return rc->in_pos > rc->in_limit; + return rc->in_pos > rc->in_limit; } /* @@ -480,17 +480,17 @@ static inline bool rc_limit_exceeded(const struct rc_dec *rc) */ static inline bool rc_is_finished(const struct rc_dec *rc) { - return rc->code == 0; + return rc->code == 0; } /* Read the next input byte if needed. */ static __always_inline void rc_normalize(struct rc_dec *rc) { - if (rc->range < RC_TOP_VALUE) - { - rc->range <<= RC_SHIFT_BITS; - rc->code = (rc->code << RC_SHIFT_BITS) + rc->in[rc->in_pos++]; - } + if (rc->range < RC_TOP_VALUE) + { + rc->range <<= RC_SHIFT_BITS; + rc->code = (rc->code << RC_SHIFT_BITS) + rc->in[rc->in_pos++]; + } } /* @@ -506,79 +506,79 @@ static __always_inline void rc_normalize(struct rc_dec *rc) */ static __always_inline int rc_bit(struct rc_dec *rc, uint16_t *prob) { - uint32_t bound; - int bit; - - rc_normalize(rc); - bound = (rc->range >> RC_BIT_MODEL_TOTAL_BITS) * *prob; - if (rc->code < bound) - { - rc->range = bound; - *prob += (RC_BIT_MODEL_TOTAL - *prob) >> RC_MOVE_BITS; - bit = 0; - } - else - { - rc->range -= bound; - rc->code -= bound; - *prob -= *prob >> RC_MOVE_BITS; - bit = 1; - } - - return bit; + uint32_t bound; + int bit; + + rc_normalize(rc); + bound = (rc->range >> RC_BIT_MODEL_TOTAL_BITS) * *prob; + if (rc->code < bound) + { + rc->range = bound; + *prob += (RC_BIT_MODEL_TOTAL - *prob) >> RC_MOVE_BITS; + bit = 0; + } + else + { + rc->range -= bound; + rc->code -= bound; + *prob -= *prob >> RC_MOVE_BITS; + bit = 1; + } + + return bit; } /* Decode a bittree starting from the most significant bit. */ static __always_inline uint32_t rc_bittree(struct rc_dec *rc, uint16_t *probs, uint32_t limit) { - uint32_t symbol = 1; + uint32_t symbol = 1; - do - { - if (rc_bit(rc, &probs[symbol])) - symbol = (symbol << 1) + 1; - else - symbol <<= 1; - } while (symbol < limit); + do + { + if (rc_bit(rc, &probs[symbol])) + symbol = (symbol << 1) + 1; + else + symbol <<= 1; + } while (symbol < limit); - return symbol; + return symbol; } /* Decode a bittree starting from the least significant bit. */ static __always_inline void rc_bittree_reverse(struct rc_dec *rc, uint16_t *probs, - uint32_t *dest, uint32_t limit) + uint32_t *dest, uint32_t limit) { - uint32_t symbol = 1; - uint32_t i = 0; - - do - { - if (rc_bit(rc, &probs[symbol])) - { - symbol = (symbol << 1) + 1; - *dest += 1 << i; - } - else - { - symbol <<= 1; - } - } while (++i < limit); + uint32_t symbol = 1; + uint32_t i = 0; + + do + { + if (rc_bit(rc, &probs[symbol])) + { + symbol = (symbol << 1) + 1; + *dest += 1 << i; + } + else + { + symbol <<= 1; + } + } while (++i < limit); } /* Decode direct bits (fixed fifty-fifty probability) */ static inline void rc_direct(struct rc_dec *rc, uint32_t *dest, uint32_t limit) { - uint32_t mask; - - do - { - rc_normalize(rc); - rc->range >>= 1; - rc->code -= rc->range; - mask = (uint32_t)0 - (rc->code >> 31); - rc->code += rc->range & mask; - *dest = (*dest << 1) + (mask + 1); - } while (--limit > 0); + uint32_t mask; + + do + { + rc_normalize(rc); + rc->range >>= 1; + rc->code -= rc->range; + mask = (uint32_t)0 - (rc->code >> 31); + rc->code += rc->range & mask; + *dest = (*dest << 1) + (mask + 1); + } while (--limit > 0); } /******** @@ -588,128 +588,128 @@ static inline void rc_direct(struct rc_dec *rc, uint32_t *dest, uint32_t limit) /* Get pointer to literal coder probability array. */ static uint16_t *lzma_literal_probs(struct xz_dec_lzma2 *s) { - uint32_t prev_byte = dict_get(&s->dict, 0); - uint32_t low = prev_byte >> (8 - s->lzma.lc); - uint32_t high = (s->dict.pos & s->lzma.literal_pos_mask) << s->lzma.lc; - return s->lzma.literal[low + high]; + uint32_t prev_byte = dict_get(&s->dict, 0); + uint32_t low = prev_byte >> (8 - s->lzma.lc); + uint32_t high = (s->dict.pos & s->lzma.literal_pos_mask) << s->lzma.lc; + return s->lzma.literal[low + high]; } /* Decode a literal (one 8-bit byte) */ static void lzma_literal(struct xz_dec_lzma2 *s) { - uint16_t *probs; - uint32_t symbol; - uint32_t match_byte; - uint32_t match_bit; - uint32_t offset; - uint32_t i; - - probs = lzma_literal_probs(s); - - if (lzma_state_is_literal(s->lzma.state)) - { - symbol = rc_bittree(&s->rc, probs, 0x100); - } - else - { - symbol = 1; - match_byte = dict_get(&s->dict, s->lzma.rep0) << 1; - offset = 0x100; - - do - { - match_bit = match_byte & offset; - match_byte <<= 1; - i = offset + match_bit + symbol; - - if (rc_bit(&s->rc, &probs[i])) - { - symbol = (symbol << 1) + 1; - offset &= match_bit; - } - else - { - symbol <<= 1; - offset &= ~match_bit; - } - } while (symbol < 0x100); - } - - dict_put(&s->dict, (uint8_t)symbol); - lzma_state_literal(&s->lzma.state); + uint16_t *probs; + uint32_t symbol; + uint32_t match_byte; + uint32_t match_bit; + uint32_t offset; + uint32_t i; + + probs = lzma_literal_probs(s); + + if (lzma_state_is_literal(s->lzma.state)) + { + symbol = rc_bittree(&s->rc, probs, 0x100); + } + else + { + symbol = 1; + match_byte = dict_get(&s->dict, s->lzma.rep0) << 1; + offset = 0x100; + + do + { + match_bit = match_byte & offset; + match_byte <<= 1; + i = offset + match_bit + symbol; + + if (rc_bit(&s->rc, &probs[i])) + { + symbol = (symbol << 1) + 1; + offset &= match_bit; + } + else + { + symbol <<= 1; + offset &= ~match_bit; + } + } while (symbol < 0x100); + } + + dict_put(&s->dict, (uint8_t)symbol); + lzma_state_literal(&s->lzma.state); } /* Decode the length of the match into s->lzma.len. */ static void lzma_len(struct xz_dec_lzma2 *s, struct lzma_len_dec *l, uint32_t pos_state) { - uint16_t *probs; - uint32_t limit; - - if (!rc_bit(&s->rc, &l->choice)) - { - probs = l->low[pos_state]; - limit = LEN_LOW_SYMBOLS; - s->lzma.len = MATCH_LEN_MIN; - } - else - { - if (!rc_bit(&s->rc, &l->choice2)) - { - probs = l->mid[pos_state]; - limit = LEN_MID_SYMBOLS; - s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS; - } - else - { - probs = l->high; - limit = LEN_HIGH_SYMBOLS; - s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS; - } - } - - s->lzma.len += rc_bittree(&s->rc, probs, limit) - limit; + uint16_t *probs; + uint32_t limit; + + if (!rc_bit(&s->rc, &l->choice)) + { + probs = l->low[pos_state]; + limit = LEN_LOW_SYMBOLS; + s->lzma.len = MATCH_LEN_MIN; + } + else + { + if (!rc_bit(&s->rc, &l->choice2)) + { + probs = l->mid[pos_state]; + limit = LEN_MID_SYMBOLS; + s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS; + } + else + { + probs = l->high; + limit = LEN_HIGH_SYMBOLS; + s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS; + } + } + + s->lzma.len += rc_bittree(&s->rc, probs, limit) - limit; } /* Decode a match. The distance will be stored in s->lzma.rep0. */ static void lzma_match(struct xz_dec_lzma2 *s, uint32_t pos_state) { - uint16_t *probs; - uint32_t dist_slot; - uint32_t limit; - - lzma_state_match(&s->lzma.state); - - s->lzma.rep3 = s->lzma.rep2; - s->lzma.rep2 = s->lzma.rep1; - s->lzma.rep1 = s->lzma.rep0; - - lzma_len(s, &s->lzma.match_len_dec, pos_state); - - probs = s->lzma.dist_slot[lzma_get_dist_state(s->lzma.len)]; - dist_slot = rc_bittree(&s->rc, probs, DIST_SLOTS) - DIST_SLOTS; - - if (dist_slot < DIST_MODEL_START) - { - s->lzma.rep0 = dist_slot; - } - else - { - limit = (dist_slot >> 1) - 1; - s->lzma.rep0 = 2 + (dist_slot & 1); - - if (dist_slot < DIST_MODEL_END) - { - s->lzma.rep0 <<= limit; - probs = s->lzma.dist_special + s->lzma.rep0 - dist_slot - 1; - rc_bittree_reverse(&s->rc, probs, &s->lzma.rep0, limit); - } - else - { - rc_direct(&s->rc, &s->lzma.rep0, limit - ALIGN_BITS); - s->lzma.rep0 <<= ALIGN_BITS; - rc_bittree_reverse(&s->rc, s->lzma.dist_align, &s->lzma.rep0, ALIGN_BITS); - } - } + uint16_t *probs; + uint32_t dist_slot; + uint32_t limit; + + lzma_state_match(&s->lzma.state); + + s->lzma.rep3 = s->lzma.rep2; + s->lzma.rep2 = s->lzma.rep1; + s->lzma.rep1 = s->lzma.rep0; + + lzma_len(s, &s->lzma.match_len_dec, pos_state); + + probs = s->lzma.dist_slot[lzma_get_dist_state(s->lzma.len)]; + dist_slot = rc_bittree(&s->rc, probs, DIST_SLOTS) - DIST_SLOTS; + + if (dist_slot < DIST_MODEL_START) + { + s->lzma.rep0 = dist_slot; + } + else + { + limit = (dist_slot >> 1) - 1; + s->lzma.rep0 = 2 + (dist_slot & 1); + + if (dist_slot < DIST_MODEL_END) + { + s->lzma.rep0 <<= limit; + probs = s->lzma.dist_special + s->lzma.rep0 - dist_slot - 1; + rc_bittree_reverse(&s->rc, probs, &s->lzma.rep0, limit); + } + else + { + rc_direct(&s->rc, &s->lzma.rep0, limit - ALIGN_BITS); + s->lzma.rep0 <<= ALIGN_BITS; + rc_bittree_reverse(&s->rc, s->lzma.dist_align, &s->lzma.rep0, ALIGN_BITS); + } + } } /* @@ -718,89 +718,89 @@ static void lzma_match(struct xz_dec_lzma2 *s, uint32_t pos_state) */ static void lzma_rep_match(struct xz_dec_lzma2 *s, uint32_t pos_state) { - uint32_t tmp; - - if (!rc_bit(&s->rc, &s->lzma.is_rep0[s->lzma.state])) - { - if (!rc_bit(&s->rc, &s->lzma.is_rep0_long[s->lzma.state][pos_state])) - { - lzma_state_short_rep(&s->lzma.state); - s->lzma.len = 1; - return; - } - } - else - { - if (!rc_bit(&s->rc, &s->lzma.is_rep1[s->lzma.state])) - { - tmp = s->lzma.rep1; - } - else - { - if (!rc_bit(&s->rc, &s->lzma.is_rep2[s->lzma.state])) - { - tmp = s->lzma.rep2; - } - else - { - tmp = s->lzma.rep3; - s->lzma.rep3 = s->lzma.rep2; - } - - s->lzma.rep2 = s->lzma.rep1; - } - - s->lzma.rep1 = s->lzma.rep0; - s->lzma.rep0 = tmp; - } - - lzma_state_long_rep(&s->lzma.state); - lzma_len(s, &s->lzma.rep_len_dec, pos_state); + uint32_t tmp; + + if (!rc_bit(&s->rc, &s->lzma.is_rep0[s->lzma.state])) + { + if (!rc_bit(&s->rc, &s->lzma.is_rep0_long[s->lzma.state][pos_state])) + { + lzma_state_short_rep(&s->lzma.state); + s->lzma.len = 1; + return; + } + } + else + { + if (!rc_bit(&s->rc, &s->lzma.is_rep1[s->lzma.state])) + { + tmp = s->lzma.rep1; + } + else + { + if (!rc_bit(&s->rc, &s->lzma.is_rep2[s->lzma.state])) + { + tmp = s->lzma.rep2; + } + else + { + tmp = s->lzma.rep3; + s->lzma.rep3 = s->lzma.rep2; + } + + s->lzma.rep2 = s->lzma.rep1; + } + + s->lzma.rep1 = s->lzma.rep0; + s->lzma.rep0 = tmp; + } + + lzma_state_long_rep(&s->lzma.state); + lzma_len(s, &s->lzma.rep_len_dec, pos_state); } /* LZMA decoder core */ static bool lzma_main(struct xz_dec_lzma2 *s) { - uint32_t pos_state; - - /* - * If the dictionary was reached during the previous call, try to - * finish the possibly pending repeat in the dictionary. - */ - if (dict_has_space(&s->dict) && s->lzma.len > 0) - dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0); - - /* - * Decode more LZMA symbols. One iteration may consume up to - * LZMA_IN_REQUIRED - 1 bytes. - */ - while (dict_has_space(&s->dict) && !rc_limit_exceeded(&s->rc)) - { - pos_state = s->dict.pos & s->lzma.pos_mask; - - if (!rc_bit(&s->rc, &s->lzma.is_match[s->lzma.state][pos_state])) - { - lzma_literal(s); - } - else - { - if (rc_bit(&s->rc, &s->lzma.is_rep[s->lzma.state])) - lzma_rep_match(s, pos_state); - else - lzma_match(s, pos_state); - - if (!dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0)) - return false; - } - } - - /* - * Having the range decoder always normalized when we are outside - * this function makes it easier to correctly handle end of the chunk. - */ - rc_normalize(&s->rc); - - return true; + uint32_t pos_state; + + /* + * If the dictionary was reached during the previous call, try to + * finish the possibly pending repeat in the dictionary. + */ + if (dict_has_space(&s->dict) && s->lzma.len > 0) + dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0); + + /* + * Decode more LZMA symbols. One iteration may consume up to + * LZMA_IN_REQUIRED - 1 bytes. + */ + while (dict_has_space(&s->dict) && !rc_limit_exceeded(&s->rc)) + { + pos_state = s->dict.pos & s->lzma.pos_mask; + + if (!rc_bit(&s->rc, &s->lzma.is_match[s->lzma.state][pos_state])) + { + lzma_literal(s); + } + else + { + if (rc_bit(&s->rc, &s->lzma.is_rep[s->lzma.state])) + lzma_rep_match(s, pos_state); + else + lzma_match(s, pos_state); + + if (!dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0)) + return false; + } + } + + /* + * Having the range decoder always normalized when we are outside + * this function makes it easier to correctly handle end of the chunk. + */ + rc_normalize(&s->rc); + + return true; } /* @@ -809,29 +809,29 @@ static bool lzma_main(struct xz_dec_lzma2 *s) */ static void lzma_reset(struct xz_dec_lzma2 *s) { - uint16_t *probs; - size_t i; - - s->lzma.state = STATE_LIT_LIT; - s->lzma.rep0 = 0; - s->lzma.rep1 = 0; - s->lzma.rep2 = 0; - s->lzma.rep3 = 0; - - /* - * All probabilities are initialized to the same value. This hack - * makes the code smaller by avoiding a separate loop for each - * probability array. - * - * This could be optimized so that only that part of literal - * probabilities that are actually required. In the common case - * we would write 12 KiB less. - */ - probs = s->lzma.is_match[0]; - for (i = 0; i < PROBS_TOTAL; ++i) - probs[i] = RC_BIT_MODEL_TOTAL / 2; - - rc_reset(&s->rc); + uint16_t *probs; + size_t i; + + s->lzma.state = STATE_LIT_LIT; + s->lzma.rep0 = 0; + s->lzma.rep1 = 0; + s->lzma.rep2 = 0; + s->lzma.rep3 = 0; + + /* + * All probabilities are initialized to the same value. This hack + * makes the code smaller by avoiding a separate loop for each + * probability array. + * + * This could be optimized so that only that part of literal + * probabilities that are actually required. In the common case + * we would write 12 KiB less. + */ + probs = s->lzma.is_match[0]; + for (i = 0; i < PROBS_TOTAL; ++i) + probs[i] = RC_BIT_MODEL_TOTAL / 2; + + rc_reset(&s->rc); } /* @@ -841,35 +841,35 @@ static void lzma_reset(struct xz_dec_lzma2 *s) */ static bool lzma_props(struct xz_dec_lzma2 *s, uint8_t props) { - if (props > (4 * 5 + 4) * 9 + 8) - return false; + if (props > (4 * 5 + 4) * 9 + 8) + return false; - s->lzma.pos_mask = 0; - while (props >= 9 * 5) - { - props -= 9 * 5; - ++s->lzma.pos_mask; - } + s->lzma.pos_mask = 0; + while (props >= 9 * 5) + { + props -= 9 * 5; + ++s->lzma.pos_mask; + } - s->lzma.pos_mask = (1 << s->lzma.pos_mask) - 1; + s->lzma.pos_mask = (1 << s->lzma.pos_mask) - 1; - s->lzma.literal_pos_mask = 0; - while (props >= 9) - { - props -= 9; - ++s->lzma.literal_pos_mask; - } + s->lzma.literal_pos_mask = 0; + while (props >= 9) + { + props -= 9; + ++s->lzma.literal_pos_mask; + } - s->lzma.lc = props; + s->lzma.lc = props; - if (s->lzma.lc + s->lzma.literal_pos_mask > 4) - return false; + if (s->lzma.lc + s->lzma.literal_pos_mask > 4) + return false; - s->lzma.literal_pos_mask = (1 << s->lzma.literal_pos_mask) - 1; + s->lzma.literal_pos_mask = (1 << s->lzma.literal_pos_mask) - 1; - lzma_reset(s); + lzma_reset(s); - return true; + return true; } /********* @@ -890,89 +890,89 @@ static bool lzma_props(struct xz_dec_lzma2 *s, uint8_t props) */ static bool lzma2_lzma(struct xz_dec_lzma2 *s, struct xz_buf *b) { - size_t in_avail; - uint32_t tmp; - - in_avail = b->in_size - b->in_pos; - if (s->temp.size > 0 || s->lzma2.compressed == 0) - { - tmp = 2 * LZMA_IN_REQUIRED - s->temp.size; - if (tmp > s->lzma2.compressed - s->temp.size) - tmp = s->lzma2.compressed - s->temp.size; - if (tmp > in_avail) - tmp = in_avail; - - memcpy(s->temp.buf + s->temp.size, b->in + b->in_pos, tmp); - - if (s->temp.size + tmp == s->lzma2.compressed) - { - memzero(s->temp.buf + s->temp.size + tmp, sizeof(s->temp.buf) - s->temp.size - tmp); - s->rc.in_limit = s->temp.size + tmp; - } - else if (s->temp.size + tmp < LZMA_IN_REQUIRED) - { - s->temp.size += tmp; - b->in_pos += tmp; - return true; - } - else - { - s->rc.in_limit = s->temp.size + tmp - LZMA_IN_REQUIRED; - } - - s->rc.in = s->temp.buf; - s->rc.in_pos = 0; - - if (!lzma_main(s) || s->rc.in_pos > s->temp.size + tmp) - return false; - - s->lzma2.compressed -= s->rc.in_pos; - - if (s->rc.in_pos < s->temp.size) - { - s->temp.size -= s->rc.in_pos; - memmove(s->temp.buf, s->temp.buf + s->rc.in_pos, s->temp.size); - return true; - } - - b->in_pos += s->rc.in_pos - s->temp.size; - s->temp.size = 0; - } - - in_avail = b->in_size - b->in_pos; - if (in_avail >= LZMA_IN_REQUIRED) - { - s->rc.in = b->in; - s->rc.in_pos = b->in_pos; - - if (in_avail >= s->lzma2.compressed + LZMA_IN_REQUIRED) - s->rc.in_limit = b->in_pos + s->lzma2.compressed; - else - s->rc.in_limit = b->in_size - LZMA_IN_REQUIRED; - - if (!lzma_main(s)) - return false; - - in_avail = s->rc.in_pos - b->in_pos; - if (in_avail > s->lzma2.compressed) - return false; - - s->lzma2.compressed -= in_avail; - b->in_pos = s->rc.in_pos; - } - - in_avail = b->in_size - b->in_pos; - if (in_avail < LZMA_IN_REQUIRED) - { - if (in_avail > s->lzma2.compressed) - in_avail = s->lzma2.compressed; - - memcpy(s->temp.buf, b->in + b->in_pos, in_avail); - s->temp.size = in_avail; - b->in_pos += in_avail; - } - - return true; + size_t in_avail; + uint32_t tmp; + + in_avail = b->in_size - b->in_pos; + if (s->temp.size > 0 || s->lzma2.compressed == 0) + { + tmp = 2 * LZMA_IN_REQUIRED - s->temp.size; + if (tmp > s->lzma2.compressed - s->temp.size) + tmp = s->lzma2.compressed - s->temp.size; + if (tmp > in_avail) + tmp = in_avail; + + memcpy(s->temp.buf + s->temp.size, b->in + b->in_pos, tmp); + + if (s->temp.size + tmp == s->lzma2.compressed) + { + memzero(s->temp.buf + s->temp.size + tmp, sizeof(s->temp.buf) - s->temp.size - tmp); + s->rc.in_limit = s->temp.size + tmp; + } + else if (s->temp.size + tmp < LZMA_IN_REQUIRED) + { + s->temp.size += tmp; + b->in_pos += tmp; + return true; + } + else + { + s->rc.in_limit = s->temp.size + tmp - LZMA_IN_REQUIRED; + } + + s->rc.in = s->temp.buf; + s->rc.in_pos = 0; + + if (!lzma_main(s) || s->rc.in_pos > s->temp.size + tmp) + return false; + + s->lzma2.compressed -= s->rc.in_pos; + + if (s->rc.in_pos < s->temp.size) + { + s->temp.size -= s->rc.in_pos; + memmove(s->temp.buf, s->temp.buf + s->rc.in_pos, s->temp.size); + return true; + } + + b->in_pos += s->rc.in_pos - s->temp.size; + s->temp.size = 0; + } + + in_avail = b->in_size - b->in_pos; + if (in_avail >= LZMA_IN_REQUIRED) + { + s->rc.in = b->in; + s->rc.in_pos = b->in_pos; + + if (in_avail >= s->lzma2.compressed + LZMA_IN_REQUIRED) + s->rc.in_limit = b->in_pos + s->lzma2.compressed; + else + s->rc.in_limit = b->in_size - LZMA_IN_REQUIRED; + + if (!lzma_main(s)) + return false; + + in_avail = s->rc.in_pos - b->in_pos; + if (in_avail > s->lzma2.compressed) + return false; + + s->lzma2.compressed -= in_avail; + b->in_pos = s->rc.in_pos; + } + + in_avail = b->in_size - b->in_pos; + if (in_avail < LZMA_IN_REQUIRED) + { + if (in_avail > s->lzma2.compressed) + in_avail = s->lzma2.compressed; + + memcpy(s->temp.buf, b->in + b->in_pos, in_avail); + s->temp.size = in_avail; + b->in_pos += in_avail; + } + + return true; } /* @@ -981,251 +981,251 @@ static bool lzma2_lzma(struct xz_dec_lzma2 *s, struct xz_buf *b) */ XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s, struct xz_buf *b) { - uint32_t tmp; - - while (b->in_pos < b->in_size || s->lzma2.sequence == SEQ_LZMA_RUN) - { - switch (s->lzma2.sequence) - { - case SEQ_CONTROL: - /* - * LZMA2 control byte - * - * Exact values: - * 0x00 End marker - * 0x01 Dictionary reset followed by - * an uncompressed chunk - * 0x02 Uncompressed chunk (no dictionary reset) - * - * Highest three bits (s->control & 0xE0): - * 0xE0 Dictionary reset, new properties and state - * reset, followed by LZMA compressed chunk - * 0xC0 New properties and state reset, followed - * by LZMA compressed chunk (no dictionary - * reset) - * 0xA0 State reset using old properties, - * followed by LZMA compressed chunk (no - * dictionary reset) - * 0x80 LZMA chunk (no dictionary or state reset) - * - * For LZMA compressed chunks, the lowest five bits - * (s->control & 1F) are the highest bits of the - * uncompressed size (bits 16-20). - * - * A new LZMA2 stream must begin with a dictionary - * reset. The first LZMA chunk must set new - * properties and reset the LZMA state. - * - * Values that don't match anything described above - * are invalid and we return XZ_DATA_ERROR. - */ - tmp = b->in[b->in_pos++]; - - if (tmp == 0x00) - return XZ_STREAM_END; - - if (tmp >= 0xE0 || tmp == 0x01) - { - s->lzma2.need_props = true; - s->lzma2.need_dict_reset = false; - dict_reset(&s->dict, b); - } - else if (s->lzma2.need_dict_reset) - { - return XZ_DATA_ERROR; - } - - if (tmp >= 0x80) - { - s->lzma2.uncompressed = (tmp & 0x1F) << 16; - s->lzma2.sequence = SEQ_UNCOMPRESSED_1; - - if (tmp >= 0xC0) - { - /* - * When there are new properties, - * state reset is done at - * SEQ_PROPERTIES. - */ - s->lzma2.need_props = false; - s->lzma2.next_sequence = SEQ_PROPERTIES; - } - else if (s->lzma2.need_props) - { - return XZ_DATA_ERROR; - } - else - { - s->lzma2.next_sequence = SEQ_LZMA_PREPARE; - if (tmp >= 0xA0) - lzma_reset(s); - } - } - else - { - if (tmp > 0x02) - return XZ_DATA_ERROR; - - s->lzma2.sequence = SEQ_COMPRESSED_0; - s->lzma2.next_sequence = SEQ_COPY; - } - - break; - - case SEQ_UNCOMPRESSED_1: - s->lzma2.uncompressed += (uint32_t)b->in[b->in_pos++] << 8; - s->lzma2.sequence = SEQ_UNCOMPRESSED_2; - break; - - case SEQ_UNCOMPRESSED_2: - s->lzma2.uncompressed += (uint32_t)b->in[b->in_pos++] + 1; - s->lzma2.sequence = SEQ_COMPRESSED_0; - break; - - case SEQ_COMPRESSED_0: - s->lzma2.compressed = (uint32_t)b->in[b->in_pos++] << 8; - s->lzma2.sequence = SEQ_COMPRESSED_1; - break; - - case SEQ_COMPRESSED_1: - s->lzma2.compressed += (uint32_t)b->in[b->in_pos++] + 1; - s->lzma2.sequence = s->lzma2.next_sequence; - break; - - case SEQ_PROPERTIES: - if (!lzma_props(s, b->in[b->in_pos++])) - return XZ_DATA_ERROR; - - s->lzma2.sequence = SEQ_LZMA_PREPARE; - - case SEQ_LZMA_PREPARE: - if (s->lzma2.compressed < RC_INIT_BYTES) - return XZ_DATA_ERROR; - - if (!rc_read_init(&s->rc, b)) - return XZ_OK; - - s->lzma2.compressed -= RC_INIT_BYTES; - s->lzma2.sequence = SEQ_LZMA_RUN; - - case SEQ_LZMA_RUN: - /* - * Set dictionary limit to indicate how much we want - * to be encoded at maximum. Decode new data into the - * dictionary. Flush the new data from dictionary to - * b->out. Check if we finished decoding this chunk. - * In case the dictionary got full but we didn't fill - * the output buffer yet, we may run this loop - * multiple times without changing s->lzma2.sequence. - */ - dict_limit(&s->dict, - min_t(size_t, b->out_size - b->out_pos, s->lzma2.uncompressed)); - if (!lzma2_lzma(s, b)) - return XZ_DATA_ERROR; - - s->lzma2.uncompressed -= dict_flush(&s->dict, b); - - if (s->lzma2.uncompressed == 0) - { - if (s->lzma2.compressed > 0 || s->lzma.len > 0 || !rc_is_finished(&s->rc)) - return XZ_DATA_ERROR; - - rc_reset(&s->rc); - s->lzma2.sequence = SEQ_CONTROL; - } - else if (b->out_pos == b->out_size || - (b->in_pos == b->in_size && s->temp.size < s->lzma2.compressed)) - { - return XZ_OK; - } - - break; - - case SEQ_COPY: - dict_uncompressed(&s->dict, b, &s->lzma2.compressed); - if (s->lzma2.compressed > 0) - return XZ_OK; - - s->lzma2.sequence = SEQ_CONTROL; - break; - } - } - - return XZ_OK; + uint32_t tmp; + + while (b->in_pos < b->in_size || s->lzma2.sequence == SEQ_LZMA_RUN) + { + switch (s->lzma2.sequence) + { + case SEQ_CONTROL: + /* + * LZMA2 control byte + * + * Exact values: + * 0x00 End marker + * 0x01 Dictionary reset followed by + * an uncompressed chunk + * 0x02 Uncompressed chunk (no dictionary reset) + * + * Highest three bits (s->control & 0xE0): + * 0xE0 Dictionary reset, new properties and state + * reset, followed by LZMA compressed chunk + * 0xC0 New properties and state reset, followed + * by LZMA compressed chunk (no dictionary + * reset) + * 0xA0 State reset using old properties, + * followed by LZMA compressed chunk (no + * dictionary reset) + * 0x80 LZMA chunk (no dictionary or state reset) + * + * For LZMA compressed chunks, the lowest five bits + * (s->control & 1F) are the highest bits of the + * uncompressed size (bits 16-20). + * + * A new LZMA2 stream must begin with a dictionary + * reset. The first LZMA chunk must set new + * properties and reset the LZMA state. + * + * Values that don't match anything described above + * are invalid and we return XZ_DATA_ERROR. + */ + tmp = b->in[b->in_pos++]; + + if (tmp == 0x00) + return XZ_STREAM_END; + + if (tmp >= 0xE0 || tmp == 0x01) + { + s->lzma2.need_props = true; + s->lzma2.need_dict_reset = false; + dict_reset(&s->dict, b); + } + else if (s->lzma2.need_dict_reset) + { + return XZ_DATA_ERROR; + } + + if (tmp >= 0x80) + { + s->lzma2.uncompressed = (tmp & 0x1F) << 16; + s->lzma2.sequence = SEQ_UNCOMPRESSED_1; + + if (tmp >= 0xC0) + { + /* + * When there are new properties, + * state reset is done at + * SEQ_PROPERTIES. + */ + s->lzma2.need_props = false; + s->lzma2.next_sequence = SEQ_PROPERTIES; + } + else if (s->lzma2.need_props) + { + return XZ_DATA_ERROR; + } + else + { + s->lzma2.next_sequence = SEQ_LZMA_PREPARE; + if (tmp >= 0xA0) + lzma_reset(s); + } + } + else + { + if (tmp > 0x02) + return XZ_DATA_ERROR; + + s->lzma2.sequence = SEQ_COMPRESSED_0; + s->lzma2.next_sequence = SEQ_COPY; + } + + break; + + case SEQ_UNCOMPRESSED_1: + s->lzma2.uncompressed += (uint32_t)b->in[b->in_pos++] << 8; + s->lzma2.sequence = SEQ_UNCOMPRESSED_2; + break; + + case SEQ_UNCOMPRESSED_2: + s->lzma2.uncompressed += (uint32_t)b->in[b->in_pos++] + 1; + s->lzma2.sequence = SEQ_COMPRESSED_0; + break; + + case SEQ_COMPRESSED_0: + s->lzma2.compressed = (uint32_t)b->in[b->in_pos++] << 8; + s->lzma2.sequence = SEQ_COMPRESSED_1; + break; + + case SEQ_COMPRESSED_1: + s->lzma2.compressed += (uint32_t)b->in[b->in_pos++] + 1; + s->lzma2.sequence = s->lzma2.next_sequence; + break; + + case SEQ_PROPERTIES: + if (!lzma_props(s, b->in[b->in_pos++])) + return XZ_DATA_ERROR; + + s->lzma2.sequence = SEQ_LZMA_PREPARE; + + case SEQ_LZMA_PREPARE: + if (s->lzma2.compressed < RC_INIT_BYTES) + return XZ_DATA_ERROR; + + if (!rc_read_init(&s->rc, b)) + return XZ_OK; + + s->lzma2.compressed -= RC_INIT_BYTES; + s->lzma2.sequence = SEQ_LZMA_RUN; + + case SEQ_LZMA_RUN: + /* + * Set dictionary limit to indicate how much we want + * to be encoded at maximum. Decode new data into the + * dictionary. Flush the new data from dictionary to + * b->out. Check if we finished decoding this chunk. + * In case the dictionary got full but we didn't fill + * the output buffer yet, we may run this loop + * multiple times without changing s->lzma2.sequence. + */ + dict_limit(&s->dict, + min_t(size_t, b->out_size - b->out_pos, s->lzma2.uncompressed)); + if (!lzma2_lzma(s, b)) + return XZ_DATA_ERROR; + + s->lzma2.uncompressed -= dict_flush(&s->dict, b); + + if (s->lzma2.uncompressed == 0) + { + if (s->lzma2.compressed > 0 || s->lzma.len > 0 || !rc_is_finished(&s->rc)) + return XZ_DATA_ERROR; + + rc_reset(&s->rc); + s->lzma2.sequence = SEQ_CONTROL; + } + else if (b->out_pos == b->out_size || + (b->in_pos == b->in_size && s->temp.size < s->lzma2.compressed)) + { + return XZ_OK; + } + + break; + + case SEQ_COPY: + dict_uncompressed(&s->dict, b, &s->lzma2.compressed); + if (s->lzma2.compressed > 0) + return XZ_OK; + + s->lzma2.sequence = SEQ_CONTROL; + break; + } + } + + return XZ_OK; } XZ_EXTERN struct xz_dec_lzma2 *xz_dec_lzma2_create(enum xz_mode mode, uint32_t dict_max) { - struct xz_dec_lzma2 *s = kmalloc(sizeof(*s), GFP_KERNEL); - if (s == NULL) - return NULL; - - s->dict.mode = mode; - s->dict.size_max = dict_max; - - if (DEC_IS_PREALLOC(mode)) - { - s->dict.buf = vmalloc(dict_max); - if (s->dict.buf == NULL) - { - kfree(s); - return NULL; - } - } - else if (DEC_IS_DYNALLOC(mode)) - { - s->dict.buf = NULL; - s->dict.allocated = 0; - } - - return s; + struct xz_dec_lzma2 *s = kmalloc(sizeof(*s), GFP_KERNEL); + if (s == NULL) + return NULL; + + s->dict.mode = mode; + s->dict.size_max = dict_max; + + if (DEC_IS_PREALLOC(mode)) + { + s->dict.buf = vmalloc(dict_max); + if (s->dict.buf == NULL) + { + kfree(s); + return NULL; + } + } + else if (DEC_IS_DYNALLOC(mode)) + { + s->dict.buf = NULL; + s->dict.allocated = 0; + } + + return s; } XZ_EXTERN enum xz_ret xz_dec_lzma2_reset(struct xz_dec_lzma2 *s, uint8_t props) { - /* This limits dictionary size to 3 GiB to keep parsing simpler. */ - if (props > 39) - return XZ_OPTIONS_ERROR; - - s->dict.size = 2 + (props & 1); - s->dict.size <<= (props >> 1) + 11; - - if (DEC_IS_MULTI(s->dict.mode)) - { - if (s->dict.size > s->dict.size_max) - return XZ_MEMLIMIT_ERROR; - - s->dict.end = s->dict.size; - - if (DEC_IS_DYNALLOC(s->dict.mode)) - { - if (s->dict.allocated < s->dict.size) - { - vfree(s->dict.buf); - s->dict.buf = vmalloc(s->dict.size); - if (s->dict.buf == NULL) - { - s->dict.allocated = 0; - return XZ_MEM_ERROR; - } - } - } - } - - s->lzma.len = 0; - - s->lzma2.sequence = SEQ_CONTROL; - s->lzma2.need_dict_reset = true; - - s->temp.size = 0; - - return XZ_OK; + /* This limits dictionary size to 3 GiB to keep parsing simpler. */ + if (props > 39) + return XZ_OPTIONS_ERROR; + + s->dict.size = 2 + (props & 1); + s->dict.size <<= (props >> 1) + 11; + + if (DEC_IS_MULTI(s->dict.mode)) + { + if (s->dict.size > s->dict.size_max) + return XZ_MEMLIMIT_ERROR; + + s->dict.end = s->dict.size; + + if (DEC_IS_DYNALLOC(s->dict.mode)) + { + if (s->dict.allocated < s->dict.size) + { + vfree(s->dict.buf); + s->dict.buf = vmalloc(s->dict.size); + if (s->dict.buf == NULL) + { + s->dict.allocated = 0; + return XZ_MEM_ERROR; + } + } + } + } + + s->lzma.len = 0; + + s->lzma2.sequence = SEQ_CONTROL; + s->lzma2.need_dict_reset = true; + + s->temp.size = 0; + + return XZ_OK; } XZ_EXTERN void xz_dec_lzma2_end(struct xz_dec_lzma2 *s) { - if (DEC_IS_MULTI(s->dict.mode)) - vfree(s->dict.buf); + if (DEC_IS_MULTI(s->dict.mode)) + vfree(s->dict.buf); - kfree(s); + kfree(s); } |