// checkCanonical reports whether all codes are canonical. func (pc PrefixCodes) checkCanonical() bool { // Rule #1: All codes of a given bit-length are consecutive values. var vals [valueBits + 1]PrefixCode for _, c := range pc { if c.Len > 0 { c.Val = internal.ReverseUint32N(c.Val, uint(c.Len)) if vals[c.Len].Cnt > 0 && vals[c.Len].Val+1 != c.Val { return false } vals[c.Len].Val = c.Val vals[c.Len].Cnt++ } } // Rule #2: Shorter codes lexicographically precede longer codes. var last PrefixCode for _, v := range vals { if v.Cnt > 0 { curVal := v.Val - uint32(v.Cnt) + 1 if last.Cnt != 0 && last.Val >= curVal { return false } last = v } } return true }
// GeneratePrefixes assigns a prefix value to all codes according to the // bit-lengths. This function is used by both compressors and decompressors. // // The input codes must have the Sym and Len fields populated, be sorted by // symbol and be densely packed. The bit-lengths of each code must be properly // allocated, such that it forms a complete tree. // // The result will have the Val field populated and will produce a canonical // prefix tree. func GeneratePrefixes(codes PrefixCodes) error { if len(codes) <= 1 { if len(codes) == 1 { if codes[0].Len != 0 { return internal.ErrInvalid } codes[0].Val = 0 } return nil } // Compute basic statistics on the symbols. var bitCnts [valueBits + 1]uint c0 := codes[0] bitCnts[c0.Len]++ minBits, maxBits, symLast := c0.Len, c0.Len, c0.Sym for _, c := range codes[1:] { if c.Sym <= symLast { return internal.ErrInvalid // Non-unique or non-monotonically increasing } if minBits > c.Len { minBits = c.Len } if maxBits < c.Len { maxBits = c.Len } bitCnts[c.Len]++ // Histogram of bit counts symLast = c.Sym // Keep track of last symbol } if minBits == 0 { return internal.ErrInvalid // Bit-length is too short } // Compute the next code for a symbol of a given bit length. var nextCodes [valueBits + 1]uint var code uint for i := minBits; i <= maxBits; i++ { code <<= 1 nextCodes[i] = code code += bitCnts[i] } if code != 1<<maxBits { return internal.ErrInvalid // Tree is under or over subscribed } // Assign the code to each symbol. for i, c := range codes { codes[i].Val = internal.ReverseUint32N(uint32(nextCodes[c.Len]), uint(c.Len)) nextCodes[c.Len]++ } if internal.Debug && !codes.checkPrefixes() { panic("overlapping prefixes detected") } if internal.Debug && !codes.checkCanonical() { panic("non-canonical prefixes detected") } return nil }
func (pr *prefixReader) ReadBitsBE64(nb uint) uint64 { if nb <= 32 { v := uint32(pr.ReadBits(nb)) return uint64(internal.ReverseUint32N(v, nb)) } v0 := internal.ReverseUint32(uint32(pr.ReadBits(32))) v1 := internal.ReverseUint32(uint32(pr.ReadBits(nb - 32))) v := uint64(v0)<<32 | uint64(v1) return v >> (64 - nb) }
func (pw *prefixWriter) WriteBitsBE64(v uint64, nb uint) { if nb <= 32 { v := internal.ReverseUint32N(uint32(v), nb) pw.WriteBits(uint(v), nb) return } v <<= (64 - nb) v0 := internal.ReverseUint32(uint32(v >> 32)) v1 := internal.ReverseUint32(uint32(v)) pw.WriteBits(uint(v0), 32) pw.WriteBits(uint(v1), nb-32) return }