本站源代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

702 lines
18KB

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