github.com/letsencrypt/go@v0.0.0-20160714163537-4054769a31f6/src/compress/flate/deflate.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 "fmt" 9 "io" 10 "math" 11 ) 12 13 const ( 14 NoCompression = 0 15 BestSpeed = 1 16 BestCompression = 9 17 DefaultCompression = -1 18 HuffmanOnly = -2 // Disables match search and only does Huffman entropy reduction. 19 ) 20 21 const ( 22 logWindowSize = 15 23 windowSize = 1 << logWindowSize 24 windowMask = windowSize - 1 25 26 // The LZ77 step produces a sequence of literal tokens and <length, offset> 27 // pair tokens. The offset is also known as distance. The underlying wire 28 // format limits the range of lengths and offsets. For example, there are 29 // 256 legitimate lengths: those in the range [3, 258]. This package's 30 // compressor uses a higher minimum match length, enabling optimizations 31 // such as finding matches via 32-bit loads and compares. 32 baseMatchLength = 3 // The smallest match length per the RFC section 3.2.5 33 minMatchLength = 4 // The smallest match length that the compressor actually emits 34 maxMatchLength = 258 // The largest match length 35 baseMatchOffset = 1 // The smallest match offset 36 maxMatchOffset = 1 << 15 // The largest match offset 37 38 // The maximum number of tokens we put into a single flate block, just to 39 // stop things from getting too large. 40 maxFlateBlockTokens = 1 << 14 41 maxStoreBlockSize = 65535 42 hashBits = 17 // After 17 performance degrades 43 hashSize = 1 << hashBits 44 hashMask = (1 << hashBits) - 1 45 maxHashOffset = 1 << 24 46 47 skipNever = math.MaxInt32 48 ) 49 50 type compressionLevel struct { 51 level, good, lazy, nice, chain, fastSkipHashing int 52 } 53 54 var levels = []compressionLevel{ 55 {0, 0, 0, 0, 0, 0}, // NoCompression. 56 {1, 0, 0, 0, 0, 0}, // BestSpeed uses a custom algorithm; see deflatefast.go. 57 // For levels 2-3 we don't bother trying with lazy matches. 58 {2, 4, 0, 16, 8, 5}, 59 {3, 4, 0, 32, 32, 6}, 60 // Levels 4-9 use increasingly more lazy matching 61 // and increasingly stringent conditions for "good enough". 62 {4, 4, 4, 16, 16, skipNever}, 63 {5, 8, 16, 32, 32, skipNever}, 64 {6, 8, 16, 128, 128, skipNever}, 65 {7, 8, 32, 128, 256, skipNever}, 66 {8, 32, 128, 258, 1024, skipNever}, 67 {9, 32, 258, 258, 4096, skipNever}, 68 } 69 70 type compressor struct { 71 compressionLevel 72 73 w *huffmanBitWriter 74 bulkHasher func([]byte, []uint32) 75 76 // compression algorithm 77 fill func(*compressor, []byte) int // copy data to window 78 step func(*compressor) // process window 79 sync bool // requesting flush 80 81 // Input hash chains 82 // hashHead[hashValue] contains the largest inputIndex with the specified hash value 83 // If hashHead[hashValue] is within the current window, then 84 // hashPrev[hashHead[hashValue] & windowMask] contains the previous index 85 // with the same hash value. 86 chainHead int 87 hashHead [hashSize]uint32 88 hashPrev [windowSize]uint32 89 hashOffset int 90 91 // input window: unprocessed data is window[index:windowEnd] 92 index int 93 window []byte 94 windowEnd int 95 blockStart int // window index where current tokens start 96 byteAvailable bool // if true, still need to process window[index-1]. 97 98 // queued output tokens 99 tokens []token 100 101 // deflate state 102 length int 103 offset int 104 hash uint32 105 maxInsertIndex int 106 err error 107 108 // hashMatch must be able to contain hashes for the maximum match length. 109 hashMatch [maxMatchLength - 1]uint32 110 } 111 112 func (d *compressor) fillDeflate(b []byte) int { 113 if d.index >= 2*windowSize-(minMatchLength+maxMatchLength) { 114 // shift the window by windowSize 115 copy(d.window, d.window[windowSize:2*windowSize]) 116 d.index -= windowSize 117 d.windowEnd -= windowSize 118 if d.blockStart >= windowSize { 119 d.blockStart -= windowSize 120 } else { 121 d.blockStart = math.MaxInt32 122 } 123 d.hashOffset += windowSize 124 if d.hashOffset > maxHashOffset { 125 delta := d.hashOffset - 1 126 d.hashOffset -= delta 127 d.chainHead -= delta 128 for i, v := range d.hashPrev { 129 if int(v) > delta { 130 d.hashPrev[i] = uint32(int(v) - delta) 131 } else { 132 d.hashPrev[i] = 0 133 } 134 } 135 for i, v := range d.hashHead { 136 if int(v) > delta { 137 d.hashHead[i] = uint32(int(v) - delta) 138 } else { 139 d.hashHead[i] = 0 140 } 141 } 142 } 143 } 144 n := copy(d.window[d.windowEnd:], b) 145 d.windowEnd += n 146 return n 147 } 148 149 func (d *compressor) writeBlock(tokens []token, index int) error { 150 if index > 0 { 151 var window []byte 152 if d.blockStart <= index { 153 window = d.window[d.blockStart:index] 154 } 155 d.blockStart = index 156 d.w.writeBlock(tokens, false, window) 157 return d.w.err 158 } 159 return nil 160 } 161 162 // fillWindow will fill the current window with the supplied 163 // dictionary and calculate all hashes. 164 // This is much faster than doing a full encode. 165 // Should only be used after a reset. 166 func (d *compressor) fillWindow(b []byte) { 167 // Do not fill window if we are in store-only mode. 168 if d.compressionLevel.level < 2 { 169 return 170 } 171 if d.index != 0 || d.windowEnd != 0 { 172 panic("internal error: fillWindow called with stale data") 173 } 174 175 // If we are given too much, cut it. 176 if len(b) > windowSize { 177 b = b[len(b)-windowSize:] 178 } 179 // Add all to window. 180 n := copy(d.window, b) 181 182 // Calculate 256 hashes at the time (more L1 cache hits) 183 loops := (n + 256 - minMatchLength) / 256 184 for j := 0; j < loops; j++ { 185 index := j * 256 186 end := index + 256 + minMatchLength - 1 187 if end > n { 188 end = n 189 } 190 toCheck := d.window[index:end] 191 dstSize := len(toCheck) - minMatchLength + 1 192 193 if dstSize <= 0 { 194 continue 195 } 196 197 dst := d.hashMatch[:dstSize] 198 d.bulkHasher(toCheck, dst) 199 var newH uint32 200 for i, val := range dst { 201 di := i + index 202 newH = val 203 hh := &d.hashHead[newH&hashMask] 204 // Get previous value with the same hash. 205 // Our chain should point to the previous value. 206 d.hashPrev[di&windowMask] = *hh 207 // Set the head of the hash chain to us. 208 *hh = uint32(di + d.hashOffset) 209 } 210 d.hash = newH 211 } 212 // Update window information. 213 d.windowEnd = n 214 d.index = n 215 } 216 217 // Try to find a match starting at index whose length is greater than prevSize. 218 // We only look at chainCount possibilities before giving up. 219 func (d *compressor) findMatch(pos int, prevHead int, prevLength int, lookahead int) (length, offset int, ok bool) { 220 minMatchLook := maxMatchLength 221 if lookahead < minMatchLook { 222 minMatchLook = lookahead 223 } 224 225 win := d.window[0 : pos+minMatchLook] 226 227 // We quit when we get a match that's at least nice long 228 nice := len(win) - pos 229 if d.nice < nice { 230 nice = d.nice 231 } 232 233 // If we've got a match that's good enough, only look in 1/4 the chain. 234 tries := d.chain 235 length = prevLength 236 if length >= d.good { 237 tries >>= 2 238 } 239 240 wEnd := win[pos+length] 241 wPos := win[pos:] 242 minIndex := pos - windowSize 243 244 for i := prevHead; tries > 0; tries-- { 245 if wEnd == win[i+length] { 246 n := matchLen(win[i:], wPos, minMatchLook) 247 248 if n > length && (n > minMatchLength || pos-i <= 4096) { 249 length = n 250 offset = pos - i 251 ok = true 252 if n >= nice { 253 // The match is good enough that we don't try to find a better one. 254 break 255 } 256 wEnd = win[pos+n] 257 } 258 } 259 if i == minIndex { 260 // hashPrev[i & windowMask] has already been overwritten, so stop now. 261 break 262 } 263 i = int(d.hashPrev[i&windowMask]) - d.hashOffset 264 if i < minIndex || i < 0 { 265 break 266 } 267 } 268 return 269 } 270 271 func (d *compressor) writeStoredBlock(buf []byte) error { 272 if d.w.writeStoredHeader(len(buf), false); d.w.err != nil { 273 return d.w.err 274 } 275 d.w.writeBytes(buf) 276 return d.w.err 277 } 278 279 const hashmul = 0x1e35a7bd 280 281 // hash4 returns a hash representation of the first 4 bytes 282 // of the supplied slice. 283 // The caller must ensure that len(b) >= 4. 284 func hash4(b []byte) uint32 { 285 return ((uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24) * hashmul) >> (32 - hashBits) 286 } 287 288 // bulkHash4 will compute hashes using the same 289 // algorithm as hash4 290 func bulkHash4(b []byte, dst []uint32) { 291 if len(b) < minMatchLength { 292 return 293 } 294 hb := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 295 dst[0] = (hb * hashmul) >> (32 - hashBits) 296 end := len(b) - minMatchLength + 1 297 for i := 1; i < end; i++ { 298 hb = (hb << 8) | uint32(b[i+3]) 299 dst[i] = (hb * hashmul) >> (32 - hashBits) 300 } 301 } 302 303 // matchLen returns the number of matching bytes in a and b 304 // up to length 'max'. Both slices must be at least 'max' 305 // bytes in size. 306 func matchLen(a, b []byte, max int) int { 307 a = a[:max] 308 b = b[:len(a)] 309 for i, av := range a { 310 if b[i] != av { 311 return i 312 } 313 } 314 return max 315 } 316 317 // encSpeed will compress and store the currently added data, 318 // if enough has been accumulated or we at the end of the stream. 319 // Any error that occurred will be in d.err 320 func (d *compressor) encSpeed() { 321 // We only compress if we have maxStoreBlockSize. 322 if d.windowEnd < maxStoreBlockSize { 323 if !d.sync { 324 return 325 } 326 327 // Handle small sizes. 328 if d.windowEnd < 128 { 329 switch { 330 case d.windowEnd == 0: 331 return 332 case d.windowEnd <= 16: 333 d.err = d.writeStoredBlock(d.window[:d.windowEnd]) 334 default: 335 d.w.writeBlockHuff(false, d.window[:d.windowEnd]) 336 d.err = d.w.err 337 } 338 d.windowEnd = 0 339 return 340 } 341 342 } 343 // Encode the block. 344 d.tokens = encodeBestSpeed(d.tokens[:0], d.window[:d.windowEnd]) 345 346 // If we removed less than 1/16th, Huffman compress the block. 347 if len(d.tokens) > d.windowEnd-(d.windowEnd>>4) { 348 d.w.writeBlockHuff(false, d.window[:d.windowEnd]) 349 } else { 350 d.w.writeBlockDynamic(d.tokens, false, d.window[:d.windowEnd]) 351 } 352 d.err = d.w.err 353 d.windowEnd = 0 354 } 355 356 func (d *compressor) initDeflate() { 357 d.window = make([]byte, 2*windowSize) 358 d.hashOffset = 1 359 d.tokens = make([]token, 0, maxFlateBlockTokens+1) 360 d.length = minMatchLength - 1 361 d.offset = 0 362 d.byteAvailable = false 363 d.index = 0 364 d.hash = 0 365 d.chainHead = -1 366 d.bulkHasher = bulkHash4 367 } 368 369 func (d *compressor) deflate() { 370 if d.windowEnd-d.index < minMatchLength+maxMatchLength && !d.sync { 371 return 372 } 373 374 d.maxInsertIndex = d.windowEnd - (minMatchLength - 1) 375 if d.index < d.maxInsertIndex { 376 d.hash = hash4(d.window[d.index : d.index+minMatchLength]) 377 } 378 379 Loop: 380 for { 381 if d.index > d.windowEnd { 382 panic("index > windowEnd") 383 } 384 lookahead := d.windowEnd - d.index 385 if lookahead < minMatchLength+maxMatchLength { 386 if !d.sync { 387 break Loop 388 } 389 if d.index > d.windowEnd { 390 panic("index > windowEnd") 391 } 392 if lookahead == 0 { 393 // Flush current output block if any. 394 if d.byteAvailable { 395 // There is still one pending token that needs to be flushed 396 d.tokens = append(d.tokens, literalToken(uint32(d.window[d.index-1]))) 397 d.byteAvailable = false 398 } 399 if len(d.tokens) > 0 { 400 if d.err = d.writeBlock(d.tokens, d.index); d.err != nil { 401 return 402 } 403 d.tokens = d.tokens[:0] 404 } 405 break Loop 406 } 407 } 408 if d.index < d.maxInsertIndex { 409 // Update the hash 410 d.hash = hash4(d.window[d.index : d.index+minMatchLength]) 411 hh := &d.hashHead[d.hash&hashMask] 412 d.chainHead = int(*hh) 413 d.hashPrev[d.index&windowMask] = uint32(d.chainHead) 414 *hh = uint32(d.index + d.hashOffset) 415 } 416 prevLength := d.length 417 prevOffset := d.offset 418 d.length = minMatchLength - 1 419 d.offset = 0 420 minIndex := d.index - windowSize 421 if minIndex < 0 { 422 minIndex = 0 423 } 424 425 if d.chainHead-d.hashOffset >= minIndex && 426 (d.fastSkipHashing != skipNever && lookahead > minMatchLength-1 || 427 d.fastSkipHashing == skipNever && lookahead > prevLength && prevLength < d.lazy) { 428 if newLength, newOffset, ok := d.findMatch(d.index, d.chainHead-d.hashOffset, minMatchLength-1, lookahead); ok { 429 d.length = newLength 430 d.offset = newOffset 431 } 432 } 433 if d.fastSkipHashing != skipNever && d.length >= minMatchLength || 434 d.fastSkipHashing == skipNever && prevLength >= minMatchLength && d.length <= prevLength { 435 // There was a match at the previous step, and the current match is 436 // not better. Output the previous match. 437 if d.fastSkipHashing != skipNever { 438 d.tokens = append(d.tokens, matchToken(uint32(d.length-baseMatchLength), uint32(d.offset-baseMatchOffset))) 439 } else { 440 d.tokens = append(d.tokens, matchToken(uint32(prevLength-baseMatchLength), uint32(prevOffset-baseMatchOffset))) 441 } 442 // Insert in the hash table all strings up to the end of the match. 443 // index and index-1 are already inserted. If there is not enough 444 // lookahead, the last two strings are not inserted into the hash 445 // table. 446 if d.length <= d.fastSkipHashing { 447 var newIndex int 448 if d.fastSkipHashing != skipNever { 449 newIndex = d.index + d.length 450 } else { 451 newIndex = d.index + prevLength - 1 452 } 453 for d.index++; d.index < newIndex; d.index++ { 454 if d.index < d.maxInsertIndex { 455 d.hash = hash4(d.window[d.index : d.index+minMatchLength]) 456 // Get previous value with the same hash. 457 // Our chain should point to the previous value. 458 hh := &d.hashHead[d.hash&hashMask] 459 d.hashPrev[d.index&windowMask] = *hh 460 // Set the head of the hash chain to us. 461 *hh = uint32(d.index + d.hashOffset) 462 } 463 } 464 if d.fastSkipHashing == skipNever { 465 d.byteAvailable = false 466 d.length = minMatchLength - 1 467 } 468 } else { 469 // For matches this long, we don't bother inserting each individual 470 // item into the table. 471 d.index += d.length 472 if d.index < d.maxInsertIndex { 473 d.hash = hash4(d.window[d.index : d.index+minMatchLength]) 474 } 475 } 476 if len(d.tokens) == maxFlateBlockTokens { 477 // The block includes the current character 478 if d.err = d.writeBlock(d.tokens, d.index); d.err != nil { 479 return 480 } 481 d.tokens = d.tokens[:0] 482 } 483 } else { 484 if d.fastSkipHashing != skipNever || d.byteAvailable { 485 i := d.index - 1 486 if d.fastSkipHashing != skipNever { 487 i = d.index 488 } 489 d.tokens = append(d.tokens, literalToken(uint32(d.window[i]))) 490 if len(d.tokens) == maxFlateBlockTokens { 491 if d.err = d.writeBlock(d.tokens, i+1); d.err != nil { 492 return 493 } 494 d.tokens = d.tokens[:0] 495 } 496 } 497 d.index++ 498 if d.fastSkipHashing == skipNever { 499 d.byteAvailable = true 500 } 501 } 502 } 503 } 504 505 func (d *compressor) fillStore(b []byte) int { 506 n := copy(d.window[d.windowEnd:], b) 507 d.windowEnd += n 508 return n 509 } 510 511 func (d *compressor) store() { 512 if d.windowEnd > 0 { 513 d.err = d.writeStoredBlock(d.window[:d.windowEnd]) 514 } 515 d.windowEnd = 0 516 } 517 518 // storeHuff compresses and stores the currently added data 519 // when the d.window is full or we are at the end of the stream. 520 // Any error that occurred will be in d.err 521 func (d *compressor) storeHuff() { 522 if d.windowEnd < len(d.window) && !d.sync || d.windowEnd == 0 { 523 return 524 } 525 d.w.writeBlockHuff(false, d.window[:d.windowEnd]) 526 d.err = d.w.err 527 d.windowEnd = 0 528 } 529 530 func (d *compressor) write(b []byte) (n int, err error) { 531 if d.err != nil { 532 return 0, d.err 533 } 534 n = len(b) 535 for len(b) > 0 { 536 d.step(d) 537 b = b[d.fill(d, b):] 538 if d.err != nil { 539 return 0, d.err 540 } 541 } 542 return n, nil 543 } 544 545 func (d *compressor) syncFlush() error { 546 if d.err != nil { 547 return d.err 548 } 549 d.sync = true 550 d.step(d) 551 if d.err == nil { 552 d.w.writeStoredHeader(0, false) 553 d.w.flush() 554 d.err = d.w.err 555 } 556 d.sync = false 557 return d.err 558 } 559 560 func (d *compressor) init(w io.Writer, level int) (err error) { 561 d.w = newHuffmanBitWriter(w) 562 563 switch { 564 case level == NoCompression: 565 d.window = make([]byte, maxStoreBlockSize) 566 d.fill = (*compressor).fillStore 567 d.step = (*compressor).store 568 case level == HuffmanOnly: 569 d.window = make([]byte, maxStoreBlockSize) 570 d.fill = (*compressor).fillStore 571 d.step = (*compressor).storeHuff 572 case level == BestSpeed: 573 d.compressionLevel = levels[level] 574 d.window = make([]byte, maxStoreBlockSize) 575 d.fill = (*compressor).fillStore 576 d.step = (*compressor).encSpeed 577 d.tokens = make([]token, maxStoreBlockSize) 578 case level == DefaultCompression: 579 level = 6 580 fallthrough 581 case 2 <= level && level <= 9: 582 d.compressionLevel = levels[level] 583 d.initDeflate() 584 d.fill = (*compressor).fillDeflate 585 d.step = (*compressor).deflate 586 default: 587 return fmt.Errorf("flate: invalid compression level %d: want value in range [-2, 9]", level) 588 } 589 return nil 590 } 591 592 func (d *compressor) reset(w io.Writer) { 593 d.w.reset(w) 594 d.sync = false 595 d.err = nil 596 switch d.compressionLevel.level { 597 case NoCompression: 598 d.windowEnd = 0 599 case BestSpeed: 600 d.windowEnd = 0 601 d.tokens = d.tokens[:0] 602 default: 603 d.chainHead = -1 604 for i := range d.hashHead { 605 d.hashHead[i] = 0 606 } 607 for i := range d.hashPrev { 608 d.hashPrev[i] = 0 609 } 610 d.hashOffset = 1 611 d.index, d.windowEnd = 0, 0 612 d.blockStart, d.byteAvailable = 0, false 613 d.tokens = d.tokens[:0] 614 d.length = minMatchLength - 1 615 d.offset = 0 616 d.hash = 0 617 d.maxInsertIndex = 0 618 } 619 } 620 621 func (d *compressor) close() error { 622 if d.err != nil { 623 return d.err 624 } 625 d.sync = true 626 d.step(d) 627 if d.err != nil { 628 return d.err 629 } 630 if d.w.writeStoredHeader(0, true); d.w.err != nil { 631 return d.w.err 632 } 633 d.w.flush() 634 return d.w.err 635 } 636 637 // NewWriter returns a new Writer compressing data at the given level. 638 // Following zlib, levels range from 1 (BestSpeed) to 9 (BestCompression); 639 // higher levels typically run slower but compress more. Level 0 640 // (NoCompression) does not attempt any compression; it only adds the 641 // necessary DEFLATE framing. 642 // Level -1 (DefaultCompression) uses the default compression level. 643 // Level -2 (HuffmanOnly) will use Huffman compression only, giving 644 // a very fast compression for all types of input, but sacrificing considerable 645 // compression efficiency. 646 // 647 // 648 // If level is in the range [-2, 9] then the error returned will be nil. 649 // Otherwise the error returned will be non-nil. 650 func NewWriter(w io.Writer, level int) (*Writer, error) { 651 var dw Writer 652 if err := dw.d.init(w, level); err != nil { 653 return nil, err 654 } 655 return &dw, nil 656 } 657 658 // NewWriterDict is like NewWriter but initializes the new 659 // Writer with a preset dictionary. The returned Writer behaves 660 // as if the dictionary had been written to it without producing 661 // any compressed output. The compressed data written to w 662 // can only be decompressed by a Reader initialized with the 663 // same dictionary. 664 func NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error) { 665 dw := &dictWriter{w} 666 zw, err := NewWriter(dw, level) 667 if err != nil { 668 return nil, err 669 } 670 zw.d.fillWindow(dict) 671 zw.dict = append(zw.dict, dict...) // duplicate dictionary for Reset method. 672 return zw, err 673 } 674 675 type dictWriter struct { 676 w io.Writer 677 } 678 679 func (w *dictWriter) Write(b []byte) (n int, err error) { 680 return w.w.Write(b) 681 } 682 683 // A Writer takes data written to it and writes the compressed 684 // form of that data to an underlying writer (see NewWriter). 685 type Writer struct { 686 d compressor 687 dict []byte 688 } 689 690 // Write writes data to w, which will eventually write the 691 // compressed form of data to its underlying writer. 692 func (w *Writer) Write(data []byte) (n int, err error) { 693 return w.d.write(data) 694 } 695 696 // Flush flushes any pending compressed data to the underlying writer. 697 // It is useful mainly in compressed network protocols, to ensure that 698 // a remote reader has enough data to reconstruct a packet. 699 // Flush does not return until the data has been written. 700 // If the underlying writer returns an error, Flush returns that error. 701 // 702 // In the terminology of the zlib library, Flush is equivalent to Z_SYNC_FLUSH. 703 func (w *Writer) Flush() error { 704 // For more about flushing: 705 // http://www.bolet.org/~pornin/deflate-flush.html 706 return w.d.syncFlush() 707 } 708 709 // Close flushes and closes the writer. 710 func (w *Writer) Close() error { 711 return w.d.close() 712 } 713 714 // Reset discards the writer's state and makes it equivalent to 715 // the result of NewWriter or NewWriterDict called with dst 716 // and w's level and dictionary. 717 func (w *Writer) Reset(dst io.Writer) { 718 if dw, ok := w.d.w.w.(*dictWriter); ok { 719 // w was created with NewWriterDict 720 dw.w = dst 721 w.d.reset(dw) 722 w.d.fillWindow(w.dict) 723 } else { 724 // w was created with NewWriter 725 w.d.reset(dst) 726 } 727 }