blockenc.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889
  1. // Copyright 2019+ Klaus Post. All rights reserved.
  2. // License information can be found in the LICENSE file.
  3. // Based on work by Yann Collet, released under BSD License.
  4. package zstd
  5. import (
  6. "errors"
  7. "fmt"
  8. "math"
  9. "math/bits"
  10. "github.com/klauspost/compress/huff0"
  11. )
  12. type blockEnc struct {
  13. size int
  14. literals []byte
  15. sequences []seq
  16. coders seqCoders
  17. litEnc *huff0.Scratch
  18. dictLitEnc *huff0.Scratch
  19. wr bitWriter
  20. extraLits int
  21. output []byte
  22. recentOffsets [3]uint32
  23. prevRecentOffsets [3]uint32
  24. last bool
  25. lowMem bool
  26. }
  27. // init should be used once the block has been created.
  28. // If called more than once, the effect is the same as calling reset.
  29. func (b *blockEnc) init() {
  30. if b.lowMem {
  31. // 1K literals
  32. if cap(b.literals) < 1<<10 {
  33. b.literals = make([]byte, 0, 1<<10)
  34. }
  35. const defSeqs = 20
  36. if cap(b.sequences) < defSeqs {
  37. b.sequences = make([]seq, 0, defSeqs)
  38. }
  39. // 1K
  40. if cap(b.output) < 1<<10 {
  41. b.output = make([]byte, 0, 1<<10)
  42. }
  43. } else {
  44. if cap(b.literals) < maxCompressedBlockSize {
  45. b.literals = make([]byte, 0, maxCompressedBlockSize)
  46. }
  47. const defSeqs = 2000
  48. if cap(b.sequences) < defSeqs {
  49. b.sequences = make([]seq, 0, defSeqs)
  50. }
  51. if cap(b.output) < maxCompressedBlockSize {
  52. b.output = make([]byte, 0, maxCompressedBlockSize)
  53. }
  54. }
  55. if b.coders.mlEnc == nil {
  56. b.coders.mlEnc = &fseEncoder{}
  57. b.coders.mlPrev = &fseEncoder{}
  58. b.coders.ofEnc = &fseEncoder{}
  59. b.coders.ofPrev = &fseEncoder{}
  60. b.coders.llEnc = &fseEncoder{}
  61. b.coders.llPrev = &fseEncoder{}
  62. }
  63. b.litEnc = &huff0.Scratch{WantLogLess: 4}
  64. b.reset(nil)
  65. }
  66. // initNewEncode can be used to reset offsets and encoders to the initial state.
  67. func (b *blockEnc) initNewEncode() {
  68. b.recentOffsets = [3]uint32{1, 4, 8}
  69. b.litEnc.Reuse = huff0.ReusePolicyNone
  70. b.coders.setPrev(nil, nil, nil)
  71. }
  72. // reset will reset the block for a new encode, but in the same stream,
  73. // meaning that state will be carried over, but the block content is reset.
  74. // If a previous block is provided, the recent offsets are carried over.
  75. func (b *blockEnc) reset(prev *blockEnc) {
  76. b.extraLits = 0
  77. b.literals = b.literals[:0]
  78. b.size = 0
  79. b.sequences = b.sequences[:0]
  80. b.output = b.output[:0]
  81. b.last = false
  82. if prev != nil {
  83. b.recentOffsets = prev.prevRecentOffsets
  84. }
  85. b.dictLitEnc = nil
  86. }
  87. // reset will reset the block for a new encode, but in the same stream,
  88. // meaning that state will be carried over, but the block content is reset.
  89. // If a previous block is provided, the recent offsets are carried over.
  90. func (b *blockEnc) swapEncoders(prev *blockEnc) {
  91. b.coders.swap(&prev.coders)
  92. b.litEnc, prev.litEnc = prev.litEnc, b.litEnc
  93. }
  94. // blockHeader contains the information for a block header.
  95. type blockHeader uint32
  96. // setLast sets the 'last' indicator on a block.
  97. func (h *blockHeader) setLast(b bool) {
  98. if b {
  99. *h = *h | 1
  100. } else {
  101. const mask = (1 << 24) - 2
  102. *h = *h & mask
  103. }
  104. }
  105. // setSize will store the compressed size of a block.
  106. func (h *blockHeader) setSize(v uint32) {
  107. const mask = 7
  108. *h = (*h)&mask | blockHeader(v<<3)
  109. }
  110. // setType sets the block type.
  111. func (h *blockHeader) setType(t blockType) {
  112. const mask = 1 | (((1 << 24) - 1) ^ 7)
  113. *h = (*h & mask) | blockHeader(t<<1)
  114. }
  115. // appendTo will append the block header to a slice.
  116. func (h blockHeader) appendTo(b []byte) []byte {
  117. return append(b, uint8(h), uint8(h>>8), uint8(h>>16))
  118. }
  119. // String returns a string representation of the block.
  120. func (h blockHeader) String() string {
  121. return fmt.Sprintf("Type: %d, Size: %d, Last:%t", (h>>1)&3, h>>3, h&1 == 1)
  122. }
  123. // literalsHeader contains literals header information.
  124. type literalsHeader uint64
  125. // setType can be used to set the type of literal block.
  126. func (h *literalsHeader) setType(t literalsBlockType) {
  127. const mask = math.MaxUint64 - 3
  128. *h = (*h & mask) | literalsHeader(t)
  129. }
  130. // setSize can be used to set a single size, for uncompressed and RLE content.
  131. func (h *literalsHeader) setSize(regenLen int) {
  132. inBits := bits.Len32(uint32(regenLen))
  133. // Only retain 2 bits
  134. const mask = 3
  135. lh := uint64(*h & mask)
  136. switch {
  137. case inBits < 5:
  138. lh |= (uint64(regenLen) << 3) | (1 << 60)
  139. if debugEncoder {
  140. got := int(lh>>3) & 0xff
  141. if got != regenLen {
  142. panic(fmt.Sprint("litRegenSize = ", regenLen, "(want) != ", got, "(got)"))
  143. }
  144. }
  145. case inBits < 12:
  146. lh |= (1 << 2) | (uint64(regenLen) << 4) | (2 << 60)
  147. case inBits < 20:
  148. lh |= (3 << 2) | (uint64(regenLen) << 4) | (3 << 60)
  149. default:
  150. panic(fmt.Errorf("internal error: block too big (%d)", regenLen))
  151. }
  152. *h = literalsHeader(lh)
  153. }
  154. // setSizes will set the size of a compressed literals section and the input length.
  155. func (h *literalsHeader) setSizes(compLen, inLen int, single bool) {
  156. compBits, inBits := bits.Len32(uint32(compLen)), bits.Len32(uint32(inLen))
  157. // Only retain 2 bits
  158. const mask = 3
  159. lh := uint64(*h & mask)
  160. switch {
  161. case compBits <= 10 && inBits <= 10:
  162. if !single {
  163. lh |= 1 << 2
  164. }
  165. lh |= (uint64(inLen) << 4) | (uint64(compLen) << (10 + 4)) | (3 << 60)
  166. if debugEncoder {
  167. const mmask = (1 << 24) - 1
  168. n := (lh >> 4) & mmask
  169. if int(n&1023) != inLen {
  170. panic(fmt.Sprint("regensize:", int(n&1023), "!=", inLen, inBits))
  171. }
  172. if int(n>>10) != compLen {
  173. panic(fmt.Sprint("compsize:", int(n>>10), "!=", compLen, compBits))
  174. }
  175. }
  176. case compBits <= 14 && inBits <= 14:
  177. lh |= (2 << 2) | (uint64(inLen) << 4) | (uint64(compLen) << (14 + 4)) | (4 << 60)
  178. if single {
  179. panic("single stream used with more than 10 bits length.")
  180. }
  181. case compBits <= 18 && inBits <= 18:
  182. lh |= (3 << 2) | (uint64(inLen) << 4) | (uint64(compLen) << (18 + 4)) | (5 << 60)
  183. if single {
  184. panic("single stream used with more than 10 bits length.")
  185. }
  186. default:
  187. panic("internal error: block too big")
  188. }
  189. *h = literalsHeader(lh)
  190. }
  191. // appendTo will append the literals header to a byte slice.
  192. func (h literalsHeader) appendTo(b []byte) []byte {
  193. size := uint8(h >> 60)
  194. switch size {
  195. case 1:
  196. b = append(b, uint8(h))
  197. case 2:
  198. b = append(b, uint8(h), uint8(h>>8))
  199. case 3:
  200. b = append(b, uint8(h), uint8(h>>8), uint8(h>>16))
  201. case 4:
  202. b = append(b, uint8(h), uint8(h>>8), uint8(h>>16), uint8(h>>24))
  203. case 5:
  204. b = append(b, uint8(h), uint8(h>>8), uint8(h>>16), uint8(h>>24), uint8(h>>32))
  205. default:
  206. panic(fmt.Errorf("internal error: literalsHeader has invalid size (%d)", size))
  207. }
  208. return b
  209. }
  210. // size returns the output size with currently set values.
  211. func (h literalsHeader) size() int {
  212. return int(h >> 60)
  213. }
  214. func (h literalsHeader) String() string {
  215. return fmt.Sprintf("Type: %d, SizeFormat: %d, Size: 0x%d, Bytes:%d", literalsBlockType(h&3), (h>>2)&3, h&((1<<60)-1)>>4, h>>60)
  216. }
  217. // pushOffsets will push the recent offsets to the backup store.
  218. func (b *blockEnc) pushOffsets() {
  219. b.prevRecentOffsets = b.recentOffsets
  220. }
  221. // pushOffsets will push the recent offsets to the backup store.
  222. func (b *blockEnc) popOffsets() {
  223. b.recentOffsets = b.prevRecentOffsets
  224. }
  225. // matchOffset will adjust recent offsets and return the adjusted one,
  226. // if it matches a previous offset.
  227. func (b *blockEnc) matchOffset(offset, lits uint32) uint32 {
  228. // Check if offset is one of the recent offsets.
  229. // Adjusts the output offset accordingly.
  230. // Gives a tiny bit of compression, typically around 1%.
  231. if true {
  232. if lits > 0 {
  233. switch offset {
  234. case b.recentOffsets[0]:
  235. offset = 1
  236. case b.recentOffsets[1]:
  237. b.recentOffsets[1] = b.recentOffsets[0]
  238. b.recentOffsets[0] = offset
  239. offset = 2
  240. case b.recentOffsets[2]:
  241. b.recentOffsets[2] = b.recentOffsets[1]
  242. b.recentOffsets[1] = b.recentOffsets[0]
  243. b.recentOffsets[0] = offset
  244. offset = 3
  245. default:
  246. b.recentOffsets[2] = b.recentOffsets[1]
  247. b.recentOffsets[1] = b.recentOffsets[0]
  248. b.recentOffsets[0] = offset
  249. offset += 3
  250. }
  251. } else {
  252. switch offset {
  253. case b.recentOffsets[1]:
  254. b.recentOffsets[1] = b.recentOffsets[0]
  255. b.recentOffsets[0] = offset
  256. offset = 1
  257. case b.recentOffsets[2]:
  258. b.recentOffsets[2] = b.recentOffsets[1]
  259. b.recentOffsets[1] = b.recentOffsets[0]
  260. b.recentOffsets[0] = offset
  261. offset = 2
  262. case b.recentOffsets[0] - 1:
  263. b.recentOffsets[2] = b.recentOffsets[1]
  264. b.recentOffsets[1] = b.recentOffsets[0]
  265. b.recentOffsets[0] = offset
  266. offset = 3
  267. default:
  268. b.recentOffsets[2] = b.recentOffsets[1]
  269. b.recentOffsets[1] = b.recentOffsets[0]
  270. b.recentOffsets[0] = offset
  271. offset += 3
  272. }
  273. }
  274. } else {
  275. offset += 3
  276. }
  277. return offset
  278. }
  279. // encodeRaw can be used to set the output to a raw representation of supplied bytes.
  280. func (b *blockEnc) encodeRaw(a []byte) {
  281. var bh blockHeader
  282. bh.setLast(b.last)
  283. bh.setSize(uint32(len(a)))
  284. bh.setType(blockTypeRaw)
  285. b.output = bh.appendTo(b.output[:0])
  286. b.output = append(b.output, a...)
  287. if debugEncoder {
  288. println("Adding RAW block, length", len(a), "last:", b.last)
  289. }
  290. }
  291. // encodeRaw can be used to set the output to a raw representation of supplied bytes.
  292. func (b *blockEnc) encodeRawTo(dst, src []byte) []byte {
  293. var bh blockHeader
  294. bh.setLast(b.last)
  295. bh.setSize(uint32(len(src)))
  296. bh.setType(blockTypeRaw)
  297. dst = bh.appendTo(dst)
  298. dst = append(dst, src...)
  299. if debugEncoder {
  300. println("Adding RAW block, length", len(src), "last:", b.last)
  301. }
  302. return dst
  303. }
  304. // encodeLits can be used if the block is only litLen.
  305. func (b *blockEnc) encodeLits(lits []byte, raw bool) error {
  306. var bh blockHeader
  307. bh.setLast(b.last)
  308. bh.setSize(uint32(len(lits)))
  309. // Don't compress extremely small blocks
  310. if len(lits) < 8 || (len(lits) < 32 && b.dictLitEnc == nil) || raw {
  311. if debugEncoder {
  312. println("Adding RAW block, length", len(lits), "last:", b.last)
  313. }
  314. bh.setType(blockTypeRaw)
  315. b.output = bh.appendTo(b.output)
  316. b.output = append(b.output, lits...)
  317. return nil
  318. }
  319. var (
  320. out []byte
  321. reUsed, single bool
  322. err error
  323. )
  324. if b.dictLitEnc != nil {
  325. b.litEnc.TransferCTable(b.dictLitEnc)
  326. b.litEnc.Reuse = huff0.ReusePolicyAllow
  327. b.dictLitEnc = nil
  328. }
  329. if len(lits) >= 1024 {
  330. // Use 4 Streams.
  331. out, reUsed, err = huff0.Compress4X(lits, b.litEnc)
  332. } else if len(lits) > 16 {
  333. // Use 1 stream
  334. single = true
  335. out, reUsed, err = huff0.Compress1X(lits, b.litEnc)
  336. } else {
  337. err = huff0.ErrIncompressible
  338. }
  339. if err == nil && len(out)+5 > len(lits) {
  340. // If we are close, we may still be worse or equal to raw.
  341. var lh literalsHeader
  342. lh.setSizes(len(out), len(lits), single)
  343. if len(out)+lh.size() >= len(lits) {
  344. err = huff0.ErrIncompressible
  345. }
  346. }
  347. switch err {
  348. case huff0.ErrIncompressible:
  349. if debugEncoder {
  350. println("Adding RAW block, length", len(lits), "last:", b.last)
  351. }
  352. bh.setType(blockTypeRaw)
  353. b.output = bh.appendTo(b.output)
  354. b.output = append(b.output, lits...)
  355. return nil
  356. case huff0.ErrUseRLE:
  357. if debugEncoder {
  358. println("Adding RLE block, length", len(lits))
  359. }
  360. bh.setType(blockTypeRLE)
  361. b.output = bh.appendTo(b.output)
  362. b.output = append(b.output, lits[0])
  363. return nil
  364. case nil:
  365. default:
  366. return err
  367. }
  368. // Compressed...
  369. // Now, allow reuse
  370. b.litEnc.Reuse = huff0.ReusePolicyAllow
  371. bh.setType(blockTypeCompressed)
  372. var lh literalsHeader
  373. if reUsed {
  374. if debugEncoder {
  375. println("Reused tree, compressed to", len(out))
  376. }
  377. lh.setType(literalsBlockTreeless)
  378. } else {
  379. if debugEncoder {
  380. println("New tree, compressed to", len(out), "tree size:", len(b.litEnc.OutTable))
  381. }
  382. lh.setType(literalsBlockCompressed)
  383. }
  384. // Set sizes
  385. lh.setSizes(len(out), len(lits), single)
  386. bh.setSize(uint32(len(out) + lh.size() + 1))
  387. // Write block headers.
  388. b.output = bh.appendTo(b.output)
  389. b.output = lh.appendTo(b.output)
  390. // Add compressed data.
  391. b.output = append(b.output, out...)
  392. // No sequences.
  393. b.output = append(b.output, 0)
  394. return nil
  395. }
  396. // fuzzFseEncoder can be used to fuzz the FSE encoder.
  397. func fuzzFseEncoder(data []byte) int {
  398. if len(data) > maxSequences || len(data) < 2 {
  399. return 0
  400. }
  401. enc := fseEncoder{}
  402. hist := enc.Histogram()
  403. maxSym := uint8(0)
  404. for i, v := range data {
  405. v = v & 63
  406. data[i] = v
  407. hist[v]++
  408. if v > maxSym {
  409. maxSym = v
  410. }
  411. }
  412. if maxSym == 0 {
  413. // All 0
  414. return 0
  415. }
  416. maxCount := func(a []uint32) int {
  417. var max uint32
  418. for _, v := range a {
  419. if v > max {
  420. max = v
  421. }
  422. }
  423. return int(max)
  424. }
  425. cnt := maxCount(hist[:maxSym])
  426. if cnt == len(data) {
  427. // RLE
  428. return 0
  429. }
  430. enc.HistogramFinished(maxSym, cnt)
  431. err := enc.normalizeCount(len(data))
  432. if err != nil {
  433. return 0
  434. }
  435. _, err = enc.writeCount(nil)
  436. if err != nil {
  437. panic(err)
  438. }
  439. return 1
  440. }
  441. // encode will encode the block and append the output in b.output.
  442. // Previous offset codes must be pushed if more blocks are expected.
  443. func (b *blockEnc) encode(org []byte, raw, rawAllLits bool) error {
  444. if len(b.sequences) == 0 {
  445. return b.encodeLits(b.literals, rawAllLits)
  446. }
  447. // We want some difference to at least account for the headers.
  448. saved := b.size - len(b.literals) - (b.size >> 6)
  449. if saved < 16 {
  450. if org == nil {
  451. return errIncompressible
  452. }
  453. b.popOffsets()
  454. return b.encodeLits(org, rawAllLits)
  455. }
  456. var bh blockHeader
  457. var lh literalsHeader
  458. bh.setLast(b.last)
  459. bh.setType(blockTypeCompressed)
  460. // Store offset of the block header. Needed when we know the size.
  461. bhOffset := len(b.output)
  462. b.output = bh.appendTo(b.output)
  463. var (
  464. out []byte
  465. reUsed, single bool
  466. err error
  467. )
  468. if b.dictLitEnc != nil {
  469. b.litEnc.TransferCTable(b.dictLitEnc)
  470. b.litEnc.Reuse = huff0.ReusePolicyAllow
  471. b.dictLitEnc = nil
  472. }
  473. if len(b.literals) >= 1024 && !raw {
  474. // Use 4 Streams.
  475. out, reUsed, err = huff0.Compress4X(b.literals, b.litEnc)
  476. } else if len(b.literals) > 16 && !raw {
  477. // Use 1 stream
  478. single = true
  479. out, reUsed, err = huff0.Compress1X(b.literals, b.litEnc)
  480. } else {
  481. err = huff0.ErrIncompressible
  482. }
  483. if err == nil && len(out)+5 > len(b.literals) {
  484. // If we are close, we may still be worse or equal to raw.
  485. var lh literalsHeader
  486. lh.setSize(len(b.literals))
  487. szRaw := lh.size()
  488. lh.setSizes(len(out), len(b.literals), single)
  489. szComp := lh.size()
  490. if len(out)+szComp >= len(b.literals)+szRaw {
  491. err = huff0.ErrIncompressible
  492. }
  493. }
  494. switch err {
  495. case huff0.ErrIncompressible:
  496. lh.setType(literalsBlockRaw)
  497. lh.setSize(len(b.literals))
  498. b.output = lh.appendTo(b.output)
  499. b.output = append(b.output, b.literals...)
  500. if debugEncoder {
  501. println("Adding literals RAW, length", len(b.literals))
  502. }
  503. case huff0.ErrUseRLE:
  504. lh.setType(literalsBlockRLE)
  505. lh.setSize(len(b.literals))
  506. b.output = lh.appendTo(b.output)
  507. b.output = append(b.output, b.literals[0])
  508. if debugEncoder {
  509. println("Adding literals RLE")
  510. }
  511. case nil:
  512. // Compressed litLen...
  513. if reUsed {
  514. if debugEncoder {
  515. println("reused tree")
  516. }
  517. lh.setType(literalsBlockTreeless)
  518. } else {
  519. if debugEncoder {
  520. println("new tree, size:", len(b.litEnc.OutTable))
  521. }
  522. lh.setType(literalsBlockCompressed)
  523. if debugEncoder {
  524. _, _, err := huff0.ReadTable(out, nil)
  525. if err != nil {
  526. panic(err)
  527. }
  528. }
  529. }
  530. lh.setSizes(len(out), len(b.literals), single)
  531. if debugEncoder {
  532. printf("Compressed %d literals to %d bytes", len(b.literals), len(out))
  533. println("Adding literal header:", lh)
  534. }
  535. b.output = lh.appendTo(b.output)
  536. b.output = append(b.output, out...)
  537. b.litEnc.Reuse = huff0.ReusePolicyAllow
  538. if debugEncoder {
  539. println("Adding literals compressed")
  540. }
  541. default:
  542. if debugEncoder {
  543. println("Adding literals ERROR:", err)
  544. }
  545. return err
  546. }
  547. // Sequence compression
  548. // Write the number of sequences
  549. switch {
  550. case len(b.sequences) < 128:
  551. b.output = append(b.output, uint8(len(b.sequences)))
  552. case len(b.sequences) < 0x7f00: // TODO: this could be wrong
  553. n := len(b.sequences)
  554. b.output = append(b.output, 128+uint8(n>>8), uint8(n))
  555. default:
  556. n := len(b.sequences) - 0x7f00
  557. b.output = append(b.output, 255, uint8(n), uint8(n>>8))
  558. }
  559. if debugEncoder {
  560. println("Encoding", len(b.sequences), "sequences")
  561. }
  562. b.genCodes()
  563. llEnc := b.coders.llEnc
  564. ofEnc := b.coders.ofEnc
  565. mlEnc := b.coders.mlEnc
  566. err = llEnc.normalizeCount(len(b.sequences))
  567. if err != nil {
  568. return err
  569. }
  570. err = ofEnc.normalizeCount(len(b.sequences))
  571. if err != nil {
  572. return err
  573. }
  574. err = mlEnc.normalizeCount(len(b.sequences))
  575. if err != nil {
  576. return err
  577. }
  578. // Choose the best compression mode for each type.
  579. // Will evaluate the new vs predefined and previous.
  580. chooseComp := func(cur, prev, preDef *fseEncoder) (*fseEncoder, seqCompMode) {
  581. // See if predefined/previous is better
  582. hist := cur.count[:cur.symbolLen]
  583. nSize := cur.approxSize(hist) + cur.maxHeaderSize()
  584. predefSize := preDef.approxSize(hist)
  585. prevSize := prev.approxSize(hist)
  586. // Add a small penalty for new encoders.
  587. // Don't bother with extremely small (<2 byte gains).
  588. nSize = nSize + (nSize+2*8*16)>>4
  589. switch {
  590. case predefSize <= prevSize && predefSize <= nSize || forcePreDef:
  591. if debugEncoder {
  592. println("Using predefined", predefSize>>3, "<=", nSize>>3)
  593. }
  594. return preDef, compModePredefined
  595. case prevSize <= nSize:
  596. if debugEncoder {
  597. println("Using previous", prevSize>>3, "<=", nSize>>3)
  598. }
  599. return prev, compModeRepeat
  600. default:
  601. if debugEncoder {
  602. println("Using new, predef", predefSize>>3, ". previous:", prevSize>>3, ">", nSize>>3, "header max:", cur.maxHeaderSize()>>3, "bytes")
  603. println("tl:", cur.actualTableLog, "symbolLen:", cur.symbolLen, "norm:", cur.norm[:cur.symbolLen], "hist", cur.count[:cur.symbolLen])
  604. }
  605. return cur, compModeFSE
  606. }
  607. }
  608. // Write compression mode
  609. var mode uint8
  610. if llEnc.useRLE {
  611. mode |= uint8(compModeRLE) << 6
  612. llEnc.setRLE(b.sequences[0].llCode)
  613. if debugEncoder {
  614. println("llEnc.useRLE")
  615. }
  616. } else {
  617. var m seqCompMode
  618. llEnc, m = chooseComp(llEnc, b.coders.llPrev, &fsePredefEnc[tableLiteralLengths])
  619. mode |= uint8(m) << 6
  620. }
  621. if ofEnc.useRLE {
  622. mode |= uint8(compModeRLE) << 4
  623. ofEnc.setRLE(b.sequences[0].ofCode)
  624. if debugEncoder {
  625. println("ofEnc.useRLE")
  626. }
  627. } else {
  628. var m seqCompMode
  629. ofEnc, m = chooseComp(ofEnc, b.coders.ofPrev, &fsePredefEnc[tableOffsets])
  630. mode |= uint8(m) << 4
  631. }
  632. if mlEnc.useRLE {
  633. mode |= uint8(compModeRLE) << 2
  634. mlEnc.setRLE(b.sequences[0].mlCode)
  635. if debugEncoder {
  636. println("mlEnc.useRLE, code: ", b.sequences[0].mlCode, "value", b.sequences[0].matchLen)
  637. }
  638. } else {
  639. var m seqCompMode
  640. mlEnc, m = chooseComp(mlEnc, b.coders.mlPrev, &fsePredefEnc[tableMatchLengths])
  641. mode |= uint8(m) << 2
  642. }
  643. b.output = append(b.output, mode)
  644. if debugEncoder {
  645. printf("Compression modes: 0b%b", mode)
  646. }
  647. b.output, err = llEnc.writeCount(b.output)
  648. if err != nil {
  649. return err
  650. }
  651. start := len(b.output)
  652. b.output, err = ofEnc.writeCount(b.output)
  653. if err != nil {
  654. return err
  655. }
  656. if false {
  657. println("block:", b.output[start:], "tablelog", ofEnc.actualTableLog, "maxcount:", ofEnc.maxCount)
  658. fmt.Printf("selected TableLog: %d, Symbol length: %d\n", ofEnc.actualTableLog, ofEnc.symbolLen)
  659. for i, v := range ofEnc.norm[:ofEnc.symbolLen] {
  660. fmt.Printf("%3d: %5d -> %4d \n", i, ofEnc.count[i], v)
  661. }
  662. }
  663. b.output, err = mlEnc.writeCount(b.output)
  664. if err != nil {
  665. return err
  666. }
  667. // Maybe in block?
  668. wr := &b.wr
  669. wr.reset(b.output)
  670. var ll, of, ml cState
  671. // Current sequence
  672. seq := len(b.sequences) - 1
  673. s := b.sequences[seq]
  674. llEnc.setBits(llBitsTable[:])
  675. mlEnc.setBits(mlBitsTable[:])
  676. ofEnc.setBits(nil)
  677. llTT, ofTT, mlTT := llEnc.ct.symbolTT[:256], ofEnc.ct.symbolTT[:256], mlEnc.ct.symbolTT[:256]
  678. // We have 3 bounds checks here (and in the loop).
  679. // Since we are iterating backwards it is kinda hard to avoid.
  680. llB, ofB, mlB := llTT[s.llCode], ofTT[s.ofCode], mlTT[s.mlCode]
  681. ll.init(wr, &llEnc.ct, llB)
  682. of.init(wr, &ofEnc.ct, ofB)
  683. wr.flush32()
  684. ml.init(wr, &mlEnc.ct, mlB)
  685. // Each of these lookups also generates a bounds check.
  686. wr.addBits32NC(s.litLen, llB.outBits)
  687. wr.addBits32NC(s.matchLen, mlB.outBits)
  688. wr.flush32()
  689. wr.addBits32NC(s.offset, ofB.outBits)
  690. if debugSequences {
  691. println("Encoded seq", seq, s, "codes:", s.llCode, s.mlCode, s.ofCode, "states:", ll.state, ml.state, of.state, "bits:", llB, mlB, ofB)
  692. }
  693. seq--
  694. // Store sequences in reverse...
  695. for seq >= 0 {
  696. s = b.sequences[seq]
  697. ofB := ofTT[s.ofCode]
  698. wr.flush32() // tablelog max is below 8 for each, so it will fill max 24 bits.
  699. //of.encode(ofB)
  700. nbBitsOut := (uint32(of.state) + ofB.deltaNbBits) >> 16
  701. dstState := int32(of.state>>(nbBitsOut&15)) + int32(ofB.deltaFindState)
  702. wr.addBits16NC(of.state, uint8(nbBitsOut))
  703. of.state = of.stateTable[dstState]
  704. // Accumulate extra bits.
  705. outBits := ofB.outBits & 31
  706. extraBits := uint64(s.offset & bitMask32[outBits])
  707. extraBitsN := outBits
  708. mlB := mlTT[s.mlCode]
  709. //ml.encode(mlB)
  710. nbBitsOut = (uint32(ml.state) + mlB.deltaNbBits) >> 16
  711. dstState = int32(ml.state>>(nbBitsOut&15)) + int32(mlB.deltaFindState)
  712. wr.addBits16NC(ml.state, uint8(nbBitsOut))
  713. ml.state = ml.stateTable[dstState]
  714. outBits = mlB.outBits & 31
  715. extraBits = extraBits<<outBits | uint64(s.matchLen&bitMask32[outBits])
  716. extraBitsN += outBits
  717. llB := llTT[s.llCode]
  718. //ll.encode(llB)
  719. nbBitsOut = (uint32(ll.state) + llB.deltaNbBits) >> 16
  720. dstState = int32(ll.state>>(nbBitsOut&15)) + int32(llB.deltaFindState)
  721. wr.addBits16NC(ll.state, uint8(nbBitsOut))
  722. ll.state = ll.stateTable[dstState]
  723. outBits = llB.outBits & 31
  724. extraBits = extraBits<<outBits | uint64(s.litLen&bitMask32[outBits])
  725. extraBitsN += outBits
  726. wr.flush32()
  727. wr.addBits64NC(extraBits, extraBitsN)
  728. if debugSequences {
  729. println("Encoded seq", seq, s)
  730. }
  731. seq--
  732. }
  733. ml.flush(mlEnc.actualTableLog)
  734. of.flush(ofEnc.actualTableLog)
  735. ll.flush(llEnc.actualTableLog)
  736. wr.close()
  737. b.output = wr.out
  738. // Maybe even add a bigger margin.
  739. if len(b.output)-3-bhOffset >= b.size {
  740. // Discard and encode as raw block.
  741. b.output = b.encodeRawTo(b.output[:bhOffset], org)
  742. b.popOffsets()
  743. b.litEnc.Reuse = huff0.ReusePolicyNone
  744. return nil
  745. }
  746. // Size is output minus block header.
  747. bh.setSize(uint32(len(b.output)-bhOffset) - 3)
  748. if debugEncoder {
  749. println("Rewriting block header", bh)
  750. }
  751. _ = bh.appendTo(b.output[bhOffset:bhOffset])
  752. b.coders.setPrev(llEnc, mlEnc, ofEnc)
  753. return nil
  754. }
  755. var errIncompressible = errors.New("incompressible")
  756. func (b *blockEnc) genCodes() {
  757. if len(b.sequences) == 0 {
  758. // nothing to do
  759. return
  760. }
  761. if len(b.sequences) > math.MaxUint16 {
  762. panic("can only encode up to 64K sequences")
  763. }
  764. // No bounds checks after here:
  765. llH := b.coders.llEnc.Histogram()
  766. ofH := b.coders.ofEnc.Histogram()
  767. mlH := b.coders.mlEnc.Histogram()
  768. for i := range llH {
  769. llH[i] = 0
  770. }
  771. for i := range ofH {
  772. ofH[i] = 0
  773. }
  774. for i := range mlH {
  775. mlH[i] = 0
  776. }
  777. var llMax, ofMax, mlMax uint8
  778. for i := range b.sequences {
  779. seq := &b.sequences[i]
  780. v := llCode(seq.litLen)
  781. seq.llCode = v
  782. llH[v]++
  783. if v > llMax {
  784. llMax = v
  785. }
  786. v = ofCode(seq.offset)
  787. seq.ofCode = v
  788. ofH[v]++
  789. if v > ofMax {
  790. ofMax = v
  791. }
  792. v = mlCode(seq.matchLen)
  793. seq.mlCode = v
  794. mlH[v]++
  795. if v > mlMax {
  796. mlMax = v
  797. if debugAsserts && mlMax > maxMatchLengthSymbol {
  798. panic(fmt.Errorf("mlMax > maxMatchLengthSymbol (%d), matchlen: %d", mlMax, seq.matchLen))
  799. }
  800. }
  801. }
  802. maxCount := func(a []uint32) int {
  803. var max uint32
  804. for _, v := range a {
  805. if v > max {
  806. max = v
  807. }
  808. }
  809. return int(max)
  810. }
  811. if debugAsserts && mlMax > maxMatchLengthSymbol {
  812. panic(fmt.Errorf("mlMax > maxMatchLengthSymbol (%d)", mlMax))
  813. }
  814. if debugAsserts && ofMax > maxOffsetBits {
  815. panic(fmt.Errorf("ofMax > maxOffsetBits (%d)", ofMax))
  816. }
  817. if debugAsserts && llMax > maxLiteralLengthSymbol {
  818. panic(fmt.Errorf("llMax > maxLiteralLengthSymbol (%d)", llMax))
  819. }
  820. b.coders.mlEnc.HistogramFinished(mlMax, maxCount(mlH[:mlMax+1]))
  821. b.coders.ofEnc.HistogramFinished(ofMax, maxCount(ofH[:ofMax+1]))
  822. b.coders.llEnc.HistogramFinished(llMax, maxCount(llH[:llMax+1]))
  823. }