github.com/andybalholm/brotli@v1.0.6/bit_reader.go (about) 1 package brotli 2 3 import "encoding/binary" 4 5 /* Copyright 2013 Google Inc. All Rights Reserved. 6 7 Distributed under MIT license. 8 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 9 */ 10 11 /* Bit reading helpers */ 12 13 const shortFillBitWindowRead = (8 >> 1) 14 15 var kBitMask = [33]uint32{ 16 0x00000000, 17 0x00000001, 18 0x00000003, 19 0x00000007, 20 0x0000000F, 21 0x0000001F, 22 0x0000003F, 23 0x0000007F, 24 0x000000FF, 25 0x000001FF, 26 0x000003FF, 27 0x000007FF, 28 0x00000FFF, 29 0x00001FFF, 30 0x00003FFF, 31 0x00007FFF, 32 0x0000FFFF, 33 0x0001FFFF, 34 0x0003FFFF, 35 0x0007FFFF, 36 0x000FFFFF, 37 0x001FFFFF, 38 0x003FFFFF, 39 0x007FFFFF, 40 0x00FFFFFF, 41 0x01FFFFFF, 42 0x03FFFFFF, 43 0x07FFFFFF, 44 0x0FFFFFFF, 45 0x1FFFFFFF, 46 0x3FFFFFFF, 47 0x7FFFFFFF, 48 0xFFFFFFFF, 49 } 50 51 func bitMask(n uint32) uint32 { 52 return kBitMask[n] 53 } 54 55 type bitReader struct { 56 val_ uint64 57 bit_pos_ uint32 58 input []byte 59 input_len uint 60 byte_pos uint 61 } 62 63 type bitReaderState struct { 64 val_ uint64 65 bit_pos_ uint32 66 input []byte 67 input_len uint 68 byte_pos uint 69 } 70 71 /* Initializes the BrotliBitReader fields. */ 72 73 /* Ensures that accumulator is not empty. 74 May consume up to sizeof(brotli_reg_t) - 1 bytes of input. 75 Returns false if data is required but there is no input available. 76 For BROTLI_ALIGNED_READ this function also prepares bit reader for aligned 77 reading. */ 78 func bitReaderSaveState(from *bitReader, to *bitReaderState) { 79 to.val_ = from.val_ 80 to.bit_pos_ = from.bit_pos_ 81 to.input = from.input 82 to.input_len = from.input_len 83 to.byte_pos = from.byte_pos 84 } 85 86 func bitReaderRestoreState(to *bitReader, from *bitReaderState) { 87 to.val_ = from.val_ 88 to.bit_pos_ = from.bit_pos_ 89 to.input = from.input 90 to.input_len = from.input_len 91 to.byte_pos = from.byte_pos 92 } 93 94 func getAvailableBits(br *bitReader) uint32 { 95 return 64 - br.bit_pos_ 96 } 97 98 /* Returns amount of unread bytes the bit reader still has buffered from the 99 BrotliInput, including whole bytes in br->val_. */ 100 func getRemainingBytes(br *bitReader) uint { 101 return uint(uint32(br.input_len-br.byte_pos) + (getAvailableBits(br) >> 3)) 102 } 103 104 /* Checks if there is at least |num| bytes left in the input ring-buffer 105 (excluding the bits remaining in br->val_). */ 106 func checkInputAmount(br *bitReader, num uint) bool { 107 return br.input_len-br.byte_pos >= num 108 } 109 110 /* Guarantees that there are at least |n_bits| + 1 bits in accumulator. 111 Precondition: accumulator contains at least 1 bit. 112 |n_bits| should be in the range [1..24] for regular build. For portable 113 non-64-bit little-endian build only 16 bits are safe to request. */ 114 func fillBitWindow(br *bitReader, n_bits uint32) { 115 if br.bit_pos_ >= 32 { 116 br.val_ >>= 32 117 br.bit_pos_ ^= 32 /* here same as -= 32 because of the if condition */ 118 br.val_ |= (uint64(binary.LittleEndian.Uint32(br.input[br.byte_pos:]))) << 32 119 br.byte_pos += 4 120 } 121 } 122 123 /* Mostly like BrotliFillBitWindow, but guarantees only 16 bits and reads no 124 more than BROTLI_SHORT_FILL_BIT_WINDOW_READ bytes of input. */ 125 func fillBitWindow16(br *bitReader) { 126 fillBitWindow(br, 17) 127 } 128 129 /* Tries to pull one byte of input to accumulator. 130 Returns false if there is no input available. */ 131 func pullByte(br *bitReader) bool { 132 if br.byte_pos == br.input_len { 133 return false 134 } 135 136 br.val_ >>= 8 137 br.val_ |= (uint64(br.input[br.byte_pos])) << 56 138 br.bit_pos_ -= 8 139 br.byte_pos++ 140 return true 141 } 142 143 /* Returns currently available bits. 144 The number of valid bits could be calculated by BrotliGetAvailableBits. */ 145 func getBitsUnmasked(br *bitReader) uint64 { 146 return br.val_ >> br.bit_pos_ 147 } 148 149 /* Like BrotliGetBits, but does not mask the result. 150 The result contains at least 16 valid bits. */ 151 func get16BitsUnmasked(br *bitReader) uint32 { 152 fillBitWindow(br, 16) 153 return uint32(getBitsUnmasked(br)) 154 } 155 156 /* Returns the specified number of bits from |br| without advancing bit 157 position. */ 158 func getBits(br *bitReader, n_bits uint32) uint32 { 159 fillBitWindow(br, n_bits) 160 return uint32(getBitsUnmasked(br)) & bitMask(n_bits) 161 } 162 163 /* Tries to peek the specified amount of bits. Returns false, if there 164 is not enough input. */ 165 func safeGetBits(br *bitReader, n_bits uint32, val *uint32) bool { 166 for getAvailableBits(br) < n_bits { 167 if !pullByte(br) { 168 return false 169 } 170 } 171 172 *val = uint32(getBitsUnmasked(br)) & bitMask(n_bits) 173 return true 174 } 175 176 /* Advances the bit pos by |n_bits|. */ 177 func dropBits(br *bitReader, n_bits uint32) { 178 br.bit_pos_ += n_bits 179 } 180 181 func bitReaderUnload(br *bitReader) { 182 var unused_bytes uint32 = getAvailableBits(br) >> 3 183 var unused_bits uint32 = unused_bytes << 3 184 br.byte_pos -= uint(unused_bytes) 185 if unused_bits == 64 { 186 br.val_ = 0 187 } else { 188 br.val_ <<= unused_bits 189 } 190 191 br.bit_pos_ += unused_bits 192 } 193 194 /* Reads the specified number of bits from |br| and advances the bit pos. 195 Precondition: accumulator MUST contain at least |n_bits|. */ 196 func takeBits(br *bitReader, n_bits uint32, val *uint32) { 197 *val = uint32(getBitsUnmasked(br)) & bitMask(n_bits) 198 dropBits(br, n_bits) 199 } 200 201 /* Reads the specified number of bits from |br| and advances the bit pos. 202 Assumes that there is enough input to perform BrotliFillBitWindow. */ 203 func readBits(br *bitReader, n_bits uint32) uint32 { 204 var val uint32 205 fillBitWindow(br, n_bits) 206 takeBits(br, n_bits, &val) 207 return val 208 } 209 210 /* Tries to read the specified amount of bits. Returns false, if there 211 is not enough input. |n_bits| MUST be positive. */ 212 func safeReadBits(br *bitReader, n_bits uint32, val *uint32) bool { 213 for getAvailableBits(br) < n_bits { 214 if !pullByte(br) { 215 return false 216 } 217 } 218 219 takeBits(br, n_bits, val) 220 return true 221 } 222 223 /* Advances the bit reader position to the next byte boundary and verifies 224 that any skipped bits are set to zero. */ 225 func bitReaderJumpToByteBoundary(br *bitReader) bool { 226 var pad_bits_count uint32 = getAvailableBits(br) & 0x7 227 var pad_bits uint32 = 0 228 if pad_bits_count != 0 { 229 takeBits(br, pad_bits_count, &pad_bits) 230 } 231 232 return pad_bits == 0 233 } 234 235 /* Copies remaining input bytes stored in the bit reader to the output. Value 236 |num| may not be larger than BrotliGetRemainingBytes. The bit reader must be 237 warmed up again after this. */ 238 func copyBytes(dest []byte, br *bitReader, num uint) { 239 for getAvailableBits(br) >= 8 && num > 0 { 240 dest[0] = byte(getBitsUnmasked(br)) 241 dropBits(br, 8) 242 dest = dest[1:] 243 num-- 244 } 245 246 copy(dest, br.input[br.byte_pos:][:num]) 247 br.byte_pos += num 248 } 249 250 func initBitReader(br *bitReader) { 251 br.val_ = 0 252 br.bit_pos_ = 64 253 } 254 255 func warmupBitReader(br *bitReader) bool { 256 /* Fixing alignment after unaligned BrotliFillWindow would result accumulator 257 overflow. If unalignment is caused by BrotliSafeReadBits, then there is 258 enough space in accumulator to fix alignment. */ 259 if getAvailableBits(br) == 0 { 260 if !pullByte(br) { 261 return false 262 } 263 } 264 265 return true 266 }