deflate.go 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Copyright (c) 2015 Klaus Post
  3. // Use of this source code is governed by a BSD-style
  4. // license that can be found in the LICENSE file.
  5. package flate
  6. import (
  7. "fmt"
  8. "io"
  9. "math"
  10. )
  11. const (
  12. NoCompression = 0
  13. BestSpeed = 1
  14. fastCompression = 3
  15. BestCompression = 9
  16. DefaultCompression = -1
  17. ConstantCompression = -2 // Does only Huffman encoding
  18. logWindowSize = 15
  19. windowSize = 1 << logWindowSize
  20. windowMask = windowSize - 1
  21. logMaxOffsetSize = 15 // Standard DEFLATE
  22. minMatchLength = 4 // The smallest match that the compressor looks for
  23. maxMatchLength = 258 // The longest match for the compressor
  24. minOffsetSize = 1 // The shortest offset that makes any sense
  25. // The maximum number of tokens we put into a single flat block, just too
  26. // stop things from getting too large.
  27. maxFlateBlockTokens = 1 << 14
  28. maxStoreBlockSize = 65535
  29. hashBits = 17 // After 17 performance degrades
  30. hashSize = 1 << hashBits
  31. hashMask = (1 << hashBits) - 1
  32. hashShift = (hashBits + minMatchLength - 1) / minMatchLength
  33. maxHashOffset = 1 << 24
  34. skipNever = math.MaxInt32
  35. )
  36. var useSSE42 bool
  37. type compressionLevel struct {
  38. good, lazy, nice, chain, fastSkipHashing, level int
  39. }
  40. var levels = []compressionLevel{
  41. {}, // 0
  42. // For levels 1-3 we don't bother trying with lazy matches
  43. {4, 0, 8, 4, 4, 1},
  44. {4, 0, 16, 8, 5, 2},
  45. {4, 0, 32, 32, 6, 3},
  46. // Levels 4-9 use increasingly more lazy matching
  47. // and increasingly stringent conditions for "good enough".
  48. {4, 4, 16, 16, skipNever, 4},
  49. {8, 16, 32, 32, skipNever, 5},
  50. {8, 16, 128, 128, skipNever, 6},
  51. {8, 32, 128, 256, skipNever, 7},
  52. {32, 128, 258, 1024, skipNever, 8},
  53. {32, 258, 258, 4096, skipNever, 9},
  54. }
  55. type hashid uint32
  56. type compressor struct {
  57. compressionLevel
  58. w *huffmanBitWriter
  59. bulkHasher func([]byte, []hash)
  60. // compression algorithm
  61. fill func(*compressor, []byte) int // copy data to window
  62. step func(*compressor) // process window
  63. sync bool // requesting flush
  64. // Input hash chains
  65. // hashHead[hashValue] contains the largest inputIndex with the specified hash value
  66. // If hashHead[hashValue] is within the current window, then
  67. // hashPrev[hashHead[hashValue] & windowMask] contains the previous index
  68. // with the same hash value.
  69. chainHead int
  70. hashHead []hashid
  71. hashPrev []hashid
  72. hashOffset int
  73. // input window: unprocessed data is window[index:windowEnd]
  74. index int
  75. window []byte
  76. windowEnd int
  77. blockStart int // window index where current tokens start
  78. byteAvailable bool // if true, still need to process window[index-1].
  79. // queued output tokens
  80. tokens tokens
  81. // deflate state
  82. length int
  83. offset int
  84. hash hash
  85. maxInsertIndex int
  86. err error
  87. ii uint16 // position of last match, intended to overflow to reset.
  88. hashMatch [maxMatchLength + minMatchLength]hash
  89. }
  90. type hash int32
  91. func (d *compressor) fillDeflate(b []byte) int {
  92. if d.index >= 2*windowSize-(minMatchLength+maxMatchLength) {
  93. // shift the window by windowSize
  94. copy(d.window, d.window[windowSize:2*windowSize])
  95. d.index -= windowSize
  96. d.windowEnd -= windowSize
  97. if d.blockStart >= windowSize {
  98. d.blockStart -= windowSize
  99. } else {
  100. d.blockStart = math.MaxInt32
  101. }
  102. d.hashOffset += windowSize
  103. if d.hashOffset > maxHashOffset {
  104. delta := d.hashOffset - 1
  105. d.hashOffset -= delta
  106. d.chainHead -= delta
  107. for i, v := range d.hashPrev {
  108. if int(v) > delta {
  109. d.hashPrev[i] = hashid(int(v) - delta)
  110. } else {
  111. d.hashPrev[i] = 0
  112. }
  113. }
  114. for i, v := range d.hashHead {
  115. if int(v) > delta {
  116. d.hashHead[i] = hashid(int(v) - delta)
  117. } else {
  118. d.hashHead[i] = 0
  119. }
  120. }
  121. }
  122. }
  123. n := copy(d.window[d.windowEnd:], b)
  124. d.windowEnd += n
  125. return n
  126. }
  127. func (d *compressor) writeBlock(tok tokens, index int, eof bool) error {
  128. if index > 0 || eof {
  129. var window []byte
  130. if d.blockStart <= index {
  131. window = d.window[d.blockStart:index]
  132. }
  133. d.blockStart = index
  134. d.w.writeBlock(tok, eof, window)
  135. return d.w.err
  136. }
  137. return nil
  138. }
  139. // fillWindow will fill the current window with the supplied
  140. // dictionary and calculate all hashes.
  141. // This is much faster than doing a full encode.
  142. // Should only be used after a start/reset.
  143. func (d *compressor) fillWindow(b []byte) {
  144. // Do not fill window if we are in store-only mode,
  145. // use constant or Snappy compression.
  146. if d.compressionLevel.level == 0 {
  147. return
  148. }
  149. // If we are given too much, cut it.
  150. if len(b) > windowSize {
  151. b = b[len(b)-windowSize:]
  152. }
  153. // Add all to window.
  154. n := copy(d.window[d.windowEnd:], b)
  155. // Calculate 256 hashes at the time (more L1 cache hits)
  156. loops := (n + 256 - minMatchLength) / 256
  157. for j := 0; j < loops; j++ {
  158. startindex := j * 256
  159. end := startindex + 256 + minMatchLength - 1
  160. if end > n {
  161. end = n
  162. }
  163. tocheck := d.window[startindex:end]
  164. dstSize := len(tocheck) - minMatchLength + 1
  165. if dstSize <= 0 {
  166. continue
  167. }
  168. dst := d.hashMatch[:dstSize]
  169. d.bulkHasher(tocheck, dst)
  170. var newH hash
  171. for i, val := range dst {
  172. di := i + startindex
  173. newH = val & hashMask
  174. // Get previous value with the same hash.
  175. // Our chain should point to the previous value.
  176. d.hashPrev[di&windowMask] = d.hashHead[newH]
  177. // Set the head of the hash chain to us.
  178. d.hashHead[newH] = hashid(di + d.hashOffset)
  179. }
  180. d.hash = newH
  181. }
  182. // Update window information.
  183. d.windowEnd += n
  184. d.index = n
  185. }
  186. // Try to find a match starting at index whose length is greater than prevSize.
  187. // We only look at chainCount possibilities before giving up.
  188. // pos = d.index, prevHead = d.chainHead-d.hashOffset, prevLength=minMatchLength-1, lookahead
  189. func (d *compressor) findMatch(pos int, prevHead int, prevLength int, lookahead int) (length, offset int, ok bool) {
  190. minMatchLook := maxMatchLength
  191. if lookahead < minMatchLook {
  192. minMatchLook = lookahead
  193. }
  194. win := d.window[0 : pos+minMatchLook]
  195. // We quit when we get a match that's at least nice long
  196. nice := len(win) - pos
  197. if d.nice < nice {
  198. nice = d.nice
  199. }
  200. // If we've got a match that's good enough, only look in 1/4 the chain.
  201. tries := d.chain
  202. length = prevLength
  203. if length >= d.good {
  204. tries >>= 2
  205. }
  206. wEnd := win[pos+length]
  207. wPos := win[pos:]
  208. minIndex := pos - windowSize
  209. for i := prevHead; tries > 0; tries-- {
  210. if wEnd == win[i+length] {
  211. n := matchLen(win[i:], wPos, minMatchLook)
  212. if n > length && (n > minMatchLength || pos-i <= 4096) {
  213. length = n
  214. offset = pos - i
  215. ok = true
  216. if n >= nice {
  217. // The match is good enough that we don't try to find a better one.
  218. break
  219. }
  220. wEnd = win[pos+n]
  221. }
  222. }
  223. if i == minIndex {
  224. // hashPrev[i & windowMask] has already been overwritten, so stop now.
  225. break
  226. }
  227. i = int(d.hashPrev[i&windowMask]) - d.hashOffset
  228. if i < minIndex || i < 0 {
  229. break
  230. }
  231. }
  232. return
  233. }
  234. // Try to find a match starting at index whose length is greater than prevSize.
  235. // We only look at chainCount possibilities before giving up.
  236. // pos = d.index, prevHead = d.chainHead-d.hashOffset, prevLength=minMatchLength-1, lookahead
  237. func (d *compressor) findMatchSSE(pos int, prevHead int, prevLength int, lookahead int) (length, offset int, ok bool) {
  238. minMatchLook := maxMatchLength
  239. if lookahead < minMatchLook {
  240. minMatchLook = lookahead
  241. }
  242. win := d.window[0 : pos+minMatchLook]
  243. // We quit when we get a match that's at least nice long
  244. nice := len(win) - pos
  245. if d.nice < nice {
  246. nice = d.nice
  247. }
  248. // If we've got a match that's good enough, only look in 1/4 the chain.
  249. tries := d.chain
  250. length = prevLength
  251. if length >= d.good {
  252. tries >>= 2
  253. }
  254. wEnd := win[pos+length]
  255. wPos := win[pos:]
  256. minIndex := pos - windowSize
  257. for i := prevHead; tries > 0; tries-- {
  258. if wEnd == win[i+length] {
  259. n := matchLenSSE4(win[i:], wPos, minMatchLook)
  260. if n > length && (n > minMatchLength || pos-i <= 4096) {
  261. length = n
  262. offset = pos - i
  263. ok = true
  264. if n >= nice {
  265. // The match is good enough that we don't try to find a better one.
  266. break
  267. }
  268. wEnd = win[pos+n]
  269. }
  270. }
  271. if i == minIndex {
  272. // hashPrev[i & windowMask] has already been overwritten, so stop now.
  273. break
  274. }
  275. i = int(d.hashPrev[i&windowMask]) - d.hashOffset
  276. if i < minIndex || i < 0 {
  277. break
  278. }
  279. }
  280. return
  281. }
  282. func (d *compressor) writeStoredBlock(buf []byte) error {
  283. if d.w.writeStoredHeader(len(buf), false); d.w.err != nil {
  284. return d.w.err
  285. }
  286. d.w.writeBytes(buf)
  287. return d.w.err
  288. }
  289. // oldHash is the hash function used when no native crc32 calculation
  290. // or similar is present.
  291. func oldHash(b []byte) hash {
  292. return hash(b[0])<<(hashShift*3) + hash(b[1])<<(hashShift*2) + hash(b[2])<<hashShift + hash(b[3])
  293. }
  294. // oldBulkHash will compute hashes using the same
  295. // algorithm as oldHash
  296. func oldBulkHash(b []byte, dst []hash) {
  297. if len(b) < minMatchLength {
  298. return
  299. }
  300. h := oldHash(b)
  301. dst[0] = h
  302. i := 1
  303. end := len(b) - minMatchLength + 1
  304. for ; i < end; i++ {
  305. h = (h << hashShift) + hash(b[i+3])
  306. dst[i] = h
  307. }
  308. }
  309. // matchLen returns the number of matching bytes in a and b
  310. // up to length 'max'. Both slices must be at least 'max'
  311. // bytes in size.
  312. func matchLen(a, b []byte, max int) int {
  313. a = a[:max]
  314. for i, av := range a {
  315. if b[i] != av {
  316. return i
  317. }
  318. }
  319. return max
  320. }
  321. func (d *compressor) initDeflate() {
  322. d.hashHead = make([]hashid, hashSize)
  323. d.hashPrev = make([]hashid, windowSize)
  324. d.window = make([]byte, 2*windowSize)
  325. d.hashOffset = 1
  326. d.tokens.tokens = make([]token, maxFlateBlockTokens+1)
  327. d.length = minMatchLength - 1
  328. d.offset = 0
  329. d.byteAvailable = false
  330. d.index = 0
  331. d.hash = 0
  332. d.chainHead = -1
  333. d.bulkHasher = oldBulkHash
  334. if useSSE42 {
  335. d.bulkHasher = crc32sseAll
  336. }
  337. }
  338. // Assumes that d.fastSkipHashing != skipNever,
  339. // otherwise use deflateNoSkip
  340. func (d *compressor) deflate() {
  341. // Sanity enables additional runtime tests.
  342. // It's intended to be used during development
  343. // to supplement the currently ad-hoc unit tests.
  344. const sanity = false
  345. if d.windowEnd-d.index < minMatchLength+maxMatchLength && !d.sync {
  346. return
  347. }
  348. d.maxInsertIndex = d.windowEnd - (minMatchLength - 1)
  349. if d.index < d.maxInsertIndex {
  350. d.hash = oldHash(d.window[d.index:d.index+minMatchLength]) & hashMask
  351. }
  352. for {
  353. if sanity && d.index > d.windowEnd {
  354. panic("index > windowEnd")
  355. }
  356. lookahead := d.windowEnd - d.index
  357. if lookahead < minMatchLength+maxMatchLength {
  358. if !d.sync {
  359. return
  360. }
  361. if sanity && d.index > d.windowEnd {
  362. panic("index > windowEnd")
  363. }
  364. if lookahead == 0 {
  365. if d.tokens.n > 0 {
  366. if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
  367. return
  368. }
  369. d.tokens.n = 0
  370. }
  371. return
  372. }
  373. }
  374. if d.index < d.maxInsertIndex {
  375. // Update the hash
  376. d.hash = oldHash(d.window[d.index:d.index+minMatchLength]) & hashMask
  377. ch := d.hashHead[d.hash]
  378. d.chainHead = int(ch)
  379. d.hashPrev[d.index&windowMask] = ch
  380. d.hashHead[d.hash] = hashid(d.index + d.hashOffset)
  381. }
  382. d.length = minMatchLength - 1
  383. d.offset = 0
  384. minIndex := d.index - windowSize
  385. if minIndex < 0 {
  386. minIndex = 0
  387. }
  388. if d.chainHead-d.hashOffset >= minIndex && lookahead > minMatchLength-1 {
  389. if newLength, newOffset, ok := d.findMatch(d.index, d.chainHead-d.hashOffset, minMatchLength-1, lookahead); ok {
  390. d.length = newLength
  391. d.offset = newOffset
  392. }
  393. }
  394. if d.length >= minMatchLength {
  395. d.ii = 0
  396. // There was a match at the previous step, and the current match is
  397. // not better. Output the previous match.
  398. // "d.length-3" should NOT be "d.length-minMatchLength", since the format always assume 3
  399. d.tokens.tokens[d.tokens.n] = matchToken(uint32(d.length-3), uint32(d.offset-minOffsetSize))
  400. d.tokens.n++
  401. // Insert in the hash table all strings up to the end of the match.
  402. // index and index-1 are already inserted. If there is not enough
  403. // lookahead, the last two strings are not inserted into the hash
  404. // table.
  405. if d.length <= d.fastSkipHashing {
  406. var newIndex int
  407. newIndex = d.index + d.length
  408. // Calculate missing hashes
  409. end := newIndex
  410. if end > d.maxInsertIndex {
  411. end = d.maxInsertIndex
  412. }
  413. end += minMatchLength - 1
  414. startindex := d.index + 1
  415. if startindex > d.maxInsertIndex {
  416. startindex = d.maxInsertIndex
  417. }
  418. tocheck := d.window[startindex:end]
  419. dstSize := len(tocheck) - minMatchLength + 1
  420. if dstSize > 0 {
  421. dst := d.hashMatch[:dstSize]
  422. oldBulkHash(tocheck, dst)
  423. var newH hash
  424. for i, val := range dst {
  425. di := i + startindex
  426. newH = val & hashMask
  427. // Get previous value with the same hash.
  428. // Our chain should point to the previous value.
  429. d.hashPrev[di&windowMask] = d.hashHead[newH]
  430. // Set the head of the hash chain to us.
  431. d.hashHead[newH] = hashid(di + d.hashOffset)
  432. }
  433. d.hash = newH
  434. }
  435. d.index = newIndex
  436. } else {
  437. // For matches this long, we don't bother inserting each individual
  438. // item into the table.
  439. d.index += d.length
  440. if d.index < d.maxInsertIndex {
  441. d.hash = oldHash(d.window[d.index:d.index+minMatchLength]) & hashMask
  442. }
  443. }
  444. if d.tokens.n == maxFlateBlockTokens {
  445. // The block includes the current character
  446. if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
  447. return
  448. }
  449. d.tokens.n = 0
  450. }
  451. } else {
  452. d.ii++
  453. end := d.index + int(d.ii>>uint(d.fastSkipHashing)) + 1
  454. if end > d.windowEnd {
  455. end = d.windowEnd
  456. }
  457. for i := d.index; i < end; i++ {
  458. d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[i]))
  459. d.tokens.n++
  460. if d.tokens.n == maxFlateBlockTokens {
  461. if d.err = d.writeBlock(d.tokens, i+1, false); d.err != nil {
  462. return
  463. }
  464. d.tokens.n = 0
  465. }
  466. }
  467. d.index = end
  468. }
  469. }
  470. }
  471. // deflateLazy is the same as deflate, but with d.fastSkipHashing == skipNever,
  472. // meaning it always has lazy matching on.
  473. func (d *compressor) deflateLazy() {
  474. // Sanity enables additional runtime tests.
  475. // It's intended to be used during development
  476. // to supplement the currently ad-hoc unit tests.
  477. const sanity = false
  478. if d.windowEnd-d.index < minMatchLength+maxMatchLength && !d.sync {
  479. return
  480. }
  481. d.maxInsertIndex = d.windowEnd - (minMatchLength - 1)
  482. if d.index < d.maxInsertIndex {
  483. d.hash = oldHash(d.window[d.index:d.index+minMatchLength]) & hashMask
  484. }
  485. for {
  486. if sanity && d.index > d.windowEnd {
  487. panic("index > windowEnd")
  488. }
  489. lookahead := d.windowEnd - d.index
  490. if lookahead < minMatchLength+maxMatchLength {
  491. if !d.sync {
  492. return
  493. }
  494. if sanity && d.index > d.windowEnd {
  495. panic("index > windowEnd")
  496. }
  497. if lookahead == 0 {
  498. // Flush current output block if any.
  499. if d.byteAvailable {
  500. // There is still one pending token that needs to be flushed
  501. d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[d.index-1]))
  502. d.tokens.n++
  503. d.byteAvailable = false
  504. }
  505. if d.tokens.n > 0 {
  506. if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
  507. return
  508. }
  509. d.tokens.n = 0
  510. }
  511. return
  512. }
  513. }
  514. if d.index < d.maxInsertIndex {
  515. // Update the hash
  516. d.hash = oldHash(d.window[d.index:d.index+minMatchLength]) & hashMask
  517. ch := d.hashHead[d.hash]
  518. d.chainHead = int(ch)
  519. d.hashPrev[d.index&windowMask] = ch
  520. d.hashHead[d.hash] = hashid(d.index + d.hashOffset)
  521. }
  522. prevLength := d.length
  523. prevOffset := d.offset
  524. d.length = minMatchLength - 1
  525. d.offset = 0
  526. minIndex := d.index - windowSize
  527. if minIndex < 0 {
  528. minIndex = 0
  529. }
  530. if d.chainHead-d.hashOffset >= minIndex && lookahead > prevLength && prevLength < d.lazy {
  531. if newLength, newOffset, ok := d.findMatch(d.index, d.chainHead-d.hashOffset, minMatchLength-1, lookahead); ok {
  532. d.length = newLength
  533. d.offset = newOffset
  534. }
  535. }
  536. if prevLength >= minMatchLength && d.length <= prevLength {
  537. // There was a match at the previous step, and the current match is
  538. // not better. Output the previous match.
  539. d.tokens.tokens[d.tokens.n] = matchToken(uint32(prevLength-3), uint32(prevOffset-minOffsetSize))
  540. d.tokens.n++
  541. // Insert in the hash table all strings up to the end of the match.
  542. // index and index-1 are already inserted. If there is not enough
  543. // lookahead, the last two strings are not inserted into the hash
  544. // table.
  545. var newIndex int
  546. newIndex = d.index + prevLength - 1
  547. // Calculate missing hashes
  548. end := newIndex
  549. if end > d.maxInsertIndex {
  550. end = d.maxInsertIndex
  551. }
  552. end += minMatchLength - 1
  553. startindex := d.index + 1
  554. if startindex > d.maxInsertIndex {
  555. startindex = d.maxInsertIndex
  556. }
  557. tocheck := d.window[startindex:end]
  558. dstSize := len(tocheck) - minMatchLength + 1
  559. if dstSize > 0 {
  560. dst := d.hashMatch[:dstSize]
  561. oldBulkHash(tocheck, dst)
  562. var newH hash
  563. for i, val := range dst {
  564. di := i + startindex
  565. newH = val & hashMask
  566. // Get previous value with the same hash.
  567. // Our chain should point to the previous value.
  568. d.hashPrev[di&windowMask] = d.hashHead[newH]
  569. // Set the head of the hash chain to us.
  570. d.hashHead[newH] = hashid(di + d.hashOffset)
  571. }
  572. d.hash = newH
  573. }
  574. d.index = newIndex
  575. d.byteAvailable = false
  576. d.length = minMatchLength - 1
  577. if d.tokens.n == maxFlateBlockTokens {
  578. // The block includes the current character
  579. if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
  580. return
  581. }
  582. d.tokens.n = 0
  583. }
  584. } else {
  585. // Reset, if we got a match this run.
  586. if d.length >= minMatchLength {
  587. d.ii = 0
  588. }
  589. // We have a byte waiting. Emit it.
  590. if d.byteAvailable {
  591. d.ii++
  592. d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[d.index-1]))
  593. d.tokens.n++
  594. if d.tokens.n == maxFlateBlockTokens {
  595. if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
  596. return
  597. }
  598. d.tokens.n = 0
  599. }
  600. d.index++
  601. // If we have a long run of no matches, skip additional bytes
  602. // Resets when d.ii overflows after 64KB.
  603. if d.ii > 31 {
  604. n := int(d.ii >> 6)
  605. for j := 0; j < n; j++ {
  606. if d.index >= d.windowEnd-1 {
  607. break
  608. }
  609. d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[d.index-1]))
  610. d.tokens.n++
  611. if d.tokens.n == maxFlateBlockTokens {
  612. if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
  613. return
  614. }
  615. d.tokens.n = 0
  616. }
  617. d.index++
  618. }
  619. // Flush last byte
  620. d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[d.index-1]))
  621. d.tokens.n++
  622. d.byteAvailable = false
  623. // d.length = minMatchLength - 1 // not needed, since d.ii is reset above, so it should never be > minMatchLength
  624. if d.tokens.n == maxFlateBlockTokens {
  625. if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
  626. return
  627. }
  628. d.tokens.n = 0
  629. }
  630. }
  631. } else {
  632. d.index++
  633. d.byteAvailable = true
  634. }
  635. }
  636. }
  637. }
  638. // Assumes that d.fastSkipHashing != skipNever,
  639. // otherwise use deflateNoSkip
  640. func (d *compressor) deflateSSE() {
  641. // Sanity enables additional runtime tests.
  642. // It's intended to be used during development
  643. // to supplement the currently ad-hoc unit tests.
  644. const sanity = false
  645. if d.windowEnd-d.index < minMatchLength+maxMatchLength && !d.sync {
  646. return
  647. }
  648. d.maxInsertIndex = d.windowEnd - (minMatchLength - 1)
  649. if d.index < d.maxInsertIndex {
  650. d.hash = oldHash(d.window[d.index:d.index+minMatchLength]) & hashMask
  651. }
  652. for {
  653. if sanity && d.index > d.windowEnd {
  654. panic("index > windowEnd")
  655. }
  656. lookahead := d.windowEnd - d.index
  657. if lookahead < minMatchLength+maxMatchLength {
  658. if !d.sync {
  659. return
  660. }
  661. if sanity && d.index > d.windowEnd {
  662. panic("index > windowEnd")
  663. }
  664. if lookahead == 0 {
  665. if d.tokens.n > 0 {
  666. if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
  667. return
  668. }
  669. d.tokens.n = 0
  670. }
  671. return
  672. }
  673. }
  674. if d.index < d.maxInsertIndex {
  675. // Update the hash
  676. d.hash = crc32sse(d.window[d.index:d.index+minMatchLength]) & hashMask
  677. ch := d.hashHead[d.hash]
  678. d.chainHead = int(ch)
  679. d.hashPrev[d.index&windowMask] = ch
  680. d.hashHead[d.hash] = hashid(d.index + d.hashOffset)
  681. }
  682. d.length = minMatchLength - 1
  683. d.offset = 0
  684. minIndex := d.index - windowSize
  685. if minIndex < 0 {
  686. minIndex = 0
  687. }
  688. if d.chainHead-d.hashOffset >= minIndex && lookahead > minMatchLength-1 {
  689. if newLength, newOffset, ok := d.findMatchSSE(d.index, d.chainHead-d.hashOffset, minMatchLength-1, lookahead); ok {
  690. d.length = newLength
  691. d.offset = newOffset
  692. }
  693. }
  694. if d.length >= minMatchLength {
  695. d.ii = 0
  696. // There was a match at the previous step, and the current match is
  697. // not better. Output the previous match.
  698. // "d.length-3" should NOT be "d.length-minMatchLength", since the format always assume 3
  699. d.tokens.tokens[d.tokens.n] = matchToken(uint32(d.length-3), uint32(d.offset-minOffsetSize))
  700. d.tokens.n++
  701. // Insert in the hash table all strings up to the end of the match.
  702. // index and index-1 are already inserted. If there is not enough
  703. // lookahead, the last two strings are not inserted into the hash
  704. // table.
  705. if d.length <= d.fastSkipHashing {
  706. var newIndex int
  707. newIndex = d.index + d.length
  708. // Calculate missing hashes
  709. end := newIndex
  710. if end > d.maxInsertIndex {
  711. end = d.maxInsertIndex
  712. }
  713. end += minMatchLength - 1
  714. startindex := d.index + 1
  715. if startindex > d.maxInsertIndex {
  716. startindex = d.maxInsertIndex
  717. }
  718. tocheck := d.window[startindex:end]
  719. dstSize := len(tocheck) - minMatchLength + 1
  720. if dstSize > 0 {
  721. dst := d.hashMatch[:dstSize]
  722. crc32sseAll(tocheck, dst)
  723. var newH hash
  724. for i, val := range dst {
  725. di := i + startindex
  726. newH = val & hashMask
  727. // Get previous value with the same hash.
  728. // Our chain should point to the previous value.
  729. d.hashPrev[di&windowMask] = d.hashHead[newH]
  730. // Set the head of the hash chain to us.
  731. d.hashHead[newH] = hashid(di + d.hashOffset)
  732. }
  733. d.hash = newH
  734. }
  735. d.index = newIndex
  736. } else {
  737. // For matches this long, we don't bother inserting each individual
  738. // item into the table.
  739. d.index += d.length
  740. if d.index < d.maxInsertIndex {
  741. d.hash = crc32sse(d.window[d.index:d.index+minMatchLength]) & hashMask
  742. }
  743. }
  744. if d.tokens.n == maxFlateBlockTokens {
  745. // The block includes the current character
  746. if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
  747. return
  748. }
  749. d.tokens.n = 0
  750. }
  751. } else {
  752. d.ii++
  753. end := d.index + int(d.ii>>uint(d.fastSkipHashing)) + 1
  754. if end > d.windowEnd {
  755. end = d.windowEnd
  756. }
  757. for i := d.index; i < end; i++ {
  758. d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[i]))
  759. d.tokens.n++
  760. if d.tokens.n == maxFlateBlockTokens {
  761. if d.err = d.writeBlock(d.tokens, i+1, false); d.err != nil {
  762. return
  763. }
  764. d.tokens.n = 0
  765. }
  766. }
  767. d.index = end
  768. }
  769. }
  770. }
  771. // deflateLazy is the same as deflate, but with d.fastSkipHashing == skipNever,
  772. // meaning it always has lazy matching on.
  773. func (d *compressor) deflateLazySSE() {
  774. // Sanity enables additional runtime tests.
  775. // It's intended to be used during development
  776. // to supplement the currently ad-hoc unit tests.
  777. const sanity = false
  778. if d.windowEnd-d.index < minMatchLength+maxMatchLength && !d.sync {
  779. return
  780. }
  781. d.maxInsertIndex = d.windowEnd - (minMatchLength - 1)
  782. if d.index < d.maxInsertIndex {
  783. d.hash = crc32sse(d.window[d.index:d.index+minMatchLength]) & hashMask
  784. }
  785. for {
  786. if sanity && d.index > d.windowEnd {
  787. panic("index > windowEnd")
  788. }
  789. lookahead := d.windowEnd - d.index
  790. if lookahead < minMatchLength+maxMatchLength {
  791. if !d.sync {
  792. return
  793. }
  794. if sanity && d.index > d.windowEnd {
  795. panic("index > windowEnd")
  796. }
  797. if lookahead == 0 {
  798. // Flush current output block if any.
  799. if d.byteAvailable {
  800. // There is still one pending token that needs to be flushed
  801. d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[d.index-1]))
  802. d.tokens.n++
  803. d.byteAvailable = false
  804. }
  805. if d.tokens.n > 0 {
  806. if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
  807. return
  808. }
  809. d.tokens.n = 0
  810. }
  811. return
  812. }
  813. }
  814. if d.index < d.maxInsertIndex {
  815. // Update the hash
  816. d.hash = crc32sse(d.window[d.index:d.index+minMatchLength]) & hashMask
  817. ch := d.hashHead[d.hash]
  818. d.chainHead = int(ch)
  819. d.hashPrev[d.index&windowMask] = ch
  820. d.hashHead[d.hash] = hashid(d.index + d.hashOffset)
  821. }
  822. prevLength := d.length
  823. prevOffset := d.offset
  824. d.length = minMatchLength - 1
  825. d.offset = 0
  826. minIndex := d.index - windowSize
  827. if minIndex < 0 {
  828. minIndex = 0
  829. }
  830. if d.chainHead-d.hashOffset >= minIndex && lookahead > prevLength && prevLength < d.lazy {
  831. if newLength, newOffset, ok := d.findMatchSSE(d.index, d.chainHead-d.hashOffset, minMatchLength-1, lookahead); ok {
  832. d.length = newLength
  833. d.offset = newOffset
  834. }
  835. }
  836. if prevLength >= minMatchLength && d.length <= prevLength {
  837. // There was a match at the previous step, and the current match is
  838. // not better. Output the previous match.
  839. d.tokens.tokens[d.tokens.n] = matchToken(uint32(prevLength-3), uint32(prevOffset-minOffsetSize))
  840. d.tokens.n++
  841. // Insert in the hash table all strings up to the end of the match.
  842. // index and index-1 are already inserted. If there is not enough
  843. // lookahead, the last two strings are not inserted into the hash
  844. // table.
  845. var newIndex int
  846. newIndex = d.index + prevLength - 1
  847. // Calculate missing hashes
  848. end := newIndex
  849. if end > d.maxInsertIndex {
  850. end = d.maxInsertIndex
  851. }
  852. end += minMatchLength - 1
  853. startindex := d.index + 1
  854. if startindex > d.maxInsertIndex {
  855. startindex = d.maxInsertIndex
  856. }
  857. tocheck := d.window[startindex:end]
  858. dstSize := len(tocheck) - minMatchLength + 1
  859. if dstSize > 0 {
  860. dst := d.hashMatch[:dstSize]
  861. crc32sseAll(tocheck, dst)
  862. var newH hash
  863. for i, val := range dst {
  864. di := i + startindex
  865. newH = val & hashMask
  866. // Get previous value with the same hash.
  867. // Our chain should point to the previous value.
  868. d.hashPrev[di&windowMask] = d.hashHead[newH]
  869. // Set the head of the hash chain to us.
  870. d.hashHead[newH] = hashid(di + d.hashOffset)
  871. }
  872. d.hash = newH
  873. }
  874. d.index = newIndex
  875. d.byteAvailable = false
  876. d.length = minMatchLength - 1
  877. if d.tokens.n == maxFlateBlockTokens {
  878. // The block includes the current character
  879. if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
  880. return
  881. }
  882. d.tokens.n = 0
  883. }
  884. } else {
  885. // Reset, if we got a match this run.
  886. if d.length >= minMatchLength {
  887. d.ii = 0
  888. }
  889. // We have a byte waiting. Emit it.
  890. if d.byteAvailable {
  891. d.ii++
  892. d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[d.index-1]))
  893. d.tokens.n++
  894. if d.tokens.n == maxFlateBlockTokens {
  895. if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
  896. return
  897. }
  898. d.tokens.n = 0
  899. }
  900. d.index++
  901. // If we have a long run of no matches, skip additional bytes
  902. // Resets when d.ii overflows after 64KB.
  903. if d.ii > 31 {
  904. n := int(d.ii >> 6)
  905. for j := 0; j < n; j++ {
  906. if d.index >= d.windowEnd-1 {
  907. break
  908. }
  909. d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[d.index-1]))
  910. d.tokens.n++
  911. if d.tokens.n == maxFlateBlockTokens {
  912. if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
  913. return
  914. }
  915. d.tokens.n = 0
  916. }
  917. d.index++
  918. }
  919. // Flush last byte
  920. d.tokens.tokens[d.tokens.n] = literalToken(uint32(d.window[d.index-1]))
  921. d.tokens.n++
  922. d.byteAvailable = false
  923. // d.length = minMatchLength - 1 // not needed, since d.ii is reset above, so it should never be > minMatchLength
  924. if d.tokens.n == maxFlateBlockTokens {
  925. if d.err = d.writeBlock(d.tokens, d.index, false); d.err != nil {
  926. return
  927. }
  928. d.tokens.n = 0
  929. }
  930. }
  931. } else {
  932. d.index++
  933. d.byteAvailable = true
  934. }
  935. }
  936. }
  937. }
  938. func (d *compressor) fillStore(b []byte) int {
  939. n := copy(d.window[d.windowEnd:], b)
  940. d.windowEnd += n
  941. return n
  942. }
  943. func (d *compressor) store() {
  944. if d.windowEnd > 0 {
  945. d.err = d.writeStoredBlock(d.window[:d.windowEnd])
  946. }
  947. d.windowEnd = 0
  948. }
  949. // fillHuff will fill the buffer with data for huffman-only compression.
  950. // The number of bytes copied is returned.
  951. func (d *compressor) fillHuff(b []byte) int {
  952. n := copy(d.window[d.windowEnd:], b)
  953. d.windowEnd += n
  954. return n
  955. }
  956. // storeHuff will compress and store the currently added data,
  957. // if enough has been accumulated or we at the end of the stream.
  958. // Any error that occurred will be in d.err
  959. func (d *compressor) storeHuff() {
  960. // We only compress if we have maxStoreBlockSize or we are at end-of-stream
  961. if d.windowEnd < maxStoreBlockSize && !d.sync {
  962. return
  963. }
  964. if d.windowEnd == 0 {
  965. return
  966. }
  967. d.w.writeBlockHuff(false, d.window[:d.windowEnd])
  968. d.err = d.w.err
  969. d.windowEnd = 0
  970. }
  971. // storeHuff will compress and store the currently added data,
  972. // if enough has been accumulated or we at the end of the stream.
  973. // Any error that occurred will be in d.err
  974. func (d *compressor) storeSnappy() {
  975. // We only compress if we have maxStoreBlockSize.
  976. if d.windowEnd < maxStoreBlockSize && !d.sync {
  977. return
  978. }
  979. if d.windowEnd == 0 {
  980. return
  981. }
  982. snappyEncode(&d.tokens, d.window[:d.windowEnd])
  983. d.w.writeBlock(d.tokens, false, d.window[:d.windowEnd])
  984. d.err = d.w.err
  985. d.tokens.n = 0
  986. d.windowEnd = 0
  987. }
  988. // write will add input byte to the stream.
  989. // Unless an error occurs all bytes will be consumed.
  990. func (d *compressor) write(b []byte) (n int, err error) {
  991. if d.err != nil {
  992. return 0, d.err
  993. }
  994. n = len(b)
  995. for len(b) > 0 {
  996. d.step(d)
  997. b = b[d.fill(d, b):]
  998. if d.err != nil {
  999. return 0, d.err
  1000. }
  1001. }
  1002. return n, d.err
  1003. }
  1004. func (d *compressor) syncFlush() error {
  1005. d.sync = true
  1006. if d.err != nil {
  1007. return d.err
  1008. }
  1009. d.step(d)
  1010. if d.err == nil {
  1011. d.w.writeStoredHeader(0, false)
  1012. d.w.flush()
  1013. d.err = d.w.err
  1014. }
  1015. d.sync = false
  1016. return d.err
  1017. }
  1018. func (d *compressor) init(w io.Writer, level int) (err error) {
  1019. d.w = newHuffmanBitWriter(w)
  1020. switch {
  1021. case level == NoCompression:
  1022. d.window = make([]byte, maxStoreBlockSize)
  1023. d.fill = (*compressor).fillStore
  1024. d.step = (*compressor).store
  1025. case level == ConstantCompression:
  1026. d.window = make([]byte, maxStoreBlockSize)
  1027. d.fill = (*compressor).fillHuff
  1028. d.step = (*compressor).storeHuff
  1029. case level == 1:
  1030. d.window = make([]byte, maxStoreBlockSize)
  1031. d.fill = (*compressor).fillHuff
  1032. d.step = (*compressor).storeSnappy
  1033. d.tokens.tokens = make([]token, maxStoreBlockSize+1)
  1034. case level == DefaultCompression:
  1035. level = 6
  1036. fallthrough
  1037. case 2 <= level && level <= 9:
  1038. d.compressionLevel = levels[level]
  1039. d.initDeflate()
  1040. d.fill = (*compressor).fillDeflate
  1041. if d.fastSkipHashing == skipNever {
  1042. if useSSE42 {
  1043. d.step = (*compressor).deflateLazySSE
  1044. } else {
  1045. d.step = (*compressor).deflateLazy
  1046. }
  1047. } else {
  1048. if useSSE42 {
  1049. d.step = (*compressor).deflateSSE
  1050. } else {
  1051. d.step = (*compressor).deflate
  1052. }
  1053. }
  1054. default:
  1055. return fmt.Errorf("flate: invalid compression level %d: want value in range [-2, 9]", level)
  1056. }
  1057. return nil
  1058. }
  1059. // Used for zeroing the hash slice
  1060. var hzeroes [256]hashid
  1061. // reset the state of the compressor.
  1062. func (d *compressor) reset(w io.Writer) {
  1063. d.w.reset(w)
  1064. d.sync = false
  1065. d.err = nil
  1066. switch d.compressionLevel.chain {
  1067. case 0:
  1068. // level was NoCompression or ConstantCompresssion.
  1069. d.windowEnd = 0
  1070. default:
  1071. d.chainHead = -1
  1072. for s := d.hashHead; len(s) > 0; {
  1073. n := copy(s, hzeroes[:])
  1074. s = s[n:]
  1075. }
  1076. for s := d.hashPrev; len(s) > 0; s = s[len(hzeroes):] {
  1077. copy(s, hzeroes[:])
  1078. }
  1079. d.hashOffset = 1
  1080. d.index, d.windowEnd = 0, 0
  1081. d.blockStart, d.byteAvailable = 0, false
  1082. d.tokens.n = 0
  1083. d.length = minMatchLength - 1
  1084. d.offset = 0
  1085. d.hash = 0
  1086. d.ii = 0
  1087. d.maxInsertIndex = 0
  1088. }
  1089. }
  1090. func (d *compressor) close() error {
  1091. if d.err != nil {
  1092. return d.err
  1093. }
  1094. d.sync = true
  1095. d.step(d)
  1096. if d.err != nil {
  1097. return d.err
  1098. }
  1099. if d.w.writeStoredHeader(0, true); d.w.err != nil {
  1100. return d.w.err
  1101. }
  1102. d.w.flush()
  1103. return d.w.err
  1104. }
  1105. // NewWriter returns a new Writer compressing data at the given level.
  1106. // Following zlib, levels range from 1 (BestSpeed) to 9 (BestCompression);
  1107. // higher levels typically run slower but compress more. Level 0
  1108. // (NoCompression) does not attempt any compression; it only adds the
  1109. // necessary DEFLATE framing. Level -1 (DefaultCompression) uses the default
  1110. // compression level.
  1111. // Level -2 (ConstantCompression) will use Huffman compression only, giving
  1112. // a very fast compression for all types of input, but sacrificing considerable
  1113. // compression efficiency.
  1114. //
  1115. // If level is in the range [-2, 9] then the error returned will be nil.
  1116. // Otherwise the error returned will be non-nil.
  1117. func NewWriter(w io.Writer, level int) (*Writer, error) {
  1118. var dw Writer
  1119. if err := dw.d.init(w, level); err != nil {
  1120. return nil, err
  1121. }
  1122. return &dw, nil
  1123. }
  1124. // NewWriterDict is like NewWriter but initializes the new
  1125. // Writer with a preset dictionary. The returned Writer behaves
  1126. // as if the dictionary had been written to it without producing
  1127. // any compressed output. The compressed data written to w
  1128. // can only be decompressed by a Reader initialized with the
  1129. // same dictionary.
  1130. func NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error) {
  1131. dw := &dictWriter{w}
  1132. zw, err := NewWriter(dw, level)
  1133. if err != nil {
  1134. return nil, err
  1135. }
  1136. zw.d.fillWindow(dict)
  1137. zw.dict = append(zw.dict, dict...) // duplicate dictionary for Reset method.
  1138. return zw, err
  1139. }
  1140. type dictWriter struct {
  1141. w io.Writer
  1142. }
  1143. func (w *dictWriter) Write(b []byte) (n int, err error) {
  1144. return w.w.Write(b)
  1145. }
  1146. // A Writer takes data written to it and writes the compressed
  1147. // form of that data to an underlying writer (see NewWriter).
  1148. type Writer struct {
  1149. d compressor
  1150. dict []byte
  1151. }
  1152. // Write writes data to w, which will eventually write the
  1153. // compressed form of data to its underlying writer.
  1154. func (w *Writer) Write(data []byte) (n int, err error) {
  1155. return w.d.write(data)
  1156. }
  1157. // Flush flushes any pending compressed data to the underlying writer.
  1158. // It is useful mainly in compressed network protocols, to ensure that
  1159. // a remote reader has enough data to reconstruct a packet.
  1160. // Flush does not return until the data has been written.
  1161. // If the underlying writer returns an error, Flush returns that error.
  1162. //
  1163. // In the terminology of the zlib library, Flush is equivalent to Z_SYNC_FLUSH.
  1164. func (w *Writer) Flush() error {
  1165. // For more about flushing:
  1166. // http://www.bolet.org/~pornin/deflate-flush.html
  1167. return w.d.syncFlush()
  1168. }
  1169. // Close flushes and closes the writer.
  1170. func (w *Writer) Close() error {
  1171. return w.d.close()
  1172. }
  1173. // Reset discards the writer's state and makes it equivalent to
  1174. // the result of NewWriter or NewWriterDict called with dst
  1175. // and w's level and dictionary.
  1176. func (w *Writer) Reset(dst io.Writer) {
  1177. if dw, ok := w.d.w.w.(*dictWriter); ok {
  1178. // w was created with NewWriterDict
  1179. dw.w = dst
  1180. w.d.reset(dw)
  1181. w.d.fillWindow(w.dict)
  1182. } else {
  1183. // w was created with NewWriter
  1184. w.d.reset(dst)
  1185. }
  1186. }
  1187. // ResetDict discards the writer's state and makes it equivalent to
  1188. // the result of NewWriter or NewWriterDict called with dst
  1189. // and w's level, but sets a specific dictionary.
  1190. func (w *Writer) ResetDict(dst io.Writer, dict []byte) {
  1191. w.dict = dict
  1192. w.d.reset(dst)
  1193. w.d.fillWindow(w.dict)
  1194. }