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