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  }