github.com/la5nta/wl2k-go@v0.11.8/lzhuf/lzhuf.go (about) 1 // Copyright 2016 Martin Hebnes Pedersen (LA5NTA). All rights reserved. 2 // Use of this source code is governed by the MIT-license that can be 3 // found in the LICENSE file. 4 5 // Package lzhuf implements the lzhuf compression used by the binary FBB protocols B, B1 and B2. 6 // 7 // The compression is LZHUF with a CRC16 checksum of the compressed data prepended (B2F option). 8 package lzhuf 9 10 const ( 11 // LZHUF variables 12 _N = 2048 // Buffer size 13 _F = 60 // Lookahead buffer size 14 _NIL = _N // Leaf of tree 15 _NumChar = 256 - _Threshold + _F // Kinds of characters (character code = 0..N_CHAR-1) 16 _T = (_NumChar * 2) - 1 // Size of table 17 _R = _T - 1 // Position of root 18 _MaxFreq = 0x8000 // Updates tree when the 19 _Threshold = 2 20 ) 21 22 type lzhuf struct { 23 // Frequency table. 24 freq [_T + 1]uint 25 26 // Pointers to parent nodes. 27 // 28 // Expect for the elements [T..T+N_CHAR-1] which are 29 // used to get the positions of leaves corresponding to the codes. 30 prnt [_T + _NumChar]int 31 32 // Pointers to child nodes. 33 son [_T]int 34 35 dad [_N + 1]int 36 lson [_N + 1]int 37 rson [_N + 257]int 38 39 textBuf [_N + _F - 1]byte 40 matchLength int 41 matchPosition int 42 } 43 44 func (z *lzhuf) InitTree() { 45 for i := _N + 1; i <= _N+256; i++ { 46 z.rson[i] = _NIL // root 47 } 48 for i := 0; i < _N; i++ { 49 z.dad[i] = _NIL // node 50 } 51 } 52 53 // TODO: Should not be exported 54 func newLZHUFF() *lzhuf { 55 z := new(lzhuf) 56 57 for i := 0; i < _NumChar; i++ { 58 z.freq[i] = 1 59 z.son[i] = i + _T 60 z.prnt[i+_T] = i 61 } 62 63 for i, j := 0, _NumChar; j <= _R; { 64 z.freq[j] = z.freq[i] + z.freq[i+1] 65 z.son[j] = i 66 z.prnt[i] = j 67 z.prnt[i+1] = j 68 i += 2 69 j++ 70 } 71 z.freq[_T] = 0xffff 72 z.prnt[_R] = 0 73 74 return z 75 } 76 77 // Delete from tree 78 func (z *lzhuf) DeleteNode(p int) { 79 if z.dad[p] == _NIL { 80 return // not registered 81 } 82 83 var q int 84 switch { 85 case z.rson[p] == _NIL: 86 q = z.lson[p] 87 case z.lson[p] == _NIL: 88 q = z.rson[p] 89 default: 90 q = z.lson[p] 91 if z.rson[q] != _NIL { 92 for z.rson[q] != _NIL { 93 q = z.rson[q] 94 } 95 z.rson[z.dad[q]] = z.lson[q] 96 z.dad[z.lson[q]] = z.dad[q] 97 z.lson[q] = z.lson[p] 98 z.dad[z.lson[p]] = q 99 } 100 z.rson[q] = z.rson[p] 101 z.dad[z.rson[p]] = q 102 } 103 104 z.dad[q] = z.dad[p] 105 if z.rson[z.dad[p]] == p { 106 z.rson[z.dad[p]] = q 107 } else { 108 z.lson[z.dad[p]] = q 109 } 110 111 z.dad[p] = _NIL 112 } 113 114 // Insert to tree 115 func (z *lzhuf) InsertNode(r int) { 116 var i, p, cmp int 117 var key []byte 118 var c uint 119 120 cmp = 1 121 key = z.textBuf[r:] 122 p = _N + 1 + int(key[0]) 123 z.rson[r], z.lson[r] = _NIL, _NIL 124 z.matchLength = 0 125 for { 126 if cmp >= 0 { 127 if z.rson[p] != _NIL { 128 p = z.rson[p] 129 } else { 130 z.rson[p] = r 131 z.dad[r] = p 132 return 133 } 134 } else { 135 if z.lson[p] != _NIL { 136 p = z.lson[p] 137 } else { 138 z.lson[p] = r 139 z.dad[r] = p 140 return 141 } 142 } 143 for i = 1; i < _F; i++ { 144 cmp = int(key[i]) - int(z.textBuf[p+i]) 145 if cmp != 0 { 146 break 147 } 148 } 149 if i > _Threshold { 150 if i > z.matchLength { 151 z.matchPosition = ((r - p) & (_N - 1)) - 1 152 z.matchLength = i 153 if z.matchLength >= _F { 154 break 155 } 156 } 157 if i == z.matchLength { 158 c = uint(((r - p) & (_N - 1)) - 1) 159 if int(c) < z.matchPosition { 160 z.matchPosition = int(c) 161 } 162 } 163 } 164 } 165 z.dad[r] = z.dad[p] 166 z.lson[r] = z.lson[p] 167 z.rson[r] = z.rson[p] 168 z.dad[z.lson[p]] = r 169 z.dad[z.rson[p]] = r 170 if z.rson[z.dad[p]] == p { 171 z.rson[z.dad[p]] = r 172 } else { 173 z.lson[z.dad[p]] = r 174 } 175 z.dad[p] = _NIL // remove p 176 } 177 178 func (z *lzhuf) reconst() { 179 // collect leaf nodes in the first half of the table and replace the freq by (freq + 1) / 2 180 for i, j := 0, 0; i < _T; i++ { 181 if z.son[i] >= _T { 182 z.freq[j] = (z.freq[i] + 1) / 2 183 z.son[j] = z.son[i] 184 j++ 185 } 186 } 187 188 // Begin constructing tree by connecting children nodes 189 for i, j := 0, _NumChar; j < _T; i, j = i+2, j+1 { 190 k := i + 1 191 z.freq[j] = z.freq[i] + z.freq[k] 192 193 first := uint(z.freq[j]) 194 for k = j; first < uint(z.freq[k-1]); { 195 k-- 196 } 197 198 last := int(j - k) // Number of elements to move right 199 200 copy(z.freq[k+1:], z.freq[k:k+last]) 201 z.freq[k] = first 202 203 copy(z.son[k+1:], z.son[k:k+last]) 204 z.son[k] = i 205 } 206 207 // Connect parent nodes 208 for i := 0; i < _T; i++ { 209 k := z.son[i] 210 if k >= _T { 211 z.prnt[k] = i 212 } else { 213 z.prnt[k+1] = i 214 z.prnt[k] = i 215 } 216 } 217 } 218 219 func (z *lzhuf) update(c int) { 220 if z.freq[_R] == _MaxFreq { 221 z.reconst() 222 } 223 224 // Swap nodes to keep the tree freq-ordered 225 c = z.prnt[c+_T] 226 for { 227 z.freq[c]++ 228 229 if z.freq[c] <= z.freq[c+1] || len(z.freq) <= c+2 { 230 if c = z.prnt[c]; c == 0 { 231 break 232 } 233 continue // Order is ok 234 } 235 236 l, k := c+1, z.freq[c] 237 for k > z.freq[l+1] { 238 l++ 239 } 240 241 z.freq[c] = z.freq[l] 242 z.freq[l] = k 243 244 i := z.son[c] 245 z.prnt[i] = l 246 if i < _T { 247 z.prnt[i+1] = l 248 } 249 250 j := z.son[l] 251 z.son[l] = i 252 253 z.prnt[j] = c 254 if j < _T { 255 z.prnt[j+1] = c 256 } 257 z.son[c] = j 258 259 if c = z.prnt[l]; c == 0 { 260 break 261 } 262 } 263 } 264 265 /* 266 * Huffman coding 267 * 268 * table for encoding and decoding the upper 6 bits of position 269 */ 270 271 // for encoding 272 var pCode = [64]byte{ 273 0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68, 274 0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C, 275 0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC, 276 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, 277 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE, 278 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE, 279 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 280 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 281 } 282 var pLen = [64]byte{ 283 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 284 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 285 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 286 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 287 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 288 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 289 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 290 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 291 } 292 293 // for decoding 294 var dCode = [256]byte{ 295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 297 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 299 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 300 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 301 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 302 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 303 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 304 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 305 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 306 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 307 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 308 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 309 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 310 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 311 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 312 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 313 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 314 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, 315 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 316 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 317 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 318 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 319 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B, 320 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F, 321 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 322 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 323 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B, 324 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F, 325 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 326 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 327 } 328 var dLen = [256]byte{ 329 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 330 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 331 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 332 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 333 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 334 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 335 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 336 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 337 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 338 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 339 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 340 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 341 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 342 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 343 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 344 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 345 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 346 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 347 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 348 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 349 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 350 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 351 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 352 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 353 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 354 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 355 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 356 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 357 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 358 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 359 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 360 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 361 }