diff --git a/c/dec/decode.c b/c/dec/decode.c index 953523f37..220c7e85c 100644 --- a/c/dec/decode.c +++ b/c/dec/decode.c @@ -149,7 +149,7 @@ static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s, } BrotliTakeBits(br, 3, &n); if (n != 0) { - s->window_bits = 17 + n; + s->window_bits = (17u + n) & 63u; return BROTLI_DECODER_SUCCESS; } BrotliTakeBits(br, 3, &n); @@ -166,7 +166,7 @@ static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s, } } if (n != 0) { - s->window_bits = 8 + n; + s->window_bits = (8u + n) & 63u; return BROTLI_DECODER_SUCCESS; } s->window_bits = 17; @@ -2422,7 +2422,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream( result = BROTLI_DECODER_NEEDS_MORE_INPUT; break; } - s->window_bits = (brotli_reg_t)bits; + s->window_bits = bits & 63u; if (s->window_bits < BROTLI_LARGE_MIN_WBITS || s->window_bits > BROTLI_LARGE_MAX_WBITS) { result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS); diff --git a/c/dec/state.c b/c/dec/state.c index c2fefbee4..be6a26680 100644 --- a/c/dec/state.c +++ b/c/dec/state.c @@ -98,9 +98,9 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s, void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s) { s->meta_block_remaining_len = 0; - s->block_length[0] = 1U << 24; - s->block_length[1] = 1U << 24; - s->block_length[2] = 1U << 24; + s->block_length[0] = BROTLI_BLOCK_SIZE_CAP; + s->block_length[1] = BROTLI_BLOCK_SIZE_CAP; + s->block_length[2] = BROTLI_BLOCK_SIZE_CAP; s->num_block_types[0] = 1; s->num_block_types[1] = 1; s->num_block_types[2] = 1; diff --git a/c/dec/state.h b/c/dec/state.h index 49319f5f5..fd250b684 100644 --- a/c/dec/state.h +++ b/c/dec/state.h @@ -233,6 +233,7 @@ typedef struct BrotliMetablockHeaderArena { uint8_t code_length_code_lengths[BROTLI_CODE_LENGTH_CODES]; /* Population counts for the code lengths. */ uint16_t code_length_histo[16]; + /* TODO(eustas): +2 bytes padding */ /* For HuffmanTreeGroupDecode. */ int htree_index; @@ -278,6 +279,8 @@ struct BrotliDecoderStateStruct { int dist_rb_idx; int dist_rb[4]; int error_code; + int meta_block_remaining_len; + uint8_t* ringbuffer; uint8_t* ringbuffer_end; HuffmanCode* htree_command; @@ -299,7 +302,6 @@ struct BrotliDecoderStateStruct { computed. After distance computation it is used as a temporary variable. */ int distance_context; brotli_reg_t block_length[3]; - int meta_block_remaining_len; brotli_reg_t block_length_index; brotli_reg_t num_block_types[3]; brotli_reg_t block_type_rb[6]; @@ -308,10 +310,6 @@ struct BrotliDecoderStateStruct { brotli_reg_t num_dist_htrees; uint8_t* dist_context_map; HuffmanCode* literal_htree; - uint8_t dist_htree_index; - - int copy_length; - int distance_code; /* For partial write operations. */ size_t rb_roundtrips; /* how many times we went around the ring-buffer */ @@ -321,6 +319,12 @@ struct BrotliDecoderStateStruct { brotli_reg_t mtf_upper_bound; uint32_t mtf[64 + 1]; + int copy_length; + int distance_code; + + uint8_t dist_htree_index; + /* TODO(eustas): +3 bytes padding */ + /* Less used attributes are at the end of this struct. */ brotli_decoder_metadata_start_func metadata_start_func; @@ -336,16 +340,18 @@ struct BrotliDecoderStateStruct { BrotliRunningDecodeUint8State substate_decode_uint8; BrotliRunningReadBlockLengthState substate_read_block_length; + int new_ringbuffer_size; + /* TODO(eustas): +4 bytes padding */ + unsigned int is_last_metablock : 1; unsigned int is_uncompressed : 1; unsigned int is_metadata : 1; unsigned int should_wrap_ringbuffer : 1; unsigned int canny_ringbuffer_allocation : 1; unsigned int large_window : 1; + unsigned int window_bits : 6; unsigned int size_nibbles : 8; - brotli_reg_t window_bits; - - int new_ringbuffer_size; + /* TODO(eustas): +12 bits padding */ brotli_reg_t num_literal_htrees; uint8_t* context_map; @@ -383,6 +389,10 @@ BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit( X = NULL; \ } +/* Literal/Command/Distance block size maximum; same as maximum metablock size; + used as block size when there is no block switching. */ +#define BROTLI_BLOCK_SIZE_CAP (1U << 24) + #if defined(__cplusplus) || defined(c_plusplus) } /* extern "C" */ #endif