github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/src/compress/flate/huffman_bit_writer.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package flate
     6  
     7  import (
     8  	"io"
     9  	"math"
    10  )
    11  
    12  const (
    13  	// The largest offset code.
    14  	offsetCodeCount = 30
    15  
    16  	// The special code used to mark the end of a block.
    17  	endBlockMarker = 256
    18  
    19  	// The first length code.
    20  	lengthCodesStart = 257
    21  
    22  	// The number of codegen codes.
    23  	codegenCodeCount = 19
    24  	badCode          = 255
    25  
    26  	// bufferFlushSize indicates the buffer size
    27  	// after which bytes are flushed to the writer.
    28  	// Should preferably be a multiple of 6, since
    29  	// we accumulate 6 bytes between writes to the buffer.
    30  	bufferFlushSize = 240
    31  
    32  	// bufferSize is the actual output byte buffer size.
    33  	// It must have additional headroom for a flush
    34  	// which can contain up to 8 bytes.
    35  	bufferSize = bufferFlushSize + 8
    36  )
    37  
    38  // The number of extra bits needed by length code X - LENGTH_CODES_START.
    39  var lengthExtraBits = []int8{
    40  	/* 257 */ 0, 0, 0,
    41  	/* 260 */ 0, 0, 0, 0, 0, 1, 1, 1, 1, 2,
    42  	/* 270 */ 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
    43  	/* 280 */ 4, 5, 5, 5, 5, 0,
    44  }
    45  
    46  // The length indicated by length code X - LENGTH_CODES_START.
    47  var lengthBase = []uint32{
    48  	0, 1, 2, 3, 4, 5, 6, 7, 8, 10,
    49  	12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
    50  	64, 80, 96, 112, 128, 160, 192, 224, 255,
    51  }
    52  
    53  // offset code word extra bits.
    54  var offsetExtraBits = []int8{
    55  	0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
    56  	4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
    57  	9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
    58  	/* extended window */
    59  	14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20,
    60  }
    61  
    62  var offsetBase = []uint32{
    63  	/* normal deflate */
    64  	0x000000, 0x000001, 0x000002, 0x000003, 0x000004,
    65  	0x000006, 0x000008, 0x00000c, 0x000010, 0x000018,
    66  	0x000020, 0x000030, 0x000040, 0x000060, 0x000080,
    67  	0x0000c0, 0x000100, 0x000180, 0x000200, 0x000300,
    68  	0x000400, 0x000600, 0x000800, 0x000c00, 0x001000,
    69  	0x001800, 0x002000, 0x003000, 0x004000, 0x006000,
    70  
    71  	/* extended window */
    72  	0x008000, 0x00c000, 0x010000, 0x018000, 0x020000,
    73  	0x030000, 0x040000, 0x060000, 0x080000, 0x0c0000,
    74  	0x100000, 0x180000, 0x200000, 0x300000,
    75  }
    76  
    77  // The odd order in which the codegen code sizes are written.
    78  var codegenOrder = []uint32{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}
    79  
    80  type huffmanBitWriter struct {
    81  	w io.Writer
    82  	// Data waiting to be written is bytes[0:nbytes]
    83  	// and then the low nbits of bits.
    84  	bits            uint64
    85  	nbits           uint
    86  	bytes           [bufferSize]byte
    87  	nbytes          int
    88  	literalFreq     []int32
    89  	offsetFreq      []int32
    90  	codegen         []uint8
    91  	codegenFreq     []int32
    92  	literalEncoding *huffmanEncoder
    93  	offsetEncoding  *huffmanEncoder
    94  	codegenEncoding *huffmanEncoder
    95  	err             error
    96  }
    97  
    98  func newHuffmanBitWriter(w io.Writer) *huffmanBitWriter {
    99  	return &huffmanBitWriter{
   100  		w:               w,
   101  		literalFreq:     make([]int32, maxNumLit),
   102  		offsetFreq:      make([]int32, offsetCodeCount),
   103  		codegen:         make([]uint8, maxNumLit+offsetCodeCount+1),
   104  		codegenFreq:     make([]int32, codegenCodeCount),
   105  		literalEncoding: newHuffmanEncoder(maxNumLit),
   106  		codegenEncoding: newHuffmanEncoder(codegenCodeCount),
   107  		offsetEncoding:  newHuffmanEncoder(offsetCodeCount),
   108  	}
   109  }
   110  
   111  func (w *huffmanBitWriter) reset(writer io.Writer) {
   112  	w.w = writer
   113  	w.bits, w.nbits, w.nbytes, w.err = 0, 0, 0, nil
   114  	w.bytes = [bufferSize]byte{}
   115  }
   116  
   117  func (w *huffmanBitWriter) flush() {
   118  	if w.err != nil {
   119  		w.nbits = 0
   120  		return
   121  	}
   122  	n := w.nbytes
   123  	for w.nbits != 0 {
   124  		w.bytes[n] = byte(w.bits)
   125  		w.bits >>= 8
   126  		if w.nbits > 8 { // Avoid underflow
   127  			w.nbits -= 8
   128  		} else {
   129  			w.nbits = 0
   130  		}
   131  		n++
   132  	}
   133  	w.bits = 0
   134  	_, w.err = w.w.Write(w.bytes[:n])
   135  	w.nbytes = 0
   136  }
   137  
   138  func (w *huffmanBitWriter) writeBits(b int32, nb uint) {
   139  	w.bits |= uint64(b) << w.nbits
   140  	w.nbits += nb
   141  	if w.nbits >= 48 {
   142  		bits := w.bits
   143  		w.bits >>= 48
   144  		w.nbits -= 48
   145  		n := w.nbytes
   146  		w.bytes[n+0] = byte(bits)
   147  		w.bytes[n+1] = byte(bits >> 8)
   148  		w.bytes[n+2] = byte(bits >> 16)
   149  		w.bytes[n+3] = byte(bits >> 24)
   150  		w.bytes[n+4] = byte(bits >> 32)
   151  		w.bytes[n+5] = byte(bits >> 40)
   152  		n += 6
   153  		if n >= bufferFlushSize {
   154  			_, w.err = w.w.Write(w.bytes[:n])
   155  			n = 0
   156  		}
   157  		w.nbytes = n
   158  	}
   159  }
   160  
   161  func (w *huffmanBitWriter) writeBytes(bytes []byte) {
   162  	if w.err != nil {
   163  		return
   164  	}
   165  	n := w.nbytes
   166  	if w.nbits&7 != 0 {
   167  		w.err = InternalError("writeBytes with unfinished bits")
   168  		return
   169  	}
   170  	for w.nbits != 0 {
   171  		w.bytes[n] = byte(w.bits)
   172  		w.bits >>= 8
   173  		w.nbits -= 8
   174  		n++
   175  	}
   176  	if n != 0 {
   177  		_, w.err = w.w.Write(w.bytes[:n])
   178  		if w.err != nil {
   179  			return
   180  		}
   181  	}
   182  	w.nbytes = 0
   183  	_, w.err = w.w.Write(bytes)
   184  }
   185  
   186  // RFC 1951 3.2.7 specifies a special run-length encoding for specifying
   187  // the literal and offset lengths arrays (which are concatenated into a single
   188  // array).  This method generates that run-length encoding.
   189  //
   190  // The result is written into the codegen array, and the frequencies
   191  // of each code is written into the codegenFreq array.
   192  // Codes 0-15 are single byte codes. Codes 16-18 are followed by additional
   193  // information. Code badCode is an end marker
   194  //
   195  //  numLiterals      The number of literals in literalEncoding
   196  //  numOffsets       The number of offsets in offsetEncoding
   197  //  litenc, offenc   The literal and offset encoder to use
   198  func (w *huffmanBitWriter) generateCodegen(numLiterals int, numOffsets int, litEnc, offEnc *huffmanEncoder) {
   199  	for i := range w.codegenFreq {
   200  		w.codegenFreq[i] = 0
   201  	}
   202  	// Note that we are using codegen both as a temporary variable for holding
   203  	// a copy of the frequencies, and as the place where we put the result.
   204  	// This is fine because the output is always shorter than the input used
   205  	// so far.
   206  	codegen := w.codegen // cache
   207  	// Copy the concatenated code sizes to codegen. Put a marker at the end.
   208  	cgnl := codegen[:numLiterals]
   209  	for i := range cgnl {
   210  		cgnl[i] = uint8(litEnc.codes[i].len)
   211  	}
   212  
   213  	cgnl = codegen[numLiterals : numLiterals+numOffsets]
   214  	for i := range cgnl {
   215  		cgnl[i] = uint8(offEnc.codes[i].len)
   216  	}
   217  	codegen[numLiterals+numOffsets] = badCode
   218  
   219  	size := codegen[0]
   220  	count := 1
   221  	outIndex := 0
   222  	for inIndex := 1; size != badCode; inIndex++ {
   223  		// INVARIANT: We have seen "count" copies of size that have not yet
   224  		// had output generated for them.
   225  		nextSize := codegen[inIndex]
   226  		if nextSize == size {
   227  			count++
   228  			continue
   229  		}
   230  		// We need to generate codegen indicating "count" of size.
   231  		if size != 0 {
   232  			codegen[outIndex] = size
   233  			outIndex++
   234  			w.codegenFreq[size]++
   235  			count--
   236  			for count >= 3 {
   237  				n := 6
   238  				if n > count {
   239  					n = count
   240  				}
   241  				codegen[outIndex] = 16
   242  				outIndex++
   243  				codegen[outIndex] = uint8(n - 3)
   244  				outIndex++
   245  				w.codegenFreq[16]++
   246  				count -= n
   247  			}
   248  		} else {
   249  			for count >= 11 {
   250  				n := 138
   251  				if n > count {
   252  					n = count
   253  				}
   254  				codegen[outIndex] = 18
   255  				outIndex++
   256  				codegen[outIndex] = uint8(n - 11)
   257  				outIndex++
   258  				w.codegenFreq[18]++
   259  				count -= n
   260  			}
   261  			if count >= 3 {
   262  				// count >= 3 && count <= 10
   263  				codegen[outIndex] = 17
   264  				outIndex++
   265  				codegen[outIndex] = uint8(count - 3)
   266  				outIndex++
   267  				w.codegenFreq[17]++
   268  				count = 0
   269  			}
   270  		}
   271  		count--
   272  		for ; count >= 0; count-- {
   273  			codegen[outIndex] = size
   274  			outIndex++
   275  			w.codegenFreq[size]++
   276  		}
   277  		// Set up invariant for next time through the loop.
   278  		size = nextSize
   279  		count = 1
   280  	}
   281  	// Marker indicating the end of the codegen.
   282  	codegen[outIndex] = badCode
   283  }
   284  
   285  func (w *huffmanBitWriter) writeCode(c hcode) {
   286  	if w.err != nil {
   287  		return
   288  	}
   289  	w.bits |= uint64(c.code) << w.nbits
   290  	w.nbits += uint(c.len)
   291  	if w.nbits >= 48 {
   292  		bits := w.bits
   293  		w.bits >>= 48
   294  		w.nbits -= 48
   295  		n := w.nbytes
   296  		w.bytes[n+0] = byte(bits)
   297  		w.bytes[n+1] = byte(bits >> 8)
   298  		w.bytes[n+2] = byte(bits >> 16)
   299  		w.bytes[n+3] = byte(bits >> 24)
   300  		w.bytes[n+4] = byte(bits >> 32)
   301  		w.bytes[n+5] = byte(bits >> 40)
   302  		n += 6
   303  		if n >= bufferFlushSize {
   304  			_, w.err = w.w.Write(w.bytes[:n])
   305  			n = 0
   306  		}
   307  		w.nbytes = n
   308  	}
   309  }
   310  
   311  // Write the header of a dynamic Huffman block to the output stream.
   312  //
   313  //  numLiterals  The number of literals specified in codegen
   314  //  numOffsets   The number of offsets specified in codegen
   315  //  numCodegens  The number of codegens used in codegen
   316  func (w *huffmanBitWriter) writeDynamicHeader(numLiterals int, numOffsets int, numCodegens int, isEof bool) {
   317  	if w.err != nil {
   318  		return
   319  	}
   320  	var firstBits int32 = 4
   321  	if isEof {
   322  		firstBits = 5
   323  	}
   324  	w.writeBits(firstBits, 3)
   325  	w.writeBits(int32(numLiterals-257), 5)
   326  	w.writeBits(int32(numOffsets-1), 5)
   327  	w.writeBits(int32(numCodegens-4), 4)
   328  
   329  	for i := 0; i < numCodegens; i++ {
   330  		value := uint(w.codegenEncoding.codes[codegenOrder[i]].len)
   331  		w.writeBits(int32(value), 3)
   332  	}
   333  
   334  	i := 0
   335  	for {
   336  		var codeWord int = int(w.codegen[i])
   337  		i++
   338  		if codeWord == badCode {
   339  			break
   340  		}
   341  		w.writeCode(w.codegenEncoding.codes[uint32(codeWord)])
   342  
   343  		switch codeWord {
   344  		case 16:
   345  			w.writeBits(int32(w.codegen[i]), 2)
   346  			i++
   347  			break
   348  		case 17:
   349  			w.writeBits(int32(w.codegen[i]), 3)
   350  			i++
   351  			break
   352  		case 18:
   353  			w.writeBits(int32(w.codegen[i]), 7)
   354  			i++
   355  			break
   356  		}
   357  	}
   358  }
   359  
   360  func (w *huffmanBitWriter) writeStoredHeader(length int, isEof bool) {
   361  	if w.err != nil {
   362  		return
   363  	}
   364  	var flag int32
   365  	if isEof {
   366  		flag = 1
   367  	}
   368  	w.writeBits(flag, 3)
   369  	w.flush()
   370  	w.writeBits(int32(length), 16)
   371  	w.writeBits(int32(^uint16(length)), 16)
   372  }
   373  
   374  func (w *huffmanBitWriter) writeFixedHeader(isEof bool) {
   375  	if w.err != nil {
   376  		return
   377  	}
   378  	// Indicate that we are a fixed Huffman block
   379  	var value int32 = 2
   380  	if isEof {
   381  		value = 3
   382  	}
   383  	w.writeBits(value, 3)
   384  }
   385  
   386  func (w *huffmanBitWriter) writeBlock(tokens []token, eof bool, input []byte) {
   387  	if w.err != nil {
   388  		return
   389  	}
   390  
   391  	tokens = append(tokens, endBlockMarker)
   392  	numLiterals, numOffsets := w.indexTokens(tokens)
   393  
   394  	storedBytes := 0
   395  	if input != nil {
   396  		storedBytes = len(input)
   397  	}
   398  	var extraBits int64
   399  	var storedSize int64 = math.MaxInt64
   400  	if storedBytes <= maxStoreBlockSize && input != nil {
   401  		storedSize = int64((storedBytes + 5) * 8)
   402  		// We only bother calculating the costs of the extra bits required by
   403  		// the length of offset fields (which will be the same for both fixed
   404  		// and dynamic encoding), if we need to compare those two encodings
   405  		// against stored encoding.
   406  		for lengthCode := lengthCodesStart + 8; lengthCode < numLiterals; lengthCode++ {
   407  			// First eight length codes have extra size = 0.
   408  			extraBits += int64(w.literalFreq[lengthCode]) * int64(lengthExtraBits[lengthCode-lengthCodesStart])
   409  		}
   410  		for offsetCode := 4; offsetCode < numOffsets; offsetCode++ {
   411  			// First four offset codes have extra size = 0.
   412  			extraBits += int64(w.offsetFreq[offsetCode]) * int64(offsetExtraBits[offsetCode])
   413  		}
   414  	}
   415  
   416  	// Figure out smallest code.
   417  	// Fixed Huffman baseline.
   418  	var size = int64(3) +
   419  		fixedLiteralEncoding.bitLength(w.literalFreq) +
   420  		fixedOffsetEncoding.bitLength(w.offsetFreq) +
   421  		extraBits
   422  	var literalEncoding = fixedLiteralEncoding
   423  	var offsetEncoding = fixedOffsetEncoding
   424  
   425  	// Dynamic Huffman?
   426  	var numCodegens int
   427  
   428  	// Generate codegen and codegenFrequencies, which indicates how to encode
   429  	// the literalEncoding and the offsetEncoding.
   430  	w.generateCodegen(numLiterals, numOffsets, w.literalEncoding, w.offsetEncoding)
   431  	w.codegenEncoding.generate(w.codegenFreq, 7)
   432  	numCodegens = len(w.codegenFreq)
   433  	for numCodegens > 4 && w.codegenFreq[codegenOrder[numCodegens-1]] == 0 {
   434  		numCodegens--
   435  	}
   436  	dynamicHeader := int64(3+5+5+4+(3*numCodegens)) +
   437  		w.codegenEncoding.bitLength(w.codegenFreq) +
   438  		int64(extraBits) +
   439  		int64(w.codegenFreq[16]*2) +
   440  		int64(w.codegenFreq[17]*3) +
   441  		int64(w.codegenFreq[18]*7)
   442  	dynamicSize := dynamicHeader +
   443  		w.literalEncoding.bitLength(w.literalFreq) +
   444  		w.offsetEncoding.bitLength(w.offsetFreq)
   445  
   446  	if dynamicSize < size {
   447  		size = dynamicSize
   448  		literalEncoding = w.literalEncoding
   449  		offsetEncoding = w.offsetEncoding
   450  	}
   451  
   452  	// Stored bytes?
   453  	if storedSize < size {
   454  		w.writeStoredHeader(storedBytes, eof)
   455  		w.writeBytes(input[:storedBytes])
   456  		return
   457  	}
   458  
   459  	// Huffman.
   460  	if literalEncoding == fixedLiteralEncoding {
   461  		w.writeFixedHeader(eof)
   462  	} else {
   463  		w.writeDynamicHeader(numLiterals, numOffsets, numCodegens, eof)
   464  	}
   465  
   466  	// Write the tokens.
   467  	w.writeTokens(tokens, literalEncoding.codes, offsetEncoding.codes)
   468  
   469  }
   470  
   471  // writeBlockDynamic encodes a block using a dynamic Huffman table.
   472  // This should be used if the symbols used have a disproportionate
   473  // histogram distribution.
   474  func (w *huffmanBitWriter) writeBlockDynamic(tokens []token, eof bool, input []byte) {
   475  	if w.err != nil {
   476  		return
   477  	}
   478  
   479  	tokens = append(tokens, endBlockMarker)
   480  	numLiterals, numOffsets := w.indexTokens(tokens)
   481  
   482  	// Generate codegen and codegenFrequencies, which indicates how to encode
   483  	// the literalEncoding and the offsetEncoding.
   484  	w.generateCodegen(numLiterals, numOffsets, w.literalEncoding, w.offsetEncoding)
   485  	w.codegenEncoding.generate(w.codegenFreq, 7)
   486  	numCodegens := len(w.codegenFreq)
   487  	for numCodegens > 4 && w.codegenFreq[codegenOrder[numCodegens-1]] == 0 {
   488  		numCodegens--
   489  	}
   490  
   491  	// Write Huffman table.
   492  	w.writeDynamicHeader(numLiterals, numOffsets, numCodegens, eof)
   493  
   494  	// Write the tokens.
   495  	w.writeTokens(tokens, w.literalEncoding.codes, w.offsetEncoding.codes)
   496  }
   497  
   498  // indexTokens indexes a slice of tokens, and updates
   499  // literalFreq and offsetFreq, and generates literalEncoding
   500  // and offsetEncoding.
   501  // The number of literal and offset tokens is returned.
   502  func (w *huffmanBitWriter) indexTokens(tokens []token) (numLiterals, numOffsets int) {
   503  	for i := range w.literalFreq {
   504  		w.literalFreq[i] = 0
   505  	}
   506  	for i := range w.offsetFreq {
   507  		w.offsetFreq[i] = 0
   508  	}
   509  
   510  	for _, t := range tokens {
   511  		if t < matchType {
   512  			w.literalFreq[t.literal()]++
   513  			continue
   514  		}
   515  		length := t.length()
   516  		offset := t.offset()
   517  		w.literalFreq[lengthCodesStart+lengthCode(length)]++
   518  		w.offsetFreq[offsetCode(offset)]++
   519  	}
   520  
   521  	// get the number of literals
   522  	numLiterals = len(w.literalFreq)
   523  	for w.literalFreq[numLiterals-1] == 0 {
   524  		numLiterals--
   525  	}
   526  	// get the number of offsets
   527  	numOffsets = len(w.offsetFreq)
   528  	for numOffsets > 0 && w.offsetFreq[numOffsets-1] == 0 {
   529  		numOffsets--
   530  	}
   531  	if numOffsets == 0 {
   532  		// We haven't found a single match. If we want to go with the dynamic encoding,
   533  		// we should count at least one offset to be sure that the offset huffman tree could be encoded.
   534  		w.offsetFreq[0] = 1
   535  		numOffsets = 1
   536  	}
   537  	w.literalEncoding.generate(w.literalFreq, 15)
   538  	w.offsetEncoding.generate(w.offsetFreq, 15)
   539  	return
   540  }
   541  
   542  // writeTokens writes a slice of tokens to the output.
   543  // codes for literal and offset encoding must be supplied.
   544  func (w *huffmanBitWriter) writeTokens(tokens []token, leCodes, oeCodes []hcode) {
   545  	for _, t := range tokens {
   546  		if t < matchType {
   547  			w.writeCode(leCodes[t.literal()])
   548  			continue
   549  		}
   550  		// Write the length
   551  		length := t.length()
   552  		lengthCode := lengthCode(length)
   553  		w.writeCode(leCodes[lengthCode+lengthCodesStart])
   554  		extraLengthBits := uint(lengthExtraBits[lengthCode])
   555  		if extraLengthBits > 0 {
   556  			extraLength := int32(length - lengthBase[lengthCode])
   557  			w.writeBits(extraLength, extraLengthBits)
   558  		}
   559  		// Write the offset
   560  		offset := t.offset()
   561  		offsetCode := offsetCode(offset)
   562  		w.writeCode(oeCodes[offsetCode])
   563  		extraOffsetBits := uint(offsetExtraBits[offsetCode])
   564  		if extraOffsetBits > 0 {
   565  			extraOffset := int32(offset - offsetBase[offsetCode])
   566  			w.writeBits(extraOffset, extraOffsetBits)
   567  		}
   568  	}
   569  }
   570  
   571  // huffOffset is a static offset encoder used for huffman only encoding.
   572  // It can be reused since we will not be encoding offset values.
   573  var huffOffset *huffmanEncoder
   574  
   575  func init() {
   576  	w := newHuffmanBitWriter(nil)
   577  	w.offsetFreq[0] = 1
   578  	huffOffset = newHuffmanEncoder(offsetCodeCount)
   579  	huffOffset.generate(w.offsetFreq, 15)
   580  }
   581  
   582  // writeBlockHuff encodes a block of bytes as either
   583  // Huffman encoded literals or uncompressed bytes if the
   584  // results only gains very little from compression.
   585  func (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte) {
   586  	if w.err != nil {
   587  		return
   588  	}
   589  
   590  	// Clear histogram
   591  	for i := range w.literalFreq {
   592  		w.literalFreq[i] = 0
   593  	}
   594  
   595  	// Add everything as literals
   596  	histogram(input, w.literalFreq)
   597  
   598  	w.literalFreq[endBlockMarker] = 1
   599  
   600  	const numLiterals = endBlockMarker + 1
   601  	const numOffsets = 1
   602  
   603  	w.literalEncoding.generate(w.literalFreq, 15)
   604  
   605  	// Figure out smallest code.
   606  	// Always use dynamic Huffman or Store
   607  	var numCodegens int
   608  
   609  	// Generate codegen and codegenFrequencies, which indicates how to encode
   610  	// the literalEncoding and the offsetEncoding.
   611  	w.generateCodegen(numLiterals, numOffsets, w.literalEncoding, huffOffset)
   612  	w.codegenEncoding.generate(w.codegenFreq, 7)
   613  	numCodegens = len(w.codegenFreq)
   614  	for numCodegens > 4 && w.codegenFreq[codegenOrder[numCodegens-1]] == 0 {
   615  		numCodegens--
   616  	}
   617  	headerSize := int64(3+5+5+4+(3*numCodegens)) +
   618  		w.codegenEncoding.bitLength(w.codegenFreq) +
   619  		int64(w.codegenFreq[16]*2) +
   620  		int64(w.codegenFreq[17]*3) +
   621  		int64(w.codegenFreq[18]*7)
   622  
   623  	// Includes EOB marker
   624  	size := headerSize + w.literalEncoding.bitLength(w.literalFreq)
   625  
   626  	// Calculate stored size
   627  	var storedSize int64 = math.MaxInt64
   628  	var storedBytes = len(input)
   629  	if storedBytes <= maxStoreBlockSize {
   630  		storedSize = int64(storedBytes+5) * 8
   631  	}
   632  
   633  	// Store bytes, if we don't get a reasonable improvement.
   634  	if storedSize < (size + size>>4) {
   635  		w.writeStoredHeader(storedBytes, eof)
   636  		w.writeBytes(input)
   637  		return
   638  	}
   639  
   640  	// Huffman.
   641  	w.writeDynamicHeader(numLiterals, numOffsets, numCodegens, eof)
   642  	encoding := w.literalEncoding.codes
   643  	n := w.nbytes
   644  	for _, t := range input {
   645  		// Bitwriting inlined, ~30% speedup
   646  		c := encoding[t]
   647  		w.bits |= uint64(c.code) << w.nbits
   648  		w.nbits += uint(c.len)
   649  		if w.nbits < 48 {
   650  			continue
   651  		}
   652  		// Store 6 bytes
   653  		bits := w.bits
   654  		w.bits >>= 48
   655  		w.nbits -= 48
   656  		w.bytes[n+0] = byte(bits)
   657  		w.bytes[n+1] = byte(bits >> 8)
   658  		w.bytes[n+2] = byte(bits >> 16)
   659  		w.bytes[n+3] = byte(bits >> 24)
   660  		w.bytes[n+4] = byte(bits >> 32)
   661  		w.bytes[n+5] = byte(bits >> 40)
   662  		n += 6
   663  		if n < bufferFlushSize {
   664  			continue
   665  		}
   666  		_, w.err = w.w.Write(w.bytes[:n])
   667  		if w.err != nil {
   668  			return
   669  		}
   670  		n = 0
   671  	}
   672  	w.nbytes = n
   673  	w.writeCode(encoding[endBlockMarker])
   674  }
   675  
   676  // histogram accumulates a histogram of b in h.
   677  //
   678  // len(h) must be >= 256, and h's elements must be all zeroes.
   679  func histogram(b []byte, h []int32) {
   680  	for _, t := range b {
   681  		h[t]++
   682  	}
   683  }