Simplify uncompressed block decoding state machine.

This commit is contained in:
Zoltan Szabadka 2015-09-28 12:40:39 +02:00
parent 5919712922
commit 03c4ab5967
2 changed files with 23 additions and 44 deletions

View File

@ -786,6 +786,7 @@ BrotliResult BROTLI_NOINLINE CopyUncompressedBlockToOutput(BrotliOutput output,
BrotliState* s) {
BrotliResult result;
int num_read;
int nbytes;
/* State machine */
for (;;) {
switch ((int)s->substate_uncompressed) {
@ -797,21 +798,17 @@ BrotliResult BROTLI_NOINLINE CopyUncompressedBlockToOutput(BrotliOutput output,
break;
}
/* Copy remaining bytes from s->br.buf_ to ringbuffer. */
s->nbytes = (int)BrotliGetRemainingBytes(&s->br);
BrotliCopyBytes(&s->ringbuffer[pos], &s->br, (size_t)s->nbytes);
pos += s->nbytes;
s->meta_block_remaining_len -= s->nbytes;
nbytes = (int)BrotliGetRemainingBytes(&s->br);
BrotliCopyBytes(&s->ringbuffer[pos], &s->br, (size_t)nbytes);
pos += nbytes;
s->meta_block_remaining_len -= nbytes;
if (pos >= s->ringbuffer_size) {
s->to_write = s->ringbuffer_size;
s->partially_written = 0;
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE_1;
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE;
break;
}
if (pos + s->meta_block_remaining_len >= s->ringbuffer_size) {
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_FILL;
} else {
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_COPY;
}
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_COPY;
break;
case BROTLI_STATE_UNCOMPRESSED_SHORT:
if (!BrotliWarmupBitReader(&s->br)) {
@ -827,14 +824,13 @@ BrotliResult BROTLI_NOINLINE CopyUncompressedBlockToOutput(BrotliOutput output,
if (pos >= s->ringbuffer_size) {
s->to_write = s->ringbuffer_size;
s->partially_written = 0;
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE_2;
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE;
} else {
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
return BROTLI_RESULT_SUCCESS;
}
/* No break, if state is updated, continue to next state */
case BROTLI_STATE_UNCOMPRESSED_WRITE_1:
case BROTLI_STATE_UNCOMPRESSED_WRITE_2:
case BROTLI_STATE_UNCOMPRESSED_WRITE:
result = WriteRingBuffer(output, s);
if (result != BROTLI_RESULT_SUCCESS) {
return result;
@ -845,41 +841,29 @@ BrotliResult BROTLI_NOINLINE CopyUncompressedBlockToOutput(BrotliOutput output,
of the ringbuffer to its beginning and flush the ringbuffer to the
output. */
memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)pos);
if (pos + s->meta_block_remaining_len >= s->ringbuffer_size) {
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_FILL;
} else {
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_COPY;
break;
}
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_COPY;
/* No break, continue to next state */
case BROTLI_STATE_UNCOMPRESSED_FILL:
/* If we have more to copy than the remaining size of the ringbuffer,
then we first fill the ringbuffer from the input and then flush the
ringbuffer to the output */
s->nbytes = s->ringbuffer_size - pos;
num_read = BrotliRead(s->br.input_, &s->ringbuffer[pos],
(size_t)s->nbytes);
pos += num_read;
s->meta_block_remaining_len -= num_read;
if (num_read < s->nbytes) {
if (num_read < 0) return BROTLI_FAILURE();
return BROTLI_RESULT_NEEDS_MORE_INPUT;
}
s->to_write = s->ringbuffer_size;
s->partially_written = 0;
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE_1;
break;
case BROTLI_STATE_UNCOMPRESSED_COPY:
/* Copy straight from the input onto the ringbuffer. The ringbuffer will
be flushed to the output at a later time. */
nbytes = s->meta_block_remaining_len;
if (pos + nbytes > s->ringbuffer_size) {
nbytes = s->ringbuffer_size - pos;
}
num_read = BrotliRead(s->br.input_, &s->ringbuffer[pos],
(size_t)s->meta_block_remaining_len);
(size_t)nbytes);
pos += num_read;
s->meta_block_remaining_len -= num_read;
if (s->meta_block_remaining_len > 0) {
if (num_read < nbytes) {
if (num_read < 0) return BROTLI_FAILURE();
return BROTLI_RESULT_NEEDS_MORE_INPUT;
}
if (pos == s->ringbuffer_size) {
s->to_write = s->ringbuffer_size;
s->partially_written = 0;
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE;
break;
}
s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
return BROTLI_RESULT_SUCCESS;
}

View File

@ -67,10 +67,8 @@ typedef enum {
typedef enum {
BROTLI_STATE_UNCOMPRESSED_NONE,
BROTLI_STATE_UNCOMPRESSED_SHORT,
BROTLI_STATE_UNCOMPRESSED_FILL,
BROTLI_STATE_UNCOMPRESSED_COPY,
BROTLI_STATE_UNCOMPRESSED_WRITE_1,
BROTLI_STATE_UNCOMPRESSED_WRITE_2
BROTLI_STATE_UNCOMPRESSED_WRITE
} BrotliRunningUncompressedState;
typedef enum {
@ -200,9 +198,6 @@ typedef struct {
uint8_t size_nibbles;
uint32_t window_bits;
/* For CopyUncompressedBlockToOutput */
int nbytes;
int num_literal_htrees;
uint8_t* context_map;
uint8_t* context_modes;