mirror of
https://github.com/google/brotli.git
synced 2024-11-24 02:13:27 +08:00
Simplify uncompressed block decoding state machine.
This commit is contained in:
parent
5919712922
commit
03c4ab5967
60
dec/decode.c
60
dec/decode.c
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user