Beispiel #1
0
// 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
}
Beispiel #2
0
// 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
}
Beispiel #3
0
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)
}
Beispiel #4
0
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
}