static BROTLI_INLINE brotli_reg_t BitMask(brotli_reg_t n) { if (BROTLI_IS_CONSTANT(n) || BROTLI_HAS_UBFX) { /* Masking with this expression turns to a single
"Unsigned Bit Field Extract" UBFX instruction on ARM. */ return ~(~((brotli_reg_t)0) << n);
} else { return kBrotliBitMask[n];
}
}
typedefstruct {
brotli_reg_t val_; /* pre-fetched bits */
brotli_reg_t bit_pos_; /* current bit-reading position in val_ */ const uint8_t* next_in; /* the byte we're reading from */ const uint8_t* guard_in; /* position from which "fast-path" is prohibited */ const uint8_t* last_in; /* == next_in + avail_in */
} BrotliBitReader;
/* Returns amount of unread bytes the bit reader still has buffered from the BrotliInput,includingwholebytesinbr->val_.Resultiscappedwith
maximal ring-buffer size (larger number won't be utilized anyway). */ static BROTLI_INLINE size_t BrotliGetRemainingBytes(BrotliBitReader* br) { staticconst size_t kCap = (size_t)1 << BROTLI_LARGE_MAX_WBITS;
size_t avail_in = BrotliBitReaderGetAvailIn(br); if (avail_in > kCap) return kCap; return avail_in + (BrotliGetAvailableBits(br) >> 3);
}
/* Checks if there is at least |num| bytes left in the input ring-buffer
(excluding the bits remaining in br->val_). */ static BROTLI_INLINE BROTLI_BOOL BrotliCheckInputAmount(
BrotliBitReader* const br) { return TO_BROTLI_BOOL(br->next_in < br->guard_in);
}
/* Mostly like BrotliFillBitWindow, but guarantees only 16 bits and reads no
more than BROTLI_SHORT_FILL_BIT_WINDOW_READ bytes of input. */ static BROTLI_INLINE void BrotliFillBitWindow16(BrotliBitReader* const br) {
BrotliFillBitWindow(br, 17);
}
/* Tries to pull one byte of input to accumulator.
Returns BROTLI_FALSE if there is no input available. */ static BROTLI_INLINE BROTLI_BOOL BrotliPullByte(BrotliBitReader* const br) { if (br->next_in == br->last_in) { return BROTLI_FALSE;
}
br->val_ = BrotliBitReaderLoadBits(br->val_,
(brotli_reg_t)*br->next_in, 8, br->bit_pos_);
br->bit_pos_ += 8;
++br->next_in; return BROTLI_TRUE;
}
/* Returns currently available bits.
The number of valid bits could be calculated by BrotliGetAvailableBits. */ static BROTLI_INLINE brotli_reg_t BrotliGetBitsUnmasked(
BrotliBitReader* const br) { return br->val_;
}
/* Like BrotliGetBits, but does not mask the result.
The result contains at least 16 valid bits. */ static BROTLI_INLINE brotli_reg_t BrotliGet16BitsUnmasked(
BrotliBitReader* const br) {
BrotliFillBitWindow(br, 16); return (brotli_reg_t)BrotliGetBitsUnmasked(br);
}
/* Returns the specified number of bits from |br| without advancing bit
position. */ static BROTLI_INLINE brotli_reg_t BrotliGetBits(
BrotliBitReader* const br, brotli_reg_t n_bits) {
BrotliFillBitWindow(br, n_bits); return BrotliGetBitsUnmasked(br) & BitMask(n_bits);
}
/* Tries to peek the specified amount of bits. Returns BROTLI_FALSE, if there
is not enough input. */ static BROTLI_INLINE BROTLI_BOOL BrotliSafeGetBits(
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) { while (BrotliGetAvailableBits(br) < n_bits) { if (!BrotliPullByte(br)) { return BROTLI_FALSE;
}
}
*val = BrotliGetBitsUnmasked(br) & BitMask(n_bits); return BROTLI_TRUE;
}
/* Advances the bit pos by |n_bits|. */ static BROTLI_INLINE void BrotliDropBits(
BrotliBitReader* const br, brotli_reg_t n_bits) {
br->bit_pos_ -= n_bits;
br->val_ >>= n_bits;
}
/* Make sure that there are no spectre bits in accumulator. Thisisimportantforthecaseswhensomebytesareskipped
(i.e. never placed into accumulator). */ static BROTLI_INLINE void BrotliBitReaderNormalize(BrotliBitReader* br) { /* Actually, it is enough to normalize when br->bit_pos_ == 0 */ if (br->bit_pos_ < (sizeof(brotli_reg_t) << 3u)) {
br->val_ &= (((brotli_reg_t)1) << br->bit_pos_) - 1;
}
}
/* Tries to read the specified amount of bits. Returns BROTLI_FALSE, if there isnotenoughinput.|n_bits|MUSTbepositive.
Up to 24 bits are allowed to be requested from this method. */ static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits(
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
BROTLI_DCHECK(n_bits <= 24); while (BrotliGetAvailableBits(br) < n_bits) { if (!BrotliPullByte(br)) { return BROTLI_FALSE;
}
}
BrotliTakeBits(br, n_bits, val); return BROTLI_TRUE;
}
/* Same as BrotliSafeReadBits, but allows reading up to 32 bits. */ static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits32(
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
BROTLI_DCHECK(n_bits <= 32); if (BROTLI_64_BITS || (n_bits <= 24)) { while (BrotliGetAvailableBits(br) < n_bits) { if (!BrotliPullByte(br)) { return BROTLI_FALSE;
}
}
BrotliTakeBits(br, n_bits, val); return BROTLI_TRUE;
} else { return BrotliSafeReadBits32Slow(br, n_bits, val);
}
}
/* Advances the bit reader position to the next byte boundary and verifies
that any skipped bits are set to zero. */ static BROTLI_INLINE BROTLI_BOOL BrotliJumpToByteBoundary(BrotliBitReader* br) {
brotli_reg_t pad_bits_count = BrotliGetAvailableBits(br) & 0x7;
brotli_reg_t pad_bits = 0; if (pad_bits_count != 0) {
BrotliTakeBits(br, pad_bits_count, &pad_bits);
}
BrotliBitReaderNormalize(br); return TO_BROTLI_BOOL(pad_bits == 0);
}
static BROTLI_INLINE void BrotliDropBytes(BrotliBitReader* br, size_t num) { /* Check detour is legal: accumulator must to be empty. */
BROTLI_DCHECK(br->bit_pos_ == 0);
BROTLI_DCHECK(br->val_ == 0);
br->next_in += num;
}
/* Copies remaining input bytes stored in the bit reader to the output. Value |num|maynotbelargerthanBrotliGetRemainingBytes.Thebitreadermustbe
warmed up again after this. */ static BROTLI_INLINE void BrotliCopyBytes(uint8_t* dest,
BrotliBitReader* br, size_t num) { while (BrotliGetAvailableBits(br) >= 8 && num > 0) {
*dest = (uint8_t)BrotliGetBitsUnmasked(br);
BrotliDropBits(br, 8);
++dest;
--num;
}
BrotliBitReaderNormalize(br); if (num > 0) {
memcpy(dest, br->next_in, num);
BrotliDropBytes(br, num);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.