Relax the prerequisites of WriteBrotliData().

Instead of returning false, if it is called with no
new input for a non-last block, just check if it has
any already processed data to flush, and if not,
return true with empty output.
This commit is contained in:
Zoltan Szabadka 2016-01-12 14:45:35 +01:00
parent 4d5ce42e4b
commit 82c9e1972d
2 changed files with 15 additions and 3 deletions

View File

@ -338,12 +338,18 @@ bool BrotliCompressor::WriteBrotliData(const bool is_last,
const uint8_t* data = ringbuffer_->start();
const uint32_t mask = ringbuffer_->mask();
if (delta > input_block_size() || (delta == 0 && !is_last)) {
if (delta > input_block_size()) {
return false;
}
const uint32_t bytes = static_cast<uint32_t>(delta);
if (params_.quality <= 1) {
if (delta == 0 && !is_last) {
// We have no new input data and we don't have to finish the stream, so
// nothing to do.
*out_size = 0;
return true;
}
const size_t max_out_size = 2 * bytes + 500;
uint8_t* storage = GetBrotliStorage(max_out_size);
storage[0] = last_byte_;
@ -379,7 +385,7 @@ bool BrotliCompressor::WriteBrotliData(const bool is_last,
if (newsize > cmd_alloc_size_) {
// Reserve a bit more memory to allow merging with a next block
// without realloc: that would impact speed.
newsize += bytes / 4;
newsize += (bytes / 4) + 16;
cmd_alloc_size_ = newsize;
commands_ =
static_cast<Command*>(realloc(commands_, sizeof(Command) * newsize));
@ -522,6 +528,12 @@ void DecideOverLiteralContextModeling(const uint8_t* input,
void BrotliCompressor::WriteMetaBlockInternal(const bool is_last,
size_t* out_size,
uint8_t** output) {
if (!is_last && input_pos_ == last_flush_pos_) {
// We have no new input data and we don't have to finish the stream, so
// nothing to do.
*out_size = 0;
return;
}
assert(input_pos_ >= last_flush_pos_);
assert(input_pos_ > last_flush_pos_ || is_last);
assert(input_pos_ - last_flush_pos_ <= 1u << 24);

View File

@ -117,7 +117,7 @@ class BrotliCompressor {
// If *out_size is positive, *output points to the start of the output data.
// If is_last or force_flush is true, an output meta-block is always created.
// Returns false if the size of the input data is larger than
// input_block_size() or if there is no new input data and is_last is false.
// input_block_size().
bool WriteBrotliData(const bool is_last, const bool force_flush,
size_t* out_size, uint8_t** output);