...

Source file src/github.com/klauspost/compress/huff0/bitwriter.go

Documentation: github.com/klauspost/compress/huff0

     1  // Copyright 2018 Klaus Post. 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  // Based on work Copyright (c) 2013, Yann Collet, released under BSD License.
     5  
     6  package huff0
     7  
     8  // bitWriter will write bits.
     9  // First bit will be LSB of the first byte of output.
    10  type bitWriter struct {
    11  	bitContainer uint64
    12  	nBits        uint8
    13  	out          []byte
    14  }
    15  
    16  // addBits16Clean will add up to 16 bits. value may not contain more set bits than indicated.
    17  // It will not check if there is space for them, so the caller must ensure that it has flushed recently.
    18  func (b *bitWriter) addBits16Clean(value uint16, bits uint8) {
    19  	b.bitContainer |= uint64(value) << (b.nBits & 63)
    20  	b.nBits += bits
    21  }
    22  
    23  // encSymbol will add up to 16 bits. value may not contain more set bits than indicated.
    24  // It will not check if there is space for them, so the caller must ensure that it has flushed recently.
    25  func (b *bitWriter) encSymbol(ct cTable, symbol byte) {
    26  	enc := ct[symbol]
    27  	b.bitContainer |= uint64(enc.val) << (b.nBits & 63)
    28  	if false {
    29  		if enc.nBits == 0 {
    30  			panic("nbits 0")
    31  		}
    32  	}
    33  	b.nBits += enc.nBits
    34  }
    35  
    36  // encTwoSymbols will add up to 32 bits. value may not contain more set bits than indicated.
    37  // It will not check if there is space for them, so the caller must ensure that it has flushed recently.
    38  func (b *bitWriter) encTwoSymbols(ct cTable, av, bv byte) {
    39  	encA := ct[av]
    40  	encB := ct[bv]
    41  	sh := b.nBits & 63
    42  	combined := uint64(encA.val) | (uint64(encB.val) << (encA.nBits & 63))
    43  	b.bitContainer |= combined << sh
    44  	if false {
    45  		if encA.nBits == 0 {
    46  			panic("nbitsA 0")
    47  		}
    48  		if encB.nBits == 0 {
    49  			panic("nbitsB 0")
    50  		}
    51  	}
    52  	b.nBits += encA.nBits + encB.nBits
    53  }
    54  
    55  // encFourSymbols adds up to 32 bits from four symbols.
    56  // It will not check if there is space for them,
    57  // so the caller must ensure that b has been flushed recently.
    58  func (b *bitWriter) encFourSymbols(encA, encB, encC, encD cTableEntry) {
    59  	bitsA := encA.nBits
    60  	bitsB := bitsA + encB.nBits
    61  	bitsC := bitsB + encC.nBits
    62  	bitsD := bitsC + encD.nBits
    63  	combined := uint64(encA.val) |
    64  		(uint64(encB.val) << (bitsA & 63)) |
    65  		(uint64(encC.val) << (bitsB & 63)) |
    66  		(uint64(encD.val) << (bitsC & 63))
    67  	b.bitContainer |= combined << (b.nBits & 63)
    68  	b.nBits += bitsD
    69  }
    70  
    71  // flush32 will flush out, so there are at least 32 bits available for writing.
    72  func (b *bitWriter) flush32() {
    73  	if b.nBits < 32 {
    74  		return
    75  	}
    76  	b.out = append(b.out,
    77  		byte(b.bitContainer),
    78  		byte(b.bitContainer>>8),
    79  		byte(b.bitContainer>>16),
    80  		byte(b.bitContainer>>24))
    81  	b.nBits -= 32
    82  	b.bitContainer >>= 32
    83  }
    84  
    85  // flushAlign will flush remaining full bytes and align to next byte boundary.
    86  func (b *bitWriter) flushAlign() {
    87  	nbBytes := (b.nBits + 7) >> 3
    88  	for i := uint8(0); i < nbBytes; i++ {
    89  		b.out = append(b.out, byte(b.bitContainer>>(i*8)))
    90  	}
    91  	b.nBits = 0
    92  	b.bitContainer = 0
    93  }
    94  
    95  // close will write the alignment bit and write the final byte(s)
    96  // to the output.
    97  func (b *bitWriter) close() {
    98  	// End mark
    99  	b.addBits16Clean(1, 1)
   100  	// flush until next byte.
   101  	b.flushAlign()
   102  }
   103  

View as plain text