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[:]) }
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[:]) }
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) } }
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) } } }
// 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 } } } }