您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

296 行
7.4 KiB

  1. //go:build !amd64 || appengine || !gc || noasm
  2. // +build !amd64 appengine !gc noasm
  3. // This file contains a generic implementation of Decoder.Decompress4X.
  4. package huff0
  5. import (
  6. "errors"
  7. "fmt"
  8. )
  9. // Decompress4X will decompress a 4X encoded stream.
  10. // The length of the supplied input must match the end of a block exactly.
  11. // The *capacity* of the dst slice must match the destination size of
  12. // the uncompressed data exactly.
  13. func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) {
  14. if len(d.dt.single) == 0 {
  15. return nil, errors.New("no table loaded")
  16. }
  17. if len(src) < 6+(4*1) {
  18. return nil, errors.New("input too small")
  19. }
  20. if use8BitTables && d.actualTableLog <= 8 {
  21. return d.decompress4X8bit(dst, src)
  22. }
  23. var br [4]bitReaderShifted
  24. // Decode "jump table"
  25. start := 6
  26. for i := 0; i < 3; i++ {
  27. length := int(src[i*2]) | (int(src[i*2+1]) << 8)
  28. if start+length >= len(src) {
  29. return nil, errors.New("truncated input (or invalid offset)")
  30. }
  31. err := br[i].init(src[start : start+length])
  32. if err != nil {
  33. return nil, err
  34. }
  35. start += length
  36. }
  37. err := br[3].init(src[start:])
  38. if err != nil {
  39. return nil, err
  40. }
  41. // destination, offset to match first output
  42. dstSize := cap(dst)
  43. dst = dst[:dstSize]
  44. out := dst
  45. dstEvery := (dstSize + 3) / 4
  46. const tlSize = 1 << tableLogMax
  47. const tlMask = tlSize - 1
  48. single := d.dt.single[:tlSize]
  49. // Use temp table to avoid bound checks/append penalty.
  50. buf := d.buffer()
  51. var off uint8
  52. var decoded int
  53. // Decode 2 values from each decoder/loop.
  54. const bufoff = 256
  55. for {
  56. if br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4 {
  57. break
  58. }
  59. {
  60. const stream = 0
  61. const stream2 = 1
  62. br[stream].fillFast()
  63. br[stream2].fillFast()
  64. val := br[stream].peekBitsFast(d.actualTableLog)
  65. val2 := br[stream2].peekBitsFast(d.actualTableLog)
  66. v := single[val&tlMask]
  67. v2 := single[val2&tlMask]
  68. br[stream].advance(uint8(v.entry))
  69. br[stream2].advance(uint8(v2.entry))
  70. buf[stream][off] = uint8(v.entry >> 8)
  71. buf[stream2][off] = uint8(v2.entry >> 8)
  72. val = br[stream].peekBitsFast(d.actualTableLog)
  73. val2 = br[stream2].peekBitsFast(d.actualTableLog)
  74. v = single[val&tlMask]
  75. v2 = single[val2&tlMask]
  76. br[stream].advance(uint8(v.entry))
  77. br[stream2].advance(uint8(v2.entry))
  78. buf[stream][off+1] = uint8(v.entry >> 8)
  79. buf[stream2][off+1] = uint8(v2.entry >> 8)
  80. }
  81. {
  82. const stream = 2
  83. const stream2 = 3
  84. br[stream].fillFast()
  85. br[stream2].fillFast()
  86. val := br[stream].peekBitsFast(d.actualTableLog)
  87. val2 := br[stream2].peekBitsFast(d.actualTableLog)
  88. v := single[val&tlMask]
  89. v2 := single[val2&tlMask]
  90. br[stream].advance(uint8(v.entry))
  91. br[stream2].advance(uint8(v2.entry))
  92. buf[stream][off] = uint8(v.entry >> 8)
  93. buf[stream2][off] = uint8(v2.entry >> 8)
  94. val = br[stream].peekBitsFast(d.actualTableLog)
  95. val2 = br[stream2].peekBitsFast(d.actualTableLog)
  96. v = single[val&tlMask]
  97. v2 = single[val2&tlMask]
  98. br[stream].advance(uint8(v.entry))
  99. br[stream2].advance(uint8(v2.entry))
  100. buf[stream][off+1] = uint8(v.entry >> 8)
  101. buf[stream2][off+1] = uint8(v2.entry >> 8)
  102. }
  103. off += 2
  104. if off == 0 {
  105. if bufoff > dstEvery {
  106. d.bufs.Put(buf)
  107. return nil, errors.New("corruption detected: stream overrun 1")
  108. }
  109. copy(out, buf[0][:])
  110. copy(out[dstEvery:], buf[1][:])
  111. copy(out[dstEvery*2:], buf[2][:])
  112. copy(out[dstEvery*3:], buf[3][:])
  113. out = out[bufoff:]
  114. decoded += bufoff * 4
  115. // There must at least be 3 buffers left.
  116. if len(out) < dstEvery*3 {
  117. d.bufs.Put(buf)
  118. return nil, errors.New("corruption detected: stream overrun 2")
  119. }
  120. }
  121. }
  122. if off > 0 {
  123. ioff := int(off)
  124. if len(out) < dstEvery*3+ioff {
  125. d.bufs.Put(buf)
  126. return nil, errors.New("corruption detected: stream overrun 3")
  127. }
  128. copy(out, buf[0][:off])
  129. copy(out[dstEvery:], buf[1][:off])
  130. copy(out[dstEvery*2:], buf[2][:off])
  131. copy(out[dstEvery*3:], buf[3][:off])
  132. decoded += int(off) * 4
  133. out = out[off:]
  134. }
  135. // Decode remaining.
  136. remainBytes := dstEvery - (decoded / 4)
  137. for i := range br {
  138. offset := dstEvery * i
  139. endsAt := offset + remainBytes
  140. if endsAt > len(out) {
  141. endsAt = len(out)
  142. }
  143. br := &br[i]
  144. bitsLeft := br.remaining()
  145. for bitsLeft > 0 {
  146. br.fill()
  147. if offset >= endsAt {
  148. d.bufs.Put(buf)
  149. return nil, errors.New("corruption detected: stream overrun 4")
  150. }
  151. // Read value and increment offset.
  152. val := br.peekBitsFast(d.actualTableLog)
  153. v := single[val&tlMask].entry
  154. nBits := uint8(v)
  155. br.advance(nBits)
  156. bitsLeft -= uint(nBits)
  157. out[offset] = uint8(v >> 8)
  158. offset++
  159. }
  160. if offset != endsAt {
  161. d.bufs.Put(buf)
  162. return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt)
  163. }
  164. decoded += offset - dstEvery*i
  165. err = br.close()
  166. if err != nil {
  167. return nil, err
  168. }
  169. }
  170. d.bufs.Put(buf)
  171. if dstSize != decoded {
  172. return nil, errors.New("corruption detected: short output block")
  173. }
  174. return dst, nil
  175. }
  176. // Decompress1X will decompress a 1X encoded stream.
  177. // The cap of the output buffer will be the maximum decompressed size.
  178. // The length of the supplied input must match the end of a block exactly.
  179. func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) {
  180. if len(d.dt.single) == 0 {
  181. return nil, errors.New("no table loaded")
  182. }
  183. if use8BitTables && d.actualTableLog <= 8 {
  184. return d.decompress1X8Bit(dst, src)
  185. }
  186. var br bitReaderShifted
  187. err := br.init(src)
  188. if err != nil {
  189. return dst, err
  190. }
  191. maxDecodedSize := cap(dst)
  192. dst = dst[:0]
  193. // Avoid bounds check by always having full sized table.
  194. const tlSize = 1 << tableLogMax
  195. const tlMask = tlSize - 1
  196. dt := d.dt.single[:tlSize]
  197. // Use temp table to avoid bound checks/append penalty.
  198. bufs := d.buffer()
  199. buf := &bufs[0]
  200. var off uint8
  201. for br.off >= 8 {
  202. br.fillFast()
  203. v := dt[br.peekBitsFast(d.actualTableLog)&tlMask]
  204. br.advance(uint8(v.entry))
  205. buf[off+0] = uint8(v.entry >> 8)
  206. v = dt[br.peekBitsFast(d.actualTableLog)&tlMask]
  207. br.advance(uint8(v.entry))
  208. buf[off+1] = uint8(v.entry >> 8)
  209. // Refill
  210. br.fillFast()
  211. v = dt[br.peekBitsFast(d.actualTableLog)&tlMask]
  212. br.advance(uint8(v.entry))
  213. buf[off+2] = uint8(v.entry >> 8)
  214. v = dt[br.peekBitsFast(d.actualTableLog)&tlMask]
  215. br.advance(uint8(v.entry))
  216. buf[off+3] = uint8(v.entry >> 8)
  217. off += 4
  218. if off == 0 {
  219. if len(dst)+256 > maxDecodedSize {
  220. br.close()
  221. d.bufs.Put(bufs)
  222. return nil, ErrMaxDecodedSizeExceeded
  223. }
  224. dst = append(dst, buf[:]...)
  225. }
  226. }
  227. if len(dst)+int(off) > maxDecodedSize {
  228. d.bufs.Put(bufs)
  229. br.close()
  230. return nil, ErrMaxDecodedSizeExceeded
  231. }
  232. dst = append(dst, buf[:off]...)
  233. // br < 8, so uint8 is fine
  234. bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead
  235. for bitsLeft > 0 {
  236. br.fill()
  237. if false && br.bitsRead >= 32 {
  238. if br.off >= 4 {
  239. v := br.in[br.off-4:]
  240. v = v[:4]
  241. low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
  242. br.value = (br.value << 32) | uint64(low)
  243. br.bitsRead -= 32
  244. br.off -= 4
  245. } else {
  246. for br.off > 0 {
  247. br.value = (br.value << 8) | uint64(br.in[br.off-1])
  248. br.bitsRead -= 8
  249. br.off--
  250. }
  251. }
  252. }
  253. if len(dst) >= maxDecodedSize {
  254. d.bufs.Put(bufs)
  255. br.close()
  256. return nil, ErrMaxDecodedSizeExceeded
  257. }
  258. v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask]
  259. nBits := uint8(v.entry)
  260. br.advance(nBits)
  261. bitsLeft -= nBits
  262. dst = append(dst, uint8(v.entry>>8))
  263. }
  264. d.bufs.Put(bufs)
  265. return dst, br.close()
  266. }