github.com/andybalholm/brotli@v1.0.6/command.go (about) 1 package brotli 2 3 var kInsBase = []uint32{ 4 0, 5 1, 6 2, 7 3, 8 4, 9 5, 10 6, 11 8, 12 10, 13 14, 14 18, 15 26, 16 34, 17 50, 18 66, 19 98, 20 130, 21 194, 22 322, 23 578, 24 1090, 25 2114, 26 6210, 27 22594, 28 } 29 30 var kInsExtra = []uint32{ 31 0, 32 0, 33 0, 34 0, 35 0, 36 0, 37 1, 38 1, 39 2, 40 2, 41 3, 42 3, 43 4, 44 4, 45 5, 46 5, 47 6, 48 7, 49 8, 50 9, 51 10, 52 12, 53 14, 54 24, 55 } 56 57 var kCopyBase = []uint32{ 58 2, 59 3, 60 4, 61 5, 62 6, 63 7, 64 8, 65 9, 66 10, 67 12, 68 14, 69 18, 70 22, 71 30, 72 38, 73 54, 74 70, 75 102, 76 134, 77 198, 78 326, 79 582, 80 1094, 81 2118, 82 } 83 84 var kCopyExtra = []uint32{ 85 0, 86 0, 87 0, 88 0, 89 0, 90 0, 91 0, 92 0, 93 1, 94 1, 95 2, 96 2, 97 3, 98 3, 99 4, 100 4, 101 5, 102 5, 103 6, 104 7, 105 8, 106 9, 107 10, 108 24, 109 } 110 111 func getInsertLengthCode(insertlen uint) uint16 { 112 if insertlen < 6 { 113 return uint16(insertlen) 114 } else if insertlen < 130 { 115 var nbits uint32 = log2FloorNonZero(insertlen-2) - 1 116 return uint16((nbits << 1) + uint32((insertlen-2)>>nbits) + 2) 117 } else if insertlen < 2114 { 118 return uint16(log2FloorNonZero(insertlen-66) + 10) 119 } else if insertlen < 6210 { 120 return 21 121 } else if insertlen < 22594 { 122 return 22 123 } else { 124 return 23 125 } 126 } 127 128 func getCopyLengthCode(copylen uint) uint16 { 129 if copylen < 10 { 130 return uint16(copylen - 2) 131 } else if copylen < 134 { 132 var nbits uint32 = log2FloorNonZero(copylen-6) - 1 133 return uint16((nbits << 1) + uint32((copylen-6)>>nbits) + 4) 134 } else if copylen < 2118 { 135 return uint16(log2FloorNonZero(copylen-70) + 12) 136 } else { 137 return 23 138 } 139 } 140 141 func combineLengthCodes(inscode uint16, copycode uint16, use_last_distance bool) uint16 { 142 var bits64 uint16 = uint16(copycode&0x7 | (inscode&0x7)<<3) 143 if use_last_distance && inscode < 8 && copycode < 16 { 144 if copycode < 8 { 145 return bits64 146 } else { 147 return bits64 | 64 148 } 149 } else { 150 /* Specification: 5 Encoding of ... (last table) */ 151 /* offset = 2 * index, where index is in range [0..8] */ 152 var offset uint32 = 2 * ((uint32(copycode) >> 3) + 3*(uint32(inscode)>>3)) 153 154 /* All values in specification are K * 64, 155 where K = [2, 3, 6, 4, 5, 8, 7, 9, 10], 156 i + 1 = [1, 2, 3, 4, 5, 6, 7, 8, 9], 157 K - i - 1 = [1, 1, 3, 0, 0, 2, 0, 1, 2] = D. 158 All values in D require only 2 bits to encode. 159 Magic constant is shifted 6 bits left, to avoid final multiplication. */ 160 offset = (offset << 5) + 0x40 + ((0x520D40 >> offset) & 0xC0) 161 162 return uint16(offset | uint32(bits64)) 163 } 164 } 165 166 func getLengthCode(insertlen uint, copylen uint, use_last_distance bool, code *uint16) { 167 var inscode uint16 = getInsertLengthCode(insertlen) 168 var copycode uint16 = getCopyLengthCode(copylen) 169 *code = combineLengthCodes(inscode, copycode, use_last_distance) 170 } 171 172 func getInsertBase(inscode uint16) uint32 { 173 return kInsBase[inscode] 174 } 175 176 func getInsertExtra(inscode uint16) uint32 { 177 return kInsExtra[inscode] 178 } 179 180 func getCopyBase(copycode uint16) uint32 { 181 return kCopyBase[copycode] 182 } 183 184 func getCopyExtra(copycode uint16) uint32 { 185 return kCopyExtra[copycode] 186 } 187 188 type command struct { 189 insert_len_ uint32 190 copy_len_ uint32 191 dist_extra_ uint32 192 cmd_prefix_ uint16 193 dist_prefix_ uint16 194 } 195 196 /* distance_code is e.g. 0 for same-as-last short code, or 16 for offset 1. */ 197 func makeCommand(dist *distanceParams, insertlen uint, copylen uint, copylen_code_delta int, distance_code uint) (cmd command) { 198 /* Don't rely on signed int representation, use honest casts. */ 199 var delta uint32 = uint32(byte(int8(copylen_code_delta))) 200 cmd.insert_len_ = uint32(insertlen) 201 cmd.copy_len_ = uint32(uint32(copylen) | delta<<25) 202 203 /* The distance prefix and extra bits are stored in this Command as if 204 npostfix and ndirect were 0, they are only recomputed later after the 205 clustering if needed. */ 206 prefixEncodeCopyDistance(distance_code, uint(dist.num_direct_distance_codes), uint(dist.distance_postfix_bits), &cmd.dist_prefix_, &cmd.dist_extra_) 207 getLengthCode(insertlen, uint(int(copylen)+copylen_code_delta), (cmd.dist_prefix_&0x3FF == 0), &cmd.cmd_prefix_) 208 209 return cmd 210 } 211 212 func makeInsertCommand(insertlen uint) (cmd command) { 213 cmd.insert_len_ = uint32(insertlen) 214 cmd.copy_len_ = 4 << 25 215 cmd.dist_extra_ = 0 216 cmd.dist_prefix_ = numDistanceShortCodes 217 getLengthCode(insertlen, 4, false, &cmd.cmd_prefix_) 218 return cmd 219 } 220 221 func commandRestoreDistanceCode(self *command, dist *distanceParams) uint32 { 222 if uint32(self.dist_prefix_&0x3FF) < numDistanceShortCodes+dist.num_direct_distance_codes { 223 return uint32(self.dist_prefix_) & 0x3FF 224 } else { 225 var dcode uint32 = uint32(self.dist_prefix_) & 0x3FF 226 var nbits uint32 = uint32(self.dist_prefix_) >> 10 227 var extra uint32 = self.dist_extra_ 228 var postfix_mask uint32 = (1 << dist.distance_postfix_bits) - 1 229 var hcode uint32 = (dcode - dist.num_direct_distance_codes - numDistanceShortCodes) >> dist.distance_postfix_bits 230 var lcode uint32 = (dcode - dist.num_direct_distance_codes - numDistanceShortCodes) & postfix_mask 231 var offset uint32 = ((2 + (hcode & 1)) << nbits) - 4 232 return ((offset + extra) << dist.distance_postfix_bits) + lcode + dist.num_direct_distance_codes + numDistanceShortCodes 233 } 234 } 235 236 func commandDistanceContext(self *command) uint32 { 237 var r uint32 = uint32(self.cmd_prefix_) >> 6 238 var c uint32 = uint32(self.cmd_prefix_) & 7 239 if (r == 0 || r == 2 || r == 4 || r == 7) && (c <= 2) { 240 return c 241 } 242 243 return 3 244 } 245 246 func commandCopyLen(self *command) uint32 { 247 return self.copy_len_ & 0x1FFFFFF 248 } 249 250 func commandCopyLenCode(self *command) uint32 { 251 var modifier uint32 = self.copy_len_ >> 25 252 var delta int32 = int32(int8(byte(modifier | (modifier&0x40)<<1))) 253 return uint32(int32(self.copy_len_&0x1FFFFFF) + delta) 254 }