123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- package flate
- import (
- "math"
- "sort"
- )
- type hcode struct {
- code, len uint16
- }
- type huffmanEncoder struct {
- codes []hcode
- freqcache []literalNode
- bitCount [17]int32
- lns byLiteral
- lfs byFreq
- }
- type literalNode struct {
- literal uint16
- freq int32
- }
- type levelInfo struct {
-
- level int32
-
- lastFreq int32
-
- nextCharFreq int32
-
-
- nextPairFreq int32
-
-
- needed int32
- }
- func (h *hcode) set(code uint16, length uint16) {
- h.len = length
- h.code = code
- }
- func maxNode() literalNode { return literalNode{math.MaxUint16, math.MaxInt32} }
- func newHuffmanEncoder(size int) *huffmanEncoder {
- return &huffmanEncoder{codes: make([]hcode, size)}
- }
- func generateFixedLiteralEncoding() *huffmanEncoder {
- h := newHuffmanEncoder(maxNumLit)
- codes := h.codes
- var ch uint16
- for ch = 0; ch < maxNumLit; ch++ {
- var bits uint16
- var size uint16
- switch {
- case ch < 144:
-
- bits = ch + 48
- size = 8
- break
- case ch < 256:
-
- bits = ch + 400 - 144
- size = 9
- break
- case ch < 280:
-
- bits = ch - 256
- size = 7
- break
- default:
-
- bits = ch + 192 - 280
- size = 8
- }
- codes[ch] = hcode{code: reverseBits(bits, byte(size)), len: size}
- }
- return h
- }
- func generateFixedOffsetEncoding() *huffmanEncoder {
- h := newHuffmanEncoder(30)
- codes := h.codes
- for ch := range codes {
- codes[ch] = hcode{code: reverseBits(uint16(ch), 5), len: 5}
- }
- return h
- }
- var fixedLiteralEncoding *huffmanEncoder = generateFixedLiteralEncoding()
- var fixedOffsetEncoding *huffmanEncoder = generateFixedOffsetEncoding()
- func (h *huffmanEncoder) bitLength(freq []int32) int {
- var total int
- for i, f := range freq {
- if f != 0 {
- total += int(f) * int(h.codes[i].len)
- }
- }
- return total
- }
- const maxBitsLimit = 16
- func (h *huffmanEncoder) bitCounts(list []literalNode, maxBits int32) []int32 {
- if maxBits >= maxBitsLimit {
- panic("flate: maxBits too large")
- }
- n := int32(len(list))
- list = list[0 : n+1]
- list[n] = maxNode()
-
-
- if maxBits > n-1 {
- maxBits = n - 1
- }
-
-
-
-
- var levels [maxBitsLimit]levelInfo
-
-
-
-
- var leafCounts [maxBitsLimit][maxBitsLimit]int32
- for level := int32(1); level <= maxBits; level++ {
-
-
- levels[level] = levelInfo{
- level: level,
- lastFreq: list[1].freq,
- nextCharFreq: list[2].freq,
- nextPairFreq: list[0].freq + list[1].freq,
- }
- leafCounts[level][level] = 2
- if level == 1 {
- levels[level].nextPairFreq = math.MaxInt32
- }
- }
-
- levels[maxBits].needed = 2*n - 4
- level := maxBits
- for {
- l := &levels[level]
- if l.nextPairFreq == math.MaxInt32 && l.nextCharFreq == math.MaxInt32 {
-
-
-
-
- l.needed = 0
- levels[level+1].nextPairFreq = math.MaxInt32
- level++
- continue
- }
- prevFreq := l.lastFreq
- if l.nextCharFreq < l.nextPairFreq {
-
- n := leafCounts[level][level] + 1
- l.lastFreq = l.nextCharFreq
-
- leafCounts[level][level] = n
- l.nextCharFreq = list[n].freq
- } else {
-
-
-
- l.lastFreq = l.nextPairFreq
-
- copy(leafCounts[level][:level], leafCounts[level-1][:level])
- levels[l.level-1].needed = 2
- }
- if l.needed--; l.needed == 0 {
-
-
-
-
- if l.level == maxBits {
-
- break
- }
- levels[l.level+1].nextPairFreq = prevFreq + l.lastFreq
- level++
- } else {
-
- for levels[level-1].needed > 0 {
- level--
- }
- }
- }
-
-
- if leafCounts[maxBits][maxBits] != n {
- panic("leafCounts[maxBits][maxBits] != n")
- }
- bitCount := h.bitCount[:maxBits+1]
- bits := 1
- counts := &leafCounts[maxBits]
- for level := maxBits; level > 0; level-- {
-
-
- bitCount[bits] = counts[level] - counts[level-1]
- bits++
- }
- return bitCount
- }
- func (h *huffmanEncoder) assignEncodingAndSize(bitCount []int32, list []literalNode) {
- code := uint16(0)
- for n, bits := range bitCount {
- code <<= 1
- if n == 0 || bits == 0 {
- continue
- }
-
-
-
-
- chunk := list[len(list)-int(bits):]
- h.lns.sort(chunk)
- for _, node := range chunk {
- h.codes[node.literal] = hcode{code: reverseBits(code, uint8(n)), len: uint16(n)}
- code++
- }
- list = list[0 : len(list)-int(bits)]
- }
- }
- func (h *huffmanEncoder) generate(freq []int32, maxBits int32) {
- if h.freqcache == nil {
-
-
-
- h.freqcache = make([]literalNode, maxNumLit+1)
- }
- list := h.freqcache[:len(freq)+1]
-
- count := 0
-
- for i, f := range freq {
- if f != 0 {
- list[count] = literalNode{uint16(i), f}
- count++
- } else {
- list[count] = literalNode{}
- h.codes[i].len = 0
- }
- }
- list[len(freq)] = literalNode{}
- list = list[:count]
- if count <= 2 {
-
-
- for i, node := range list {
-
- h.codes[node.literal].set(uint16(i), 1)
- }
- return
- }
- h.lfs.sort(list)
-
- bitCount := h.bitCounts(list, maxBits)
-
- h.assignEncodingAndSize(bitCount, list)
- }
- type byLiteral []literalNode
- func (s *byLiteral) sort(a []literalNode) {
- *s = byLiteral(a)
- sort.Sort(s)
- }
- func (s byLiteral) Len() int { return len(s) }
- func (s byLiteral) Less(i, j int) bool {
- return s[i].literal < s[j].literal
- }
- func (s byLiteral) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
- type byFreq []literalNode
- func (s *byFreq) sort(a []literalNode) {
- *s = byFreq(a)
- sort.Sort(s)
- }
- func (s byFreq) Len() int { return len(s) }
- func (s byFreq) Less(i, j int) bool {
- if s[i].freq == s[j].freq {
- return s[i].literal < s[j].literal
- }
- return s[i].freq < s[j].freq
- }
- func (s byFreq) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|