blockdec.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  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. "bytes"
  7. "encoding/binary"
  8. "errors"
  9. "fmt"
  10. "hash/crc32"
  11. "io"
  12. "os"
  13. "path/filepath"
  14. "sync"
  15. "github.com/klauspost/compress/huff0"
  16. "github.com/klauspost/compress/zstd/internal/xxhash"
  17. )
  18. type blockType uint8
  19. //go:generate stringer -type=blockType,literalsBlockType,seqCompMode,tableIndex
  20. const (
  21. blockTypeRaw blockType = iota
  22. blockTypeRLE
  23. blockTypeCompressed
  24. blockTypeReserved
  25. )
  26. type literalsBlockType uint8
  27. const (
  28. literalsBlockRaw literalsBlockType = iota
  29. literalsBlockRLE
  30. literalsBlockCompressed
  31. literalsBlockTreeless
  32. )
  33. const (
  34. // maxCompressedBlockSize is the biggest allowed compressed block size (128KB)
  35. maxCompressedBlockSize = 128 << 10
  36. compressedBlockOverAlloc = 16
  37. maxCompressedBlockSizeAlloc = 128<<10 + compressedBlockOverAlloc
  38. // Maximum possible block size (all Raw+Uncompressed).
  39. maxBlockSize = (1 << 21) - 1
  40. maxMatchLen = 131074
  41. maxSequences = 0x7f00 + 0xffff
  42. // We support slightly less than the reference decoder to be able to
  43. // use ints on 32 bit archs.
  44. maxOffsetBits = 30
  45. )
  46. var (
  47. huffDecoderPool = sync.Pool{New: func() interface{} {
  48. return &huff0.Scratch{}
  49. }}
  50. fseDecoderPool = sync.Pool{New: func() interface{} {
  51. return &fseDecoder{}
  52. }}
  53. )
  54. type blockDec struct {
  55. // Raw source data of the block.
  56. data []byte
  57. dataStorage []byte
  58. // Destination of the decoded data.
  59. dst []byte
  60. // Buffer for literals data.
  61. literalBuf []byte
  62. // Window size of the block.
  63. WindowSize uint64
  64. err error
  65. // Check against this crc, if hasCRC is true.
  66. checkCRC uint32
  67. hasCRC bool
  68. // Frame to use for singlethreaded decoding.
  69. // Should not be used by the decoder itself since parent may be another frame.
  70. localFrame *frameDec
  71. sequence []seqVals
  72. async struct {
  73. newHist *history
  74. literals []byte
  75. seqData []byte
  76. seqSize int // Size of uncompressed sequences
  77. fcs uint64
  78. }
  79. // Block is RLE, this is the size.
  80. RLESize uint32
  81. Type blockType
  82. // Is this the last block of a frame?
  83. Last bool
  84. // Use less memory
  85. lowMem bool
  86. }
  87. func (b *blockDec) String() string {
  88. if b == nil {
  89. return "<nil>"
  90. }
  91. return fmt.Sprintf("Steam Size: %d, Type: %v, Last: %t, Window: %d", len(b.data), b.Type, b.Last, b.WindowSize)
  92. }
  93. func newBlockDec(lowMem bool) *blockDec {
  94. b := blockDec{
  95. lowMem: lowMem,
  96. }
  97. return &b
  98. }
  99. // reset will reset the block.
  100. // Input must be a start of a block and will be at the end of the block when returned.
  101. func (b *blockDec) reset(br byteBuffer, windowSize uint64) error {
  102. b.WindowSize = windowSize
  103. tmp, err := br.readSmall(3)
  104. if err != nil {
  105. println("Reading block header:", err)
  106. return err
  107. }
  108. bh := uint32(tmp[0]) | (uint32(tmp[1]) << 8) | (uint32(tmp[2]) << 16)
  109. b.Last = bh&1 != 0
  110. b.Type = blockType((bh >> 1) & 3)
  111. // find size.
  112. cSize := int(bh >> 3)
  113. maxSize := maxCompressedBlockSizeAlloc
  114. switch b.Type {
  115. case blockTypeReserved:
  116. return ErrReservedBlockType
  117. case blockTypeRLE:
  118. if cSize > maxCompressedBlockSize || cSize > int(b.WindowSize) {
  119. if debugDecoder {
  120. printf("rle block too big: csize:%d block: %+v\n", uint64(cSize), b)
  121. }
  122. return ErrWindowSizeExceeded
  123. }
  124. b.RLESize = uint32(cSize)
  125. if b.lowMem {
  126. maxSize = cSize
  127. }
  128. cSize = 1
  129. case blockTypeCompressed:
  130. if debugDecoder {
  131. println("Data size on stream:", cSize)
  132. }
  133. b.RLESize = 0
  134. maxSize = maxCompressedBlockSizeAlloc
  135. if windowSize < maxCompressedBlockSize && b.lowMem {
  136. maxSize = int(windowSize) + compressedBlockOverAlloc
  137. }
  138. if cSize > maxCompressedBlockSize || uint64(cSize) > b.WindowSize {
  139. if debugDecoder {
  140. printf("compressed block too big: csize:%d block: %+v\n", uint64(cSize), b)
  141. }
  142. return ErrCompressedSizeTooBig
  143. }
  144. // Empty compressed blocks must at least be 2 bytes
  145. // for Literals_Block_Type and one for Sequences_Section_Header.
  146. if cSize < 2 {
  147. return ErrBlockTooSmall
  148. }
  149. case blockTypeRaw:
  150. if cSize > maxCompressedBlockSize || cSize > int(b.WindowSize) {
  151. if debugDecoder {
  152. printf("rle block too big: csize:%d block: %+v\n", uint64(cSize), b)
  153. }
  154. return ErrWindowSizeExceeded
  155. }
  156. b.RLESize = 0
  157. // We do not need a destination for raw blocks.
  158. maxSize = -1
  159. default:
  160. panic("Invalid block type")
  161. }
  162. // Read block data.
  163. if _, ok := br.(*byteBuf); !ok && cap(b.dataStorage) < cSize {
  164. // byteBuf doesn't need a destination buffer.
  165. if b.lowMem || cSize > maxCompressedBlockSize {
  166. b.dataStorage = make([]byte, 0, cSize+compressedBlockOverAlloc)
  167. } else {
  168. b.dataStorage = make([]byte, 0, maxCompressedBlockSizeAlloc)
  169. }
  170. }
  171. b.data, err = br.readBig(cSize, b.dataStorage)
  172. if err != nil {
  173. if debugDecoder {
  174. println("Reading block:", err, "(", cSize, ")", len(b.data))
  175. printf("%T", br)
  176. }
  177. return err
  178. }
  179. if cap(b.dst) <= maxSize {
  180. b.dst = make([]byte, 0, maxSize+1)
  181. }
  182. return nil
  183. }
  184. // sendEOF will make the decoder send EOF on this frame.
  185. func (b *blockDec) sendErr(err error) {
  186. b.Last = true
  187. b.Type = blockTypeReserved
  188. b.err = err
  189. }
  190. // Close will release resources.
  191. // Closed blockDec cannot be reset.
  192. func (b *blockDec) Close() {
  193. }
  194. // decodeBuf
  195. func (b *blockDec) decodeBuf(hist *history) error {
  196. switch b.Type {
  197. case blockTypeRLE:
  198. if cap(b.dst) < int(b.RLESize) {
  199. if b.lowMem {
  200. b.dst = make([]byte, b.RLESize)
  201. } else {
  202. b.dst = make([]byte, maxCompressedBlockSize)
  203. }
  204. }
  205. b.dst = b.dst[:b.RLESize]
  206. v := b.data[0]
  207. for i := range b.dst {
  208. b.dst[i] = v
  209. }
  210. hist.appendKeep(b.dst)
  211. return nil
  212. case blockTypeRaw:
  213. hist.appendKeep(b.data)
  214. return nil
  215. case blockTypeCompressed:
  216. saved := b.dst
  217. // Append directly to history
  218. if hist.ignoreBuffer == 0 {
  219. b.dst = hist.b
  220. hist.b = nil
  221. } else {
  222. b.dst = b.dst[:0]
  223. }
  224. err := b.decodeCompressed(hist)
  225. if debugDecoder {
  226. println("Decompressed to total", len(b.dst), "bytes, hash:", xxhash.Sum64(b.dst), "error:", err)
  227. }
  228. if hist.ignoreBuffer == 0 {
  229. hist.b = b.dst
  230. b.dst = saved
  231. } else {
  232. hist.appendKeep(b.dst)
  233. }
  234. return err
  235. case blockTypeReserved:
  236. // Used for returning errors.
  237. return b.err
  238. default:
  239. panic("Invalid block type")
  240. }
  241. }
  242. func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err error) {
  243. // There must be at least one byte for Literals_Block_Type and one for Sequences_Section_Header
  244. if len(in) < 2 {
  245. return in, ErrBlockTooSmall
  246. }
  247. litType := literalsBlockType(in[0] & 3)
  248. var litRegenSize int
  249. var litCompSize int
  250. sizeFormat := (in[0] >> 2) & 3
  251. var fourStreams bool
  252. var literals []byte
  253. switch litType {
  254. case literalsBlockRaw, literalsBlockRLE:
  255. switch sizeFormat {
  256. case 0, 2:
  257. // Regenerated_Size uses 5 bits (0-31). Literals_Section_Header uses 1 byte.
  258. litRegenSize = int(in[0] >> 3)
  259. in = in[1:]
  260. case 1:
  261. // Regenerated_Size uses 12 bits (0-4095). Literals_Section_Header uses 2 bytes.
  262. litRegenSize = int(in[0]>>4) + (int(in[1]) << 4)
  263. in = in[2:]
  264. case 3:
  265. // Regenerated_Size uses 20 bits (0-1048575). Literals_Section_Header uses 3 bytes.
  266. if len(in) < 3 {
  267. println("too small: litType:", litType, " sizeFormat", sizeFormat, len(in))
  268. return in, ErrBlockTooSmall
  269. }
  270. litRegenSize = int(in[0]>>4) + (int(in[1]) << 4) + (int(in[2]) << 12)
  271. in = in[3:]
  272. }
  273. case literalsBlockCompressed, literalsBlockTreeless:
  274. switch sizeFormat {
  275. case 0, 1:
  276. // Both Regenerated_Size and Compressed_Size use 10 bits (0-1023).
  277. if len(in) < 3 {
  278. println("too small: litType:", litType, " sizeFormat", sizeFormat, len(in))
  279. return in, ErrBlockTooSmall
  280. }
  281. n := uint64(in[0]>>4) + (uint64(in[1]) << 4) + (uint64(in[2]) << 12)
  282. litRegenSize = int(n & 1023)
  283. litCompSize = int(n >> 10)
  284. fourStreams = sizeFormat == 1
  285. in = in[3:]
  286. case 2:
  287. fourStreams = true
  288. if len(in) < 4 {
  289. println("too small: litType:", litType, " sizeFormat", sizeFormat, len(in))
  290. return in, ErrBlockTooSmall
  291. }
  292. n := uint64(in[0]>>4) + (uint64(in[1]) << 4) + (uint64(in[2]) << 12) + (uint64(in[3]) << 20)
  293. litRegenSize = int(n & 16383)
  294. litCompSize = int(n >> 14)
  295. in = in[4:]
  296. case 3:
  297. fourStreams = true
  298. if len(in) < 5 {
  299. println("too small: litType:", litType, " sizeFormat", sizeFormat, len(in))
  300. return in, ErrBlockTooSmall
  301. }
  302. n := uint64(in[0]>>4) + (uint64(in[1]) << 4) + (uint64(in[2]) << 12) + (uint64(in[3]) << 20) + (uint64(in[4]) << 28)
  303. litRegenSize = int(n & 262143)
  304. litCompSize = int(n >> 18)
  305. in = in[5:]
  306. }
  307. }
  308. if debugDecoder {
  309. println("literals type:", litType, "litRegenSize:", litRegenSize, "litCompSize:", litCompSize, "sizeFormat:", sizeFormat, "4X:", fourStreams)
  310. }
  311. if litRegenSize > int(b.WindowSize) || litRegenSize > maxCompressedBlockSize {
  312. return in, ErrWindowSizeExceeded
  313. }
  314. switch litType {
  315. case literalsBlockRaw:
  316. if len(in) < litRegenSize {
  317. println("too small: litType:", litType, " sizeFormat", sizeFormat, "remain:", len(in), "want:", litRegenSize)
  318. return in, ErrBlockTooSmall
  319. }
  320. literals = in[:litRegenSize]
  321. in = in[litRegenSize:]
  322. //printf("Found %d uncompressed literals\n", litRegenSize)
  323. case literalsBlockRLE:
  324. if len(in) < 1 {
  325. println("too small: litType:", litType, " sizeFormat", sizeFormat, "remain:", len(in), "want:", 1)
  326. return in, ErrBlockTooSmall
  327. }
  328. if cap(b.literalBuf) < litRegenSize {
  329. if b.lowMem {
  330. b.literalBuf = make([]byte, litRegenSize, litRegenSize+compressedBlockOverAlloc)
  331. } else {
  332. b.literalBuf = make([]byte, litRegenSize, maxCompressedBlockSize+compressedBlockOverAlloc)
  333. }
  334. }
  335. literals = b.literalBuf[:litRegenSize]
  336. v := in[0]
  337. for i := range literals {
  338. literals[i] = v
  339. }
  340. in = in[1:]
  341. if debugDecoder {
  342. printf("Found %d RLE compressed literals\n", litRegenSize)
  343. }
  344. case literalsBlockTreeless:
  345. if len(in) < litCompSize {
  346. println("too small: litType:", litType, " sizeFormat", sizeFormat, "remain:", len(in), "want:", litCompSize)
  347. return in, ErrBlockTooSmall
  348. }
  349. // Store compressed literals, so we defer decoding until we get history.
  350. literals = in[:litCompSize]
  351. in = in[litCompSize:]
  352. if debugDecoder {
  353. printf("Found %d compressed literals\n", litCompSize)
  354. }
  355. huff := hist.huffTree
  356. if huff == nil {
  357. return in, errors.New("literal block was treeless, but no history was defined")
  358. }
  359. // Ensure we have space to store it.
  360. if cap(b.literalBuf) < litRegenSize {
  361. if b.lowMem {
  362. b.literalBuf = make([]byte, 0, litRegenSize+compressedBlockOverAlloc)
  363. } else {
  364. b.literalBuf = make([]byte, 0, maxCompressedBlockSize+compressedBlockOverAlloc)
  365. }
  366. }
  367. var err error
  368. // Use our out buffer.
  369. huff.MaxDecodedSize = litRegenSize
  370. if fourStreams {
  371. literals, err = huff.Decoder().Decompress4X(b.literalBuf[:0:litRegenSize], literals)
  372. } else {
  373. literals, err = huff.Decoder().Decompress1X(b.literalBuf[:0:litRegenSize], literals)
  374. }
  375. // Make sure we don't leak our literals buffer
  376. if err != nil {
  377. println("decompressing literals:", err)
  378. return in, err
  379. }
  380. if len(literals) != litRegenSize {
  381. return in, fmt.Errorf("literal output size mismatch want %d, got %d", litRegenSize, len(literals))
  382. }
  383. case literalsBlockCompressed:
  384. if len(in) < litCompSize {
  385. println("too small: litType:", litType, " sizeFormat", sizeFormat, "remain:", len(in), "want:", litCompSize)
  386. return in, ErrBlockTooSmall
  387. }
  388. literals = in[:litCompSize]
  389. in = in[litCompSize:]
  390. // Ensure we have space to store it.
  391. if cap(b.literalBuf) < litRegenSize {
  392. if b.lowMem {
  393. b.literalBuf = make([]byte, 0, litRegenSize+compressedBlockOverAlloc)
  394. } else {
  395. b.literalBuf = make([]byte, 0, maxCompressedBlockSize+compressedBlockOverAlloc)
  396. }
  397. }
  398. huff := hist.huffTree
  399. if huff == nil || (hist.dict != nil && huff == hist.dict.litEnc) {
  400. huff = huffDecoderPool.Get().(*huff0.Scratch)
  401. if huff == nil {
  402. huff = &huff0.Scratch{}
  403. }
  404. }
  405. var err error
  406. if debugDecoder {
  407. println("huff table input:", len(literals), "CRC:", crc32.ChecksumIEEE(literals))
  408. }
  409. huff, literals, err = huff0.ReadTable(literals, huff)
  410. if err != nil {
  411. println("reading huffman table:", err)
  412. return in, err
  413. }
  414. hist.huffTree = huff
  415. huff.MaxDecodedSize = litRegenSize
  416. // Use our out buffer.
  417. if fourStreams {
  418. literals, err = huff.Decoder().Decompress4X(b.literalBuf[:0:litRegenSize], literals)
  419. } else {
  420. literals, err = huff.Decoder().Decompress1X(b.literalBuf[:0:litRegenSize], literals)
  421. }
  422. if err != nil {
  423. println("decoding compressed literals:", err)
  424. return in, err
  425. }
  426. // Make sure we don't leak our literals buffer
  427. if len(literals) != litRegenSize {
  428. return in, fmt.Errorf("literal output size mismatch want %d, got %d", litRegenSize, len(literals))
  429. }
  430. // Re-cap to get extra size.
  431. literals = b.literalBuf[:len(literals)]
  432. if debugDecoder {
  433. printf("Decompressed %d literals into %d bytes\n", litCompSize, litRegenSize)
  434. }
  435. }
  436. hist.decoders.literals = literals
  437. return in, nil
  438. }
  439. // decodeCompressed will start decompressing a block.
  440. func (b *blockDec) decodeCompressed(hist *history) error {
  441. in := b.data
  442. in, err := b.decodeLiterals(in, hist)
  443. if err != nil {
  444. return err
  445. }
  446. err = b.prepareSequences(in, hist)
  447. if err != nil {
  448. return err
  449. }
  450. if hist.decoders.nSeqs == 0 {
  451. b.dst = append(b.dst, hist.decoders.literals...)
  452. return nil
  453. }
  454. before := len(hist.decoders.out)
  455. err = hist.decoders.decodeSync(hist.b[hist.ignoreBuffer:])
  456. if err != nil {
  457. return err
  458. }
  459. if hist.decoders.maxSyncLen > 0 {
  460. hist.decoders.maxSyncLen += uint64(before)
  461. hist.decoders.maxSyncLen -= uint64(len(hist.decoders.out))
  462. }
  463. b.dst = hist.decoders.out
  464. hist.recentOffsets = hist.decoders.prevOffset
  465. return nil
  466. }
  467. func (b *blockDec) prepareSequences(in []byte, hist *history) (err error) {
  468. if debugDecoder {
  469. printf("prepareSequences: %d byte(s) input\n", len(in))
  470. }
  471. // Decode Sequences
  472. // https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#sequences-section
  473. if len(in) < 1 {
  474. return ErrBlockTooSmall
  475. }
  476. var nSeqs int
  477. seqHeader := in[0]
  478. switch {
  479. case seqHeader < 128:
  480. nSeqs = int(seqHeader)
  481. in = in[1:]
  482. case seqHeader < 255:
  483. if len(in) < 2 {
  484. return ErrBlockTooSmall
  485. }
  486. nSeqs = int(seqHeader-128)<<8 | int(in[1])
  487. in = in[2:]
  488. case seqHeader == 255:
  489. if len(in) < 3 {
  490. return ErrBlockTooSmall
  491. }
  492. nSeqs = 0x7f00 + int(in[1]) + (int(in[2]) << 8)
  493. in = in[3:]
  494. }
  495. if nSeqs == 0 && len(in) != 0 {
  496. // When no sequences, there should not be any more data...
  497. if debugDecoder {
  498. printf("prepareSequences: 0 sequences, but %d byte(s) left on stream\n", len(in))
  499. }
  500. return ErrUnexpectedBlockSize
  501. }
  502. var seqs = &hist.decoders
  503. seqs.nSeqs = nSeqs
  504. if nSeqs > 0 {
  505. if len(in) < 1 {
  506. return ErrBlockTooSmall
  507. }
  508. br := byteReader{b: in, off: 0}
  509. compMode := br.Uint8()
  510. br.advance(1)
  511. if debugDecoder {
  512. printf("Compression modes: 0b%b", compMode)
  513. }
  514. for i := uint(0); i < 3; i++ {
  515. mode := seqCompMode((compMode >> (6 - i*2)) & 3)
  516. if debugDecoder {
  517. println("Table", tableIndex(i), "is", mode)
  518. }
  519. var seq *sequenceDec
  520. switch tableIndex(i) {
  521. case tableLiteralLengths:
  522. seq = &seqs.litLengths
  523. case tableOffsets:
  524. seq = &seqs.offsets
  525. case tableMatchLengths:
  526. seq = &seqs.matchLengths
  527. default:
  528. panic("unknown table")
  529. }
  530. switch mode {
  531. case compModePredefined:
  532. if seq.fse != nil && !seq.fse.preDefined {
  533. fseDecoderPool.Put(seq.fse)
  534. }
  535. seq.fse = &fsePredef[i]
  536. case compModeRLE:
  537. if br.remain() < 1 {
  538. return ErrBlockTooSmall
  539. }
  540. v := br.Uint8()
  541. br.advance(1)
  542. if seq.fse == nil || seq.fse.preDefined {
  543. seq.fse = fseDecoderPool.Get().(*fseDecoder)
  544. }
  545. symb, err := decSymbolValue(v, symbolTableX[i])
  546. if err != nil {
  547. printf("RLE Transform table (%v) error: %v", tableIndex(i), err)
  548. return err
  549. }
  550. seq.fse.setRLE(symb)
  551. if debugDecoder {
  552. printf("RLE set to 0x%x, code: %v", symb, v)
  553. }
  554. case compModeFSE:
  555. println("Reading table for", tableIndex(i))
  556. if seq.fse == nil || seq.fse.preDefined {
  557. seq.fse = fseDecoderPool.Get().(*fseDecoder)
  558. }
  559. err := seq.fse.readNCount(&br, uint16(maxTableSymbol[i]))
  560. if err != nil {
  561. println("Read table error:", err)
  562. return err
  563. }
  564. err = seq.fse.transform(symbolTableX[i])
  565. if err != nil {
  566. println("Transform table error:", err)
  567. return err
  568. }
  569. if debugDecoder {
  570. println("Read table ok", "symbolLen:", seq.fse.symbolLen)
  571. }
  572. case compModeRepeat:
  573. seq.repeat = true
  574. }
  575. if br.overread() {
  576. return io.ErrUnexpectedEOF
  577. }
  578. }
  579. in = br.unread()
  580. }
  581. if debugDecoder {
  582. println("Literals:", len(seqs.literals), "hash:", xxhash.Sum64(seqs.literals), "and", seqs.nSeqs, "sequences.")
  583. }
  584. if nSeqs == 0 {
  585. if len(b.sequence) > 0 {
  586. b.sequence = b.sequence[:0]
  587. }
  588. return nil
  589. }
  590. br := seqs.br
  591. if br == nil {
  592. br = &bitReader{}
  593. }
  594. if err := br.init(in); err != nil {
  595. return err
  596. }
  597. if err := seqs.initialize(br, hist, b.dst); err != nil {
  598. println("initializing sequences:", err)
  599. return err
  600. }
  601. // Extract blocks...
  602. if false && hist.dict == nil {
  603. fatalErr := func(err error) {
  604. if err != nil {
  605. panic(err)
  606. }
  607. }
  608. fn := fmt.Sprintf("n-%d-lits-%d-prev-%d-%d-%d-win-%d.blk", hist.decoders.nSeqs, len(hist.decoders.literals), hist.recentOffsets[0], hist.recentOffsets[1], hist.recentOffsets[2], hist.windowSize)
  609. var buf bytes.Buffer
  610. fatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.litLengths.fse))
  611. fatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.matchLengths.fse))
  612. fatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.offsets.fse))
  613. buf.Write(in)
  614. os.WriteFile(filepath.Join("testdata", "seqs", fn), buf.Bytes(), os.ModePerm)
  615. }
  616. return nil
  617. }
  618. func (b *blockDec) decodeSequences(hist *history) error {
  619. if cap(b.sequence) < hist.decoders.nSeqs {
  620. if b.lowMem {
  621. b.sequence = make([]seqVals, 0, hist.decoders.nSeqs)
  622. } else {
  623. b.sequence = make([]seqVals, 0, 0x7F00+0xffff)
  624. }
  625. }
  626. b.sequence = b.sequence[:hist.decoders.nSeqs]
  627. if hist.decoders.nSeqs == 0 {
  628. hist.decoders.seqSize = len(hist.decoders.literals)
  629. return nil
  630. }
  631. hist.decoders.windowSize = hist.windowSize
  632. hist.decoders.prevOffset = hist.recentOffsets
  633. err := hist.decoders.decode(b.sequence)
  634. hist.recentOffsets = hist.decoders.prevOffset
  635. return err
  636. }
  637. func (b *blockDec) executeSequences(hist *history) error {
  638. hbytes := hist.b
  639. if len(hbytes) > hist.windowSize {
  640. hbytes = hbytes[len(hbytes)-hist.windowSize:]
  641. // We do not need history anymore.
  642. if hist.dict != nil {
  643. hist.dict.content = nil
  644. }
  645. }
  646. hist.decoders.windowSize = hist.windowSize
  647. hist.decoders.out = b.dst[:0]
  648. err := hist.decoders.execute(b.sequence, hbytes)
  649. if err != nil {
  650. return err
  651. }
  652. return b.updateHistory(hist)
  653. }
  654. func (b *blockDec) updateHistory(hist *history) error {
  655. if len(b.data) > maxCompressedBlockSize {
  656. return fmt.Errorf("compressed block size too large (%d)", len(b.data))
  657. }
  658. // Set output and release references.
  659. b.dst = hist.decoders.out
  660. hist.recentOffsets = hist.decoders.prevOffset
  661. if b.Last {
  662. // if last block we don't care about history.
  663. println("Last block, no history returned")
  664. hist.b = hist.b[:0]
  665. return nil
  666. } else {
  667. hist.append(b.dst)
  668. if debugDecoder {
  669. println("Finished block with ", len(b.sequence), "sequences. Added", len(b.dst), "to history, now length", len(hist.b))
  670. }
  671. }
  672. hist.decoders.out, hist.decoders.literals = nil, nil
  673. return nil
  674. }