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 }