aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Tokar <tokarip@google.com>2024-09-19 09:01:50 -0700
committerCopybara-Service <copybara-worker@google.com>2024-09-19 09:02:34 -0700
commit350100a5bb9d9671aca85213b2ec7a70a361b0cd (patch)
tree6e6a1d6cf61df2d6a55ca5e09b4aea9e357e02cf
parent39bcecf4559f9b0e75c6248a75d9c0db6b123d88 (diff)
downloadbrotli-master.zip
brotli-master.tar.gz
brotli-master.tar.bz2
Add BrotliCopyPreloadedSymbols function.HEADmaster
Add a single trivial use to avoid complier warning. PiperOrigin-RevId: 676435629
-rw-r--r--c/dec/decode.c51
1 files changed, 49 insertions, 2 deletions
diff --git a/c/dec/decode.c b/c/dec/decode.c
index 220c7e8..3ed9fe8 100644
--- a/c/dec/decode.c
+++ b/c/dec/decode.c
@@ -466,6 +466,53 @@ static BROTLI_INLINE brotli_reg_t ReadPreloadedSymbol(const HuffmanCode* table,
return result;
}
+/* Reads up to limit symbols from br and copies them into ringbuffer,
+ starting from pos. Caller must ensure that there is enough space
+ for the write. Returns the amount of symbols actually copied. */
+static BROTLI_INLINE int BrotliCopyPreloadedSymbolsToU8(const HuffmanCode* table,
+ BrotliBitReader* br,
+ brotli_reg_t* bits,
+ brotli_reg_t* value,
+ uint8_t* ringbuffer,
+ int pos,
+ const int limit) {
+ /* Calculate range where CheckInputAmount is always true.
+ Start with the number of bytes we can read. */
+ int64_t new_lim = br->guard_in - br->next_in;
+ /* Convert to bits, since sybmols use variable number of bits. */
+ new_lim *= 8;
+ /* At most 15 bits per symbol, so this is safe. */
+ new_lim /= 15;
+ const int kMaximalOverread = 4;
+ int pos_limit = limit;
+ int copies = 0;
+ if ((new_lim - kMaximalOverread) <= limit) {
+ // Safe cast, since new_lim is already < num_steps
+ pos_limit = (int)(new_lim - kMaximalOverread);
+ }
+ if (pos_limit < 0) {
+ pos_limit = 0;
+ }
+ copies = pos_limit;
+ pos_limit += pos;
+ /* Fast path, caller made sure it is safe to write,
+ we verified that is is safe to read. */
+ for (; pos < pos_limit; pos++) {
+ BROTLI_DCHECK(BrotliCheckInputAmount(br));
+ ringbuffer[pos] = (uint8_t)ReadPreloadedSymbol(table, br, bits, value);
+ BROTLI_LOG_ARRAY_INDEX(ringbuffer, pos);
+ }
+ /* Do the remainder, caller made sure it is safe to write,
+ we need to bverify that it is safe to read. */
+ while (BrotliCheckInputAmount(br) && copies < limit) {
+ ringbuffer[pos] = (uint8_t)ReadPreloadedSymbol(table, br, bits, value);
+ BROTLI_LOG_ARRAY_INDEX(ringbuffer, pos);
+ pos++;
+ copies++;
+ }
+ return copies;
+}
+
static BROTLI_INLINE brotli_reg_t Log2Floor(brotli_reg_t x) {
brotli_reg_t result = 0;
while (x) {
@@ -1969,8 +2016,8 @@ CommandInner:
goto NextLiteralBlock;
}
if (!safe) {
- s->ringbuffer[pos] =
- (uint8_t)ReadPreloadedSymbol(s->literal_htree, br, &bits, &value);
+ BrotliCopyPreloadedSymbolsToU8(s->literal_htree, br, &bits, &value,
+ s->ringbuffer, pos, 1);
} else {
brotli_reg_t literal;
if (!SafeReadSymbol(s->literal_htree, br, &literal)) {