blockdec.go 19 KB

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