bitwriter.go 3.0 KB

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