Beispiel #1
0
func init() {
	var selCodes [maxNumTrees + 1]prefix.PrefixCode
	for i := range selCodes {
		selCodes[i] = prefix.PrefixCode{Sym: uint32(i), Len: uint32(i + 1)}
	}
	selCodes[maxNumTrees] = prefix.PrefixCode{Sym: maxNumTrees, Len: maxNumTrees}
	prefix.GeneratePrefixes(selCodes[:])
	decSel.Init(selCodes[:])
	encSel.Init(selCodes[:])
}
Beispiel #2
0
func init() {
	// These come from the RFC section 3.2.5.
	lenRanges = append(prefix.MakeRangeCodes(3, []uint{
		0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5,
	}), prefix.RangeCode{Base: 258, Len: 0})
	distRanges = prefix.MakeRangeCodes(1, []uint{
		0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
	})

	// These come from the RFC section 3.2.6.
	var litCodes [288]prefix.PrefixCode
	for i := 0; i < 144; i++ {
		litCodes[i] = prefix.PrefixCode{Sym: uint32(i), Len: 8}
	}
	for i := 144; i < 256; i++ {
		litCodes[i] = prefix.PrefixCode{Sym: uint32(i), Len: 9}
	}
	for i := 256; i < 280; i++ {
		litCodes[i] = prefix.PrefixCode{Sym: uint32(i), Len: 7}
	}
	for i := 280; i < 288; i++ {
		litCodes[i] = prefix.PrefixCode{Sym: uint32(i), Len: 8}
	}
	prefix.GeneratePrefixes(litCodes[:])
	decLit.Init(litCodes[:])
	encLit.Init(litCodes[:])

	// These come from the RFC section 3.2.6.
	var distCodes [32]prefix.PrefixCode
	for i := 0; i < 32; i++ {
		distCodes[i] = prefix.PrefixCode{Sym: uint32(i), Len: 5}
	}
	prefix.GeneratePrefixes(distCodes[:])
	decDist.Init(distCodes[:])
	encDist.Init(distCodes[:])
}
Beispiel #3
0
func (pr *prefixReader) ReadPrefixCodes(codes []prefix.PrefixCodes, trees []prefix.Decoder) {
	for i, pc := range codes {
		clen := int(pr.ReadBitsBE64(5))
		sum := 1 << maxPrefixBits
		for sym := 0; sym < len(pc); sym++ {
			for {
				if clen < 1 || clen > maxPrefixBits {
					panic(ErrCorrupt)
				}

				b, ok := pr.TryReadBits(1)
				if !ok {
					b = pr.ReadBits(1)
				}
				if b == 0 {
					break
				}

				b, ok = pr.TryReadBits(1)
				if !ok {
					b = pr.ReadBits(1)
				}
				clen -= int(b*2) - 1 // +1 or -1
			}
			pc[sym] = prefix.PrefixCode{Sym: uint32(sym), Len: uint32(clen)}
			sum -= (1 << maxPrefixBits) >> uint(clen)
		}

		if sum == 0 {
			// Fast path, but only handles complete trees.
			if err := prefix.GeneratePrefixes(pc); err != nil {
				panic(err)
			}
		} else {
			// Slow path, but handles anything.
			pc = handleDegenerateCodes(pc)
			codes[i] = pc
		}
		trees[i].Init(pc)
	}
}
Beispiel #4
0
func (pw *prefixWriter) WritePrefixCodes(codes []prefix.PrefixCodes, trees []prefix.Encoder) {
	for i, pc := range codes {
		if err := prefix.GeneratePrefixes(pc); err != nil {
			panic(err)
		}
		trees[i].Init(pc)

		clen := int(pc[0].Len)
		pw.WriteBitsBE64(uint64(clen), 5)
		for _, c := range pc {
			for int(c.Len) < clen {
				pw.WriteBits(3, 2) // 11
				clen--
			}
			for int(c.Len) > clen {
				pw.WriteBits(1, 2) // 10
				clen++
			}
			pw.WriteBits(0, 1)
		}
	}
}
Beispiel #5
0
// ReadPrefixCodes reads the literal and distance prefix codes according to
// RFC section 3.2.7.
func (pr *prefixReader) ReadPrefixCodes(hl, hd *prefix.Decoder) {
	numLitSyms := pr.ReadBits(5) + 257
	numDistSyms := pr.ReadBits(5) + 1
	numCLenSyms := pr.ReadBits(4) + 4
	if numLitSyms > maxNumLitSyms || numDistSyms > maxNumDistSyms {
		panic(ErrCorrupt)
	}

	// Read the code-lengths prefix table.
	var codeCLensArr [maxNumCLenSyms]prefix.PrefixCode // Sorted, but may have holes
	for _, sym := range clenLens[:numCLenSyms] {
		clen := pr.ReadBits(3)
		if clen > 0 {
			codeCLensArr[sym] = prefix.PrefixCode{Sym: uint32(sym), Len: uint32(clen)}
		}
	}
	codeCLens := codeCLensArr[:0] // Compact the array to have no holes
	for _, c := range codeCLensArr {
		if c.Len > 0 {
			codeCLens = append(codeCLens, c)
		}
	}
	codeCLens = handleDegenerateCodes(codeCLens, maxNumCLenSyms)
	if err := prefix.GeneratePrefixes(codeCLens); err != nil {
		panic(err)
	}
	pr.clenTree.Init(codeCLens)

	// Use code-lengths table to decode HLIT and HDIST prefix tables.
	var codesArr [maxNumLitSyms + maxNumDistSyms]prefix.PrefixCode
	var clenLast uint
	codeLits := codesArr[:0]
	codeDists := codesArr[maxNumLitSyms:maxNumLitSyms]
	appendCode := func(sym, clen uint) {
		if sym < numLitSyms {
			pc := prefix.PrefixCode{Sym: uint32(sym), Len: uint32(clen)}
			codeLits = append(codeLits, pc)
		} else {
			pc := prefix.PrefixCode{Sym: uint32(sym - numLitSyms), Len: uint32(clen)}
			codeDists = append(codeDists, pc)
		}
	}
	for sym, maxSyms := uint(0), numLitSyms+numDistSyms; sym < maxSyms; {
		clen := pr.ReadSymbol(&pr.clenTree)
		if clen < 16 {
			// Literal bit-length symbol used.
			if clen > 0 {
				appendCode(sym, clen)
			}
			clenLast = clen
			sym++
		} else {
			// Repeater symbol used.
			var repCnt uint
			switch repSym := clen; repSym {
			case 16:
				if sym == 0 {
					panic(ErrCorrupt)
				}
				clen = clenLast
				repCnt = 3 + pr.ReadBits(2)
			case 17:
				clen = 0
				repCnt = 3 + pr.ReadBits(3)
			case 18:
				clen = 0
				repCnt = 11 + pr.ReadBits(7)
			default:
				panic(ErrCorrupt)
			}

			if clen > 0 {
				for symEnd := sym + repCnt; sym < symEnd; sym++ {
					appendCode(sym, clen)
				}
			} else {
				sym += repCnt
			}
			if sym > maxSyms {
				panic(ErrCorrupt)
			}
		}
	}

	codeLits = handleDegenerateCodes(codeLits, maxNumLitSyms)
	if err := prefix.GeneratePrefixes(codeLits); err != nil {
		panic(err)
	}
	hl.Init(codeLits)

	codeDists = handleDegenerateCodes(codeDists, maxNumDistSyms)
	if err := prefix.GeneratePrefixes(codeDists); err != nil {
		panic(err)
	}
	hd.Init(codeDists)

	// As an optimization, we can initialize minBits to read at a time for the
	// HLIT tree to the length of the EOB marker since we know that every block
	// must terminate with one. This preserves the property that we never read
	// any extra bytes after the end of the DEFLATE stream.
	//
	// This optimization is not helpful if the underlying reader is a
	// compress.BufferedReader since PullBits always fill the entire bit buffer.
	if !pr.IsBufferedReader() {
		for i := len(codeLits) - 1; i >= 0; i-- {
			if codeLits[i].Sym == 256 && codeLits[i].Len > 0 {
				hl.MinBits = codeLits[i].Len
				break
			}
		}
	}
}