mirror of
https://github.com/google/brotli.git
synced 2026-07-09 02:08:06 +00:00
Add function for max compressed size #71
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @nemequ on GitHub (Dec 1, 2015).
Unless I'm missing something, Brotli doesn't include a function to calculate the maximum size of a compressed buffer given a specified input size (i.e., the brotli version of zlib's
compressBoundfunction).I've been using uncompressed_size + 5 in squash, but that doesn't work with larger buffers. Based on some testing with blobs of random data, the points where the output size changes are:
24 MiB + 1 bytes requires input_size + 16, but I stopped testing there. For now I'm going to use
uncompressed_size + 5 + ((uncompressed_size / (1024 * 1024 * 8)) * 4)in Squash, but I would feel better if you provided a function or macro.@eustas commented on GitHub (Dec 2, 2015):
Yes, there is dependence between block size and maximum overhead.
I'll check the implementation and plan to add utility method to brotli encoder API.
@dsnet commented on GitHub (Dec 18, 2015):
Someone else can verify this work, but I believe this to be true.
In the worst case, when the data is highly uncompressible, the overhead comes from meta data to describe raw blocks. We compute the overhead by the followinG:
The stream header has:
The overhead to encode each raw block is:
The last block has:
Thus, we produce the following table:
These numbers, of course, assume that the encoder falls back to using raw encoding when it detects that its compressed output is worse than just encoding it raw. I cannot confirm that the C encoder does this.
@nemequ commented on GitHub (Dec 19, 2015):
FWIW I don't think it's a big deal if this isn't exact, as long as it always returns >= the number of bytes really required. Memory use shouldn't really be an issue here since if there is any concern about memory people should be using the streaming API. A lot of the plugins in Squash are actually pretty wide of the mark in their estimates.
@nemequ commented on GitHub (Mar 5, 2016):
It seems level 1 is significantly worse about this. For example, a 935 byte buffer requires 119 extra bytes.
Do you consider that to be a bug? I don't really know how the encoder works… I can understand not wanting to spend the time checking for uncompressible data, but I can also see abandoning the idea of compression and just memcpying data being a good performance optimization.
@dswd commented on GitHub (Mar 6, 2016):
The relevant commits seem to be
27688e6and417107b3dd.@nemequ commented on GitHub (Jun 16, 2016):
0.5 provides
BrotliEncoderMaxCompressedSize@eustas commented on GitHub (Jun 16, 2016):
WARNING: this function result only applicable to BrotliEncoderCompress.
Stream compression may use more output. E.g. if compress with level 0 or level 1, every chunk of input is compressed independently -> adding more overhead.
I'm going to improve BrotliCompressStream behavior later and add another function for output size estimation.
@nemequ commented on GitHub (Jun 16, 2016):
FWIW using the buffer to buffer API is all we commit to our max_compressed_size function working for in Squash, so this isn't a problem for me. Given all the complexities of estimating it with the stream API (like what happens if you flush every byte?), I don't think I would bother with that if I were you.
Note that zlib's function (
compressBound) only applies to its buffer-to-buffer functions. I think all the others do the same, but I'd have to check…